import {LineLayer, PointLayer, PolygonLayer, Popup, RasterLayer, Scene} from "@antv/l7"; import type {ICameraOptions, ISourceCFG, Point} from "@antv/l7-core"; import {Map as AntvMap} from "@antv/l7-maps"; import {formatStringByTemplate} from "@/utils/string"; import bus from "@/utils/bus"; export let scene: Scene; // 加载状态 export let loadedStatus = false; export const imageMap = new Map() function loadImage(images: any[]) { images.forEach((item: any) => { if (!imageMap.has(item.name)) { imageMap.set(item.name, item.src); scene.addImage(item.name, item.src); } }) } /** * 初始化地图 */ export function init(config: any) { scene = new Scene({ id: 'mapDiv', map: new AntvMap({ center: [119.6620473872265, 29.415337822470235], zoom: 7.1, }), }); scene.on('loaded', () => { loadedStatus = true loadBaseLayer() // 加载图片 if (config && config.images && config.images.length > 0) { loadImage(config.images) } }); // 地图平移时触发事件 scene.on('mapmove', () => { console.log('中心点:', scene.getCenter().lng, scene.getCenter().lat, scene.getZoom(), scene.getPitch()) }); } /** * 加载底图 */ function loadBaseLayer() { // 底图服务 const url1 = 'https://t0.tianditu.gov.cn/img_w/wmts?tk=a4eab5a1b0d94268669e192b8799f626&'; const layer1 = new RasterLayer().source(url1, { parser: { type: 'rasterTile', tileSize: 256, wmtsOptions: { layer: 'img', tileMatrixset: 'w', format: 'tiles', }, }, }); scene.addLayer(layer1); // const baseLayer = new RasterLayer().source( // `https://t1.tianditu.gov.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk=a4eab5a1b0d94268669e192b8799f626}`, // { // parser: { // type: 'rasterTile', // tileSize: 256, // } // } // ); // scene.addLayer(baseLayer); } /** * 设置地图视角 * @param center 中心点 * @param zoom 层级 * @param pitch 倾斜角度 * @param padding */ export function setCenter(center: Point, zoom: number, pitch = 0, padding = {}) { if (center && zoom) { scene.setZoomAndCenter(zoom, center); } else if (center) { scene.setCenter(center, padding as ICameraOptions); } else if (zoom) { scene.setZoom(zoom); } scene.setPitch(pitch); } export function loadMap(option: any) { if (option.view) { setCenter(option.view.center, option.view.zoom) } if (option.layers) { // 清空图层 scene.removeAllLayer(); // 加载地图 loadBaseLayer() option.layers.forEach((layer: any) => { switch (layer.type) { case 'point': createPointByCongfig(layer) break // case 'line': // createLineByCongfig(layer, mapJson) // break // case 'polygon': // createPolygonByCongfig(layer, mapJson) // break // case 'mark': // setMark(config) // break } }) } } function createPointByCongfig(config: any) { console.log('config', config, imageMap) const layer = new PointLayer({}) .source(config.data, config.dataOptions) .size(config.size) .active(config.emphasis.show); setLayerShape(layer, config.shape); // 颜色配置 // setLayerColor(layer, config.color); scene.addLayer(layer); setMark(config); // setPopup(layer, config); // 点击事件 layer.on('click', (e: any) => { let row = e.feature.properties || e.feature bus.emit('point_click', {data: row, e}) }); } function getValueByConditions(data: any, conditions: any, field: any) { let condition; for (const item of conditions) { if (compareByConditions(data, item)) { condition = item break } } if (!condition) { return null; } if (field === 'color') { return condition[field] } if (condition[field] !== 'image') { return condition[field] } if (condition[field] === 'image') { return condition.imageName } return null; } function compareByConditions(data: any, condition: any) { switch (condition.cond) { case 'lt': if (data < condition.value) { return true } break case 'lte': if (data <= condition.value) { return true } break case 'eq': if (data == condition.value) { return true } break case 'gt': if (data > condition.value) { return true } break case 'gte': if (data >= condition.value) { return true } break case 'ne': if (data != condition.value) { return true } break } return false; } /** * 图层数据配置 * @param dataType * @returns {{parser: {x: string, y: string, type: string}}|null} */ function getSourceOptions(dataType: any) { switch (dataType) { case 'geojson': return null; case 'list': return { parser: { type: 'json', x: '经度', y: '纬度', }, } default: } } /** * 图层形状配置 * @param layer * @param config */ function setLayerShape(layer: any, config: any) { if (config.isConstant) { layer.shape(config.value) } else { layer.shape(config.field, config.value) } } /** * 图层颜色配置 * @param layer * @param config */ function setLayerColor(layer: any, config: any) { if (config.isConstant) { layer.color(config.value) } else { const field = config.field const conditions = config.conditions layer.color(field, (field: any) => { return getValueByConditions(field, conditions, 'color'); }); } } export function setMark(config: any) { if (!config.label.show) { return } // 标注 const markLayer = new PointLayer({}) .source(config.data, config.dataOptions) .shape(config.label.field, 'text') .size(16) .color('#fff') .style({ textAnchor: config.label.position || 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left textOffset: [0, 40], // 文本相对锚点的偏移量 [水平, 垂直] spacing: 2, // 字符间距 // padding: [1, 1], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近 // stroke: '#ffffff', // 描边颜色 // strokeWidth: 2, // 描边宽度 // strokeOpacity: 1.0, }); scene.addLayer(markLayer); } function setPopup(layer: any, config: any) { if (!config.enabled) { return } layer.on(config.trigger, (e: any) => { let properties = e.feature.properties || e.feature const content = formatStringByTemplate(properties, config.content) // offsets: [0, 0], closeButton: false, const popup = new Popup({}) .setLnglat(e.lngLat) .setHTML(content); scene.addPopup(popup); }); } /** * 创建线图层 * @param config 配置 * @param dataType 图层数据类型 * @param mapData 图层数据 */ function createLineByCongfig(config: any, dataType: any, mapData: any) { const sourceOptions = getSourceOptions(dataType) as ISourceCFG const layer = new LineLayer({}) .source(mapData, sourceOptions) .size(1) .style({ lineType: 'dash', dashArray: [2, 2], }) .active(config.active); scene.addLayer(layer); setMark(config); setPopup(layer, config.popup); } /** * 创建面图层 * @param config 配置 * @param dataType 图层数据类型 * @param mapData 图层数据 */ function createPolygonByCongfig(config: any, dataType: any, mapData: any) { const sourceOptions = getSourceOptions(dataType) as ISourceCFG const layer = new PolygonLayer({}) .source(mapData, sourceOptions) .shape('fill') .active(config.active); // 颜色配置 setLayerColor(layer, config.color); scene.addLayer(layer); setMark(config); setPopup(layer, config.popup); } export function getLegendData(config: any) { const layers = config.layers const layerLegend = layers.reduce((acc: any, item: any) => { if (item.legend && item.legend.data) { return acc.concat(item.legend.data); } else { return acc; } }, []); // return layerLegend.map((item: any) => { // const data = {label: item.text} // if (item.shape === 'image') { // data.imgType = 'img' // data.src = item.imgSrc // } else { // data.imgType = 'svg' // data.src = item.shape // data.imgStyle = {fill: item.color} // } // return data // }) return null }