import { BBox, Feature, FeatureCollection, featureCollection } from "@turf/turf"; import { GeoJsonLayer } from "@deck.gl/layers"; import { PathStyleExtension } from "@deck.gl/extensions"; import { FlyToInterpolator } from "@deck.gl/core"; import EventEmitter from "eventemitter3"; import IHPaaSScene, { IHPaaSEventsMap, IHPaaSL7LayerGroup, IHPaaSLayer, IHPaaSLayerEventKeys, IHPaaSLayerOptions, IHPaaSLayerType, MouseHandler, } from "./IScene"; import { Style } from "../styles"; import convert from "color-convert"; import { HpaasEventKey } from "../types"; import HPaaSL7 from "../HPaaSL7"; import { ILayer, LineLayer, PointLayer, PolygonLayer, Popup } from "@antv/l7"; export default class SceneL7 implements IHPaaSScene { hpaas: HPaaSL7; layers: any[] = []; tooltip: { show: boolean; text?: string; html?: string } = { show: false, text: "", html: "", }; _popup: Popup; constructor(hpaas: HPaaSL7) { this.hpaas = hpaas; this._bindSceneEvent(); this._popup = new Popup({ // offsets: [iconSize / 2, 0], closeButton: false, stopPropagation: false, anchor: "bottom", }).setLnglat({ lng: 0, lat: 0 }); } private _bindSceneEvent() { this.hpaas.l7Scene.on("contextmenu", (e) => { const lng = e.lngLat.lng; const lat = e.lngLat.lat; this.sceneEvent.emit("contextmenu", { lnglat: { lng: 0, lat: 0 }, }); }); this.hpaas.l7Scene.on("click", (e) => { const lng = e.lngLat.lng; const lat = e.lngLat.lat; this.sceneEvent.emit("click", { lnglat: { lng, lat, }, feature: e.feature, }); }); this.hpaas.l7Scene.on("mousemove", (e) => { const lng = e.lngLat.lng; const lat = e.lngLat.lat; this.sceneEvent.emit("mousemove", { lnglat: { lng, lat, }, feature: e.feature, }); }); this.hpaas.l7Scene.on("zoomend", (e) => { this.sceneEvent.emit("zoomend", { zoom: this.hpaas.l7Scene.getZoom(), center: this.hpaas.l7Scene.getCenter(), }); }); this.hpaas.l7Scene.on("moveend", (e) => { this.sceneEvent.emit("moveend", { zoom: this.hpaas.l7Scene.getZoom(), center: this.hpaas.l7Scene.getCenter(), }); }); } createLayer(type: IHPaaSLayerType, style: Style, options?: IHPaaSLayerOptions): IHPaaSL7LayerGroup { if (type == "Polygon") { const layer: ILayer = new PolygonLayer({ zIndex: options?.zIndex, }) .source(featureCollection([])) .color(style.fill?.color || "#000") .shape("fill") .style({ opacity: style.fill?.opacity || 1, }); const borderLayer: ILayer = new LineLayer({ zIndex: options?.zIndex, }) .source(featureCollection([])) .style({ lineType: style.stroke?.lineType, dashArray: style.stroke?.dashArray, }) .size(style.stroke?.size || 0) .shape("line") .color(style.stroke?.color || "#000") .style({ opacity: style.stroke?.opacity, }); return [layer, borderLayer]; } else if (type == "LineString") { const layer: ILayer = new LineLayer({ zIndex: options?.zIndex, }) .source(featureCollection([])) .style({ lineType: style.stroke?.lineType, dashArray: style.stroke?.dashArray, }) .size(style.stroke?.size || 0) .shape("line") .color(style.stroke?.color || "#000") .style({ opacity: style.stroke?.opacity, }); return [layer]; } else if (type == "Point") { const layer: ILayer = new PointLayer({ zIndex: options?.zIndex, blend: "normal", pickingBuffer: 2, }) .source(featureCollection([])) .shape("circle") .size(style.size || 1) // .size('isRoadBeginPoint*isRoadEndPoint',(isBegin:boolean,isEnd:boolean)=>{ // console.log(isBegin); // if(isBegin) return 5; // if(isEnd) return 5; // return 5; // }) .active({ color: style.activeColor || "", }) .color(style.fill?.color || "#000") .style({ opacity: style.fill?.opacity, stroke: style.stroke?.lineType, strokeWidth: style.stroke?.size, }); return [layer]; } return []; } addLayer(layer: IHPaaSL7LayerGroup) { layer.forEach((l) => { this.hpaas.l7Scene.addLayer(l); }); } setData(layer: IHPaaSL7LayerGroup | undefined, data: FeatureCollection | Feature[]) { layer && layer.forEach((l) => { l.setData(data); }); } removeLayer(layer: IHPaaSL7LayerGroup) { layer.forEach((l) => { this.hpaas.l7Scene.removeLayer(l); }); } sceneEvent = new EventEmitter(); layerEvent = { on: (layer: IHPaaSL7LayerGroup, eventKey: IHPaaSLayerEventKeys, handler: (e: MouseHandler) => void) => { if (!this.hpaas.sceneLoaded) { this.hpaas.events.on(HpaasEventKey.SCENE_LOADED, () => { this.layerEvent.on(layer, eventKey, handler); }); return; } layer.forEach((l) => { l.on(eventKey, (e) => { const lng = e.lngLat.lng; const lat = e.lngLat.lat; handler({ lnglat: { lng, lat, }, feature: e.feature, }); }); }); }, off: (layer: IHPaaSLayer, eventKey: IHPaaSLayerEventKeys, handler: (e: MouseHandler) => void) => {}, }; fitBounds(b: BBox, animate?: boolean) { this.hpaas.l7Scene.fitBounds( [ [b[0], b[1]], [b[2], b[3]], ], { animate: animate, } ); } popup = { html: (html: string) => { this._popup?.setHTML(html); }, pos: (pos: { lng: number; lat: number }) => { this._popup?.setLnglat([pos.lng, pos.lat]); }, show: (html?: string, pos?: { lng: number; lat: number }) => { if (this.hpaas.sceneLoaded) { this._popup && this.hpaas.l7Scene.addPopup(this._popup); html && this._popup?.setHTML(html); pos && this._popup?.setLnglat([pos.lng, pos.lat]); this._popup?.open(); } }, hide: () => { this._popup?.close(); }, }; }