Map with overlay is not moving after zoom - google-maps

I am creating a map which returns the LatLng by pixel on screen, therefore I need a OverlayView implemented within the map. Unfortunately with the OverlayView, there is an issue after zoom in or out. When dragging the map after zoom, it does return me a new LatLng, but the screen is still showing the same location.
I am not sure how to fix it but the issue will gone once I pan the map with the pan control, then I could drag the map no matter the zoom level.
can anybody give me an advise?
Thanks,
Nick

To fix this issue, just call panTo function in the "zoom_changed" event.
google.maps.event.addListener(mymap, "zoom_changed", function() {
mymap.panTo(mymap.getCenter());
});
The map may not move smoothing because the panTo function is only called by zoom_change event unfortunately, so just call the panTo function after the map is initialized. Then the map could be moving around and different zoom level.

Related

Positioning a draggable map marker at top-left of map window

I have a Google map that I am using to allow people to suggest locations. Currently I position a draggable marker in the centre of the map using a LatLng created with
myPosition = frmMap.getCenter();
What I would like to do though is place it initially somewhere to the edge of the map, perhaps directly under the zoom control (not unlike the way you see the yellow street view man above the zoom control).
I've searched for a solution but am not coming up with anything. My only idea was to do some maths based on the Center and NortEast but I'd rather have an absolute position based on pixels if that's possible?
As I mentioned in the comments, computing a latlng value for a marker to position under the zoom controls is not only cumbersome, but might not be feasible if the user starts panning/zooming around in the map (as the marker will move wherever the latlng takes it).
My suggestion would be to use the Drawing Library provided by the Maps API. This basically gives you a drawing control, to add markers to the map (other overlays are possible too: cirlce, polygon, polyline, rectangle). And like any control google maps provides, you can strictly position them anywhere you'd like - by setting it in the options. The snippet below describes how you initialize the drawing library:
var drawingManager = new google.maps.drawing.DrawingManager({
drawingControlOptions: {
position: google.maps.ControlPosition.LEFT_BOTTOM,
drawingModes: [
google.maps.drawing.OverlayType.MARKER
]
}
});
drawingManager.setMap(map);
This gives you your drawing control, with the mode for Marker enabled, and binds it to your map object.
You can then listen to when a marker's been added by adding a listener on the drawingManager variable for the markercomplete event. Then in the call back you can get the position of the added marker, the snippet below demonstrates this:
google.maps.event.addListener(drawingManager, 'markercomplete', function (marker) {
var position = marker.getPosition();
});
I put together a small jsfiddle with this example if you'd like to see it in action. Also, click here for full reference of the Drawing Library for the maps api.
EDIT: (start mode in marker add on map load, hide drawing controls after marker added, maker marker draggable)
To start the drawing mode to add marker on map load, simply set the drawingMode option in your drawingManager variable declaration:
`drawingMode : google.maps.drawing.OverlayType.MARKER`
You can hide the drawing controls in the markercomplete event listener:
// To hide:
drawingManager.setOptions({
drawingControl: false //changes UI back to regular map interactions
});
drawingManager.setDrawingMode(null); //hides controls
Alternatively, if you're never going to need the drawing controls again later in your client interactions you can remove it from the map complete via:
drawingManager.setMap(null);
Then to make the marker draggable, just set the option in the listener as well (because the marker in the callback function is a google maps marker object anyway - which references the marker that's added to your map).
marker.setOptions({
draggable: true
});
You can then add a listener on the marker object for the dragend event to track changes to the location.
Here's in updated fiddle: http://jsfiddle.net/svigna/J5zMg/3/

Google Maps API v3: Markers not being removed

I'm creating a map that loads & destroys markers based on both the bounding box and zoom level. I'm having a real problem getting markers to properly be removed, it seems to work sometimes for certain situations.
I have an object that contains the marker info, which also contains the google maps marker object. My code detects if the market should be deleted based on the bounding box or zoom-level. I set the marker object to "setMap(null);" and using firebug I can see that its being set, I then remove the parent object entirely and the objects data length is updated properly.
I output to the firebug console when a marker is supposedly deleted, seems to be working and I can see that the marker isn't being re-crated from the ajax call for markers on the boundingbox change.
Yet if I zoom around the map I can sometimes see that the markers are being removed, if I zoom away then pan back holding the mouse down. Or sometimes the markers will all be removed if I zoomout the first time, but if I zoom in again then back out they are not removed.
I must be doing something wrong with the logic of my code, I'm stumped.
You can view the source of
http://www.trailforks.com/map/test.php?lat=49.352247&lon=-123.202413
the JS is
http://www.trailforks.com/map/includes/map.js
the code for deleting a marker is at the bottom
function clearMarkerMemory(mapItem, i) {
google.maps.event.removeListener(mapItem.lis); // remove stored listener
mapper.data[i].obj.setMap(null); // remove marker
mapper.data.splice(i, 1);
console.log("removed marker "+mapItem.icon+":"+mapItem.nid+' '+mapItem.name);
};
I added some more debug into to the console, going to a simple area of the map with only 2 markers http://www.trailforks.com/map/test.php?lat=49.43210641783767&lon=-123.49878636730955&z=14
I can see the markers created, then move the map a bit and see that the markers weren't re-created because they were detected in the marker object. I then move the viewport so one of the markers is off the screen and I can see that the marker is removed and the marker object length updates. But if I pan the map back over the marker is still on the map.
I was struggling with similar problem for a long while until I realized that the map marker's setMap-method is asynchronous. When you call that and immediately remove any references to that marker object, the browser's garbage collector steps in and cleans it up from the memory and thus prevents the actual remove operation from happening.
Try it out by just commenting out the line with the splice call and see if that helps. If it does help, you should consider delaying the removal of the object, or alternatively storing the reference to the marker object until it's really removed. How to detect if it's really removed? I have no idea.
I hope this helps!
Instead of doing:
google.maps.event.addListener(map, 'dragend', function() { refreshMarkers(); }); //refresh markers when user moves map
google.maps.event.addListener(map, 'zoom_changed', function() { refreshMarkers(); }); //refresh markers when user moves map
change it to:
EDIT, (after comments):
To prevent multiple instances of the event handler occurring simultaneously, a global variable could be used, as follows:
google.maps.event.addListener(map, 'bounds_changed', function() {
if (processing) { // var processing is global
return;
}
processing = true;
refreshMarkers();
processing = false;
}); //refresh markers when user moves map
That should cover both situations. As it is now, with two different event listeners, the AJAX calls could be conflicting, and you maybe firing a second call before the first one has completed.

How to disable "auto panning" when dragging a marker near edge of Google Maps?

Basically I don't want the map to start automatically panning when someone is dragging a marker. Today, whenever someone drags a marker near the map edge, the map starts panning, panning even continues when they are outside the boundaries of the map canvas.
Pretty sure this "auto" panning is the default for any map (Google javascript Maps API 3.x) that has draggable markers and "normal" panning capabilities.
I want to keep the ability to pan the map with the mouse but I need to disable the "auto" panning that occurs when someone is dragging a marker near the edges of the map. (also need to keep draggable markers).
Thanks in advance.
Use the dragstart and dragend events of the marker to switch on and off the draggable property of the map. The map object does not have a setDraggable method so you need to use the set method.
google.maps.event.addListener(marker, 'dragstart', function(){
map.set('draggable', false);
});
google.maps.event.addListener(marker, 'dragend', function(){
map.set('draggable', true);
});

Google Static Map API how to specify max zoom level

We have a report that shows where 2 markers are on a map, works great except when the markers are next to each other it zooms in to the highest level of zoom.
We want the min zoom to be open, but set the max zoom to a certain level. I have looked through the Google Static Map documentation, and cant see where to do it.
Does anyone know if this is possible using the static map api?
Cheers.
Google does not have that feature in place. Here is a feature request:
Issue 3909
http://code.google.com/p/gmaps-api-issues/issues/detail?id=3909
Please vote!
Well it is sort of not straight forward to get it with static maps. You can omit specifying the zoom and hope google will choose what it thinks best.
Anyway this is how I got rid of it. I had my own zoom up / zoom down buttons to show up next to the map image. Upon click, I increase or decrease the current zoom value and reload the map image.
I know it's not pretty, but it gets the job done.
I have not tried that for static maps but it works for me in normal map:
google.maps.event.addListener($map, 'zoom_changed', function(){
if($map.getZoom()<4){$map.setZoom(4);}
if($map.getZoom()>14){$map.setZoom(14);}
});
Here I am limiting both max and min zoom.
Hope it helps
K
http://maps.google.com/staticmap?markers=-21.7164,35.4384&size=640x640&key=your-api-key&format=png8&maptype=roadY&zoom=8
Note the zoom querystring parameter
I found the following code from this URL:
http://code.google.com/apis/maps/documentation/javascript/events.html
google.maps.event.addListener(marker, 'click', function() {
map.setZoom(8);
});
Instead of adding listener, you could do document.onload(function() {
map.setZoom(8));

Snap to nearest street

You guys have been helping out solving some of my problems with a Google Map lately, and thank you for that.
I am almost done with this - only one problem is left. When I place the first marker on the map, it snaps to the nearest street (which is fine!) but when I drag the first marker to another place, directions suddenly mess up. And the markers get mixes.
You can see an example on http://dev.korebogen.dk/gmap/
I need to make it possible to move the first marker (still snapping) and when I place the second marker, the directions first load. But in order to make the first marker snap again, I have to load the directions.
I hope some of you have a solution. Thanks in advance.
Blackpool Community Church Javascript Team has an excellent example of exactly this (direct link to the fourth example). Check out their other examples as well.
(disclaimer: I'm not affiliated with them, but have learned a lot about GMaps from their examples)
Edit:
I suspect the map events fire somewhat like this (pseudocode, for real event names etc. check the GMaps docs):
map click: mousedown, mouseup, click:{set red marker}
drag red marker: mousedown, dragstart{red marker}, mouseup, click:{set marker b} (mousedown+mouseup), dragend
both markers are set? Yes, get directions
What I'd suggest: in red-marker and marker-A dragstart functions, set some flag "dragging a marker", reset it in dragend function; in the Set marker B function, only set marker if we're currently NOT dragging something (flag is not set).
The code I gave you previously listened for the first two clicks, and added a marker for each. The problem is that when you drag the first marker, it's calling the "click" event again - and thus adding another marker at the same location.
Fortunately, the click event lets you know whether an overlay was clicked. So only execute the code that adds a new marker if overlay is null. Note that overlay is not a boolean.
var listener = GEvent.addListener(map, "click", function(overlay, latlng) {
if (overlay == null) {
// code to add new marker
}
});