转换 GPS 坐标以匹配自定义 2d 室外布局图像
Convert GPS Coordinates to Match Custom 2d outdoor layout Image
我不知道这是否可行,但我正在尝试拍摄自定义室外足球场布局的图像,并让球员的 GPS
坐标与图像 x
相对应和 y
位置。这样,它可以通过应用程序查看,以显示球员在场上的当前位置,作为一种实时跟踪。
我也调查过这个 Convert GPS coordinates to coordinate plane。问题是我不知道这是否行得通,想事先确认一下。 post 中提供的图像是用于室内位置的,是 11
年前的图像。
我使用了 Location
和 Google Maps
包来实现 flutter。玩家的latitude
和longitude
对应android工作室模拟器测试时显示的实际latitude
和longitude
。
有问题的布局以及与我正在寻找的结果的密切比较。
如有任何帮助,我们将不胜感激,在此先感谢您提供的所有帮助。
编辑:
在进一步了解此事后,我尝试了这个 post GPS Conversion - pixel coords to GPS coords 的答案,但它没有按预期工作。我在图像上取了一些点和相应的坐标,并遵循与答案相同的逻辑,但将其反转给我实际图像 X
、Y
positions.
上面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(不需要与真实字段的纵横比完全相同)。
步骤:
- 通过相应地标记角 (A、B、C、D) 来决定如何将实际场的方向映射到显示器。
- 对于每个玩家,画一条线到角 A 和角 B 形成一个三角形
- 使用勾股定理,使用点 A、B 和 P 的 gps 坐标计算三角形每条边 (a,b,p) 的长度。
- 利用余弦定律,计算角A的角度
- 利用[cos = adj/hyp]的规律,得到玩家相对于角A的坐标位置(W,H)
将这些 W 和 H 值转换为实际字段宽度和高度的百分比 -- 一个介于 0 和 1 之间的数字。
使用第 7 步中的数字,绘制球员在场地 2 上的位置。
我不知道这是否可行,但我正在尝试拍摄自定义室外足球场布局的图像,并让球员的 GPS
坐标与图像 x
相对应和 y
位置。这样,它可以通过应用程序查看,以显示球员在场上的当前位置,作为一种实时跟踪。
我也调查过这个 Convert GPS coordinates to coordinate plane。问题是我不知道这是否行得通,想事先确认一下。 post 中提供的图像是用于室内位置的,是 11
年前的图像。
我使用了 Location
和 Google Maps
包来实现 flutter。玩家的latitude
和longitude
对应android工作室模拟器测试时显示的实际latitude
和longitude
。
有问题的布局以及与我正在寻找的结果的密切比较。
如有任何帮助,我们将不胜感激,在此先感谢您提供的所有帮助。
编辑:
在进一步了解此事后,我尝试了这个 post GPS Conversion - pixel coords to GPS coords 的答案,但它没有按预期工作。我在图像上取了一些点和相应的坐标,并遵循与答案相同的逻辑,但将其反转给我实际图像 X
、Y
positions.
上面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(不需要与真实字段的纵横比完全相同)。
步骤:
- 通过相应地标记角 (A、B、C、D) 来决定如何将实际场的方向映射到显示器。
- 对于每个玩家,画一条线到角 A 和角 B 形成一个三角形
- 使用勾股定理,使用点 A、B 和 P 的 gps 坐标计算三角形每条边 (a,b,p) 的长度。
- 利用余弦定律,计算角A的角度
- 利用[cos = adj/hyp]的规律,得到玩家相对于角A的坐标位置(W,H)
将这些 W 和 H 值转换为实际字段宽度和高度的百分比 -- 一个介于 0 和 1 之间的数字。
使用第 7 步中的数字,绘制球员在场地 2 上的位置。