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


Answers:


96

免费的Google Geocoding API通过HTTP REST API提供此服务。请注意,该API的使用和速率受到限制,但是您可以为无限制的访问付费。

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

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


接受这个,因为这是我最终要去的:)迈克尔的答案当然是个不错的选择!
铭耀

5
仅允许将Google反向地理编码与Google Map结合使用。如果您想要一个没有这种限制的解决方案(尽管它是商业性的并且只有美国的城市),请访问:askgeo.com
James D

mapquest api是这里的另一个选择,因为在某些情况下它没有速率限制,并且对于各种地理编码需求来说,速率限制非常高。
2014年

2
自由是有争议的,只有在一定的限制下才是自由的。
Petah

@JamesD:API政策规定,如果您在地图上显示数据,则它必须是Google Map,但您不必在地图上(或根本不)显示数据。
user276648 '19

173

另外的选择:

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

优点:

  • 不依赖于外部服务器是否可用
  • 非常快(每秒轻松进行数千次查询)

缺点:

  • 不会自动更新
  • 如果要区分最近的城市在几十英里之外的情况,则需要额外的代码
  • 在两极和国际日期变更线附近可能会得出奇怪的结果(尽管无论如何这些地方都没有任何城市

5
还会为城市内的城市给出奇怪的结果,例如,罗马的某些位置可能会返回“梵蒂冈城”-取决于数据库中为每个城市指定的经/纬度。
Noel Abrahams 2012年

1
他们也有一个REST API,看起来相当不错: api.geonames.org/...
jeudyx

8
一个例子将是无价之宝
Hack-R

GeoNames还提供了一个很棒的免费网络服务!
mcont

在2020年,GeoNames.org看起来很不活跃,有人知道它是否是最新的吗?问题出在哪里,他们都没有提到网站上的最新更新日期。
joedotnot

45

你需要 geopy

pip install geopy

然后:

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

print(location.address)

获取更多信息:

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'}

2
这有什么限制吗?这似乎是最快的方法。难道没有任何理由不使用@Michael的方法吗?
Satys '19

1
那么它需要外部服务
maxbachmann

这是一个很好的方法,但是我只需要县,所以我需要完善地址。我希望有办法把县都还给我。
Fatemeh Asgarinejad


22

我正在寻找类似的功能,并且在较早的答复中看到了共享的数据“ http://download.geonames.org/export/dump/(感谢您的共享,它是一个很好的来源),并实现了基于在city1000.txt数据上。

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

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

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


它无法正常工作。如果找不到城市,它将搜索最近的已知城市。这是一个示例:scatter-otl.rhcloud.com/…它说“ Basseterre”而不是“ Saint John”……
smartmouse15年

1
没错 该算法搜索数据集中可用的最近城市。对于上面部署的服务器,我使用了“ cities1000.txt”。它只有主要城市。源代码可在github.com/turgos/Location中获得。您可以从“ download.geonames.org/export/dump ”中获得更详细的数据,开始自己的工作。
turgos,2015年

似乎citys1000.txt是可用的更详细的数据。我对吗?
smartmouse

8

我使用了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

感谢您分享此内容,但它不适用于所有坐标。坐标的位数是否需要特定大小?
Fatemeh Asgarinejad

1
我相信我正确选择了经度和纬度。我有成千上万个坐标,而随机坐标从中不起作用。现在很好 我使用了另一种方法。感谢您的答复。
Fatemeh Asgarinejad

1
欢迎。想知道哪种方法对您有用吗?如果它比更好geocoder,我也想自己尝试一下!
哈曼·塞缪尔

1
我使用了此方法:从geopy.geocoders导入Nominatim geolocator = Nominatim()location = geolocator.reverse(“ 41.4721,-72.6311”)print(location.address)它给出了整个地址,然后从中过滤出县。
Fatemeh Asgarinejad

1
谢谢,我使用了一个大型数据集,在2017年,使用GeoPy使我超时了。也许3年后他们放宽了限制,所以很高兴知道!
哈曼·塞缪尔

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>

//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: '/' }); 
                }
        });
    }
}

5

