내가 가진 위도 / 경도 값 모음을 기반으로 한 국가, 주 및 도시 목록이 필요합니다. 계층 구조가 중복되지 않고 보존되는 방식으로이 정보를 저장해야합니다 (예 : "USA"와 "United States"및 "United States of America"는 동일한 국가입니다. 내 데이터베이스에이 국가의 인스턴스 하나만 필요함). .
Google Map API로 가능합니까?
내가 가진 위도 / 경도 값 모음을 기반으로 한 국가, 주 및 도시 목록이 필요합니다. 계층 구조가 중복되지 않고 보존되는 방식으로이 정보를 저장해야합니다 (예 : "USA"와 "United States"및 "United States of America"는 동일한 국가입니다. 내 데이터베이스에이 국가의 인스턴스 하나만 필요함). .
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
합니까?
여기에 기본적인 대답이 있습니다. 위치 정보를 사용하여 도시 이름 가져 오기
그러나 당신이 찾고있는 것을 위해, 나는이 방법을 추천 할 것입니다.
admin_area_level_1도 필요한 경우에만 파리, 텍사스, 미국 및 파리, Ile-de-France, 프랑스에 대해 다른 정보를 저장하고 수동 폴백을 제공합니다.
-
Michal의 방식에는 특정 결과가 아니라 첫 번째 결과를 취하는 문제가 있습니다. 그는 결과 [0]를 사용합니다. 내가 적합하다고 생각하는 방식 (방금 코드를 수정 했음)은 유형이 "locality"인 결과 만 가져 오는 것입니다. 이는 브라우저가 지리적 위치를 지원하지 않는 경우 최종 수동 대체에서도 항상 존재합니다.
그의 방법 : 가져온 결과는 사용과 다른 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 자바 스크립트를 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;
}
});