I have a problem with google maps v3 zoom_change, as it doesn't solve my need perfectly.
I have 2 unmet requirements:
I need to get the bounds and show points that are inside the bounds after the user clicked in zoom control and zoom has been reajusted in the map. The method zoom_change do it before reajusting zoom, and the bounds aren't the ones I need.
The method zoom_change is called every time, for example, whenever I execute fitBounds or setZoom. I only need it when when zoomcontrol is clicked or when mousewheel is moved.
Is there a solution available in the v3 API for those issues?
Listen for the idle event.
From Google Maps Javascript API V3 Reference:
idle: This event is fired when the map becomes idle after panning or
zooming.
The event is called zoom_changed (NOTzoom_change). The event handler of this event is called AFTER the zoom has changed. It is indeed not straightforward to distnguish the zoom change caused by the user from that one caused by the program. A possible solution is to maintain a "global" variable say userZoom which denotes whether the user triggered the zoom.
var userZoom = true; // initial value: be prepared for user action
// Install listener
google.maps.event.addListener(Map.self, 'zoom_changed', function() {
if (userZoom) {
// the user changed zoom: do what should be done
}
else {
// zoom change caused by a program action: ignore
}
userZoom = true; // be prepared for the user zoom action
});
Before you call any of the program actions that change the zoom, set userZoom = false, e.g.
userZoom = false;
map.setZoom(9);
The only real way I have found is to create a custom zoom control on the map,
https://developers.google.com/maps/documentation/javascript/controls?utm_source=welovemaspdevelopers&utm_campaign=stackoverflow#CustomEvents
and then set an event listener on the control,
https://developers.google.com/maps/documentation/javascript/controls?utm_source=welovemaspdevelopers&utm_campaign=stackoverflow#ControlModification.
Clearly not elegant, but an option.
Related
I need to show some Sprites when the camera gets close to a building and when the camera zoom out, remove the Sprites.
Is there any event that triggered when zoom changes? Also, How can we get the current zoom value?
There is an event trigerred when Camera changes (included zoom) :
viewer.addEventListener(Autodesk.Viewing.CAMERA_CHANGE_EVENT, (e) => {
console.log(e)
})
There is a zoom property in the event received. You will additionally find a lot of informations
Recently on a project I was displaying an Info Window on the click of a map marker where the content was loaded with an XHR request. There was a noticeable delay from the time of the click event to when the AJAX callback triggered the opening of the Info Window and I wanted to change the mouse cursor to a 'wait' icon so the user knew their click had triggered something.
I first tried setting a cursor style on body, html but found the styles used by the map superseded this.
So, how to set a wait cursor regardless of the mouse pointer being positioned over the marker, map, or elsewhere on the page?
This is the first time I've posted a question I have an answer ready for. I found some posts talking about setting either a map cursor or a marker cursor buy nothing concisely explaining how to accomplish what I am asking here. Hope this saves someone a little time.
I ended up with the following code to accomplish this:
/**
* Event handler for marker click event
*/
function markerClickHandler(marker, event) {
$('html, body').css("cursor", "wait");
auctionMap.setOptions({draggableCursor: 'wait'});
marker.setCursor('wait');
$.ajax({
type: 'GET',
url: '/get-marker-info/' + marker.some_id,
dataType: 'html',
}).done(function(response) {
infoWindow.setContent(response);
infoWindow.open(map, marker);
}).fail(function() {
alert('An unknown error occurred.');
}).always(function() {
$('html, body').css("cursor", "auto");
auctionMap.setOptions({draggableCursor: null});
marker.setCursor(null);
});
}
This gets a wait cursor to display when the mouse is anywhere on the page, in or out of the map, and while over the marker.
The draggableCursor by default uses an image of an open hand (http://maps.gstatic.com/mapfiles/openhand_8_8.cur), not a standard CSS cursor property value.
This is why we use null when reverting the cursor after the call is completed, rather than say using the cursor auto.
It works well enough though is a little wonky in its interactions with mouse movement to trigger the transition. Curious if anyone could improve the code in that regard.
See an example: http://jsfiddle.net/0ere5tju/
I am working with the GoogleMaps API and I'm trying to distinguish between a rectangle object being resized or moved.
I am using the listener like so:
google.maps.event.addListener(newShape, 'bounds_changed', function() {
// do stuff
});
However, this will fire when the rectangle is resized AND when it is moved completely. Is there some way to distinguish between these two distinct events?
I tried the way #Darwin has suggested. When we just begin to drag the coordinates still remain the same and so the event is fired for drag as well as bounds_changed
An easier and more reliable way, I did is to have a global variable called isBeingDragged and set it to true in dragstart event handler. In the bounds_changed event handler, I checked if this variable is true. If it is not, its a resize event, else it is a drag event.
I again set the isBeingDragged variable to false in drag_end event handler.
Store the bounds of the rectangle initially, when the event fires check if both(soutWest and NorthEast) have been changed. When It does , the rectangle has been moved, otherwise it has been resized.
After the check update the stored bounds.
If certain conditions are met when an infoWindow is closed, I want to prevent the default close event that is fired. Is it possible to achieve that? I tried a number of things like:
Stopping event propagation
returning false from the callback method
there aren't any methods/properties exposed by the infoWindow either that prevent close.
Please let me know if this is possible.
The InfoWindow doesn't really provide a way to step event propagation. I don't know if it could work for you, but there is an InfoBox Utility Library that does give you a great deal more of control oven its behavior. Specific to your question, the InfoBoxOptionsapi-doc object includes the property:
enableEventPropagation, a boolean, that will allow you to control whether the InfoBox will: propagate mousedown, click, dblclick, and contextmenu events in the InfoBox (default is false to mimic the behavior of a google.maps.InfoWindow). Set this property to true if the InfoBox is being used as a map label. iPhone note: This property setting has no effect; events are always propagated.
The only thing you can do is catch the closeclick event which leads you nowhere.
I have hacked something together once, for a one-off solution, that might or might not work for you: I have identified a way to get to the x-mark that the user clicks to close, and removed that. The user can't close the infoWindow. At all. You still can, by calling .close().
WARNING! THIS IS A HACK
var a=document.getElementById('map_canvas');
var b=a.getElementsByTagName('img');
var i, j=b.length;
for (i=0; i<j; i++) {
if(b[i].src.match('imgs8.png')){
if(b[i].style.left=='-18px') {
c=b[i].parentElement.parentElement;
console.log(c);
if(c.innerText.match("Map data")) {
console.log('no');
} else {
b[i].parentElement.removeChild(b[i]);
}
}
}
}
Now. If you store a reference to the [x] mark, you could even turn it on and off at will.
EDIT:
A demonstration of this hack
You could always listen for the close event and then throw a javascript error to keep it from closing. Ex:
google.maps.event.addListener(my_infoWindow, 'closeclick', function(e){
// Throw an error to stop the close
throw "stop close";
})
I'm using HTML geolocation and I'd like to achieve the following:
1. User arrives at page
2. User is asked to share location
3. When user says yes, Google Maps initialises and centres on their position
4. We add marker to map showing their position
5. (ongoing) As the user moves, the marker continues to move with them
I've implemented this as follows:
// Add a marker
function addMarker(loc) { // adds marker }
function setupMap(loc) { // initialise map and centre on user's position };
setUpMap(???????);
// Start watching user's position
var watchID = navigator.geolocation.watchPosition(addMarker);
So my question is: how can I get the initial position in order to set up the map?
I can see two options, both of which have flaws:
Call setUpMap from within addMarker, but then the map gets re-initialised each time the user moves, which is obviously inefficient.
Call navigator.geolocation.getCurrentPosition before calling watchLocation - but then the user seems to get prompted twice for their location, which looks clunky.
Any better ideas?
Thanks everyone.
UPDATE
OK, it seems I haven't explained this well. My question is really: how do I get the user's location from watchPosition, as a one-off, so that I can initialise the map once?
Call this:
navigator.geolocation.watchPosition
instead of this:
navigator.geolocation.getCurrentPosition
watchPosition function also initializes positions.
3. Call watchLocation in step two, i.e. to get initial location (the user therefore will only get prompted once)