get google map zoom level when using fitBounds - asp.net

I want to get google map current zoom level, it gives me undefined error, I think because I don't use explicit zoom level in my map creation options, rather I use map.fitBounds, how can I get google map zoom level when I'm using map.fitBounds?
this is my code summary:
var mapOptions = { mapTypeId: google.maps.MapTypeId.ROADMAP };
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.fitBounds(bounds);
map.panToBounds(bounds);
now, when I want to use map.getZoom(), I get undefined, it seems that getZoom only returns explicitly set zoom levels

The Google Maps API v3 is event based. When the new zoom level is available to be queried, the zoom_changed event will fire.
To get the new zoom, do something like this:
google.maps.event.addListener(map, "zoom_changed", function() {
alert("the zoom level is now "+map.getZoom());
});
Note that this will fire every time the zoom is changed.

Related

how to add listener for markerclusterer finished loading?

I already added a map load listener after which i start adding markers to the cluster.
I wanna display a loading screen till the markerclusterer finishes the marker loading.
so how do i do that ?
this is my hide loading screen code which hides on map tiles load.
google.maps.event.addListener(map, 'tilesloaded', function() {
$("#loading").hide();
});
I know it's an old one but for anyone in the same situation I sort of found a solution.
Right after you are creating your cluster
markerCluster = new MarkerClusterer(map,
markers,
{
imagePath:
"/img/m/"
});
Add a listener for 'zoom_changed' like that:
google.maps.event.addListenerOnce(map,
'zoom_changed',
function(event) {
console.log("zoom occured");
});
(The listener once being key here, you don't want it to run every time the user zooms, you don't even need to set a different zoom value, nothing will happen visually)
and then:
map.setZoom(10);
I am using the same value (10) as in my InitMap function, so the user doesn't see any zoom in or outs.

google maps infoWindow click event re-renders map-canvas in Meteor

Hey Im trying to use google maps within my MeteorJS project to have google maps display on a map all customers, and then to display an infoWindow when you click on one of the markers.
problem is anytime you click on the marker it re-renders the map from scratch, i know this has to do with the the reactivity of the Session variable being set when the infoWindow is being clicked.
is there any way avoid the map being re-rendered when the session variable is changing?
thanks.
below is the JS and template im using in my project.
<template name="customers_map">
{{#constant}}
<div id="mapWrapper">
<div id="map-canvas"></div>
</div>
{{/constant}}
</template>
the code for making the google maps and markers.
Template.customers_map.rendered = function() {
$("#map-canvas").height("400px");
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(p) {
Session.set("myLat", p.coords.latitude);
Session.set("myLng", p.coords.longitude);
});
}
Deps.autorun(function(){
var mapOptions = {
center: new google.maps.LatLng(Session.get("myLat"), Session.get("myLng")),
zoom: 15,
zoomControl: true,
zoomControlOptions: {style: google.maps.ZoomControlStyle.SMALL},
streetViewControl: false,
mapTypeControl: false,
scaleControl: true,
mapTypeId: google.maps.MapTypeId.SMALL
}
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
var infowindow = new google.maps.InfoWindow({
content: Template.customers_infoWindow()
});
Customers.find().forEach(function(customer) {
if (customer.loc != null) {
var geo = customer.geoLocation();
var marker = new google.maps.Marker({
position: new google.maps.LatLng(geo.lat, geo.lng),
title: customer.name(),
icon:'http://maps.google.com/mapfiles/ms/icons/green-dot.png'
});
marker.setMap(map);
google.maps.event.addListener(marker, 'click', function() {
Session.set("customerId", customer._id);
infowindow.open(map,marker);
});
} else {
console.log(customer.name() + " has no geoLocation");
};
});
});
};
the infoWindow template
<template name="customers_infoWindow">
<h1>{{record.name}}</h1>
</template>
and the js for the infoWindow template
Template.customers_infoWindow.record = function() {
return Customers.findOne({_id: Session.get("customerId")});
}
If you create a global googlemaps object, you can access its properties from anywhere. This article has a nice example of doing this.
The overall gist is:
Create a googlemaps class with an initialize method. At the end of the initialize method, set a session variable for your map's existence. ( Session.set('map', true);)
Call create a googlemap object by calling the googlemap init method from within Template.customers_map.rendered.
It's a bit difficult to be sure without having a running version in front of me, but I think this is essentially because you have all your code in one big Deps.autorun block. Clicking one of the markers is changing the Session variable customerId, which will cause customers_infoWindow to re-render (as it's clearly a dependency), but I'm sure this is the intended behaviour.
However, since you're declaring var infoWindow in your Deps.autorun block to have an instance of that template as one of its properties, I think that changing customers_infoWindow will actually invalidate the entire Deps.autorun calculation, which means the whole block will be executed again, including the var map = new google.maps.Map(...) line, which will essentially re-render the map (even though it doesn't re-render that actual div element that contains it).
So, I would suggest splitting your code into separate Deps.autorun blocks, and making sure that anything in the same block should be re-run at the same time - clearly, this means that the Google Maps initialisation code and the infoWindow handler should be in separate blocks.
To reiterate, I think that's what's going on, but you'll have to try it and let me know...

