GPS 精度圆(以米为单位)与地图上的一条线相交
GPS accuracy circle (in meters) intersects a line on map
我正在画一个反映我当前位置的点。我在地图上也有一些形状。但是,由于 GPS 精度不断变化,我需要证明我已经越过地图上的线,即使 LatLng 点仍在它之前,但精度为 ~20(m)。
我有的:
- 线的起点和终点
- 圆心
- 圆的半径(以米为单位)
我能够计算线和圆的中心点之间的距离,但这给了我这样的值:0.00987506668990474 这真的没有给我任何东西,因为这个值不反映以米为单位的距离,我无法真正转换以米为单位并与精度半径进行比较。
我什至不确定我是否是获取该信息的正确目标。如果有交叉路口,也许还有另一种方法来获取信息。
感谢任何提示
更新:
使用距离 * 110km 我得到了更好的结果。
快乐脸 = 未检测到交叉点 - 距离 < 半径,悲伤脸 = 检测到交叉点 - 距离 > 半径。
黄色区域边缘为矿区线段。如您所见,当交点位于顶部(/底部)而不是左侧(/右侧)时,它会起作用。
那是我的计算算法计算从线段到点的距离。原谅乱七八糟的……我还在为此苦苦挣扎,所以它还没有优化:
public static double pointLineSegmentDistance(final List<Double> point, final List<List<Double>> line)
{
List<Double> v = line.get(0);
List<Double> w = line.get(1);
double d = pointPointSquaredDistance(v, w);
double t;
List<Double> calculateThis;
if (d > 0)
{
boolean test = (t = ((point.get(0) - v.get(0)) * (w.get(0) - v.get(0)) + (point.get(1) - v.get(1)) * (w.get(1) - v.get(1))) / d) < 0;
if (test)
{
calculateThis = v;
}
else
{
if (t > 1)
{
calculateThis = w;
}
else
{
calculateThis = new ArrayList<Double>();
calculateThis.add(v.get(0) + t * (w.get(0) - v.get(0)));
calculateThis.add(v.get(1) + t * (w.get(1) - v.get(1)));
}
}
}
else
{
calculateThis = v;
}
return Math.sqrt(pointPointSquaredDistance(point, calculateThis));
}
public static double pointPointSquaredDistance(final List<Double> v, final List<Double> w)
{
double dx = v.get(0) - w.get(0);
double dy = v.get(1) - w.get(1);
return dx * dx + dy * dy;
}
final 列表点 - 包含 2 个元素 - (0) 纬度 (1) 经度
List> line - 包含2个列表 - (0) 线段起点 (0/0)lat/(0/1)long (1) 线段终点 (1/0)lat/(1/1)long
你有两种可能:
1) 便宜的方式:
您使用 android api (distanceBetween()) 计算线 start/end 点和圆心之间的距离。结果将以米为单位,并通过点对点距离计算进行校正。取起点/终点到中心圆距离的最小值。
如果线段相对于圆的半径很长,直线到中心的正常距离,使用这种计算是错误的
2) 更好的方法,但更复杂:
您将线的起点和终点以及圆心转换为单位 = 米的笛卡尔 x,y space 并计算到线的距离
段使用笛卡尔数学。 (看距离到线段计算)
首先检查选项1,因为它只是一行代码。
你的结果 0.00987506668990474 这看起来像是以度而不是米为单位的距离。将它乘以 111km 得到大约 1km 的值。 (在赤道)
终于解决了我的问题。它的解决方案真的很简单。比我想象的要简单得多。这里有 maputil 库:
https://github.com/googlemaps/android-maps-utils
该库提供了一个名为 "isLocationOnPath" 的函数:
boolean isLocationOnPath(LatLng point, List<LatLng> polyline, boolean geodesic, double tolerance)
点 - 是一个中心或我的点。
Polyline - 我需要的是多边形的边缘,
测地线 - 真(当然)
公差 -(以米为单位)是我从 GPS 精度中获取的精度 - 基本上是一个圆半径。
希望对您有所帮助。
我正在画一个反映我当前位置的点。我在地图上也有一些形状。但是,由于 GPS 精度不断变化,我需要证明我已经越过地图上的线,即使 LatLng 点仍在它之前,但精度为 ~20(m)。 我有的: - 线的起点和终点 - 圆心 - 圆的半径(以米为单位)
我能够计算线和圆的中心点之间的距离,但这给了我这样的值:0.00987506668990474 这真的没有给我任何东西,因为这个值不反映以米为单位的距离,我无法真正转换以米为单位并与精度半径进行比较。 我什至不确定我是否是获取该信息的正确目标。如果有交叉路口,也许还有另一种方法来获取信息。
感谢任何提示
更新:
使用距离 * 110km 我得到了更好的结果。
public static double pointLineSegmentDistance(final List<Double> point, final List<List<Double>> line)
{
List<Double> v = line.get(0);
List<Double> w = line.get(1);
double d = pointPointSquaredDistance(v, w);
double t;
List<Double> calculateThis;
if (d > 0)
{
boolean test = (t = ((point.get(0) - v.get(0)) * (w.get(0) - v.get(0)) + (point.get(1) - v.get(1)) * (w.get(1) - v.get(1))) / d) < 0;
if (test)
{
calculateThis = v;
}
else
{
if (t > 1)
{
calculateThis = w;
}
else
{
calculateThis = new ArrayList<Double>();
calculateThis.add(v.get(0) + t * (w.get(0) - v.get(0)));
calculateThis.add(v.get(1) + t * (w.get(1) - v.get(1)));
}
}
}
else
{
calculateThis = v;
}
return Math.sqrt(pointPointSquaredDistance(point, calculateThis));
}
public static double pointPointSquaredDistance(final List<Double> v, final List<Double> w)
{
double dx = v.get(0) - w.get(0);
double dy = v.get(1) - w.get(1);
return dx * dx + dy * dy;
}
final 列表点 - 包含 2 个元素 - (0) 纬度 (1) 经度 List> line - 包含2个列表 - (0) 线段起点 (0/0)lat/(0/1)long (1) 线段终点 (1/0)lat/(1/1)long
你有两种可能:
1) 便宜的方式:
您使用 android api (distanceBetween()) 计算线 start/end 点和圆心之间的距离。结果将以米为单位,并通过点对点距离计算进行校正。取起点/终点到中心圆距离的最小值。 如果线段相对于圆的半径很长,直线到中心的正常距离,使用这种计算是错误的
2) 更好的方法,但更复杂:
您将线的起点和终点以及圆心转换为单位 = 米的笛卡尔 x,y space 并计算到线的距离
段使用笛卡尔数学。 (看距离到线段计算)
首先检查选项1,因为它只是一行代码。
你的结果 0.00987506668990474 这看起来像是以度而不是米为单位的距离。将它乘以 111km 得到大约 1km 的值。 (在赤道)
终于解决了我的问题。它的解决方案真的很简单。比我想象的要简单得多。这里有 maputil 库: https://github.com/googlemaps/android-maps-utils
该库提供了一个名为 "isLocationOnPath" 的函数:
boolean isLocationOnPath(LatLng point, List<LatLng> polyline, boolean geodesic, double tolerance)
点 - 是一个中心或我的点。 Polyline - 我需要的是多边形的边缘, 测地线 - 真(当然) 公差 -(以米为单位)是我从 GPS 精度中获取的精度 - 基本上是一个圆半径。
希望对您有所帮助。