import {deepMerge} from "../util"; /** * 思极地图实体基类 * 提供思极地图要素的通用功能,如弹窗管理、事件处理、飞行定位等 */ export default class SijiEntity { /** 事件监听器集合 */ private event: Record = {}; /** 信息窗口实例 */ private infoWindow: any = null; /** 地图实例 */ protected hnMap: any = null; /** 配置对象 */ protected config: any = null; /** 图形实例 */ protected graphic: any = null; /** 配置选项 */ protected option: any = null; /** 要素类型 */ protected type: string | null = null; /** 是否显示 */ protected show: boolean = false; /** 要素ID */ protected id: string | null = null; /** * 构造函数 * @param hnMap 地图实例 */ constructor(hnMap: any) { this.hnMap = hnMap; this.event = {}; this.show = false; } /** * 添加属性弹窗 * 点击要素时显示包含要素属性信息的弹窗 */ addPopupByAttr(): void { // 如果已有弹窗,先关闭 this.removePopup(); this.infoWindow = new SGMap.Popup({ offset: {bottom: [0, 0]}, className: "my-popupAttr-class", }); const handleClick = (e: any) => { const features = this.hnMap.map.map.queryRenderedFeatures(e.point); if (features.length > 0) { // 当前点击的第一层图形为当前图形时,才触发点击事件 if (features[0].layer.id === this.id) { const data = this.option.data; // 创建弹窗内容 let content = ""; for (const key in data) { content += `
${key}: ${data[key]}
`; } this.infoWindow.setHTML(content); this.infoWindow.setLngLat(e.lngLat).addTo(this.hnMap.map.map); } } }; this.hnMap.map.map.on("click", this.id, handleClick); } /** * 添加自定义DOM弹窗 * 点击要素时显示自定义DOM结构的弹窗 * @param getCustomDom 自定义DOM生成函数,接收要素数据,返回DOM字符串 */ addCustomPopup(getCustomDom: (data: any) => string): void { this.removePopup(); this.infoWindow = new SGMap.Popup({ offset: {bottom: [0, 0]}, className: "my-customPopup-class", }); const handleClick = (e: any) => { const features = this.hnMap.map.map.queryRenderedFeatures(e.point); if (features.length > 0) { // 当前点击的第一层图形为当前图形时,才触发点击事件 if (features[0].layer.id === this.id) { const data = this.option.data; const dom = getCustomDom(data); this.infoWindow.setHTML(dom); this.infoWindow.setLngLat(e.lngLat).addTo(this.hnMap.map.map); } } }; this.hnMap.map.map.on("click", this.id, handleClick); } /** * 删除弹窗 */ removePopup(): void { if (this.infoWindow) { this.infoWindow.remove(); } } /** * 飞行定位到要素 * @param option 飞行定位选项 */ flyTo(option: any = {}): void { deepMerge(this.option, option); const zoom = this.hnMap.map.map.getZoom(); let center: [number, number]; if (this.option.center) { center = this.option.center; } else { const type = this.type || ""; // 根据要素类型确定中心点 if (["line", "dash", "flicker", "flow", "arrow", "mapLabel", "rectangle"].includes(type)) { center = this.option.position[0]; } else if (type === "route") { center = [this.option.position[0][0], this.option.position[0][1]]; } else if (type === "polygon") { center = this.option.position[0][0]; } else { center = this.option.position; } } this.hnMap.map.map.flyTo({ duration: 1000, // 持续时间(毫秒) zoom: this.option.zoom || zoom, center: center, }); } /** * 销毁要素 * 从地图中移除图层和数据源 */ destroy(): void { this.hnMap.map.map.removeLayer(this.config.id); this.hnMap.map.map.removeSource(this.config.id); } /** * 监听事件 * @param eventType 事件类型 * @param callback 事件回调函数 */ on(eventType: string, callback: (data: any) => void): void { this.off(eventType); switch (eventType) { case "click": this.event[eventType] = (e: any) => { const features = this.hnMap.map.map.queryRenderedFeatures(e.point); if (features.length > 0) { // 当前点击的第一层图形为当前图形时,才触发回调 if (features[0].layer.id === this.id) { callback(this.option.data); } } }; break; } this.hnMap.map.map.on(eventType, this.id, this.event[eventType]); } /** * 移除事件监听 * @param eventType 事件类型 */ off(eventType: string): void { if (this.event[eventType]) { this.hnMap.map.map.off(eventType, this.id, this.event[eventType]); delete this.event[eventType]; } } }