How to set google map custom zoom level dynamically? - google-maps

I am working with google map. According to requirements i need to set different zoom level that is dependent to my search query.If there are multiple location on the map in country then map should focus the country. Other scenario is , if there are different locations marked in a city then map should be focused to city level.

var geoCoder = new GClientGeocoder();
geoCoder.setViewport(map.getBounds());
geoCoder.getLocations('searchquery', function(latlng) {
if( latlng.Placemark.length > 0 ) {
var box = latlng.Placemark[0].ExtendedData.LatLonBox;
var bounds = new GLatLngBounds(new GLatLng(box.south, box.west), new GLatLng(box.north, box.east));
var center = new GLatLng(box.Placemark[0].Point.coordinates[1], latlng.Placemark[0].Point.coordinates[0]);
var zoom = oMap.getBoundsZoomLevel(bounds);
map.setCenter(center, zoom);
}
});
I think the key part of this for you is
//box is a LatLonBox with the size of your resultquery. You can create this yourself as well
var box = latlng.Placemark[0].ExtendedData.LatLonBox;
//bounds are the bounds of the box
var bounds = new GLatLngBounds(new GLatLng(box.south, box.west), new GLatLng(box.north, box.east));
//center is the center of the box, you want this as the center of your screen
var center = new GLatLng(box.Placemark[0].Point.coordinates[1], latlng.Placemark[0].Point.coordinates[0]);
//zoom is the zoomlevel you need for all this
var zoom = oMap.getBoundsZoomLevel(bounds);
//the actual action
map.setCenter(center, zoom);

After you perform the search, once you have the locations, you can use bounds.extend and map.fitBounds so the map automatically zooms to show all the pins returned by your search, like this:
//places is an array that contains the search result
var bounds = new google.maps.LatLngBounds();
for (var i = 0, place; place = places[i]; i++) {
//pass the location of each place to bounds.extend
bounds.extend(place.geometry.location);
}
//tell your map to sets the viewport to contain all the places.
map.fitBounds(bounds);
On the other hand, if you do a search for a zone like zip code, city or country using the geo coder, you can also use map.fitBounds to set the viewport to show the entire specific zone that was returned by the geo coder, like this:
//response is the geocoder's response
map.fitBounds(response[0].geometry.viewport);
Here's a codepen with the geocoder example https://codepen.io/jaireina/pen/gLjEqY

I found following article very helpful. using code sample code I can able to achieveenter link description here this.
I tried the code in drupal and it is working.

Related

Google Maps in Xamarin for Android fails to center on location

