จากพิกัดละติจูด / ลองจิจูดเราจะทราบเมือง / ประเทศได้อย่างไร


141

ตัวอย่างเช่นถ้าเรามีชุดพิกัดเหล่านี้

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

เราจะทราบเมือง / ประเทศได้อย่างไร?


2
คุณอาจต้องการฐานข้อมูลบางประเภท ฉันลองเล่นกับ Google Maps API ด้วยตัวเอง ... มันรองรับ lat / long
beatgammit

คำตอบ:


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


ยอมรับสิ่งนี้เพราะนี่คือสิ่งที่ฉันจะจบลง :) คำตอบของไมเคิลเป็นตัวเลือกที่ยอดเยี่ยมอย่างแน่นอน!
หมิง Yeow

5
การเข้ารหัสภูมิศาสตร์ย้อนกลับของ Google อนุญาตให้ใช้ร่วมกับ Google Map เท่านั้น หากคุณต้องการโซลูชันที่ไม่มีข้อ จำกัด (แม้ว่าจะเป็นเชิงพาณิชย์และมีเมืองในสหรัฐฯเท่านั้น) ให้ลองดู: askgeo.com
James D

mapquest api เป็นอีกตัวเลือกหนึ่งเนื่องจากไม่มีการ จำกัด อัตราในบางกรณีและการ จำกัด อัตราสูงมากสำหรับความต้องการใช้งาน geocoding ที่หลากหลาย
Tom

2
ฟรีเป็นที่ถกเถียงกันมันฟรีเท่านั้นภายใต้ข้อ จำกัด บางอย่าง
Petah

@JamesD: นโยบาย APIระบุว่าหากคุณแสดงข้อมูลบนแผนที่ก็ต้องเป็น Google Map แต่คุณไม่จำเป็นต้องแสดงข้อมูลบนแผนที่ (หรือเลย)
276648

173

ตัวเลือกอื่น:

  • ดาวน์โหลดฐานข้อมูลเมืองจากhttp://download.geonames.org/export/dump/
  • เพิ่มแต่ละเมืองเป็นละติจูด / ลองจิจูด -> การทำแผนที่เมืองไปยังดัชนีอวกาศเช่น R-Tree (บางฐานข้อมูลยังมีฟังก์ชั่น)
  • ใช้การค้นหาเพื่อนบ้านที่ใกล้ที่สุดเพื่อค้นหาเมืองที่ใกล้ที่สุดสำหรับจุดที่กำหนด

ข้อดี:

  • ไม่ขึ้นอยู่กับเซิร์ฟเวอร์ภายนอกที่จะใช้งานได้
  • เร็วมาก (ค้นหาได้พันครั้งต่อวินาที)

