Holen Sie sich den Namen der Stadt mithilfe der Geolokalisierung

140

Ich habe es geschafft, den Breiten- und Längengrad des Benutzers mithilfe der HTML-basierten Geolokalisierung zu ermitteln.

//Check if browser supports W3C Geolocation API
if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
} 
//Get latitude and longitude;
function successFunction(position) {
    var lat = position.coords.latitude;
    var long = position.coords.longitude;
}

Ich möchte den Namen der Stadt anzeigen. Der einzige Weg, ihn zu erhalten, ist die Verwendung einer Reverse-Geolocation-API. Ich habe die Google-Dokumentation zur umgekehrten Geolokalisierung gelesen, weiß jedoch nicht, wie ich die Ausgabe auf meiner Website erhalten soll.

Ich weiß nicht, wie ich das verwenden soll: "http://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+long+'&sensor=true"um den Namen der Stadt auf der Seite anzuzeigen.

Wie kann ich das erreichen?

lisovaccaro
quelle
4
Wenn Sie keine Karten verwenden möchten, wissen Sie, dass dies gegen die Nutzungsbedingungen von Google verstößt, oder? Punkt 10.4 hier developer.google.com/maps/terms Keine Verwendung von Inhalten ohne Google Map. Sofern die Maps APIs-Dokumentation dies nicht ausdrücklich zulässt, werden Sie den Inhalt in einer Maps API-Implementierung nicht ohne eine entsprechende Google Map verwenden. Beispielsweise können Sie Street View-Bilder ohne entsprechende Google-Karte anzeigen, da die Dokumentation zu den Karten-APIs diese Verwendung ausdrücklich zulässt.
PirateApp
5
Ja, @PirateApp hat einen guten Punkt. Möglicherweise gibt es bessere Dienste. Ich habe bereits mit SmartyStreets gearbeitet und weiß, dass die Nutzungsbedingungen viel offener sind. Die meisten Dienste führen jedoch keine umgekehrte Geokodierung durch. Ich weiß, dass Texas A & M einen kostenlosen Service hat, aber sie haben die AGB- Warnung, dass Sie keine Daten über andere Personen sammeln können, und sie hatten zuvor Probleme mit der Verfügbarkeit und Genauigkeit.
Joseph Hansen

Antworten:

201

Sie würden so etwas mit der Google-API tun.

Bitte beachten Sie, dass Sie die Google Maps-Bibliothek einschließen müssen, damit dies funktioniert. Google Geocoder gibt viele Adresskomponenten zurück, sodass Sie eine fundierte Vermutung anstellen müssen, welche Stadt die Stadt haben wird.

"administrative_area_level_1" ist normalerweise das, wonach Sie suchen, aber manchmal ist der Ort die Stadt, nach der Sie suchen.

Wie auch immer - weitere Details zu Google-Antworttypen finden Sie hier und hier .

Unten ist der Code, der den Trick machen sollte:

<!DOCTYPE html> 
<html> 
<head> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
<title>Reverse Geocoding</title> 

<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript"> 
  var geocoder;

  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
} 
//Get the latitude and the longitude;
function successFunction(position) {
    var lat = position.coords.latitude;
    var lng = position.coords.longitude;
    codeLatLng(lat, lng)
}

function errorFunction(){
    alert("Geocoder failed");
}

  function initialize() {
    geocoder = new google.maps.Geocoder();



  }

  function codeLatLng(lat, lng) {

    var latlng = new google.maps.LatLng(lat, lng);
    geocoder.geocode({'latLng': latlng}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
      console.log(results)
        if (results[1]) {
         //formatted address
         alert(results[0].formatted_address)
        //find country name
             for (var i=0; i<results[0].address_components.length; i++) {
            for (var b=0;b<results[0].address_components[i].types.length;b++) {

            //there are different types that might hold a city admin_area_lvl_1 usually does in come cases looking for sublocality type will be more appropriate
                if (results[0].address_components[i].types[b] == "administrative_area_level_1") {
                    //this is the object you are looking for
                    city= results[0].address_components[i];
                    break;
                }
            }
        }
        //city data
        alert(city.short_name + " " + city.long_name)


        } else {
          alert("No results found");
        }
      } else {
        alert("Geocoder failed due to: " + status);
      }
    });
  }
</script> 
</head> 
<body onload="initialize()"> 