Google Maps and Location

I'm building an application using CakePHP that will store events including the event location. When a user visits the application they will see a Google Map that will get their location and show events near them in the form of little pins that they can click on to view the event details.
I have some questions though:
1.) How would I store the Location in the DB? Would the actual geolocation coordinates be the best bet and how would I make it easy for a user to create an event and enter them.
2.) Once I have the events in place how do I create custom pins with the info pulled from the DB? Example like foursquare:
3.) Whilst getting the users location using HTML5 Geolocation how do I show a little loader on the map again like Foursquare does?
So far I've managed to create the Map and make the controls minified and get the location of the viewer but I'm not sure how do 3 and show a better feedback to the user for the geolocation.
If someone could help me with those other two questions as well it'd be very much appreciated as I'm finding it very confusing so far. Thanks.
var map;
function initialize() {
var myOptions = {
zoom: 8,
panControl: false,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
},
mapTypeControl: false,
scaleControl: false,
streetViewControl: false,
overviewMapControl: false,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'),
myOptions);
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
var infowindow = new google.maps.InfoWindow({
map: map,
position: pos,
content: 'Location found using HTML5.'
});
map.setCenter(pos);
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
}
function handleNoGeolocation(errorFlag) {
if (errorFlag) {
var content = 'Error: The Geolocation service failed.';
} else {
var content = 'Error: Your browser doesn\'t support geolocation.';
}
var options = {
map: map,
position: new google.maps.LatLng(60, 105),
content: content
};
var infowindow = new google.maps.InfoWindow(options);
map.setCenter(options.position);
}
google.maps.event.addDomListener(window, 'load', initialize);
1) Store the actual coordinates of the location and any extra meta data (if you have it) like place name, foursquare_id, date, etc. Storing it this way will make using the data later on straightforward, such as plotting on a map or location name lookup. This will be your Location model.
Create an Event model which you can then associate to a Location. You could hack together some nice interactive functionality using event handlers on your map markers.
Something like: "the user clicks a location on the map, up pops a box asking them would like like to create a new event at this location, marker is added to the map and a form appears where they can populate the event details, etc, etc." You get the idea.
Have a look at the Marker documentation.
2) You can set a custom image for the map markers using ImageMarker Class. Take a look at the huge set of examples for ideas of what's possible.
3) The navigator.geolocation.getCurrentPosition() method as I understand it, is asynchronous. The first argument is the successCallback.
With this in mind, you could set an overlay on your map: "Finding your location", then make the call to getCurrentPosition(). In your successCallback function, you would then hide the overlay.

When is remove_at event in Google Maps API v3 triggered?

