I am developing a web application that uses Bing maps 7.0. I was wondering if there was a way to bind a function to a Map class event that listens for when the map is either dragged or zoomed. From what I see in the documentation, the viewchangeend event for the Map class is close to what I am looking for, however this event is called in situations that I do not particularly want to account for, such as if I hide the map's containing div using jQuery or on map creation/initialization. Ideally, I would also like this to be a throttled event, where the handler function gets called after a given amount of time. Any idea on how this could be implemented?
Update
As suggested by psousa, I used the viewchangeend event.
This is the hack around that I tried implementing to sort of try and detect if the map has zoomed or been dragged. I still bind the handler to the viewchangeend event, but this time I check to see if the Northwest coordinates or Southeast coordinates of the map have changed.
var map; // contains Microsoft.Maps.Map instance
var nw; // contains the NW Microsoft.Maps.LocationRect instance
var se; // contains the SE Microsoft.Maps.LocationRect instance
// initialization code goes here some where
Microsoft.Maps.Events.addThrottledHandler(map, "viewchangeend", function(arg) {
var curNW = map.getBounds().getNorthwest();
var curSE = map.getBounds().getSoutheast();
if (nw.latitude != curNW.latitude ||
nw.longitude != curNW.longitude ||
se.latitude != curSE.latitude ||
se.longitude != curSE.longitude)
{
nw = curNW;
se = curSE;
// Execute actual handler code here
}
}, 1000);
This code does not work as I had intended. As I'm debugging the code, if I go and hide the map's containing div (using jQuery), I notice that curNW and and curSE do not have the same coordinates as the ones I stored on the previous call. Why is this if I never dragged the map around or zoomed in or out? I am just hiding the map, why would the map's coordinates change? It makes no sense to me. Ideally, I wish Bing maps would provide developers with a zoomend or dragend event so I can say:
Microsoft.Maps.Map.addThrottledHandler(map, "zoomend", handler, 1000);
Microsoft.Maps.Map.addThrottledHandler(map, "dragend", handler, 1000);
Google Maps I believe provides this functionality. If anyone knows a better way to check for these events, please let me know. I don't want to add additional handlers to the elements of the page that may trigger a viewchangeend as there is way to much stuff going on in this page as it is. Appreciate the help.
The viewchangeend and viewchange are the best events for that, so no great alternative there.
Anyway, you have out-of-the-box support for throttled events. So, instead of:
Microsoft.Maps.Events.addHandler(map, 'viewchangeend', handler);
you can just use (the last argument uses milliseconds):
Microsoft.Maps.Events.addThrottledHandler(map, 'viewchangeend', handler, 500);
Reference: http://msdn.microsoft.com/en-us/library/gg427623.aspx
Related
I have a google map that I am building.
I have a listener on it:
google.maps.event.addListener(map, 'idle', function(ev){
plotzips();
});
The function on the inside calls for a kml:
var kmlLayer = new google.maps.KmlLayer(url, {
suppressInfoWindows: false,
map:map,
zindex: 0,
clickable : false
});
Now. Whenever there's a movement on the map done by a user, the kml refreshes.
This part works.
The problem is that it works too well. the trigger 'idle' works also during the refresh when the kml loads. How do I use the trigger ONLY when a user moves the map?
Thanks
Even though the API documentation (check the section under "Events") states that the 'idle' event is "fired when the map becomes idle after panning or zooming," I (like you) have found that it also fires for other things.
You might have better luck with the 'dragend' event. Check the "Events" section on the "Map" class here. To get the precise behavior you're looking for, you may need to bind to multiple events. For example, you may also wish to bind 'zoom_changed' to load KML data on map zoom in or out.
I have a scenario where I need to continually keep a particular LocationRect best-fit (i.e. result of map.setView({ bounds: myLocationRect })) visible in the map across window resizes or tablet orientation changes until the user interacts with the map to change the current view.
I need some guidance here as to how to do that. Considering how many different mouse and keyboard interactions can change the view, I don't want to filter all of those interactions; it seems more appropriate to filter out the scenarios where the map's containing HTML element changes size.
I've already attempted to do this via tracking the previous width/height of the map element and listening to the targetviewchanged event; however, that has not worked reliably for me. The reason being, if I reset the view, I cannot reliably suspend listening to targetviewchanged. For instance:
function resetView() {
if(!_keepAoiInView) return; // unhook setInterval as well; omitted for brevity
_suspend = true;
_map.setView({ bounds: theBoundsIWant });
_suspend = false;
}
function ontargetviewchanged() {
// This suspend check doesn't work -
// resetView() isn't always lower in the call stack;
// therefore, _suspend is set back to false before the
// targetviewchanged event fires.
if(_suspend) return;
_keepAoiInView = false; // unhook setInterval as well; omitted for brevity
}
If you can't seem to get targetviewchanged to work, perhaps it's worth reconsidering tracking other events.
You might be able to track all the different possible interactions more easily using pointer.js. This way, you only need to capture a few types of events that, under the hood, represent many types of events. If it plays nicely with Bing Maps, that might solve the problem of mouse, touch, and possibly gesture events.
That probably won't solve the problem for keyboard events, I suspect, but perhaps monitoring those as well is manageable.
In google maps API V3, I would like to add a marker to the map if the user control-clicked the map.
For that, I've added a listener to the map, as follows -
google.maps.event.addListener(map, 'click', function(e){
if (event.ctrlKey)
add_marker(e.position);
});
The e parameter, passed by the listener, contains some data, but mostly regarding the position of the click, while I want to be able to ask if the control button was pressed during the time the usser clicked on the map.
I found that chrome had an object event, which is the default Javascript's eventObject, that contained the data I needed (ctrlKey) and this indeed works in chrome.
However, when I tried the same code in FF, it couldn't find an object called 'event', and I can't find a way to retrieve it.
I would appreciate your help in finding a solution that will work on IE too.
Thank,
DanC
The API doesn't say anything about accessing the DOM-event-object.
The argument passed to the callback-function currently contains a property b which refers to the event-object, so you could use e.b.ctrlKey
But as this is not documented it's not reliable may change tomorrow.
Another option:
You may observe the event for the div that contains the map without using the API-method:
map.getDiv().onclick=function(e)
{
e=window.event||e;
if (e.ctrlKey)
{
//do something
}
}
As covered in an existing question, I have a piece of code which (nice and simply) keeps a div updated with the current location of the cursor like so.
function updateLocation(e) {
document.getElementById('current_coordinate').innerText = e.latLng.toUrlValue(6);
}
It works brilliantly until the cursor moves over an overlay. The overlay consumes the event so the event listener I have defined on the map never fires.
google.maps.event.addListener(map, 'mousemove', updateLocation);
Questions:
Must I redefine that listener on every overlay I create or is there simpler way?
If I must define listeners on every overlay, roughly how many overlays may I have without performance suffering?
The overlay is interactive and so setting clickable to false is not an option.
See also these discussions that indicate this is a bug - as yet unfixed:
https://groups.google.com/forum/#!topic/google-maps-js-api-v3/z_K7hxKhonI
https://groups.google.com/forum/?hl=en#!topic/google-maps-js-api-v3/mM0mB9FcyAU
I am implementing an app using Google Maps API 3. I would like to know what is the best implementation in dealing with this problem. I want to execute an action once ANY event in Google Map has been fired. Currently, what I am doing is that I call the function every time a specific event is called. I find this redundant and I have to make a listener for all of the events. So, is there a way to generalize this where I can do the following:
google.maps.addListener(everything_on_the_map_canvas, 'ANY_EVENT', function(event) {
foo();
})
function foo(){
//do something here
}
Thank you.
If the user decides to continue with map operations, they will have to move the mouse over the map to do anything. So you could simply trap a mousemove.
google.maps.event.addListener(map, 'mousemove', function(event) {foo();})
If the user can manipulate the map without moving the mouse over the map, then you will need to listen to other events.
bounds_changed will cover most eventualities with zoom and pan, heading and the like
maptype_id_changed
But that's only three instead of all of them. If the bounds don't change when the tilt does (and you can change tilt from outside the map) you may need to listen for tilt_changed as well.