mobility-toolbox-js
Version:
Toolbox for JavaScript applications in the domains of mobility and logistics.
81 lines (80 loc) • 3.24 kB
JavaScript
import { MapLibreLayerRenderer } from '@geoblocks/ol-maplibre-layer/lib';
import { toDegrees } from 'ol/math.js';
import { toLonLat } from 'ol/proj';
function sameSize(map, frameState) {
return (map.transform.width === Math.floor(frameState.size[0]) &&
map.transform.height === Math.floor(frameState.size[1]));
}
/**
* This class is usea renderer for Maplibre Layer to be able to use the native ol
* functionnalities like map.getFeaturesAtPixel or map.hasFeatureAtPixel.
* @private
*/
export default class MaplibreLayerRenderer extends MapLibreLayerRenderer {
constructor(layer, translateZoom) {
super(layer, translateZoom);
this.ignoreNextRender = false;
this.translateZoom2 = translateZoom;
this.setIsReady = this.setIsReady.bind(this);
this.ignoreNextRender = false;
}
prepareFrame() {
return true;
}
renderFrame(frameState) {
const layer = this.getLayer();
const { mapLibreMap } = layer;
const map = layer.getMapInternal();
if (!layer || !map || !mapLibreMap) {
// @ts-expect-error - can return null
return null;
}
// eslint-disable-next-line @typescript-eslint/unbound-method
void mapLibreMap.off('idle', this.setIsReady);
// When the browser is zoomed it could happens that the renderFrame call for readyness
// in setIsReady is called with a different size than the one of the mapLibreMap,
// so we need to render.
if (this.ready &&
this.ignoreNextRender &&
sameSize(mapLibreMap, frameState)) {
this.ignoreNextRender = false;
return mapLibreMap.getContainer();
}
this.ready = false;
this.ignoreNextRender = false;
const mapLibreCanvas = mapLibreMap.getCanvas();
const { viewState } = frameState;
// adjust view parameters in MapLibre
mapLibreMap.jumpTo({
bearing: toDegrees(-viewState.rotation),
center: toLonLat(viewState.center, viewState.projection),
zoom: (this.translateZoom2
? this.translateZoom2(viewState.zoom)
: viewState.zoom) - 1,
});
const opacity = layer.getOpacity().toString();
if (opacity !== (mapLibreCanvas === null || mapLibreCanvas === void 0 ? void 0 : mapLibreCanvas.style.opacity)) {
mapLibreCanvas.style.opacity = opacity;
}
if (!mapLibreCanvas.isConnected) {
// The canvas is not connected to the DOM, request a map rendering at the next animation frame
// to set the canvas size.
map.render();
}
else if (!sameSize(mapLibreMap, frameState)) {
mapLibreMap.resize();
}
// eslint-disable-next-line @typescript-eslint/unbound-method
void mapLibreMap.once('idle', this.setIsReady);
mapLibreMap.redraw();
return mapLibreMap.getContainer();
}
setIsReady() {
var _a;
if (!this.ready) {
this.ready = true;
this.ignoreNextRender = true;
(_a = this.getLayer()) === null || _a === void 0 ? void 0 : _a.changed();
}
}
}