Controlled View

In this example, the <View> component is given a center and zoom. These props can be updated to update the state of the view. The view is also given an onChange callback. This function is called after the view state changes. In this example, the callback is used to update component state and render the view properties at the bottom of the map.

import Map from '@planet/maps/Map.js';
import OSM from '@planet/maps/source/OSM.js';
import React, {useCallback, useState} from 'react';
import TileLayer from '@planet/maps/layer/WebGLTile.js';
import View from '@planet/maps/View.js';
import {useGeographic as geographic} from 'ol/proj.js';

geographic();

function round(num, digits) {
  const factor = Math.pow(10, digits);
  return Math.round(num * factor) / factor;
}

function formatViewState(viewState) {
  const lon = round(viewState.center[0], 2);
  const lat = round(viewState.center[1], 2);
  const NS = lat >= 0 ? 'N' : 'S';
  const EW = lon >= 0 ? 'E' : 'W';
  const zoom = round(viewState.zoom, 1);
  return `zoom: ${zoom}; lon: ${Math.abs(lon)}° ${EW}; lat: ${Math.abs(
    lat,
  )}° ${NS}`;
}

function ControlledView() {
  const [viewState, setViewState] = useState({center: [0, 0], zoom: 1});

  const onViewChange = useCallback(event => {
    const view = event.target;
    setViewState({
      center: view.getCenter(),
      zoom: view.getZoom(),
    });
  }, []);

  return (
    <div style={{position: 'relative', height: '100%'}}>
      <Map>
        <View
          center={viewState.center}
          zoom={viewState.zoom}
          onChange={onViewChange}
        />
        <TileLayer>
          <OSM />
        </TileLayer>
      </Map>
      <div style={{position: 'absolute', bottom: '10px', left: '10px'}}>
        {formatViewState(viewState)}
      </div>
    </div>
  );
}

export default ControlledView;