123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 |
- 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
- }
|