Return event in HERE - javascript

I am converting to HERE maps API 3.1 and haven't been able to find the same functionality in HERE that exists in both Google and Bing to return an event.
Bing: return Microsoft.Maps.Events.addThrottledHandler (_map, 'viewchangeend', callBack, 100);
Google: return google.maps.event.addListener(_map, 'bounds_changed', callBack);
What is the equivalent in HERE?

If you are looking for mapviewchange or mapviewchangeend Events below is the information:
Mapviewchange is called on each animation step in the process of changing a state of the viewport. In many cases, this operation is excessive. For example, updating a UI element with the current zoom level multiple times each time the user double-clicks on the map is inefficient.
// Displays current zoom level to the end user:
function displayZoomLevel() {...}
// A listener updates the map zoom level on each map view change
// -- this occurs more than 20 times on a double-click on the map,
// inefficient and to be avoided:
map.addEventListener('mapviewchange', function () {
var zoom = map.getZoom();
// This function is called more than 20 times on a double-click on the map!
displayZoomLevel(zoom);
});
mapviewchangeend, on the other hand, is called only once, when the viewport change is complete, therefore, we recommend using this event to update the map viewport:
/
*
Displays current zoom level to the end user
*/
function displayZoomLevel() {...}
// A listener updates the map zoom level -- it is called once when the map
// view change is complete.
map.addEventListener('mapviewchangeend', function () {
var zoom = map.getZoom();
// The function that displays the zoom level is called only once,
// after zoom level changed
displayZoomLevel(zoom);
});
The mapviewchangeend event is a 'debounced' version of mapviewchange, so, as a rule, it is more efficient to use mapviewchangeend

Related

Leaflet featureGroup with tracks fitbounds invalid

Is there a better way???
I am adding several tracks to a map (using leaflet-gpx plugin) and want to fit the maps to the bounds of all the added tracks.
By using a featureGroup layer to contain the tracks it is possible to used the fitBounds() method using the feature group.
However the featureGroup does not have a loaded event to trigger the fitBounds() and the map also doesn't seem to have a suitable trigger.
Calling fitBounds() directly on the map after it is rendered fails with 'invalid bounds' error. However delaying the call for about a second allows it to execute correctly.
I presume what is happening is that it takes time for all of the gpx layers in the group to be loaded and until that is complete the group can't return a valid set of bounds.
So using a setTimeout to delay the fitBounds() works, but causes some annoying flashing as the map re-renders itself. Is there a better way?
This works:
// mapname has been created and tracks have already been loaded into their individual layers
var tracksLayer = L.featureGroup([track1,track2,track3]);
tracksLayer.addTo(mapname);
//this works, with more and complex tracks you might need a longer timeout
setTimeout(function(){ mapname.fitBounds(tracksLayer.getBounds()); }, 1000);
// this however does not work
// mapname.on('load', function() { mapname.fitBounds(tracksLayer.getBounds());});
//nor does this despite the fact that by this stage the map has been created and the featureGroup added
// mapname.fitBounds(tracksLayer.getBounds());

HERE Maps API event delays

When panning a map with the HERE maps API, the 'mapviewchangeend' event is triggered a short time after the animation completes. This means that is difficult to synchronise, say, a Leaflet overlay without the overlaid objects lagging behind.
var map = new H.Map(document.getElementById('mapContainer'),
defaultLayers.normal.map, ...
var lMap = L.map('mapContainer', {zoomControl: false});
...
function onMapViewChange() {
lMap.setView(map.getCenter(), map.getZoom(), {animation: false});
}
map.addEventListener('mapviewchange', function () {
onMapViewChange();
});
map.addEventListener('mapviewchangeend', function () {
onMapViewChange();
});
Is there a way to remove this delay? I have experimented with different kinetic settings for H.mapevents.Behavior but so far without success.
I think you can hook into the sync events being fired by the the view model and the viewport. I seem to recall that these events fire synchronously when the map renders...
After some digging, I found the example showing something very similar on github:
maps-api-for-javascript-examples/ground-overlay

How to detect if google map loaded successfully

I'm using google-maps version 3 in my website.
I ran through problems where the map sometimes does not load, but instead it will be shown as a grey box, and the browser log will be fulled with errors - unfortunately I can't get the log now because the map is working again.
According to some researches, the problem is because of the experimental version I'm using
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=false"></script>
Is There a way to find out if the map has been loaded successfully or crashed so I can tell the user to come back soon?
P.S. I tried the idle event, but it has been invoked even when the map crashed.
I my opinion the best or most certain way is a combination of the tilesloaded event and a delayed function to test if a "success-flag" is set.
/* flag to indicate google maps is loaded */
googleMapsLoaded = false;
/* listen to the tilesloaded event
if that is triggered, google maps is loaded successfully for sure */
google.maps.event.addListener(map, 'tilesloaded', function() {
googleMapsLoaded = true;
//clear the listener, we only need it once
google.maps.event.clearListeners(map, 'tilesloaded');
});
/* a delayed check to see if google maps was ever loaded */
setTimeout(function() {
if (!googleMapsLoaded) {
//we have waited 5 secs, google maps is not loaded yet
alert('google maps is not loaded');
}
}, 5000);
Listen for the "tilesloaded" event instead. It's the last event to fire when a map (successfully) loads and you are actually showing a map.
If there's no map (e.g. you haven't set the width/height explicitly), this event won't fire even though idle does.
You can use the Map Events example and throttle your connection from within the Network tab to do some tests. Here's the same example with width/height not set for #map.
In idle event, do following on map object:
Check following:
Use if (typeof google === 'object' && typeof google.maps === 'object') {...} to check if it loaded successfully.
And then check if(map.getCenter) {
var latlng = map.getCenter();
//check here if latlng is object
}
If any of the "IF" condition fails that means something's wrong.