我知道这个问题确实很老,但是我一直在研究同一个问题,所以我发现了一个reverse_geocoder由Ajay Thampi构建的极其有效且方便的软件包。该代码在这里可用。它基于KD树的并行实现,这对于大量点非常有效(我花了几秒钟才获得100,000点。

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

如果您的任务是快速找到坐标列表的国家和城市,则此工具非常有用。


3

这实际上取决于您所拥有的技术限制。

一种方法是拥有一个空间数据库,其中包含您感兴趣的国家和城市的轮廓。通过轮廓,我的意思是将国家和城市存储为空间类型多边形。可以将您的一组坐标转换为空间类型的点,然后对多边形进行查询,以获取该点所在的国家/城市名称。

以下是一些支持空间类型的数据库:SQL Server 2008MySQLpostGIS -postgreSQL和Oracle的扩展。

如果您想使用服务而不是拥有自己的数据库,则可以使用Yahoo的GeoPlanet。对于服务方法,您可能需要在gis.stackexchange.com上查看答案,其中涵盖了用于解决问题的服务的可用性。


1

您可以使用Google Geocoding API

Bellow是返回地址,城市,州和国家/地区的php函数

public function get_location($latitude='', $longitude='')
{
    $geolocation = $latitude.','.$longitude;
    $request = 'http://maps.googleapis.com/maps/api/geocode/json?latlng='.$geolocation.'&sensor=false'; 
    $file_contents = file_get_contents($request);
    $json_decode = json_decode($file_contents);
    if(isset($json_decode->results[0])) {
        $response = array();
        foreach($json_decode->results[0]->address_components as $addressComponet) {
            if(in_array('political', $addressComponet->types)) {
                    $response[] = $addressComponet->long_name; 
            }
        }

        if(isset($response[0])){ $first  =  $response[0];  } else { $first  = 'null'; }
        if(isset($response[1])){ $second =  $response[1];  } else { $second = 'null'; } 
        if(isset($response[2])){ $third  =  $response[2];  } else { $third  = 'null'; }
        if(isset($response[3])){ $fourth =  $response[3];  } else { $fourth = 'null'; }
        if(isset($response[4])){ $fifth  =  $response[4];  } else { $fifth  = 'null'; }


        $loc['address']=''; $loc['city']=''; $loc['state']=''; $loc['country']='';
        if( $first != 'null' && $second != 'null' && $third != 'null' && $fourth != 'null' && $fifth != 'null' ) {
            $loc['address'] = $first;
            $loc['city'] = $second;
            $loc['state'] = $fourth;
            $loc['country'] = $fifth;
        }
        else if ( $first != 'null' && $second != 'null' && $third != 'null' && $fourth != 'null' && $fifth == 'null'  ) {
            $loc['address'] = $first;
            $loc['city'] = $second;
            $loc['state'] = $third;
            $loc['country'] = $fourth;
        }
        else if ( $first != 'null' && $second != 'null' && $third != 'null' && $fourth == 'null' && $fifth == 'null' ) {
            $loc['city'] = $first;
            $loc['state'] = $second;
            $loc['country'] = $third;
        }
        else if ( $first != 'null' && $second != 'null' && $third == 'null' && $fourth == 'null' && $fifth == 'null'  ) {
            $loc['state'] = $first;
            $loc['country'] = $second;
        }
        else if ( $first != 'null' && $second == 'null' && $third == 'null' && $fourth == 'null' && $fifth == 'null'  ) {
            $loc['country'] = $first;
        }
      }
      return $loc;
}

如果我只需要Administrative_area_level_ 3或位置信息(如果不提供Administrative_area_level_ 3),则应该修改哪一个?PHP的新手
8

1

Loc2country是一个基于Golang的工具,可返回给定位置坐标(纬度/经度)的ISO alpha-3国家/地区代码。它以微秒为单位响应。它使用地理哈希到国家地图。

geohash数据是使用georaptor生成的。

我们在此工具的第6级使用geohash,即大小为1.2km x 600m的盒子。



0

请检查以下答案。这个对我有用

if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position){

        initialize(position.coords.latitude,position.coords.longitude);
    }); 
}

function initialize(lat,lng) {
    //directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
    //directionsService = new google.maps.DirectionsService();
    var latlng = new google.maps.LatLng(lat, lng);

    //alert(latlng);
    getLocation(latlng);
}

function getLocation(latlng){

    var geocoder = new google.maps.Geocoder();
    geocoder.geocode({'latLng': latlng}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                if (results[0]) {
                    var loc = getCountry(results);
                    alert("location is::"+loc);
                }
            }
        });

}

function getCountry(results)
{
    for (var i = 0; i < results[0].address_components.length; i++)
    {
        var shortname = results[0].address_components[i].short_name;
        var longname = results[0].address_components[i].long_name;
        var type = results[0].address_components[i].types;
        if (type.indexOf("country") != -1)
        {
            if (!isNullOrWhitespace(shortname))
            {
                return shortname;
            }
            else
            {
                return longname;
            }
        }
    }

}

function isNullOrWhitespace(text) {
    if (text == null) {
        return true;
    }
    return text.replace(/\s/gi, '').length < 1;
}

0

如果您使用的是Google的Places API,则可以通过以下方法使用Javascript从place对象获取国家和城市:

function getCityAndCountry(location) {
  var components = {};
  for(var i = 0; i < location.address_components.length; i++) {
    components[location.address_components[i].types[0]] = location.address_components[i].long_name;
  }

  if(!components['country']) {
    console.warn('Couldn\'t extract country');
    return false;
  }

  if(components['locality']) {
    return [components['locality'], components['country']];
  } else if(components['administrative_area_level_1']) {
    return [components['administrative_area_level_1'], components['country']];
  } else {
    console.warn('Couldn\'t extract city');
    return false;
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.