How to use Viewport from Google Geocoder in Leaflet JS? - google-maps-api-3

I have successfully set up a Leaflet JS map that uses the Google maps geocoder to pan to a geocoded address. But I am also trying to use "map.fitBounds" to get the appropriate zoom level from the Viewport, but it does not seem to be working. The code I am using is:
map.panTo([results[0].geometry.location.lat(),results[0].geometry.location.lng()]);
map.fitBounds([[results[0].geometry.viewport.southwest.lat(), results[0].geometry.viewport.southwest.lng()],[results[0].geometry.viewport.northeast.lat(), results[0].geometry.viewport.northeast.lng()]]);
See example here: http://chrismccreath.hostzi.com/geocode_test.html
How can I fix it so that it zooms to the appropriate viewport returned by the google maps geocoder result?

There are no properties like results[0].geometry.viewport.southwest/northeast(I guess you were watching at the network-traffic inside the console, but what you see there will not be passed to the callback-function directly). To get the southwest/northeast use the methods getSouthWest() and getNorthEast() of google.maps.LatLngBounds .
results[0].geometry.viewport is a google.maps.LatLngBounds-object, but you can't use it directly in Leaflet.
You must "convert" it to an array or an Leaflet.LatLngBounds-object.
This should work:
map.fitBounds([
[results[0].geometry.viewport.getSouthWest().lat(),
results[0].geometry.viewport.getSouthWest().lng()],
[results[0].geometry.viewport.getNorthEast().lat(),
results[0].geometry.viewport.getNorthEast().lng()]
]);

Thanks for posting the working example. It helped a lot. It didn't work immediately for me however, had to do some tweaking for it to work.
function codeAddress() {
var address = document.getElementById('address').value;
geocoder.geocode( {'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0].geometry.viewport) {
map.fitBounds([[results[0].geometry.viewport.getSouthWest().lat(),
results[0].geometry.viewport.getSouthWest().lng()],
[results[0].geometry.viewport.getNorthEast().lat(),
results[0].geometry.viewport.getNorthEast().lng()]]);
map.setZoom(18);
} else if (results[0].geometry.bounds) {
map.fitBounds([[results[0].geometry.bounds.getSouthWest().lat(),
results[0].geometry.bounds.getSouthWest().lng()],
[results[0].geometry.bounds.getNorthEast().lat(),
results[0].geometry.bounds.getNorthEast().lng()]]);
} else { // give up, pick an arbitrary zoom level
map.panTo(results[0].geometry.location);
map.setZoom(15);
}
} else {
$('#result').html('Geocode was not successful for the following reason: ' + status);
}
});
}
Just thought I'd post it if anybody else wasn't able to figure out how to get it to work.
Thanks again!

DrMolle pointed out that leaflet map objects are not Google Maps API v3 objects (in the other question you reference). This works:
map.panTo([results[0].geometry.location.lat(),results[0].geometry.location.lng()]);
map.fitBounds([[results[0].geometry.viewport.getNorthEast()],
[results[0].geometry.viewport.getSouthWest()]]);
working example
As described in the documentation:
results[].geometry.location is a google.maps.LatLng, which panTo requires as an argument.
results[].geometry.viewport is a google.maps.LatLngBounds, which fitBounds requires as an argument.

Related

Google Maps PlacesService, PlaceResult is only returning one (1) photo for the photos property array

Having an issue with the results from the Google Maps PlacesService. The resultant PlaceResult object is now only returning one photo in the photos property array. In the past this was not the case and up to 10 photos were returned. Is this a change?
Example code:
var request = {
reference: place.reference
}
var callback = function(details, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
alert("Number of photos: " + details.photos.length);
}
}
var service = new google.maps.places.PlacesService(map);
service.getDetails(request, callback);
fiddle showing an example
In a previous answer that has been deleted I said that it must be a bug on the Google side.
I just found this issue :
https://code.google.com/p/gmaps-api-issues/issues/detail?id=6825&sort=-id&colspec=ID%20Type%20Status%20Introduced%20Fixed%20Summary%20Stars%20ApiType%20Internal
If I am right, the Google Maps PlacesService is the Javascript version of the Google Places API, so the backend code might be the same : that could explain why we have the same results (same bug(?)).
Hope this helps.

Google maps direction renderer exact match only

