函数/脚本/库,用于在没有联机APIS的情况下检索基于Lat和Long的国家名称



我正在为下一个问题寻找一个库/脚本/函数或其他任何东西。我有一个从Gps(Android(检索纬度和经度的应用程序。对于Lat和Long,我想回到符合这两个价值观的国家。

我想要一个库,因为我不想使用任何GOOGLE API或其他ip-info详细信息,等等

到目前为止我尝试过的我有一个文件,其中包含所有具有最大边界点坐标的国家。下的示例

{
"country": "Argentina",
"north": -21.7813,
"south": -55.0613,
"west": -73.583,
"east": -53.5918
},
{
"country": "Falkland Islands",
"north": -51.2407,
"south": -52.3605,
"west": -61.3452,
"east": -57.7125
},

如果我给Lat=-51.55,Long=-60.00…输出是阿根廷,因为它是数组中的第一个条目。但正确的答案是福克兰群岛。

我试图减少实际的拉特(-51.55(-福克兰岛北部(-51.2407(,以达到0以下的数字。。。为…赚了很多钱。。。循环以获得最接近0的数字。在那之后,我试着查看Long and West

for (const property in Object.entries(CountryCoords)) {
if (CountryCoords[property]["south"] <= lat && lat <= CountryCoords[property]["north"]) {
var ln = (CountryCoords[property]["north"] - lat); // 0
if (ln < 5) {
if (CountryCoords[property]["west"] <= long && long <= CountryCoords[property]["east"]) {
var ol =  CountryCoords[property]["east"] - long;
if (ol < 5) {
// console.log(ln,ol, CountryCoords[property]["country"], ln, ol)
return CountryCoords[property]["country"];
}
}
}
}
}

但这是我陷入困境的地方,因为我不知道如何解决这个算法,我从昨天开始就尝试过,但我缺乏解决这个问题的大脑。。。

*想想一些值低于0,而另一些值则超过0。

感谢

您不需要库,您需要映射。最好是矢量图,因为简单的位图没有任何帮助。国家的边界框很好,但只足以过滤出不可能的结果(如果你在欧洲,就不需要测试阿根廷(。

你可以使用VMAP 0级地图(很容易找到整个世界的地图(,它被划分为4个大区域,用于整个世界。整个文件大约有400 MB,最好将其存储在数据库中,而不是直接使用shapefile。您可以通过删除不需要的数据(河流、森林、湖泊、城镇等(并只保留国家边界来节省大量空间。

一旦你完成了这项工作并为你的计划做好了准备,你就必须解决这个问题:"有数百个地理参考多边形和一个地理位置,我在哪个多边形中">完成后,您将获得国家名称作为多边形元数据的简单条目。您可以在20 MB以下轻松获得所需的数据。

也许在这一步你需要一个数学库,但如果没有嵌入的可用地图,你就会陷入困境。

注意:VMAP级别0(也称为"VMAP0"(没有良好的精度。当位置靠近边界时,您可能需要扩展多边形,并可能返回几个国家名称。例如,如果你在摩纳哥、利希滕斯坦或安道尔,可能很难返回有效的名字。。。对于像VMAP0这样粗糙的地图来说,太小了。

对于这些多边形扩展,可能需要一个地图库。另一个解决方案是不断将你的位置扩展到一个圆圈(半径至少1秒(,在周长+中心(N、NE、E、SE、S、SW、W、NW、center(上获得8个点,然后查看返回的名称。运行时比多边形扩展更占用CPU(这可以/应该离线完成,并且应该将扩展的多边形直接存储在数据库中(,但它可以避免您获得一个像样的地图库并学习如何使用它。

不要忘记:地图处理是一个离线过程,一次性完成。一旦你得到数据,就把它存储在你喜欢的任何数据库中(SQlite应该很好,如果你不怕把它加载到RAM中,即使是一个简单的结构化文件也可以(。