var _locator = CrossGeolocator.Current;
var mapPosition = await _locator.GetPositionAsync();
var mapSpan = MapSpan.FromCenterAndRadius(
new Xamarin.Forms.Maps.Position(mapPosition.Latitude, mapPosition.Longitude),
Distance.FromMiles(2)
);
Map.MoveToRegion(mapSpan);
Using Xamarin.Forms.Maps.Postion() the correct lat and lon coordinates are calculated.
However, when I add it to MapSpan, the coordinates change to somewhere in the middle of the Atlantic ocean. Not sure what is causing this?
UPDATE:
So the problem is definitely in the Android project. For some reason, GoogleMaps is not recognizing the location passed by the Map Renderer in the shared project. OnMapReady is just using the default lat/lon.
SUCCESS!!!
async Task<Plugin.Geolocator.Abstractions.Position> GetPositionAsync()
{
var _locator = CrossGeolocator.Current;
Plugin.Geolocator.Abstractions.Position myPosition = await _locator.GetPositionAsync();
return myPosition;
}
public void OnMapReady(GoogleMap googleMap)
{
Plugin.Geolocator.Abstractions.Position myPosition = Task.Run(GetPositionAsync).Result;
map = googleMap;
map.MoveCamera(
CameraUpdateFactory.NewLatLng(
new LatLng(myPosition.Latitude, myPosition.Longitude)));
map.AnimateCamera(
CameraUpdateFactory.ZoomTo(10));
The MapSpan properties LatitudeDegree and LongitudeDegrees refer to the degrees of latitude and longitude that are spanned (i.e. the number of degrees of the map that are shown within its view.)
If you are looking for the lat/lng of the center of the map in your span, refer to the Center properties which is a Maps.Postion object.
Re: https://developer.xamarin.com/api/type/Xamarin.Forms.Maps.MapSpan/
Example:
var mapPosition = new Position(38.29, -77.45);
var mapSpan = MapSpan.FromCenterAndRadius(mapPosition, Distance.FromMiles(2));
map.MoveToRegion(mapSpan);

Get Google Map Marker Position on Screen

Is there a way to get the bounding rectangle (screen position) of Google Map API markers? I am using an Angular 2 wrapper, so I don't construct the markers like you would normally with the API (mostly irrelevant here though).
Or are they on an internal canvas with no way to pull position like you would with an html element?
I have tried something like this, but getBoundingRectangle() comes back with zero values:
var googleMapContent = document.getElementsByClassName("sebm-google-map-content")[0];
var markerList = googleMapContent.getElementsByTagName("sebm-google-map-marker");
if( markerList.length > 0 ) {
for (var i = 0; i < markerList.length; i++ ){
var marker = markerList[i];
var markerLabel = marker.getAttribute("ng-reflect-label");
var boundingRectangle = marker.getBoundingClientRect();
}
}
P.S. I have access to map center lat/lng + zoom and marker lat/lng, so I can "math" this, but that's pretty dirty.
The Marker class hasn't got either a getBoundingRectangle or
getBoundingClientRect method.
It has got getPosition() and getShape() though, which in combination might give you the information you need.

How to make fitBounds aware of custom controls

I have a large (300*500px) custom control on the left side of my google map. I'm clustering my markers together. When a user clicks on a marker, I want to zoom the map in to show the markers in that cluster.
The problem is:
When I get the bounds of my marker collection, then map.fitBounds(collection_bounds), I end up with markers underneath my large control. Is there a way to prevent fitBounds from using the whole view port?
I have tried getting the LatLng of my south west bounds point, converting that to pixels, moving that 300px in, then converting that back to a LatLng to use as the new south west bounds point. This doesn't work though because the calculations are done before the zoom, so the 300px shift ends up being too much... I thought about writing my own fitBounds, but I hit the same issue, in that it's done before the zoom.
What you said works:
I have tried getting the LatLng of my south west bounds point,
converting that to pixels, moving that 300px in, then converting that
back to a LatLng to use as the new south west bounds point.
if you do it in two steps, which is pretty much transparent to the user because it is executed so fast that you hardly notice it. So, first you do a normal map.fitBounds(bounds); where bounds is only defined by your markers, and then you re-adjust with the technique you described. So:
google.maps.event.addListenerOnce(map,'bounds_changed',function(){
// re-adjust bounds here as you described.
// This event fires only once and then the handler removes itself.
});
map.fitBounds(bounds);
I had a 400pixel wide panel on the right hand size.
Starting from a call to zoomWithPoints passing two points to include in view, the following code implements the approach others have described: 1) Zoom to bounds 2) Using the resulting zoom level calculate how much to add onto the 'maxLon' 3) Zoom to bounds again.
function zoomToBbox(minLat, minLon, maxLat, maxLon) {
var southwest = new google.maps.LatLng(minLat, minLon);
var northeast = new google.maps.LatLng(maxLat, maxLon);
var bounds = new google.maps.LatLngBounds(southwest, northeast);
map.fitBounds(bounds);
}
function zoomWithPoints(lat1, lon1, lat2, lon2) {
var maxLat = Math.max(lat1, lat2);
var maxLon = Math.max(lon1, lon2);
var minLat = Math.min(lat1, lat2);
var minLon = Math.min(lon1, lon2);
zoomToBbox(minLat, minLon, maxLat, maxLon);
var z = map.getZoom(); //get the zoom level after zooming
// Add a bit to maxLon, to result in it panning left by 400 pixels
var widthOfPanel = 400;
var degreesPerTile = 360 / (Math.pow(2,z));
var degreesPerPx = degreesPerTile / 256;
var degreesForPanel = degreesPerPx * widthOfPanel;
maxLon = maxLon + degreesForPanel;
//zoom (pan across a bit) to take account of the added bit
zoomToBbox(minLat, minLon, maxLat, maxLon);
map.setZoom(z); //put it back to right zoom level if necessary
}
...call zoomWithPoints