How to get max zoom for maptype in location

On Google Maps' JS API reference page, it says that the method getMaxZoomAtLatLng:
Returns the maximum zoom level available at a particular LatLng for
the Satellite map type.
For some reason, the terrain maptype bottoms out at level 15 in Calgary (for example) but the Satellite maptype can go all the way to zoom 19. I have two map services running simulataneously, and I want the maps to be in sync, but they can't sync up if they can't reach the same zoom level.
So, basically I want to know when the terrain map (or any maptype) can't cope, and trigger some special case functions.
Is there a method, or an alternative, for getting the maximum zoom for a location for a specific map type (since the above mentioned method only works for Satellite)?
Well, one solution I've decided to go with in the meantime is to attach a zoom-end handler to my ArcGIS map (could easily do this with Leaflet as well) and a maptypeid_changed handler to the Google map.
So, for the ArcGIS map (eMap) I did this:
eMap.on('zoom-end', function (e) {
// map zooms are synced
gMap.setCenter(esri.geometry.webMercatorToGeographic(e.extent.getCenter()));
gMap.setZoom(e.level);
// if the google map couldn't do it, reset eMap
if (gMap.getZoom() !== e.level) {
eMap.setZoom(gMap.getZoom());
// runs the handler again
}
});
And if the google map was set to Satellite, then changed, it also needed to trigger the same check, so I forced it to execute another zoomEnd handler:
google.maps.event.addListener(gMap, 'maptypeid_changed', function () {
// for some reason, ESRI has issues setting zoom to current zoom
// so it has to run an initial check before calling zoomEnd
if (gMap.getZoom() !== eMap.getZoom()) {
eMap.setZoom(gMap.getZoom());
}
});
Hope this helps someone, but really, I'm looking forward to seeing a better solution than this. Seems like an awfully complicated approach to merely firing a function if Google's maptype can't reach a certain zoom level.

OpenLayers DrawFeature control with Point destroys double click to zoom

I have some simple code that I copied from one of the openlayers examples for drawing several different types of geometries on the map. The problem is, whenever the "point" geometry is selected, I lose the ability to double-click to zoom in. The only difference between the examples and my code is I'm registering the handlers to use MOD_SHIFT, because i want to retain the ability to pan/zoom. Here is a snipit of code:
point: new OpenLayers.Control.DrawFeature(this.geometryFilterLayer,
OpenLayers.Handler.Point,
{
'done': console.info("drew point")
},
{
keyMask: OpenLayers.Handler.MOD_SHIFT
}
),
polygon: new OpenLayers.Control.DrawFeature(this.geometryFilterLayer,
OpenLayers.Handler.Polygon,
{
'done': console.info("drew polygon")
},
{
keyMask: OpenLayers.Handler.MOD_SHIFT
}
),
The funny thing about the above code is, the 'done' event only gets fired when the control/handler is created, and the keyMask doesn't work at all -- I have to loop through this object and manually set the keyMask each time, but that's not the real problem at hand.
I've tried every way I can think of to register a dblclick event, but no matter what, I can't get it to zoom in when I double click. It works fine on all the other geometries (bbox, point/radius, and polygon).
Can anybody give me some advice?
I never solved this issue, but ended up doing away with using MOD_XXX altogether. Each different draw control had too much built-in functionality for what happens when you hold shift, ctrl, alt, etc. I ended up using custom Buttons and a toolbar, that way the user can explicitly select the drawing control themselves.
this.toolbar = new OpenLayers.Control.Panel({
displayClass: 'olControlEditingToolbar'
});
map.addControl(this.toolbar);
var navButton = new OpenLayers.Control.Button({
displayClass: "olControlNavigation",
title: "Navigation",
trigger: lang.hitch(this, function(data){
this.toggleDrawControl("navigation");
navButton.activate();
pointButton.deactivate();
bboxButton.deactivate();
pointRadiusButton.deactivate();
polygonButton.deactivate();
})
});
...
this.toolbar.addControls([navButton, pointButton, bboxButton, pointRadiusButton, polygonButton]);
and my function to toggle draw controls (can be called externally, so that's why I re-call the activate and deactivate functions:
toggleDrawControl: function(geometryType){
this.currentGeometryType = geometryType;
for(key in this.drawControls) {
var control = this.drawControls[key];
if(geometryType == key) {
control.activate();
this.drawingButtons[key].activate();
} else {
control.deactivate();
this.drawingButtons[key].deactivate();
}
}
}

Categories