给定纬度/经度坐标,我们如何找出城市/国家?

min*_*eow 134 geocoding geolocation geospatial geo

例如,如果我们有这些坐标集

"latitude": 48.858844300000001,
"longitude": 2.2943506,
Run Code Online (Sandbox Code Playgroud)

我们怎样才能找到这个城市/国家?

Mic*_*rdt 169

另外一个选项:

  • http://download.geonames.org/export/dump/下载城市数据库
  • 将每个城市添加为纬度/经度 - >城市映射到空间索引,例如R树(某些数据库也具有该功能)
  • 使用最近邻搜索找到任何给定点的最近城市

好处:

  • 不依赖于外部服务器可用
  • 非常快(每秒容易进行数千次查找)

缺点:

  • 不会自动更新
  • 如果您想区分距离最近的城市几十英里的情况,则需要额外的代码
  • 可能会在极点和国际日期线附近给出奇怪的结果(尽管那些地方没有任何城市

  • 一个例子是非常宝贵的 (7认同)
  • 也会给城市内的城市怪异的结果,例如在罗马的某些位置可能会返回"梵蒂冈" - 这取决于经/纬度在数据库中每个指定. (5认同)
  • 他们还有一个 REST api,看起来很不错:http://api.geonames.org/findNearbyJSON?lat=9.9271&lng=-84.082&username=demo (2认同)

Kev*_*vin 92

免费的Google地理编码API通过HTTP REST API提供此服务.请注意,API是使用率和速率限制,但您可以支付无限制访问权限.

尝试此链接以查看输出的示例(这是在json中,输出也在XML中可用)

https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true

  • Google的反向地理编码仅允许与Google地图结合使用.如果您想要一个没有这种限制的解决方案(虽然它是商业化的,只有美国城市),请访问:http://askgeo.com (5认同)
  • *免费*是有争议的,仅在特定限制下免费。 (2认同)

Far*_*eed 40

你需要 geopy

pip install geopy
Run Code Online (Sandbox Code Playgroud)

然后:

from geopy.geocoders import Nominatim
geolocator = Nominatim()
location = geolocator.reverse("48.8588443, 2.2943506")

print(location.address)
Run Code Online (Sandbox Code Playgroud)

获取更多信息:

print (location.raw)

{'place_id': '24066644', 'osm_id': '2387784956', 'lat': '41.442115', 'lon': '-8.2939909', 'boundingbox': ['41.442015', '41.442215', '-8.2940909', '-8.2938909'], 'address': {'country': 'Portugal', 'suburb': 'Oliveira do Castelo', 'house_number': '99', 'city_district': 'Oliveira do Castelo', 'country_code': 'pt', 'city': 'Oliveira, São Paio e São Sebastião', 'state': 'Norte', 'state_district': 'Ave', 'pedestrian': 'Rua Doutor Avelino Germano', 'postcode': '4800-443', 'county': 'Guimarães'}, 'osm_type': 'node', 'display_name': '99, Rua Doutor Avelino Germano, Oliveira do Castelo, Oliveira, São Paio e São Sebastião, Guimarães, Braga, Ave, Norte, 4800-443, Portugal', 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright'}
Run Code Online (Sandbox Code Playgroud)

  • 这个有什么限制吗?这似乎是最快的方法。是否有任何理由不使用 @Michael 的方法? (2认同)

tur*_*gos 22

我正在寻找类似的功能,我在早先的回复中看到了数据" http://download.geonames.org/export/dump/ "(感谢分享,这是一个很好的来源),并实现了一个基于服务的在cities1000.txt数据上.

你可以看到它在运行 http://scatter-otl.rhcloud.com/location?lat=36&long=-78.9 (断开链接) 只需更改您所在位置的纬度和经度即可.

它部署在OpenShift(RedHat平台)上.长时间闲置后的第一次通话可能需要一段时间,但通常表现令人满意.随意使用此服务...

此外,您可以在https://github.com/turgos/Location找到项目源 .


Reg*_*ega 21

一个开源替代品是来自Open Street Map的Nominatim.您所要做的就是在URL中设置变量,并返回该位置的城市/国家/地区.请查看以下链接以获取官方文档:Nominatim

  • 请注意,Nominatim使用策略https://operations.osmfoundation.org/policies/nominatim/表示每秒一个请求的最大速率,因此仅适用于即席查询. (3认同)

Ham*_*uel 6

我使用了Geocoder,一个支持多个提供商的优秀Python库,包括Google,Geonames和OpenStreetMaps,仅举几例.我尝试过使用GeoPy库,它经常会超时.为GeoNames开发自己的代码不是最好的利用时间,最终可能会得到不稳定的代码.根据我的经验,Geocoder非常易于使用,并且具有足够好的文档.以下是按纬度和经度查找城市或按城市名称查找纬度/经度的示例代码.

import geocoder

g = geocoder.osm([53.5343609, -113.5065084], method='reverse')
print g.json['city'] # Prints Edmonton

g = geocoder.osm('Edmonton, Canada')
print g.json['lat'], g.json['lng'] # Prints 53.5343609, -113.5065084
Run Code Online (Sandbox Code Playgroud)


Gio*_*eri 6

我知道这个问题真的很老,但我一直在研究同样的问题,我发现了一个非常有效和方便的包,reverse_geocoder由 Ajay Thampi 构建。该代码可在此处获得。它基于 KD 树的并行实现,这对于大量点非常有效(我花了几秒钟才获得 100,000 个点。

它基于数据库,@turgos 已经突出显示。

如果您的任务是快速找到坐标列表的国家和城市,这是一个很好的工具。


Kai*_*sen 5

我花了大约30分钟试图找到一个如何在Javascript中执行此操作的代码示例.我找不到你发布的问题的快速明确答案.所以...我自己创造了.希望人们可以使用它,而无需深入研究API或盯着他们不知道如何阅读的代码.哈,如果没有别的我可以参考这篇文章为我自己的东西..好问题,并感谢讨论论坛!

这是利用Google API.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=<YOURGOOGLEKEY>&sensor=false&v=3&libraries=geometry"></script>
Run Code Online (Sandbox Code Playgroud)

.

//CHECK IF BROWSER HAS HTML5 GEO LOCATION
if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function (position) {

        //GET USER CURRENT LOCATION
        var locCurrent = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

        //CHECK IF THE USERS GEOLOCATION IS IN AUSTRALIA
        var geocoder = new google.maps.Geocoder();
            geocoder.geocode({ 'latLng': locCurrent }, function (results, status) {
                var locItemCount = results.length;
                var locCountryNameCount = locItemCount - 1;
                var locCountryName = results[locCountryNameCount].formatted_address;

                if (locCountryName == "Australia") {
                    //SET COOKIE FOR GIVING
                    jQuery.cookie('locCountry', locCountryName, { expires: 30, path: '/' }); 
                }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)