jquery-ui-map fit bounds with a polyline?

I'm working on a mobile app using jQuery Mobile. I also you the plugin "jquery-ui-map" to do my map (that helped alot with display issues using only GMap with jQM).
I'm able to add polyline on the map and it works just fine. But when I try to use the fitBounds method, it doesn't work. In fact, it zoom out alot. But not on my bounds.
Here is my code :
// Added some data, so you can understand the structure
// of variable "plan"
plan[0].lat_a = 45.4681; plan[0].lng_a = -73.7414;
plan[0].lat_b = 45.6797; plan[0].lng_b = -74.0386;
plan[1].lat_a = 45.6797; plan[1].lng_a = -74.0386;
plan[1].lat_b = 48.7753; plan[1].lng_b = -64.4786;
var polylinesCoords = new Array();
var bounds = new google.maps.LatLngBounds();
// Starting point
var LatLng = new google.maps.LatLng(plan[0].lat_a, plan[0].lng_a);
bounds.extend(LatLng);
// Building the polyline coords and bounds
for (var x=0; x<plan.length; x++) {
polylinesCoords.push(new google.maps.LatLng(plan[x].lat_a, plan[x].lng_a), new google.maps.LatLng(plan[x].lat_b, plan[x].lng_b));
LatLng = new google.maps.LatLng(plan[x].lat_b, plan[x].lng_b);
bounds.extend(LatLng);
}
// Drawing polyline on map
$('#map_canvas').gmap('addShape', 'Polyline', {
'path': polylinesCoords,
'strokeColor': '#c00',
'strokeThickness': 5
});
// «Focus» map on polyline with bounds
var map = $("#map_canvas").gmap("get", "map");
map.fitBounds(bounds);
Everything in this snippet seems to works fine, except for the very last line.
Any ideas ?
You might've missed to center the map to any of your pin. I got your code working with this line of code
$('#map_canvas').gmap('option', 'center', (new google.maps.LatLng(plan[0].lat_a,plan[0].lng_a)));

Google Maps: scroll map programmatically of x pixels

Is there a simple way to scroll a google map programmatically of x pixels?
I can only think of using setCenter, but the problem is that I would have to compute the new location (lat/lng) depending on the zoom level...
Can you think of something else? Telling me that it's not possible with the Google Map API is a valid answer if you're pretty sure about it.
ps: I'm using Gmaps4rails, so if you can think of a way to do that with the gem, it'd be cool. (like adjusting the bounds to a subset of the map.)
Because in the end my goal is to prevent the menu from hidding some markers. I would need to change the viewport of the map, if that makes sense, so that it fits the markers into the orange area, not the full map.
Solution:
#Shane Best, great, the idea works perfectly, but I think your solution was for Google API v2, right? Here's how I did it for V3:
var point = map.getCenter();
var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
var projection = overlay.getProjection();
var pixelpoint = projection.fromLatLngToDivPixel(point);
pixelpoint.x += my_value; # or .y
point = projection.fromDivPixelToLatLng(pixelpoint);
map.setCenter(point);
If anybody knows about a better solution with API v3, tell us about it.
Take a look at the projection object:
http://code.google.com/apis/maps/documentation/javascript/reference.html#Projection
First you would need to get the center of the map.
var point = map.getCenter();
Convert the latlng to a point value.
var pixelpoint = projection.fromLatLngToPoint(point);
Add yourvalue to the point values.
pixelpoint.x = pixelpoint.x + yourvalue;
//or
pixelpoint.y = pixelpoint.y + yourvalue;
Convert it back to a latLng.
var newpoint = projection.fromPointToLatLng(pixelpoint);
Set the new center with the new value.
map.setCenter(newpoint);
I haven't tested the above but it should work.
I believe you are looking for this:
var panListener = google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
map.panBy(0,-90);
});
setTimeout(function() {
google.maps.event.removeListener(panListener)
}, 2000);
In this case, it moves the map south by 90px.