UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

155 lines (143 loc) 4.31 kB
import mapboxgl from 'mapbox-gl'; import {ThreejsLayer, ThreejsLayerOptions, ThreejsLayerRenderFunc} from './layers/MapboxThreejsLayer'; import {BuildingsLayer} from './layers/Buildings'; import { // Vector2, Scene, Camera, } from 'three'; import {PolyScene} from '../../../engine/scene/PolyScene'; import {LngLat} from './Common'; import {MapboxViewer} from '../../../engine/viewers/Mapbox'; export interface LayersOptions { map: mapboxgl.Map; scene: PolyScene; camera: Camera; displayScene: Scene; lngLat: LngLat; renderFunc: ThreejsLayerRenderFunc; viewer: MapboxViewer; zoomControls: boolean; layer3D: boolean; layerBuildings: boolean; layerSky: boolean; } export class MapboxLayersController { public _threejsLayer: ThreejsLayer | undefined; constructor(private _options: LayersOptions) {} addLayers() { // if (!this._viewer.mapLoaded()) { // console.warn('map not loaded'); // return; // } // const map = this._viewer.map(); // if (!map) { // console.warn('no map found'); // return; // } const current_style = this._options.map.getStyle(); const layers = current_style.layers; if (!layers) { console.warn('no layers found'); return; } let label_layer_id = null; for (const layer of layers) { if (layer.type == 'symbol' && (layer.layout as mapboxgl.SymbolLayout)['text-field']) { label_layer_id = layer.id; } } // const cameraNode = this._viewer.cameraNode(); if (label_layer_id != null) { this._addLayerBuildings(label_layer_id); this._addLayerThreejs(label_layer_id); } this._addLayer3D(); this._addLayerSky(); this._addZoomControls(); } // resize(size: Vector2) { // this._threejsLayer?.resize(size); // } private _addZoomControls() { if (!this._options.zoomControls) { return; } // let nav_control = this._controls_by_container_id.get(container_id); // if (nav_control) { // if (!isBooleanTrue(this.pv.addZoomControl)) { // map.removeControl(nav_control); // this._controls_by_container_id.delete(container_id); // } // } else { // if (isBooleanTrue(this.pv.addZoomControl)) { const navControl = new mapboxgl.NavigationControl(); this._options.map.addControl(navControl, 'bottom-right'); // this._controls_by_container_id.set(container_id, nav_control); // } // } } protected _addLayer3D() { if (!this._options.layer3D) { return; } if (this._options.displayScene.background != null) { console.warn( 'the scene has the background set, which may prevent the layers from displaying correctly. Make sure to remove the background.' ); } this._options.map.addSource('mapbox-dem', { type: 'raster-dem', url: 'mapbox://mapbox.mapbox-terrain-dem-v1', tileSize: 512, maxzoom: 14, }); // add the DEM source as a terrain layer with exaggerated height this._options.map.setTerrain({source: 'mapbox-dem', exaggeration: 1.5}); } private _addLayerSky() { if (!this._options.layerSky) { return; } // add a sky layer that will show when the map is highly pitched this._options.map.addLayer({ id: 'sky', type: 'sky', paint: { 'sky-type': 'atmosphere', 'sky-atmosphere-sun': [0.0, 0.0], 'sky-atmosphere-sun-intensity': 15, }, }); } private _addLayerBuildings(label_layer_id: string) { if (!this._options.layerBuildings) { return; } if (this._hasLayerId(BuildingsLayer.id)) { return; } this._options.map.addLayer(BuildingsLayer, label_layer_id); } protected _addLayerThreejs(label_layer_id: string) { const options: ThreejsLayerOptions = { map: this._options.map, scene: this._options.scene, camera: this._options.camera, canvas: this._options.map.getCanvas(), lngLat: this._options.lngLat, renderFunc: this._options.renderFunc, viewer: this._options.viewer, }; this._threejsLayer = new ThreejsLayer(options); this._options.map.addLayer(this._threejsLayer, label_layer_id); // const threejsScene = camera_node.scene().threejsScene(); // const layer = Threejs3LayerBuilder(threejsScene); // map.addLayer(layer, label_layer_id); } private _hasLayerId(layer_id: string): boolean { const current_style = this._options.map.getStyle(); const layer_ids = current_style.layers?.map((l) => l.id) || []; return layer_ids.includes(layer_id); } }