[英]What's the most efficient way to fill a longitude / latitude map with circular points of specified radius?
因此,我试图绕过某些公司API的限制,这些API提供有关景点的数据。 API不允许我收集整个状态的结果。 相反,我必须指定纬度/经度坐标,并以1到50000m的圆形半径收集附近的位置。 该API一次一次仅返回60个结果,无论指定位置中有多少个结果。 我知道我会在指定位置遇到60多个地方,但是我打算递归地将这些情况一分为二并进行处理。
我想将纽约州作为我的第一个测试用例。
我正在使用来自https://www.arcgis.com/home/item.html?id=b07a9393ecbd430795a6f6218443dccc的shapefile获取NY的形状,并确定我的点是否在边界内。
import geopandas as gpd
from shapely.geometry import Point, Polygon
usa = gpd.read_file('states_21basic/states.shp')
polygon = usa[usa.STATE_ABBR == 'NY']['geometry'].values[0]
point = Point(-74.005974,40.712776) # create point
print(polygon.contains(point)) # check if polygon contains point
有人建议我尝试使用泛洪填充算法,但是我不确定如何从中获取间隔坐标列表(以最小化API调用),以及如何确保每个部分都被覆盖,即使是像NY这样的怪异形状。
我的主要目标是收集所有位置,同时尽量减少API调用。 我并不是真的希望有任何代码,只是关于如何解决这个问题的想法。
**很遗憾,我已经从公司除名,无法将答案标记为已接受
您的问题可能有一个好的解决方案,而不是一个完美的解决方案。 我在地图上工作了很长时间,而且大多数地图本身都很复杂。 您还有另一种复杂性,这是您无法控制的外部依赖性。 我必须在较低级别执行类似的操作,以查询Google Maps以获得较小区域(不超过20米)的站点,以尝试将最接近的地理位置与我所在的地理位置相匹配。 首先,您需要做一个假设并尝试一下。 假设可能仅使用100米半径,或多或少覆盖一个街区。 您遇到的第二个问题是密度。 您可以在一段时间内探索零兴趣点的地图(纽约有很多空旷的地方,周围可能几乎没有任何东西)。
假设您可以将解决方案围成一个形状。 建议您从密集区域(曼哈顿?)中的预定义点开始,以在开始时最大化算法发现。 它运行时间越长,越接近检测到它将得到的更少。
泛洪填充算法在您的情况下是好的,但可能不是最好的。 例如,我可能会沿着街道走一些更复杂的东西,但是使用洪水填充的第一种方法会起作用。
“洪水填充”就像使用油漆,您朝一个方向行走; 在您的情况下,我建议使用8(N,S,W,E,NW,NE,SW,SE),检测是否已“绘制”(您需要将其存放在该位置的某个位置)为了避免重复调用,如果不重复调用API,Walking将打开一棵不同的执行树,从A点开始,递归地遍历N,S,E,W,NW,NE,SW,SE。像纽约这样的区域,该区域各有100米,将导致数千级递归,您需要对其进行优化。
要考虑的第三件事是检查点是否在多边形之外。 使用PNPoly非常简单。 一旦您位于多边形外,就必须停止在该方向上行走。
我与您分享为项目编码的C#中的PNPoly实现:
public bool IsCoordinateWithinPolygon(double latitude, double longitude, Polygon polygon)
{
if(polygon == null || polygon.Coordinates.Count() == 0)
{
return false;
}
List<double> coordinatesY = new List<double>();
List<double> coordinatesX = new List<double>();
var minLatitude = double.MaxValue;
var maxLatitude = double.MinValue;
var minLongitude = double.MaxValue;
var maxLongitude = double.MinValue;
// Quick-check, determine if the coordinate is outside of the bounding rectangle
foreach(var linearRing in polygon.Coordinates)
{
foreach (var coordinate in linearRing.Coordinates)
{
coordinatesY.Add(coordinate.Latitude);
coordinatesX.Add(coordinate.Longitude);
if (coordinate.Latitude < minLatitude)
{
minLatitude = coordinate.Latitude;
}
if(coordinate.Latitude > maxLatitude)
{
maxLatitude = coordinate.Latitude;
}
if(coordinate.Longitude < minLongitude)
{
minLongitude = coordinate.Longitude;
}
if(coordinate.Longitude > maxLongitude)
{
maxLongitude = coordinate.Longitude;
}
}
}
// Determine if the coordinate is outside the bounding box
if( (latitude < minLatitude || latitude > maxLatitude) &&
(longitude < minLongitude || longitude < maxLongitude))
{
// Out of the box
return false;
}
// PNPoly Algorithm - Point Inclusion in Polygon Test
bool inclusion = false;
var verty = coordinatesY.ToArray();
var vertx = coordinatesX.ToArray();
var nvert = vertx.Length;
var testy = latitude;
var testx = longitude;
for (int i = 0, j = nvert - 1; i < nvert; j = i++)
{
if (((verty[i] > testy) != (verty[j] > testy)) &&
(testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i]))
inclusion = !inclusion;
}
return inclusion;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.