</body> 
</html> 
Michal
quelle
3
Nicht wahr für Administratorbereich Ebene 1, manchmal ist der Name der Stadt nicht vorhanden. - {"long_name" => "San Francisco", "types" => ["administrative_area_level_2", "Political"], "short_name" => "San Francisco"}, {"long_name" => "California", "types "=> [" administrative_area_level_1 "," Political "]," Short_name "=>" CA "}, {" Long_name "=>" USA "," Typen "=> [" Land "," politisch "]," Kurzname "=>" US "}
Ming Tsai
5
Für V3 sollte die Zeichenfolge {'latlng': latlng} wie in ... geocode ({'location': latlng}) in 'location' geändert werden. Dieses Beispiel hat mich fast dorthin gebracht, aber die Zeichenfolge 'latlng' scheint in neueren apis nicht mehr gültig zu sein. Einzelheiten finden Sie unter: developer.google.com/maps/documentation/javascript/… .
Binarygiant
@Michal Wie können wir nur den Ländernamen oder den Ländercode anstelle der vollständigen Adresse finden?
Ajay
1
@ajay im if-Anweisungstest für "Land" und die Stadtvariable geben jetzt Länderdaten zurück. Wenn Sie es umbenennen country = results [0] .address_components [i], können Sie auf die Daten über country.long_name und country.short_name zugreifen
Michal
Gibt es eine Möglichkeit, dies auf Städte innerhalb einer Provinz einzugrenzen oder nur zu überprüfen, ob der Standort aus einer bestimmten Provinz stammt und ob der Benutzer auf eine bestimmte Webseite umgeleitet wird?
SorryEh
52

Ein anderer Ansatz besteht darin, meinen Dienst http://ipinfo.io zu verwenden , der den Namen der Stadt, Region und des Landes basierend auf der aktuellen IP-Adresse des Benutzers zurückgibt. Hier ist ein einfaches Beispiel:

$.get("http://ipinfo.io", function(response) {
    console.log(response.city, response.country);
}, "jsonp");

Hier ist ein detaillierteres JSFiddle-Beispiel, in dem auch die vollständigen Antwortinformationen ausgedruckt werden, sodass Sie alle verfügbaren Details sehen können: http://jsfiddle.net/zK5FN/2/

