Deck.gl: Retrieving bounds and zoom of map

Created on 12 Jul 2019  路  4Comments  路  Source: visgl/deck.gl

From the onViewStateChange documentation we know that a

callback is fired when the user has interacted with the deck.gl canvas, e.g. using mouse, touch or keyboard.

So we can observe / listen for interaction and use the viewState data by putting a function inside onViewStateChange, for example

const deckgl = new deck.DeckGL({
  mapboxApiAccessToken: x,
  container: mycontainer,
  onViewStateChange: ({viewState}) => {
    console.log( viewState );
  }
});

Which gives us something like

{
    "width": 1388.0,
    "height": 400.0,
    "latitude": -2.719598,
    "longitude": -2.164757,
    "zoom": 0.2425895,
    "bearing": 0.0,
    "pitch": 0.0,
    "altitude": 1.5,
    "maxZoom": 20.0,
    "minZoom": 0.0,
    "maxPitch": 60.0,
    "minPitch": 0.0,
    "position": [
        0.0,
        0.0,
        0.0
    ],
    "transitionDuration": 0.0
}

Questions

  1. Is this the correct approach for returning and interacting with the map zoom/bearing/pitch?
  2. Is there a way or formula we can use to get the lon/lat bounds of the map, given we know the zoom, centre, pitch, bearing and the width/height of the canvas?
question

Most helpful comment

Yes, this is the correct callback to use to listen to map state changes.

To intercept and manipulate camera changes, you can do something like:

onViewStateChange: ({viewState}) => {
  return {
    ...viewState,
    zoom: Math.max(viewState.zoom, 3)
  };
}

To get the bounds of the map:

import {WebMercatorViewport} from '@deck.gl/core';

onViewStateChange: ({viewState}) => {
  const viewport = new WebMercatorViewport(viewState);

  const nw = viewport.unproject([0, 0]);
  const se = viewport.unproject([viewport.width, viewport.height]);

  // do what you need to do
}

All 4 comments

Yes, this is the correct callback to use to listen to map state changes.

To intercept and manipulate camera changes, you can do something like:

onViewStateChange: ({viewState}) => {
  return {
    ...viewState,
    zoom: Math.max(viewState.zoom, 3)
  };
}

To get the bounds of the map:

import {WebMercatorViewport} from '@deck.gl/core';

onViewStateChange: ({viewState}) => {
  const viewport = new WebMercatorViewport(viewState);

  const nw = viewport.unproject([0, 0]);
  const se = viewport.unproject([viewport.width, viewport.height]);

  // do what you need to do
}

Thanks, I'll give it a go!

@Pessimistress The documentation for unproject says

Unproject pixel coordinates on screen onto [lng, lat, altitude] on map

However, using unproject as per your suggestion, the longitude values are not restricted to (-180, 180)

Reproducible steps, log the state change

onViewStateChange: ({viewState}) => {
  const viewport = new WebMercatorViewport(viewState);
  const nw = viewport.unproject([0, 0]);
  const se = viewport.unproject([viewport.width, viewport.height]);
  console.log("north: ", nw[1], ", south: ", se[1]);
  console.log("east: ", se[0], "west: ", nw[0] );
});

and scroll the map east/west

Screen Shot 2019-09-20 at 11 37 31 am

I think another adjustment is required in unproject to get the longitude correctly into (-180, 180)?

@tgorkin do you think it's worth reopening this?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mathieudelvaux picture mathieudelvaux  路  4Comments

cosullivan picture cosullivan  路  4Comments

patilvikram picture patilvikram  路  3Comments

ToddJacobus picture ToddJacobus  路  4Comments

Dieegho picture Dieegho  路  3Comments