私が持っている緯度/経度の値のコレクションに基づく国、州、都市のリストが必要です。階層が維持され、重複のない方法でこの情報を保存する必要があります(たとえば、「USA」と「United States」および「United States of America」は同じ国です。データベースにこの国の1つのインスタンスのみが必要です)。 。
これはGoogle Map APIで可能ですか?
私が持っている緯度/経度の値のコレクションに基づく国、州、都市のリストが必要です。階層が維持され、重複のない方法でこの情報を保存する必要があります(たとえば、「USA」と「United States」および「United States of America」は同じ国です。データベースにこの国の1つのインスタンスのみが必要です)。 。
これはGoogle Map APIで可能ですか?
回答:
あなたが探しているものは、逆ジオコーディングと呼ばれています。Googleは、Google Geocoding APIを通じてサーバー側のリバースジオコーディングサービスを提供しています。これは、プロジェクトで使用できるはずです。
これは、次の要求に対する応答がどのようになるかを示しています。
http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=false
応答:
{
"status": "OK",
"results": [ {
"types": [ "street_address" ],
"formatted_address": "275-291 Bedford Ave, Brooklyn, NY 11211, USA",
"address_components": [ {
"long_name": "275-291",
"short_name": "275-291",
"types": [ "street_number" ]
}, {
"long_name": "Bedford Ave",
"short_name": "Bedford Ave",
"types": [ "route" ]
}, {
"long_name": "New York",
"short_name": "New York",
"types": [ "locality", "political" ]
}, {
"long_name": "Brooklyn",
"short_name": "Brooklyn",
"types": [ "administrative_area_level_3", "political" ]
}, {
"long_name": "Kings",
"short_name": "Kings",
"types": [ "administrative_area_level_2", "political" ]
}, {
"long_name": "New York",
"short_name": "NY",
"types": [ "administrative_area_level_1", "political" ]
}, {
"long_name": "United States",
"short_name": "US",
"types": [ "country", "political" ]
}, {
"long_name": "11211",
"short_name": "11211",
"types": [ "postal_code" ]
} ],
"geometry": {
"location": {
"lat": 40.7142298,
"lng": -73.9614669
},
"location_type": "RANGE_INTERPOLATED",
"viewport": {
"southwest": {
"lat": 40.7110822,
"lng": -73.9646145
},
"northeast": {
"lat": 40.7173774,
"lng": -73.9583193
}
}
}
},
... Additional results[] ...
リクエストURIでxmlをjsonに置き換えるだけで、jsonではなくxmlで応答を受信することもできます。
http://maps.googleapis.com/maps/api/geocode/xml?latlng=40.714224,-73.961452&sensor=false
私の知る限り、Googleは住所コンポーネントにも同じ名前を返します。国名や都市名などの上位レベルの名前の場合は特にそうです。それでも、ほとんどのアプリケーションでは結果は非常に正確ですが、時々スペルミスやあいまいな結果が見つかることがあることに注意してください。
sensor=false
ますか?
ここに基本的な答えがあります: ジオロケーションを使用して都市名を取得します
しかし、あなたが探しているもののために、私はこの方法をお勧めします。
また、administrative_area_level_1が必要な場合のみ、米国のテキサス州パリとフランスのイルドフランスの異なるものを格納し、手動のフォールバックを提供します。
-
Michalの方法には問題があり、特定の結果ではなく、最初の結果を取得します。彼はresults [0]を使用します。ブラウザがジオロケーションをサポートしていない場合の最終的な手動フォールバックでも、常に存在するタイプである「局所性」の結果のみを取得することが、私が適切だと思う方法です(彼のコードを変更しました)。
彼の方法:フェッチされた結果は、使用して異なる http://maps.googleapis.com/maps/api/geocode/json?address=bucharest&sensor=falseを 使用してからよりも http://maps.googleapis.com/maps/api/geocode /json?latlng=44.42514,26.10540&sensor=false (名前で検索/ lat&lngで検索)
この方法:同じフェッチ結果。
<!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]) {
var indice=0;
for (var j=0; j<results.length; j++)
{
if (results[j].types[0]=='locality')
{
indice=j;
break;
}
}
alert('The good number is: '+j);
console.log(results[j]);
for (var i=0; i<results[j].address_components.length; i++)
{
if (results[j].address_components[i].types[0] == "locality") {
//this is the object you are looking for City
city = results[j].address_components[i];
}
if (results[j].address_components[i].types[0] == "administrative_area_level_1") {
//this is the object you are looking for State
region = results[j].address_components[i];
}
if (results[j].address_components[i].types[0] == "country") {
//this is the object you are looking for
country = results[j].address_components[i];
}
}
//city data
alert(city.long_name + " || " + region.long_name + " || " + country.short_name)
} else {
alert("No results found");
}
//}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
</script>
</head>
<body onload="initialize()">
</body>
</html>
この質問を自分の解決策の出発点として使用しました。tabacituのコードよりも小さいため、私のコードを寄稿するのが適切であると思いました
依存関係:
コード:
if(geoPosition.init()){
var foundLocation = function(city, state, country, lat, lon){
//do stuff with your location! any of the first 3 args may be null
console.log(arguments);
}
var geocoder = new google.maps.Geocoder();
geoPosition.getCurrentPosition(function(r){
var findResult = function(results, name){
var result = _.find(results, function(obj){
return obj.types[0] == name && obj.types[1] == "political";
});
return result ? result.short_name : null;
};
geocoder.geocode({'latLng': new google.maps.LatLng(r.coords.latitude, r.coords.longitude)}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK && results.length) {
results = results[0].address_components;
var city = findResult(results, "locality");
var state = findResult(results, "administrative_area_level_1");
var country = findResult(results, "country");
foundLocation(city, state, country, r.coords.latitude, r.coords.longitude);
} else {
foundLocation(null, null, null, r.coords.latitude, r.coords.longitude);
}
});
}, { enableHighAccuracy:false, maximumAge: 1000 * 60 * 1 });
}
GeoCoder javascriptをjspファイルに含めたところ、少しバグがあることがわかりました。
これを試すこともできます:
var lat = "43.7667855" ;
var long = "-79.2157321" ;
var url = "https://maps.googleapis.com/maps/api/geocode/json?latlng="
+lat+","+long+"&sensor=false";
$.get(url).success(function(data) {
var loc1 = data.results[0];
var county, city;
$.each(loc1, function(k1,v1) {
if (k1 == "address_components") {
for (var i = 0; i < v1.length; i++) {
for (k2 in v1[i]) {
if (k2 == "types") {
var types = v1[i][k2];
if (types[0] =="sublocality_level_1") {
county = v1[i].long_name;
//alert ("county: " + county);
}
if (types[0] =="locality") {
city = v1[i].long_name;
//alert ("city: " + city);
}
}
}
}
}
});
$('#city').html(city);
});
$.get(url).success(function(data)
し $.get(url, function(data)
、うまく機能しています
この関数address_components
は、gmaps APIから返された情報に基づいて、探しているものを抽出するために作成しました。これは都市です(たとえば)。
export const getAddressCity = (address, length) => {
const findType = type => type.types[0] === "locality"
const location = address.map(obj => obj)
const rr = location.filter(findType)[0]
return (
length === 'short'
? rr.short_name
: rr.long_name
)
}
変更locality
するadministrative_area_level_1
など国家のために
私のjsコードでは私は次のように使用しています:
const location =`${getAddressCity(address_components, 'short')}, ${getAddressState(address_components, 'short')}`
戻ります: Waltham, MA
このコードを試してくださいこのコードは私と一緒に動作します
var posOptions = {timeout: 10000, enableHighAccuracy: false};
$cordovaGeolocation.getCurrentPosition(posOptions).then(function (position) {
var lat = position.coords.latitude;
var long = position.coords.longitude;
//console.log(lat +" "+long);
$http.get('https://maps.googleapis.com/maps/api/geocode/json?latlng=' + lat + ',' + long + '&key=your key here').success(function (output) {
//console.log( JSON.stringify(output.results[0]));
//console.log( JSON.stringify(output.results[0].address_components[4].short_name));
var results = output.results;
if (results[0]) {
//console.log("results.length= "+results.length);
//console.log("hi "+JSON.stringify(results[0],null,4));
for (var j = 0; j < results.length; j++){
//console.log("j= "+j);
//console.log(JSON.stringify(results[j],null,4));
for (var i = 0; i < results[j].address_components.length; i++){
if(results[j].address_components[i].types[0] == "country") {
//this is the object you are looking for
country = results[j].address_components[i];
}
}
}
console.log(country.long_name);
console.log(country.short_name);
} else {
alert("No results found");
console.log("No results found");
}
});
}, function (err) {
});
小さなマッパー関数を作成しました:
private getAddressParts(object): Object {
let address = {};
const address_components = object.address_components;
address_components.forEach(element => {
address[element.types[0]] = element.short_name;
});
return address;
}
これはAngular 4のソリューションですが、あなたはそのアイデアを理解できると思います。
使用法:
geocoder.geocode({ 'location' : latlng }, (results, status) => {
if (status === google.maps.GeocoderStatus.OK) {
const address = {
formatted_address: results[0].formatted_address,
address_parts: this.getAddressParts(results[0])
};
(....)
}
これにより、address
オブジェクトは次のようになります。
address: {
address_parts: {
administrative_area_level_1: "NY",
administrative_area_level_2: "New York County",
country: "US",
locality: "New York",
neighborhood: "Lower Manhattan",
political: "Manhattan",
postal_code: "10038",
route: "Beekman St",
street_number: "90",
},
formatted_address: "90 Beekman St, New York, NY 10038, USA"
}
それが役に立てば幸い!
<div id="location"></div>
<script>
window.onload = function () {
var startPos;
var geoOptions = {
maximumAge: 5 * 60 * 1000,
timeout: 10 * 1000,
enableHighAccuracy: true
}
var geoSuccess = function (position) {
startPos = position;
geocodeLatLng(startPos.coords.latitude, startPos.coords.longitude);
};
var geoError = function (error) {
console.log('Error occurred. Error code: ' + error.code);
// error.code can be:
// 0: unknown error
// 1: permission denied
// 2: position unavailable (error response from location provider)
// 3: timed out
};
navigator.geolocation.getCurrentPosition(geoSuccess, geoError, geoOptions);
};
function geocodeLatLng(lat, lng) {
var geocoder = new google.maps.Geocoder;
var latlng = {lat: parseFloat(lat), lng: parseFloat(lng)};
geocoder.geocode({'location': latlng}, function (results, status) {
if (status === 'OK') {
console.log(results)
if (results[0]) {
document.getElementById('location').innerHTML = results[0].formatted_address;
var street = "";
var city = "";
var state = "";
var country = "";
var zipcode = "";
for (var i = 0; i < results.length; i++) {
if (results[i].types[0] === "locality") {
city = results[i].address_components[0].long_name;
state = results[i].address_components[2].long_name;
}
if (results[i].types[0] === "postal_code" && zipcode == "") {
zipcode = results[i].address_components[0].long_name;
}
if (results[i].types[0] === "country") {
country = results[i].address_components[0].long_name;
}
if (results[i].types[0] === "route" && street == "") {
for (var j = 0; j < 4; j++) {
if (j == 0) {
street = results[i].address_components[j].long_name;
} else {
street += ", " + results[i].address_components[j].long_name;
}
}
}
if (results[i].types[0] === "street_address") {
for (var j = 0; j < 4; j++) {
if (j == 0) {
street = results[i].address_components[j].long_name;
} else {
street += ", " + results[i].address_components[j].long_name;
}
}
}
}
if (zipcode == "") {
if (typeof results[0].address_components[8] !== 'undefined') {
zipcode = results[0].address_components[8].long_name;
}
}
if (country == "") {
if (typeof results[0].address_components[7] !== 'undefined') {
country = results[0].address_components[7].long_name;
}
}
if (state == "") {
if (typeof results[0].address_components[6] !== 'undefined') {
state = results[0].address_components[6].long_name;
}
}
if (city == "") {
if (typeof results[0].address_components[5] !== 'undefined') {
city = results[0].address_components[5].long_name;
}
}
var address = {
"street": street,
"city": city,
"state": state,
"country": country,
"zipcode": zipcode,
};
document.getElementById('location').innerHTML = document.getElementById('location').innerHTML + "<br/>Street : " + address.street + "<br/>City : " + address.city + "<br/>State : " + address.state + "<br/>Country : " + address.country + "<br/>zipcode : " + address.zipcode;
console.log(address);
} else {
window.alert('No results found');
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY">
</script>
@Szkíta名前付き配列の住所部分を取得する関数を作成することで、優れたソリューションを実現しました。これは、プレーンJavaScriptを使用したい人のためのコンパイル済みソリューションです。
結果を名前付き配列に変換する関数:
function getAddressParts(obj) {
var address = [];
obj.address_components.forEach( function(el) {
address[el.types[0]] = el.short_name;
});
return address;
} //getAddressParts()
LAT / LNG値をジオコードします。
geocoder.geocode( { 'location' : latlng }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var addressParts = getAddressParts(results[0]);
// the city
var city = addressParts.locality;
// the state
var state = addressParts.administrative_area_level_1;
}
});