緯度/経度の座標を考えると、都市/国をどのようにして見つけることができますか?


141

たとえば、これらの座標セットがある場合

"latitude": 48.858844300000001,
"longitude": 2.2943506,

どのようにして都市/国を見つけることができますか?


2
おそらく何らかのデータベースが必要になるでしょう。自分でGoogle Maps APIで遊んでみます... lat / longをサポートしています。
beatgammit '28年

回答:


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


これは私が最終的に行くものなので、これを受け入れる:)マイケルの答えは確かに素晴らしい選択肢です!
ming yeow

5
Googleのリバースジオコーディングは、Googleマップとの組み合わせでのみ許可されます。そのような制限のないソリューションが必要な場合は(商用であり、米国の都市しかありません)、以下をチェックしてください:askgeo.com
James D

mapquest apiは、場合によってはレート制限がなく、さまざまなジオコーディングのニーズに対して非常に高いレート制限があるため、ここでの別のオプションです。
トム

2
無料は議論の余地があります、それは特定の制限の下でのみ無料です。
Petah

@JamesD:APIポリシーでは、データを地図に表示する場合、Googleマップである必要がありますが、地図に表示する必要はありません(またはまったく表示する必要はありません)。
user276648

173

別のオプション:

  • http://download.geonames.org/export/dump/から都市データベースをダウンロードします
  • 各都市を緯度/経度として追加->都市マッピング(Rツリーなどの空間インデックス)(一部のDBにも機能があります)
  • 最近傍検索を使用して、特定のポイントに最も近い都市を見つける

利点:

  • 利用できる外部サーバーに依存しない
  • 非常に高速(毎秒数千回の検索を簡単に実行)

短所:

  • 自動的に最新ではない
  • 最寄りの都市が数十マイル離れている場合を区別したい場合は、追加のコードが必要です。
  • 極と国際日付変更線の近くで奇妙な結果が得られる可能性があります(とにかくこれらの場所に都市はありません)

5
また、都市内の都市については奇妙な結果が得られます。たとえば、ローマの特定の場所は、「バチカン市国」を返す場合があります-データベースごとに指定されている緯度/経度によって異なります。
ノエルアブラハム

1
彼らはまた、REST APIを持っているし、かなりまともに見える: api.geonames.org/...
jeudyx

8
例は非常に貴重だったでしょう
Hack-R

GeoNamesは無料のWebサービスも提供しています。
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

1
まあそれは外部サービスを必要とする
maxbachmann

それは素晴らしいアプローチですが、郡だけが必要なので、住所を調整する必要があります。郡を取り戻す方法があったらいいのに。
Fatemeh Asgarinejad

22

オープンソースの代替案は、Open Street MapのNominatimです。URLに変数を設定するだけで、その場所の市/国が返されます。公式ドキュメントについては、次のリンクを確認してください:Nominatim


3
Nominatimの使用ポリシーoperations.osmfoundation.org/policies/nominatimには、1秒あたり1リクエストの最大レートが記載されているため、アドホッククエリにのみ適していることに注意してください。
マシューワイズ

22

私は同様の機能を探していたところ、以前の返信で共有されたデータ " http://download.geonames.org/export/dump/ "を確認しました(共有していただきありがとうございます。優れたソースです)。 ities1000.txtデータに。

あなたはそれが走っているのを見ることができます http://scatter-otl.rhcloud.com/location?lat=36&long=-78.9 (リンク切れ) 場所の緯度と経度を変更するだけです。

OpenShift(RedHatプラットフォーム)にデプロイされます。長いアイドル期間後の最初の呼び出しには時間がかかる場合がありますが、通常はパフォーマンスは問題ありません。お気軽にこのサービスをご利用ください...

また、プロジェクトのソースは https://github.com/turgos/Locationにあります


ちゃんと動きません。都市を取得できない場合は、最も近い既知の都市を検索します。次に例を示します
。scatter

1
そのとおりです。アルゴリズムは、データセットで利用可能な最も近い都市を検索します。上記のデプロイされたサーバーでは、「cities1000.txt」を使用しました。主要都市のみです。ソースコードはgithub.com/turgos/Locationで入手できます。「download.geonames.org/export/dump」から、より詳細なデータを使用して独自のデータを開始できます。
turgos

ities1000.txtがより詳細なデータであるようです。私は正しいですか?
smartmouse 2016年

8

ほんの数例を挙げれば、Google、Geonames、OpenStreetMapsを含む複数のプロバイダーをサポートする優れたPythonライブラリーであるGeocoderを使用しました。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
私はこれを使用しました:from geopy.geocoders import Nominatim geolocator = Nominatim()location = geolocator.reverse( "41.4721、-72.6311")print(location.address)住所全体を取得し、それから郡をフィルタリングします。
Fatemeh Asgarinejad

1
おかげで、私は大規模なデータセットを操作し、2017年にGeoPyを使用すると多くのタイムアウトが発生しました。多分3年後、彼らは彼らの制限を緩和したので、それは知って素晴らしいです!
ハマンサミュエル

5

Javascriptでこれを行う方法のコード例を見つけるために、約30分間費やしました。投稿された質問に対する明確な答えが見つかりませんでした。だから...私は自分で作った。うまくいけば、人々は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_geocoderAjay Thampiによって構築された非常に効率的で便利なパッケージを見つけました。コードはこちらから入手できます。これは、大量のポイントに対して非常に効率的なKDツリーの並列実装に基づいています(100,000ポイントを取得するのに数秒かかりました)。

これはこのデータベースに基づいており、@ turgosによってすでに強調表示されています。

座標のリストから国と都市をすばやく見つけることがタスクの場合、これは優れたツールです。


3

それは本当にあなたが持っているどんな技術制限に依存します。

1つの方法は、関心のある国と都市の概要を含む空間データベースを用意することです。概要では、国と都市は空間タイプのポリゴンとして保存されます。座標セットを空間タイプのポイントに変換し、ポリゴンに対してクエリを実行して、ポイントが配置されている国/都市名を取得できます。

空間タイプをサポートするデータベースの一部を以下に示します。SQLサーバー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またはlocality(administrative_area_level_ 3が使用できない場合)のみが必要な場合、どれを変更すればよいですか?php ..の新着

1

Loc2countryは、指定された位置座標(緯度/経度)のISO alpha-3国コードを返すGolangベースのツールです。マイクロ秒単位で応答します。それは国の地図への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を使用してプレイスオブジェクトから国と都市を取得する方法です。

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;
  }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.