ข้อเสีย:

  • ไม่ทันสมัยโดยอัตโนมัติ
  • ต้องใช้รหัสพิเศษหากคุณต้องการแยกแยะกรณีที่เมืองที่ใกล้ที่สุดอยู่ห่างออกไปหลายสิบไมล์
  • อาจให้ผลลัพธ์แปลก ๆ ใกล้กับเสาและบรรทัดวันที่สากล (แม้ว่าจะไม่มีเมืองใดในสถานที่เหล่านั้นอยู่ดี

5
จะให้ผลลัพธ์ที่แปลกสำหรับเมืองในเมืองเช่นสถานที่บางแห่งในโรมอาจกลับมา "นครวาติกัน" - ขึ้นอยู่กับ lat / lon ที่ระบุในฐานข้อมูลสำหรับแต่ละเมือง
Noel Abrahams

1
พวกเขายังมีส่วนที่เหลือ 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
มีข้อ จำกัด ใด ๆ สำหรับสิ่งนี้หรือไม่? นี่น่าจะเป็นวิธีที่เร็วที่สุด มีเหตุผลอะไรที่จะไม่ใช้สิ่งนี้มากกว่าแนวทางของไมเคิล?
Satys

1
มันต้องใช้บริการจากภายนอก
maxbachmann

มันเป็นวิธีการที่ยอดเยี่ยม แต่ฉันแค่ต้องการมณฑลดังนั้นฉันต้องปรับแต่งที่อยู่ ฉันหวังว่าจะมีวิธีหนึ่งในการคืนค่ามณฑล
Fatemeh Asgarinejad

22

ทางเลือกโอเพ่นซอร์สคือ Nominatim จาก Open Street Map สิ่งที่คุณต้องทำคือตั้งค่าตัวแปรใน URL และส่งคืนเมือง / ประเทศของสถานที่นั้น กรุณาตรวจสอบลิงค์ต่อไปนี้สำหรับเอกสารอย่างเป็นทางการ: Nominatim


3
โปรดทราบว่าการดำเนินการตามนโยบายการใช้งานของ Nominatim.osmfoundation.org/policies/nominatim ระบุอัตราสูงสุดหนึ่งคำขอต่อวินาทีดังนั้นจึงเหมาะสำหรับแบบสอบถาม ad-hoc เท่านั้น
Matthew Wise

22

ฉันกำลังค้นหาฟังก์ชั่นที่คล้ายกันและฉันเห็นข้อมูล " http://download.geonames.org/export/dump/ " แบ่งปันเมื่อตอบกลับก่อนหน้านี้ (ขอบคุณสำหรับการแบ่งปันมันเป็นแหล่งที่ยอดเยี่ยม) และใช้บริการตาม บนข้อมูลเมืองต่างๆ 1000.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" ...
smartmouse

1
ถูกต้อง. อัลกอริทึมค้นหาเมืองที่ใกล้เคียงที่สุดที่มีอยู่ในชุดข้อมูล สำหรับเซิร์ฟเวอร์ที่ใช้งานด้านบนฉันใช้ "Cities1000.txt" มันมีเพียงเมืองใหญ่ ๆ รหัสที่มาสามารถใช้ได้ที่github.com/turgos/Location คุณสามารถเริ่มต้นของคุณเองด้วยข้อมูลที่ละเอียดมากขึ้นจาก " download.geonames.org/export/dump "
turgos

ดูเหมือนว่า Cities1000.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") พิมพ์ (location.address) มันให้ที่อยู่ทั้งหมดแล้วกรองเขตจากมัน
Fatemeh Asgarinejad

1
ขอบคุณฉันทำงานกับชุดข้อมูลขนาดใหญ่และในปี 2560 การใช้ 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 2008 , MySQL , PostGIS - นามสกุลของ PostgreSQL และออราเคิล

หากคุณต้องการที่จะใช้บริการในสถานที่ของการมีฐานข้อมูลของคุณเองสำหรับนี้คุณสามารถใช้ของ Yahoo GeoPlanet สำหรับวิธีการบริการที่คุณอาจต้องการตรวจสอบคำตอบนี้ในgis.stackexchange.comซึ่งครอบคลุมความพร้อมของบริการสำหรับการแก้ปัญหาของคุณ


1

คุณสามารถใช้ Google Geocoding API

Bellow เป็นฟังก์ชัน php ที่ส่งคืน Adress, City, State และ Country

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

ถ้าฉันต้องการ administrator_area_level_ 3 หรือท้องที่ (ถ้า administrator_area_level_ 3 ไม่พร้อมใช้งาน) ฉันควรจะแก้ไขอันใด ใหม่เป็น PHP ..
สิงหาคม

1

Loc2countryเป็นเครื่องมือที่ใช้ Golang ซึ่งส่งคืนรหัสประเทศ ISO alpha-3 สำหรับพิกัดตำแหน่งที่กำหนด (lat / lon) มันตอบสนองในไมโครวินาที มันใช้ geohash กับแผนที่ประเทศ

ข้อมูล geohash ถูกสร้างขึ้นโดยใช้georaptor

เราใช้ geohash ที่ระดับ 6 สำหรับเครื่องมือนี้เช่นกล่องขนาด 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.