转换 GPS 坐标以匹配自定义 2d 室外布局图像

Convert GPS Coordinates to Match Custom 2d outdoor layout Image

我不知道这是否可行,但我正在尝试拍摄自定义室外足球场布局的图像,并让球员的 GPS 坐标与图像 x 相对应和 y 位置。这样,它可以通过应用程序查看,以显示球员在场上的当前位置,作为一种实时跟踪。

我也调查过这个 Convert GPS coordinates to coordinate plane。问题是我不知道这是否行得通,想事先确认一下。 post 中提供的图像是用于室内位置的,是 11 年前的图像。

我使用了 LocationGoogle Maps 包来实现 flutter。玩家的latitudelongitude对应android工作室模拟器测试时显示的实际latitudelongitude

有问题的布局以及与我正在寻找的结果的密切比较。

如有任何帮助,我们将不胜感激,在此先感谢您提供的所有帮助。

编辑:

在进一步了解此事后,我尝试了这个 post GPS Conversion - pixel coords to GPS coords 的答案,但它没有按预期工作。我在图像上取了一些点和相应的坐标,并遵循与答案相同的逻辑,但将其反转给我实际图像 XYpositions.

上面post给出的公式:

screenY0 //Screen origin (pixel corresponding to zero degrees latitude)
worldY0 //World origin (zero degrees latitude)
screenYscale //Screen scale (distance between 2 pixels)
worldYscale //World scale (distance between two latitude lines)
screenYpoint //Screen point (pixel y location)
worldYpoint //World point (latitude on the ground)   

screenY0 + screenYscale * screenYpoint = worldY0 + worldYscale * worldYpoint.

post 说 7.4 米会有一些不准确。提供的解决方案仅适用于靠近所选点的点或区域。当一名球员移动得更多时,该球员的标记将跳出图像区域或离得很远。

编辑2:

我尝试了这个 post Convert GPS coordinates to coordinate plane 的解决方案,使用以下公式来计算 X 位置:

delta_long 是田地角落 GPS 中的度数差异。 delta_x是图片的宽度。

horizontal_scale = delta_x/(cos(latitude)*delta_long) 然后 x = ( lon - lon_origin ) * horizontal_scale我现在面临的问题是标记像这样在相反的 x 轴上移动,黑色箭头是实际玩家移动的方式,红色箭头显示玩家如何在应用内移动。

首先,是的如果 GPS 坐标准确,您可以高精度地执行此操作。

其次,主要问题是旋转,如果场地是直的,带有 lat lng 线,这将很容易和直接(没有 bun 意图)。

最简单的方法是将坐标转换为类似于真实场的旋转图像,然后将每个 X、Y 点旋转到新的直线图像。 (见下图)

下面是如何旋转 x,y 知道天使:

double x,y;
double newX,newY;
double angle;

//Test values:
x=1;
y=1;
angle = 45;

double rad = angle*M_PI/180;

newX = x * cos(rad) - y * sin(rad);
newY = y * cos(rad) + x * sin(rad);

更新

long double lat1,lat2,lng1,lng2; //fill these with GPS coordinates
double x1,x2,y1,y2;//fill these of rectangle coordinate in the image

long double realWidth = distance(lat1, long1,lat2,long1);// distance btween the upper left corner & the upper right corner
long double realHieght = distance(lat1, long1,lat1,long2);// distance btween the upper left corner & the lower left corner

double image1Width = abs(x2-x1);
double image1Hieght = abs(y2-y1);

long double playerLat,playerLng;//fill the player lat lng GPS coordiantes 

POINT imagePlayerXY = convertGPS2xy(lat1,  lng1, playerLat,  playerLng, realWidth, realHieght, image1Width, image1Hieght);
//NOW rotate imagePlayerXY.x & imagePlayerXY.y to the final image
POINT convertGPS2xy(long double latOrigin, long double lngOrigin,long double playerLat, long double playerLng,long double realWidth,long double realHieght, double image1Width,double image1Hieght)
{
    double lngRatio2Width = distance(playerLat,playerLng, playerLat,lngOrigin ) / realWidth; //horizantal distance from the player place to rectangle origin (then compute the width ratio)
    double lngRatio2Hieght = distance(playerLat,playerLng, latOrigin,playerLng ) / realHieght; //virtical distance from the player place to rectangle origin (then compute the Hieght ratio)

    POINT imageXY;
    imageXY.x = image1Width * lngRatio2Width;
    imageXY.y = image1Hieght * lngRatio2Hieght;

    return imageXY;
}


long double distance(long double lat1, long double long1,
                     long double lat2, long double long2)
{
    // Convert the latitudes
    // and longitudes
    // from degree to radians.
    lat1 = toRadians(lat1);
    long1 = toRadians(long1);
    lat2 = toRadians(lat2);
    long2 = toRadians(long2);
     
    // Haversine Formula
    long double dlong = long2 - long1;
    long double dlat = lat2 - lat1;
 
    long double ans = pow(sin(dlat / 2), 2) +
                          cos(lat1) * cos(lat2) *
                          pow(sin(dlong / 2), 2);
 
    ans = 2 * asin(sqrt(ans));
 
    // Radius of Earth in
    // Kilometers, R = 6371
    // Use R = 3956 for miles
    long double R = 6371;
     
    // Calculate the result
    ans = ans * R;
 
    return ans;
}

是的,link 中的答案将有效,但前提是场地中的球门post 正好指向南北方向。他们在两个 links 中所做的基本上是缩小 GPS 坐标以适合您的屏幕,因此只有当目标 posts 像图像一样指向东西方向时才缩小比例附加缩放将起作用。

但在实际数据中,场地可以位于任何角度,可能一个目标post是NE,另一个是SW。所以为了解决这个问题也使用@Jabbar 的答案。

赏金任务已完成,但还没有描述您尝试执行的通用算法。

这种方法消除了必须校正实场方向的问题,也消除了校正实场和像素化显示器之间纵横比差异的问题。

我们将问题分为两个主要部分:

字段 1:玩家位置将被视为矢量的真实世界字段(使用字段角进行三角测量)

字段 2:您碰巧用作最终显示的像素化 canvas(不需要与真实字段的纵横比完全相同)。

步骤:

  1. 通过相应地标记角 (A、B、C、D) 来决定如何将实际场的方向映射到显示器。

  1. 对于每个玩家,画一条线到角 A 和角 B 形成一个三角形

  1. 使用勾股定理,使用点 A、B 和 P 的 gps 坐标计算三角形每条边 (a,b,p) 的长度。

  1. 利用余弦定律,计算角A的角度

  1. 利用[cos = adj/hyp]的规律,得到玩家相对于角A的坐标位置(W,H)

  1. 将这些 W 和 H 值转换为实际字段宽度和高度的百分比 -- 一个介于 0 和 1 之间的数字。

  2. 使用第 7 步中的数字,绘制球员在场地 2 上的位置。