Categories
coding tips

HERE JS API 3.1 getting and setting map bounds

Here JS API 3.1 changed the rendering quite a bit, you’re now getting a vector map that allows to set the heading and tilt of the camera.

But some of the functions also changed and ex. my way of doing the ‘recenter’ button if now not working.

Old way

The old way was to simply display something on map, set it’s bounds so that everything is contained and than saving those bounds in a variable. Next whenever you needed to recenter you’d simply set those saved bounds.

var polyline; // some polyline
var map; // our map
var recenter_bounds; // global to save the original view

map.setViewBounds(polyline.getBounds());
recenter_bounds = map.getViewBounds();

// recenter function
function recenter () {
  map.setViewBounds(recenter_bounds);
  recenter_bounds = map.getViewBounds(); // safe way
}

New way

In v. 3.1 to access map view, you have to use ViewModel. ViewModel is useful for all the new stuff that you can do with HERE map, but also changed the way map is rendered. When setting bounds in the viewmodel you only push an information to the rendered, which is responsible for updating the map, and this is asynchronous. The syncevent is fired when rendered actually updated the map.

So the new workflow needs to keep that in mind. Assume same variables.

var viewmodel = map.getViewModel();

// we need to create a listener that will capture when the map change was applied
viewmodel.addEventListener('sync', function () {
  recenter_bounds = viewmodel.getLookAtData().bounds;
}, {once: true});

// set bounding to our polyline now looks like that
viewmodel.setLookAtData({bounds: polyline.getBoundingBox() });

// our recenter function sets the bounds the same way
function recenter () {
  viewport.setLookAtData({bounds: recenter_bounds});
}

I’m firing the event once, because I actually have other listeners added to map changes and they take care in other situations. You can also add the listener again after recentering the map, just to be sure that the rendered didn’t decide to change the 8th decimal digit in the coordinates again.