Ben Dowling
quelle
23
Nicht so genau.
Salman von Abbas
4
Konnte Stadt und sogar Region von IP eines großen russischen Anbieters nicht erkennen: (
Jehy
2
Lol ... das gibt meinem internen Netzwerk IP (192.168 ...)
Major-Mann
Kann ich dies über einen Gerätebrowser (Handheld) tun?
Arti
Scheint nicht zuverlässig. Ich benutze gerade einen Laptop und ein Handy. Die Städte, die auf beiden Geräten über ipinfo.io angezeigt werden, sind 530 Kilometer voneinander entfernt!
Ashish Goyal
52

$.ajax({
  url: "https://geolocation-db.com/jsonp",
  jsonpCallback: "callback",
  dataType: "jsonp",
  success: function(location) {
    $('#country').html(location.country_name);
    $('#state').html(location.state);
    $('#city').html(location.city);
    $('#latitude').html(location.latitude);
    $('#longitude').html(location.longitude);
    $('#ip').html(location.IPv4);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

<div>Country: <span id="country"></span></div>
  <div>State: <span id="state"></span></div>
    <div>City: <span id="city"></span></div>
      <div>Latitude: <span id="latitude"></span></div>
        <div>Longitude: <span id="longitude"></span></div>
          <div>IP: <span id="ip"></span></div>

Für die Verwendung der HTML5-Geolokalisierung ist eine Benutzerberechtigung erforderlich. Wenn Sie dies nicht möchten, wählen Sie einen externen Locator wie https://geolocation-db.com. IPv6 wird unterstützt. Keine Einschränkungen und unbegrenzte Anfragen erlaubt.

Beispiel

Ein Beispiel für ein reines Javascript ohne Verwendung von jQuery finden Sie in dieser Antwort.

Kurt Van den Branden
quelle
17

Sie können den Namen der Stadt, des Landes, des Straßennamens und anderer Geodaten mithilfe der Google Maps-Geokodierungs-API abrufen

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
</head>
<body>
    <script type="text/javascript">
        navigator.geolocation.getCurrentPosition(success, error);

        function success(position) {
            console.log(position.coords.latitude)
            console.log(position.coords.longitude)

            var GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + position.coords.latitude + '%2C' + position.coords.longitude + '&language=en';

            $.getJSON(GEOCODING).done(function(location) {
                console.log(location)
            })

        }

        function error(err) {
            console.log(err)
        }
    </script>
</body>
</html>

und um diese Daten mit jQuery auf der Seite anzuzeigen

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
</head>
<body>

    <p>Country: <span id="country"></span></p>
    <p>State: <span id="state"></span></p>
    <p>City: <span id="city"></span></p>
    <p>Address: <span id="address"></span></p>

    <p>Latitude: <span id="latitude"></span></p>
    <p>Longitude: <span id="longitude"></span></p>

    <script type="text/javascript">
        navigator.geolocation.getCurrentPosition(success, error);

        function success(position) {

            var GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + position.coords.latitude + '%2C' + position.coords.longitude + '&language=en';

            $.getJSON(GEOCODING).done(function(location) {
                $('#country').html(location.results[0].address_components[5].long_name);
                $('#state').html(location.results[0].address_components[4].long_name);
                $('#city').html(location.results[0].address_components[2].long_name);
                $('#address').html(location.results[0].formatted_address);
                $('#latitude').html(position.coords.latitude);
                $('#longitude').html(position.coords.longitude);
            })

        }

        function error(err) {
            console.log(err)
        }
    </script>
</body>
</html>
Mikhail
quelle
15

Hier ist eine aktualisierte Arbeitsversion für mich, die Stadt / Stadt erhält. Es sieht so aus, als ob einige Felder in der JSON-Antwort geändert wurden. Verweisen auf frühere Antworten auf diese Fragen. (Danke an Michal & eine weitere Referenz: Link

var geocoder;

if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
}
// Get the latitude and the longitude;
function successFunction(position) {
  var lat = position.coords.latitude;
  var lng = position.coords.longitude;
  codeLatLng(lat, lng);
}

function errorFunction() {
  alert("Geocoder failed");
}

function initialize() {
  geocoder = new google.maps.Geocoder();

}

function codeLatLng(lat, lng) {
  var latlng = new google.maps.LatLng(lat, lng);
  geocoder.geocode({latLng: latlng}, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      if (results[1]) {
        var arrAddress = results;
        console.log(results);
        $.each(arrAddress, function(i, address_component) {
          if (address_component.types[0] == "locality") {
            console.log("City: " + address_component.address_components[0].long_name);
            itemLocality = address_component.address_components[0].long_name;
          }
        });
      } else {
        alert("No results found");
      }
    } else {
      alert("Geocoder failed due to: " + status);
    }
  });
}
Pradeep
quelle
10

geolocator.js kann das. (Ich bin der Autor).

Stadtnamen abrufen (begrenzte Adresse)

geolocator.locateByIP(options, function (err, location) {
    console.log(location.address.city);
});

Vollständige Adressinformationen abrufen

Im folgenden Beispiel wird zunächst die HTML5-Geolocation-API ausprobiert, um die genauen Koordinaten zu erhalten. Wenn dies fehlschlägt oder abgelehnt wird, wird auf die Geo-IP-Suche zurückgegriffen. Sobald die Koordinaten abgerufen wurden, werden die Koordinaten in eine Adresse umgekehrt geocodiert.

var options = {
    enableHighAccuracy: true,
    fallbackToIP: true, // fallback to IP if Geolocation fails or rejected
    addressLookup: true
};
geolocator.locate(options, function (err, location) {
    console.log(location.address.city);
});

Dies verwendet intern Google APIs (für die Adressensuche). Vor diesem Aufruf sollten Sie Geolocator mit Ihrem Google API-Schlüssel konfigurieren.

geolocator.config({
    language: "en",
    google: {
        version: "3",
        key: "YOUR-GOOGLE-API-KEY"
    }
});

Geolocator unterstützt Geolokalisierung (über HTML5- oder IP-Lookups), Geocodierung, Adressensuche (umgekehrte Geocodierung), Entfernung und Dauer, Zeitzoneninformationen und viele weitere Funktionen ...

Onur Yıldırım
quelle
6

Nachdem ich ein paar verschiedene Lösungen zusammen mit meinen eigenen Sachen gesucht und zusammengesetzt hatte, kam ich auf diese Funktion:

function parse_place(place)
{
    var location = [];

    for (var ac = 0; ac < place.address_components.length; ac++)
    {
        var component = place.address_components[ac];

        switch(component.types[0])
        {
            case 'locality':
                location['city'] = component.long_name;
                break;
            case 'administrative_area_level_1':
                location['state'] = component.long_name;
                break;
            case 'country':
                location['country'] = component.long_name;
                break;
        }
    };

    return location;
}
Jafo
quelle
3

Sie können https://ip-api.io/ verwenden. , um den Namen der Stadt abzurufen. Es unterstützt IPv6.

Als Bonus kann überprüft werden, ob es sich bei der IP-Adresse um einen Tor-Knoten, einen öffentlichen Proxy oder einen Spammer handelt.

Javascript Code:

$(document).ready(function () {
        $('#btnGetIpDetail').click(function () {
            if ($('#txtIP').val() == '') {
                alert('IP address is reqired');
                return false;
            }
            $.getJSON("http://ip-api.io/json/" + $('#txtIP').val(),
                 function (result) {
                     alert('City Name: ' + result.city)
                     console.log(result);
                 });
        });
    });

HTML Quelltext

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div>
    <input type="text" id="txtIP" />
    <button id="btnGetIpDetail">Get Location of IP</button>
</div>

JSON-Ausgabe

{
    "ip": "64.30.228.118",
    "country_code": "US",
    "country_name": "United States",
    "region_code": "FL",
    "region_name": "Florida",
    "city": "Fort Lauderdale",
    "zip_code": "33309",
    "time_zone": "America/New_York",
    "latitude": 26.1882,
    "longitude": -80.1711,
    "metro_code": 528,
    "suspicious_factors": {
        "is_proxy": false,
        "is_tor_node": false,
        "is_spam": false,
        "is_suspicious": false
    }
}
Vindhyachal Kumar
quelle
2

Wie @PirateApp in seinem Kommentar erwähnt hat, verstößt es ausdrücklich gegen die Google Maps API-Lizenzierung, die Maps API wie beabsichtigt zu verwenden.

Sie haben eine Reihe von Alternativen, darunter das Herunterladen und lokale Abfragen einer Geoip-Datenbank oder die Verwendung eines API-Dienstes eines Drittanbieters, z. B. meines Dienstes ipdata.co .

ipdata gibt Ihnen die Geolokalisierung, Organisation, Währung, Zeitzone, Anrufcode, Flagge und Statusdaten des Tor-Exit-Knotens von einer beliebigen IPv4- oder IPv6-Adresse an.

Und ist skalierbar mit 10 globalen Endpunkten, die jeweils> 10.000 Anfragen pro Sekunde verarbeiten können!

Diese Antwort verwendet einen 'Test'-API-Schlüssel, der sehr begrenzt ist und nur zum Testen einiger Aufrufe gedacht ist. Melden Sie sich für Ihren eigenen kostenlosen API-Schlüssel an und erhalten Sie täglich bis zu 1500 Anfragen für die Entwicklung.

$.get("https://api.ipdata.co?api-key=test", function(response) {
  $("#ip").html("IP: " + response.ip);
  $("#city").html(response.city + ", " + response.region);
  $("#response").html(JSON.stringify(response, null, 4));
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1><a href="https://ipdata.co">ipdata.co</a> - IP geolocation API</h1>

<div id="ip"></div>
<div id="city"></div>
<pre id="response"></pre>

Die Geige; https://jsfiddle.net/ipdata/6wtf0q4g/922/

Jonathan
quelle
1

Hier ist ein weiterer Versuch. Wenn Sie der akzeptierten Antwort mehr hinzufügen, ist dies möglicherweise umfassender. Natürlich lässt Switch-Case sie elegant aussehen.

function parseGeoLocationResults(result) {
    const parsedResult = {}
    const {address_components} = result;

    for (var i = 0; i < address_components.length; i++) {
        for (var b = 0; b < address_components[i].types.length; b++) {
            if (address_components[i].types[b] == "street_number") {
                //this is the object you are looking for
                parsedResult.street_number = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "route") {
                //this is the object you are looking for
                parsedResult.street_name = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "sublocality_level_1") {
                //this is the object you are looking for
                parsedResult.sublocality_level_1 = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "sublocality_level_2") {
                //this is the object you are looking for
                parsedResult.sublocality_level_2 = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "sublocality_level_3") {
                //this is the object you are looking for
                parsedResult.sublocality_level_3 = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "neighborhood") {
                //this is the object you are looking for
                parsedResult.neighborhood = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "locality") {
                //this is the object you are looking for
                parsedResult.city = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "administrative_area_level_1") {
                //this is the object you are looking for
                parsedResult.state = address_components[i].long_name;
                break;
            }

            else if (address_components[i].types[b] == "postal_code") {
                //this is the object you are looking for
                parsedResult.zip = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "country") {
                //this is the object you are looking for
                parsedResult.country = address_components[i].long_name;
                break;
            }
        }
    }
    return parsedResult;
}
user3124360
quelle
0

Hier ist eine einfache Funktion, mit der Sie sie abrufen können. Ich habe Axios verwendet , um die API-Anfrage zu stellen, aber Sie können alles andere verwenden.

async function getCountry(lat, long) {
  const { data: { results } } = await axios.get(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${long}&key=${GOOGLE_API_KEY}`);
  const { address_components } = results[0];

  for (let i = 0; i < address_components.length; i++) {
    const { types, long_name } = address_components[i];

    if (types.indexOf("country") !== -1) return long_name;
  }
}
Kingsley Kbc Comics
quelle