这是一个高效且实施起来尽可能简单的解决方案。请注意,我说的不是简单,而是尽可能简单。事实证明,这是一个棘手的问题。
1) 使用 Shapefiles 或 KFL 获取美国多边形数据,这将产生一组多边形形状(地块),每个形状由顶点列表定义。
2)为美国创建一组轴对齐边界框(AABB)矩形:一个用于阿拉斯加和每个阿拉斯加岛,一个用于每个夏威夷岛,一个用于美国大陆,一个用于每个沿海小岛美国大陆(例如,北卡罗来纳州的秃头岛,加利福尼亚海岸附近的卡塔利娜)。每个边界框被定义为一个矩形,其角是形状的最小和最大纬度和经度。我的猜测是会有几百个这样的。比如夏威夷的大岛,纬度是18°55′N到28°27′N,经度是154°48′W到178°22′W。在此步骤中,您的大多数全局纬度/经度对都会被丢弃,因为它们不在这几百个边界框中的任何一个中。例如,您的边界框位于 10°20'W,30°40' N(位于非洲拉斯帕尔马斯附近的大西洋中的一个点)不与夏威夷重叠,因为 10°20'W 小于 154°48'W。这一点在 Python 中很容易编写。
3)如果纬度/经度对确实与数百个 AABB 矩形之一重叠,那么您需要针对AABB 矩形内的单个多边形对其进行测试。为此,强烈建议使用 Minkowski 差分 (MD)。请先彻底检查本网站:
http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/
特别是,请查看页面中间的“poly vs poly”演示,并试一试。当你这样做时,你会看到当你取两个形状的 MD 时,如果那个 MD 包含原点,那么这两个形状是重叠的。因此,您需要做的就是取 2 个多边形的 Minkowski 差,这本身会产生一个新的多边形(B - A,在演示中),然后查看该多边形是否包含原点。
4)网上有很多关于实现MD的算法的论文,但我不知道你是否有能力阅读论文并将其翻译成代码。由于采用两个多边形的 MD(您正在测试的纬度/经度矩形,以及与纬度/经度矩形重叠的边界框中包含的多边形)是一个棘手的向量数学,并且您已经告诉我们您的经验级别还不高,我建议使用已经实现了MD的库,或者更好的是,实现了碰撞检测。
例如:
http://physics2d.com/content/gjk-algorithm
在这里,您可以看到相关的伪代码,您可以将其移植到 Python 中:
if aO cross ac > 0 //if O is to the right of ac
if aO dot ac > 0 //if O is ahead of the point a on the line ac
simplex = [a, c]
d =-((ac.unit() dot aO) * ac + a)
else // O is behind a on the line ac
simplex = [a]
d = aO
else if ab cross aO > 0 //if O is to the left of ab
if ab dot aO > 0 //if O is ahead of the point a on the line ab
simplex = [a, b]
d =-((ab.unit() dot aO) * ab + a)
else // O is behind a on the line ab
simplex = [a]
d = aO
else // O if both to the right of ac and to the left of ab
return true //we intersect!
如果您自己无法移植,也许您可以联系我在此处包含的 2 个链接的作者中的任何一个——他们都在 Flash 中实现了 MD 算法,也许您可以许可源代码。
5) 最后,假设您已经处理了碰撞检测,您可以简单地在数据库中存储一个关于纬度/经度对是否属于美国的布尔值。完成后,我毫不怀疑您将能够使用您的 Google 地图作品随心所欲地进行操作。
因此,总而言之,这里唯一困难的部分是 1) 实现碰撞检测 GJK 算法,或者,2) 编写一个算法,首先计算纬度/经度对与包含在其中的陆地多边形之间的 Minkowski 差异您的 AABB,然后查看该 MD 多边形是否包含原点。如果您使用这种方法,Ray Casting(典型的多边形内点解决方案)将在第二部分中发挥作用。
我希望这能让你朝着正确的方向开始!