I am using DirectionRenderer(gmap3) to show the user directions. The problem is it shows a match even if it cannot find an exact match. Eg: SomeFakePlace, myRealCity will match myRealCity even if it cannot match SomeFakePlace.
So it shows the directions from City's center to the place, instead. The destination is fixed(myLatLng)
I want it to return null and not show a route if cannot find one. I have decent error display to handle that.
$("#map-canvas-single").gmap3({
getroute:{
options:{
origin:$("#directions-from").val(),
destination:myLatlng,
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
callback: function(results){
console.log(results);
var point= results.routes[0].overview_path[0]
window.directionMarker = new google.maps.Marker({
position: new google.maps.LatLng(point.jb,point.kb),
title:$("#directions-from").val(),
//icon:"http://maps.google.com/mapfiles/ms/icons/<?php if($this->listing->type=="pg"):?>green<?php else: ?>purple<?php endif;?>-dot.png"
});
window.directionMarker.setMap($(this).gmap3("get"));
if(!results)
noty({text:"Place not found!",type:"error"});
else
{
$(this).gmap3({
directionsrenderer:{
container: $("#directions-container"),
id:"directions",
options:{
directions:results,
suppressMarkers :true //<<Look here>>
}
}
});
}
}
}
});
The code works fine and all. I think this the fault of direction renderer service, not gmaps. I am sure htere must be some parameter for an exact match
I'm not familiar with Google Maps API, but what I'd do is do a geocode lookup on the source address and find the lat, lng. You'll usually get coordinates with levels of confidence, so you can have a minimum threshold below which to throw an error.
https://developers.google.com/maps/documentation/geocoding/
Also, don't forget mapquest.
http://developer.mapquest.com/web/products/dev-services/geocoding-ws

How to search for cities in an area using Google Maps v3?

I tried to search for all cities within a visible map's bounds. How can I do that?
Below is what I tried to do:
$.fn.gmap3.geocoder.geocode({ 'address': 'Georgia' }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
globalMap.setCenter(results[0].geometry.location);
var resultBounds = new google.maps.LatLngBounds(
results[0].geometry.viewport.getSouthWest(),
results[0].geometry.viewport.getNorthEast()
);
globalMap.fitBounds(resultBounds);
// get cities in the map
var service = new google.maps.places.PlacesService(globalMap);
var request = {
bounds: resultBounds,
types: ['locality']
};
service.search(request, function (results, status) {
debugger;
});
}
});
But the result is ZERO_RESULTS. Maybe the reason is that the results are restricted to a radius of 50.000 meters?
Anyone knows how to solve my problem? Thanks a lot.
--UPDATE--
Thank, Sean, for reading my post carefully and give detail feedback.
This is how I refer to the lib:
src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=places"
I also added more detail to the geocode function to get more precise result. But I still don't get the results I want.
Check the list in this page: https://developers.google.com/places/documentation/supported_types, I realize that almost all items in the first list returns values but not for the second list. The only item return value is 'political' and it returns only 1 instead of 20.
This is my code after modifing:
this.setCenterByAddress = function (address, region) {
$.fn.gmap3.geocoder.geocode({ 'address': address, 'region': region }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
globalMap.setCenter(results[0].geometry.location);
var resultBounds = new google.maps.LatLngBounds(
results[0].geometry.viewport.getSouthWest(),
results[0].geometry.viewport.getNorthEast()
);
globalMap.fitBounds(resultBounds);
// get cities in the map
var service = new google.maps.places.PlacesService(globalMap);
var request = {
bounds: resultBounds,
types: ['country',
'administrative_area_level_1',
'administrative_area_level_2',
'administrative_area_level_3',
'colloquial_area',
'country',
'floor',
'geocode',
'intersection',
'locality',
'natural_feature',
'neighborhood',
'political',
'point_of_interest',
'post_box',
'postal_code',
'postal_code_prefix',
'postal_town',
'premise',
'room',
'route',
'street_address',
'street_number',
'sublocality',
'sublocality_level_4',
'sublocality_level_5',
'sublocality_level_3',
'sublocality_level_2',
'sublocality_level_1',
'subpremise',
'transit_station']
};
service.search(request, function (results, status) {
debugger;
});
}
});
}
MORE INFO: The same value return even when location and radius is used. And I use free map and receive "OVER_QUERY_LIMIT" all the time.
You shouldn't be limited to 50,000 meters unless you use the location and radius option, which you are not; you are using bounds. I suggest backing out a level and digging into the results that are returned from the starting call to geocode, because your usage of the PlacesService appears to be correct. What are the values internal to the resultBounds object? I also notice that you aren't using region biasing when you call the geocoder and it may be that "Georgia" is not sufficiently specific. For example, do you mean the region within the Russian Federation or the US state? And I'm not sure what URL you are using to load the Google Maps API & places library, but that could also be effecting your results.
I'd double-check the results coming back from the geocoder, because unless I am missing something, it looks like your basic approach is sound.
You can't return more than two near by localities around a particular latitude-longitude with Geocoding API/Places API
Please see this thread on Google Places API forum
This is not possible with the Google Places API as political results
such as locality, neighbourhood and sublocality are returned to
identify the area of the request and are limited to two per request.

Google Maps - Geocode 100 addresses and calibrate the view port?

I'm sure I'm dealing with a fairly common problem that's been solved many times before.
My web application requests about 100 line-delimited addresses of buildings from another service. I must now plot all these as gmarkers on a google map (with api version 3). I must also calibrate the view port to display all the gmarkers, that is determine the map center and the appropriate zoom value.
I found some code from the Google Maps API and tweaked it to plot one point:
function codeAddress() {
var address = '1 Yonge Street, Toronto, ON';
geocoder.geocode( { 'address': address}, geocodeCallBack);
}
function geocodeCallBack(results, status)
{
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
}
However, I suspect that performing 100 asynchronous geocoding calls may be slow. Does anyone have suggestion on the best way to achieve what I need?
Performing 100 Geocodes each time your page is loaded will take tens of seconds, so I suggest geocoding in advance.
If the addresses are always the same, or rarely change, you can geocode them in advance using the Geocoding Service (http://code.google.com/apis/maps/documentation/javascript/services.html) and temporarily store the resulting Lat/Lngs on your server as long as they are only ever displayed on a Maps API map.
Temporarily means that you must update these Lat/Lngs periodically (e.g. once every 30 days).
(See 10.1.3b for details: http://code.google.com/apis/maps/terms.html)

Google Maps Api v3 - new MarkerClusterer works too slow?

to create map clusterer, i use:
markerClustererGPC = new MarkerClusterer(myMap.map, markersGPC, GPCOptions);
but sometimes it does not works, and markerClustererGPC is sometimes undefined.
i search on this problem, and realise that (it looks like) server is sometimes too fast, and cluster is not defined due to that.
if server is a bit older (slower), it works without problems.
am i right about this? what can i do to avoid this problem, to make my code proper to work on any server?
i think because google map is not loaded completed so your map is unidentified.
Try add this:
var isLoad = false;
google.maps.event.addListener(map,'tilesloaded',
function () {
if (!isLoad) {
isLoad = true;
LoadClusterFunction();
}
});
after your call for creating map (map is variable for google map)

Resources