我从未对基于位置的数据做过多处理,因此对于整个GPS编码相关的问题非常新。我有一个问题,我似乎没有找到一种非常有效的方法来解决它,或者可能有一种我不太确定的算法。
假设您已经给出了4个纬度/经度坐标,这些坐标构成了某种矩形区域:(X0, Y0), (X1, Y0), (X0, Y1), (X1, Y1)
-----------------------------------
| b |
| a |
| | d
| |
| c |
-----------------------------------
e
有没有办法找到给定矩形区域内的所有点:a, b, c
以及该地区以外的所有景点? e, d
我可以很容易地构建一个2D矩阵来做到这一点,但是只有坐标是整数,但是对于纬度/长度对,坐标通常是浮点数,我们不能用它来构造一张2D桌子。
有什么好主意吗?
已编辑1:
这个Ray-casting算法怎么样?这是一个很好的算法用于GPS坐标,这是一个浮点数吗?
答案 0 :(得分:1)
如果你的矩形是轴对齐的,@ Eyal的答案是正确的(你实际上不需要8个值,但是4个就足够了)。
如果处理旋转的矩形(适用于任何四边形),光线投射方法是合适的:考虑通过测试点的水平线Y = Yt并找到穿过它的边缘(上面的一个端点,一个终点如下)。将有0或2个这样的边缘。在案例0中,你在外面。否则,计算这些边缘与线的交点的横坐标。如果测试点左侧有0或2个交点,则表示您在外面。
Xi= Xt + (Yt - Y0) (X1 - X0) / (Y1 - Y0)
答案 1 :(得分:0)
@ YvesDaoust和@ EyalSchneider的另一种解决方案是找到每个点的缠绕数或交叉数(http://geomalgorithms.com/a03-_inclusion.html)。此解决方案可扩展为任意数量顶点的多边形(无论轴对齐)。
交叉号码(cn)方法 - 计算从点P开始的光线穿过多边形边界边缘的次数。当这个“交叉数”是偶数时,这一点在外面;否则,当它是奇数时,该点在里面。这种方法有时被称为“奇偶”测试。
绕组编号(wn)方法 - 计算多边形围绕点P缠绕的次数。仅当此“缠绕数”wn = 0时,该点才在外面;否则,重点在于内部。
顺便说一句,@ YvesDaoust的解决方案有效地计算了该点的交叉数。
答案 2 :(得分:0)
矩形内有无限数量的点,因此您必须定义一个 一步(两点之间的疏远)。
你可以用两个嵌套循环迭代,
lat,lon坐标可以使用乘法因子:
乘以1E7(10000000)以获得最大1cm的精确度,或
10000000:1cm
1000000:10cm
100000:1m
10000:10m
1000:100m
100:1km
10:11km
1:111km
现在迭代
// convert to spherical integer rectangle
double toIntFact = 1E7;
int x = (int) (x0 * toIntFact);
int y = (int) (y0 * toIntFact);
int tx1 = x1 * toIntFact;
int ty1 = y1 * toIntFact;
int yStep = 100000; // about 1.11 m latitudinal span. choose desired step above in list
int xStep = (int) (yStep / cos(Math.toRadians(y0))); // longitude adaption factor depending of cos(latitude); more acurate (symetric) is to use cos of centerLatitude: (y0 + y1) / 2;
for (int px = x; px < tx1; px+= xStep) {
for (int py = y; py < ty1; py+= yStep) {
drawPoint(px, py); // or whatever
}
}
这应该给出一个点集,在点之间具有相同的距离,对于大约几公里宽的矩形。 重叠基准限制(-180到180跳)或。时,代码不起作用 当重叠两极时。提供高达80°N或S的可用结果。
此代码使用某种隐式等距(equirectangular)投影(参见cos(centerLat)除法来纠正1度纬度是以米为单位测量的另一个距离而不是一度经度的事实。
如果矩形的大小超过大约十或百公斤,那么根据您的要求,必须使用高级预测:例如,将lat,lon转换为WGS84转换为UTM。结果是以米为单位的坐标,然后你迭代模拟。
但你确定这是你想要的吗?
没人想要找到矩形内的所有原子。
可以是所有屏幕像素,也可以是方法isInsideRectangle(lat,lon, Rectangle);
所以再想想你需要什么。