I'm using Google's Geocoder to find lat lng coordinates for a given address.
var geocoder = new google.maps.Geocoder();
geocoder.geocode(
{
'address': address,
'region': 'uk'
}, function(results, status) {
if(status == google.maps.GeocoderStatus.OK) {
lat: results[0].geometry.location.lat(),
lng: results[0].geometry.location.lng()
});
address
variable is taken from an input field.
I wan开发者_Python百科t to search locations only in UK. I thought that specifying 'region': 'uk'
should be enough but it's not. When I type in "Boston" it's finding Boston in US and I wanted the one in UK.
How to restrict Geocoder to return locations only from one country or maybe from a certain lat lng range?
Thanks
Use componentRestrictions attribute:
geocoder.geocode({'address': request.term, componentRestrictions: {country: 'GB'}}
The following code will get the first matching address in the UK without the need to modify the address.
var geocoder = new google.maps.Geocoder();
geocoder.geocode(
{
'address': address,
'region': 'uk'
}, function(results, status) {
if(status == google.maps.GeocoderStatus.OK) {
for (var i=0; i<results.length; i++) {
for (var j=0; j<results[i].address_components.length; j++) {
if ($.inArray("country", results[i].address_components[j].types) >= 0) {
if (results[i].address_components[j].short_name == "GB") {
return_address = results[i].formatted_address;
return_lat = results[i].geometry.location.lat();
return_lng = results[i].geometry.location.lng();
...
return;
}
}
}
}
});
UPDATE: This answer may not be the best approach anymore. See the comments below the answer for more details.
In addition to what Pekka already suggested, you may want to concatenate ', UK'
to your address
, as in the following example:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps Geocoding only in UK Demo</title>
<script src="http://maps.google.com/maps/api/js?sensor=false"
type="text/javascript"></script>
</head>
<body>
<div id="map" style="width: 400px; height: 300px"></div>
<script type="text/javascript">
var mapOptions = {
mapTypeId: google.maps.MapTypeId.TERRAIN,
center: new google.maps.LatLng(54.00, -3.00),
zoom: 5
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
var geocoder = new google.maps.Geocoder();
var address = 'Boston';
geocoder.geocode({
'address': address + ', UK'
},
function(results, status) {
if(status == google.maps.GeocoderStatus.OK) {
new google.maps.Marker({
position:results[0].geometry.location,
map: map
});
}
});
</script>
</body>
</html>
Screenshot:
I find that this is very reliable. On the other hand, the following example shows that neither the region
parameter, nor the bounds
parameter, are having any effect in this case:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps Geocoding only in UK Demo with Bounds</title>
<script src="http://maps.google.com/maps/api/js?sensor=false"
type="text/javascript"></script>
</head>
<body>
<div id="map" style="width: 500px; height: 300px"></div>
<script type="text/javascript">
var mapOptions = {
mapTypeId: google.maps.MapTypeId.TERRAIN,
center: new google.maps.LatLng(50.00, -33.00),
zoom: 3
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
var geocoder = new google.maps.Geocoder();
// Define north-east and south-west points of UK
var ne = new google.maps.LatLng(60.00, 3.00);
var sw = new google.maps.LatLng(49.00, -13.00);
// Define bounding box for drawing
var boundingBoxPoints = [
ne, new google.maps.LatLng(ne.lat(), sw.lng()),
sw, new google.maps.LatLng(sw.lat(), ne.lng()), ne
];
// Draw bounding box on map
new google.maps.Polyline({
path: boundingBoxPoints,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2,
map: map
});
// Geocode and place marker on map
geocoder.geocode({
'address': 'Boston',
'region': 'uk',
'bounds': new google.maps.LatLngBounds(sw, ne)
},
function(results, status) {
if(status == google.maps.GeocoderStatus.OK) {
new google.maps.Marker({
position:results[0].geometry.location,
map: map
});
}
});
</script>
</body>
</html>
The correct way of doing this is by providing componentRestrictions
For example:
var request = {
address: address,
componentRestrictions: {
country: 'UK'
}
}
geocoder.geocode(request, function(results, status){
//...
});
According to the docs, the region parameter seems to set a bias only (instead of a real limit to that region). I guess when the API doesn't find the exact address in the UK place, it will expand it search no matter what region you enter.
I've fared pretty well in the past with specifying the country code in the address (in addition to the region). I haven't had much experience with identical place names in different countries yet, though. Still, it's worth a shot. Try
'address': '78 Austin Street, Boston, UK'
it should return no address (Instead of the US Boston), and
'address': '78 Main Street, Boston, UK'
Should return the Boston in the UK because that actually has a Main Street.
Update:
How to restrict Geocoder to return locations only from one country or maybe from a certain lat lng range?
You can set a bounds
parameter. See here
You would have to calculate a UK-sized rectangle for that, of course.
I found problems with putting ",UK", setting the region to UK and setting bounds. However, doing ALL THREE seems to fix it for me. Here's a snippet:-
var sw = new google.maps.LatLng(50.064192, -9.711914)
var ne = new google.maps.LatLng(61.015725, 3.691406)
var viewport = new google.maps.LatLngBounds(sw, ne);
geocoder.geocode({ 'address': postcode + ', UK', 'region': 'UK', "bounds": viewport }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
.....etc.....
I tried with the following:
geocoder.geocode( {'address':request.term + ', USA'}
And its working for me for particular region (US country).
I always found this to be pretty easy to filter through since the results can vary and the region doesn't seem to work.
response( $.map( results, function( item ) {
if (item.formatted_address.indexOf("GB") != -1) {
return {
latitude: item.geometry.location.lat(),
longitude: item.geometry.location.lng()
}
}
}
For the united kingdom, you have to use GB for region. UK is not the ISO country code!
I prefer a hybrid approach.
- Use componentRestrictions to severely limit to country first.
If that doesn't yield enough results, search more broadly (and re-introduce bias if necessary)
function MyGeocoder(address,region) { geocoder = new google.maps.Geocoder(); geocoder.geocode({ 'address': address, 'componentRestrictions': { 'country': region } }, function (r, s) { if (r.length < 10) geocoder.geocode({ 'address': address /* could also bias here */ }, function (r2, s2) { for (var j = 0; j < r2.length; j++) r.push(r2[j]); DoSomethingWithResults(r); }); else DoSomethingWithResults(r); }); }
function DoSomethingWithResults(r) { // Remove Duplicates var d = {}; r = r.filter(function (e) { var h = e.formatted_address.valueOf(); var isDup = d[h]; d[h] = true; return !isDup; });// Do something with results }
I find that for a lot of ambiguous queries, the US always takes precedence in Google, even if you try to tell it where to look. You can look at the response and perhaps ignore it if output country=US?
That is the main reason I stopped using Google Geocoder a while ago and started building my own two years ago.
https://geocode.xyz/Boston,%20UK will always return the UK location. You can make extra sure by adding region=UK: https://geocode.xyz/Boston,%20UK?region=UK
I have Created Border All Around Uk and check if my Lat and Lng are in the Range. For 3 k addresses I have around 10 up to 20 addresses in US. I just Ignore them(I can do that in my case) I use lat and lng for creating multi markers on static map with auto zoom. I will share my Solution maybe this will be help for someone. Also I'm Happy to hear different Solutions for my case.
private static string ReturnLatandLng(string GeocodeApiKey, string address)
{
string latlng = "";
Geocoder geocoder = new Geocoder(GeocodeApiKey);
var locations = geocoder.Geocode(address);
foreach (var item in locations)
{
double longitude = item.LatLng.Longitude;
double latitude = item.LatLng.Latitude;
double borderSouthLatitude = 49.895878;
double borderNorthLatitude = 62.000000;
double borderWestLongitude = -8.207676;
double borderEastLongitude = 2.000000;
//Check If Geocoded Address is inside of the UK
if (( (borderWestLongitude < longitude) && (longitude < borderEastLongitude) ) && ( (borderSouthLatitude < latitude) && (latitude < borderNorthLatitude) ) )
{
latlng = item.LatLng.ToString();
}
else
{
latlng = "";
Console.WriteLine("GEOCODED ADDRESS IS NOT LOCATED IN UK ADDRESSES LIST. DELETING MARKER FROM MAP.....");
}
}
return latlng;
}
I had to filter results to a country myself today. I found out that the two character country code in componentRestrictions:country: does not work. But the full country name does.
This is the full_name in the address_components from a result.
精彩评论