I am working on google map api v3 and want to add a feature of editing the polyline. As of the google documentation. There are 3 events fired when a polyline is in edit mode.
insert_at
set_at
remove_at
I know when first two events are fired and am able to get the edited coordinates as well. I also want to delete a node but not sure how it works?. Can anyone tell me when will the event "remove_at" will be fired ?
According to the documentation these events belong to class google.maps.MVCArray. You can find there also a description of remove_at event:
This event is fired when removeAt() is called. The event passes the
index that was passed to removeAt() and the element that was removed
from the array.
But I'm not sure you can use these events to handle changes while editing the Polyline. That's very interesting, please let us know if it works and how!
'remove_at' will be triggered when you undo an edit to an existing overlay that results in control point(s) getting removed.
I've created a fiddle to demonstrate this.
From the fiddle:
var myLatlng = new google.maps.LatLng(60.629765, 6.424094);
var myOptions = {
zoom: 14,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var drawMan = new google.maps.drawing.DrawingManager({
map: map,
drawingControl: false,
polygonOptions: {
editable: true,
draggable: true
}
});
drawMan.setDrawingMode(google.maps.drawing.OverlayType.POLYGON);
google.maps.event.addListener(drawMan, 'overlaycomplete', function (event) {
// When draw mode is set to null you can edit the polygon you just drawed
drawMan.setDrawingMode(null);
google.maps.event.addListener(event.overlay.getPath(), 'remove_at', function () {
alert('remove_at triggered');
});
});

Google Maps: InfoWindow closing after auto pan

I have a map with a bunch of markers, and a table of data that corresponds to each marker. When the user clicks on an item in the table, the InfoWindow for the corresponding marker is opened. Everything works fine when the map is zoomed out and the markers are all visible, but if the map is zoomed in, and an InfoWindow for an off-screen marker is opened by clicking the item in the table, here is what happens:
The map scrolls to the correct location, where the InfoWindow already appears open
The map stops panning, and the InfoWindow disappears.
Any suggestions as to what might be going on and how to solve this?
Alright, the issue related to the fact that I was using the Marker Clusterer on the map... essentially, the following was happening:
Click item in table, InfoWindow opens
Map gets panned to the location to display the InfoWindow
When panning is complete, the Marker Clusterer was then re-drawing (if needed), and forcing the InfoWindow closed.
My solution was that when an item in the table is clicked, I get the corresponding Marker's latlng, manually pan to this location, wait for the panning to complete via the 'idle' listener, and when complete (and the Clusterer has done it's re-draw), THEN I open the InfoWindow.
// get map, marker positions
var mapLatLng = GLOBAL_map.getCenter();
var markerLatLng = GLOBAL_markers[index].getPosition();
// pan the map
if(!markerLatLng.equals(mapLatLng)) {
// map will need to pan
GLOBAL_map.panTo(markerLatLng);
google.maps.event.addListenerOnce(GLOBAL_map, 'idle', function() {
// open InfoWindow
GLOBAL_infowindow.setContent(GLOBAL_markers_content[index]);
GLOBAL_infowindow.open(GLOBAL_map, GLOBAL_markers[index]);
});
} else {
// map won't be panning, which wouldn't trigger 'idle' listener
GLOBAL_infowindow.setContent(GLOBAL_markers_content[index]);
GLOBAL_infowindow.open(GLOBAL_map, GLOBAL_markers[index]);
}
This drove me crazy. My solution is simpler, though. I just set a timer so I don't refresh the map within one second after a pin is clicked.
start with the global:
// global timer variable
var clickTime = Date.now() - 1001;
then define you marker click like:
marker.addListener('click', function() {
infoWindow.setContent(infowincontent);
infoWindow.open(map, marker);
clickTime = Date.now();
});
then set up your idle like:
google.maps.event.addListener(map, 'idle', function () {
if (Date.now() > (clickTime + 1000))
updateMap();
});
Don't use idle event. Use dragend and zoom_changed events from the API spec instead which will allow you to open your infoBoxes without refreshing the map.
google.maps.event.addListener(map, 'dragend', function() {
getMarkers();
});
google.maps.event.addListener(map, 'zoom_changed', function() {
getMarkers();
});

Resources