<template> <div class="mapPage"> <div id="cesiumContainer"></div> </div> </template> <script setup name="OneMap"> import bus from '@/utils/utils'; import axios from 'axios'; import * as turf from '@turf/turf'; import WKT from 'terraformer-wkt-parser'; import kaifengWaterLabel1 from '@/assets/geojson/kaifengWaterLabel1.json'; import kaifengWater from '@/assets/geojson/kaifengWater.json'; const props = defineProps({ initJson: { type: String, default: () => '/static/libs/mapbox/style/floodOneMap.json', }, loadCallback: { type: Function, default: () => function () {}, }, PostionValue: Object, }); const allData = reactive({ layerIds: [], }); let geojson = { point: { type: 'FeatureCollection', features: [] }, polygon: { type: 'FeatureCollection', features: [] }, linestring: { type: 'FeatureCollection', features: [] }, }; let map = null; let config = null; let highlightLayers = { highlight_point: 1, highlight_polygon: 1, highlight_linestring: 1, }; const initeMap = async () => { config = (await axios.get(props.initJson)).data; window.newfiberMap = new mapboxL7.Scene({ id: 'cesiumContainer', map: new mapboxL7.Mapbox({ style: config.params.init.style, center: config.params.init.center, zoom: config.params.init.zoom, }), }); map = newfiberMap.map; map.ogcLayers = []; newfiberMap.unLoadLayers = []; map.on('load', async () => { // 坐标拾取器 // const mouseLocation = new mapboxL7.MouseLocation({ // transform: (position) => { // return position; // }, // }); // newfiberMap.addControl(mouseLocation); !!!map.getSource('kaifengWater') && map.addSource('kaifengWater', { type: 'geojson', data: kaifengWater }); !!!map.getLayer('kaifengWater') && map.addLayer({ id: 'kaifengWater', type: 'fill', source: 'kaifengWater', paint: { 'fill-color': 'rgba(117, 207, 240,1)', }, }); addWaterLabel(); let { sprites, l7 } = config.params; (sprites || []).forEach((url) => map.style._loadSprite(url.includes('http') ? url : window.location.href.split('#')[0] + url) ); ((l7 || []).images || []).forEach((item) => newfiberMap.addImage( item.name, item.url.includes('http') ? item.url : window.location.href.split('#')[0] + item.url ) ); await loadData(); props.loadCallback && props.loadCallback(); //getLayerIdByClick(); (config.orders || []).forEach((item) => setLayerOrder(...item)); newfiberMap.getLayers().filter((i) => highlightLayers[i.newfiberId] && (highlightLayers[i.newfiberId] = i)); let timeout = setTimeout(() => { let { pitch, center } = config.params.init; pitch && newfiberMap.map.setPitch(pitch); // center && newfiberMap.map.setCenter(center); clearTimeout(timeout); }, 2000); // three(); }); let layerIds = (config.mapbox || []).map((i) => i.id); map.on('click', (e) => { Object.values(highlightLayers).forEach((layer) => { if (layer.setData) layer.setData({ type: 'FeatureCollection', features: [] }); }); const feature = ( map.queryRenderedFeatures([ [e.point.x - 10 / 2, e.point.y - 10 / 2], [e.point.x + 10 / 2, e.point.y + 10 / 2], ]) || [] ).filter((i) => layerIds.includes(i.layer.id))[0]; bus.emit('map-click', [Object.values(e.lngLat), (feature || {}).properties]); setHighlight(feature); }); }; const setHighlight = (features = {}) => { let array = {}; features = features.forEach ? features : [features]; Object.values(highlightLayers).forEach( (layer) => layer.setData && layer.setData({ type: 'FeatureCollection', features: [] }) ); features.forEach((feature) => { if (!!!feature || !Boolean(Object.keys(feature).length) || !feature.properties.geometry) return; let geometry = WKT.parse(feature.properties.geometry); let geoFeature = turf.feature(geometry, feature.properties); let type = geometry.type.toLocaleLowerCase().replaceAll('multi', ''); let key = Object.keys(highlightLayers).filter((key) => key.lastIndexOf(type) > -1)[0]; if (!array[key]) array[key] = []; array[key].push(geoFeature); }); Object.keys(array).forEach( (key) => highlightLayers[key] && highlightLayers[key].setData({ type: 'FeatureCollection', features: array[key], }) ); }; const loadData = async () => { let { mapbox, l7, ogc } = config; if (mapbox) mapbox.forEach((item) => { let { mType, columns } = item; let params = ''; if (columns) params = `?columns=${columns}`; if (!!!map.getSource(item.id)) { let flag = mType == 'geojson'; flag ? map.addSource(item.id, { type: mType, data: geojson[item.id] }) : map.addSource(item.id, { type: 'vector', tiles: [config.params.mvt + `/v1/${mType}/${item.key}/{z}/{x}/{y}` + params], tileSize: 512, scheme: 'xyz', maxzoom: 14, minzoom: 1, }); } map.addLayer({ ...item, source: item.id }); map.moveLayer(item.id, undefined); allData.layerIds.push(item.id); }); if (l7) l7.forEach((item) => { let { id, columns } = item; let params = ''; if (columns) params = `?columns=${columns}`; id ? axios .get(config.params.mvt + `/v1/geojson/${id}` + params) .then(({ data: geojson }) => initMapBoxL7Class(item, geojson)) : initMapBoxL7Class(item, geojson[item.key] || turf.featureCollection([])); }); if (ogc) ogc.forEach((item) => { let { id, type, params, methods } = item; Object.keys(params).forEach((i) => typeof params[i] == 'string' ? (params[i].includes('||') ? eval(params[i]) : params[i]) : params[i] ); let layer = new mapboxgl1[type](params); layer.newfiberId = id; methods.forEach((method) => { let ms = method.params.map((i) => (typeof i == 'string' ? (i.includes('||') ? eval(i) : i) : i)); layer[method.name](...ms); }); map.ogcLayers.push(layer); }); function initMapBoxL7Class({ type, params, methods, id, show, key }, geojson) { let layer = new mapboxL7[type](params).source(geojson); methods.forEach((method) => { let ms = method.params.map((i) => (typeof i == 'string' ? (i.includes('||') ? eval(i) : i) : i)); layer[method.name](...ms); }); layer.newfiberId = key; if (!show) return newfiberMap.unLoadLayers.push(layer); newfiberMap.addLayer(layer); allData.layerIds.push(key); } }; const setLayerVisible = ({ layername, isCheck }) => { if (!!!(config || {}).filter) return; if (config.filter[layername]) { config.filter[layername].layerName.forEach((name, index) => { let filter = map.getFilter(name); let fValues = config.filter[layername].filter[index]; isCheck ? filter.push(...fValues) : (filter = filter.filter((i) => !fValues.includes(i))); map.setFilter(name, filter); }); return config.filter[layername].easeTo && isCheck && map.easeTo(config.filter[layername].easeTo); } let features = Object.values(geojson) .map((i) => i.features) .flat(Infinity) .filter((i) => i.properties.type == layername); if (features.length) { let types = Array.from(new Set(features.map((i) => i.geometry.type.toLocaleLowerCase()))); types.forEach((type1) => { let filter = map.getFilter(type1); isCheck ? filter.push(layername) : (filter = filter.filter((i) => i != layername)); map.setFilter(type1, filter); }); } let layer = newfiberMap.getLayers().filter((i) => i.newfiberId == layername)[0]; if (!!!layer) { layer = newfiberMap.unLoadLayers.filter((i) => i.newfiberId == layername)[0]; isCheck && layer && newfiberMap.addLayer(layer); } layer && layer[['hide', 'show'][Number(isCheck)]](); layer = map.getLayer(layername); layer && map.setLayoutProperty(layername, 'visibility', isCheck ? 'visible' : 'none'); layer = map.getLayer(layername + '_text'); layer && map.setLayoutProperty(layername, 'visibility', isCheck ? 'visible' : 'none'); layer = map.ogcLayers.filter((i) => i.id == layername)[0]; layer && (layer.map ? layer[isCheck ? 'show' : 'hide']() : layer.addTo(map)); }; const getGeojsonByType = ({ type, callback }) => { let geojs = turf.featureCollection( Object.values(geojson) .map((i) => i.features) .flat(Infinity) .filter((i) => i.properties.type == type) ); callback && callback(geojs); }; const removeLayers = (ids) => { let { getLayers, removeAllLayer, removeLayer: removeLayerL7 } = newfiberMap; let { getLayer, removeLayer } = map; if (!!!ids) { allData.layerIds.forEach((id) => getLayer(id) && removeLayer(id)); return removeAllLayer(); } ids.forEach((id) => { getLayer(id) && removeLayer(id); getLayers().forEach((layer) => layer.newfiberId == id && removeLayerL7(layer)); }); }; const removeMapDatas = (types) => { !!!types ? Object.keys(geojson).forEach((key) => (geojson[key].features.length = 0)) : Object.keys(geojson).forEach( (key) => (geojson[key].features = geojson[key].features.filter((feature) => !types.includes(feature.properties.type))) ); return refreshGeoJSON(); }; const setLegendData = (list) => { list.forEach( (i) => i.data && i.data.features.forEach((a) => { if (!!!a || !!!a.properties) return; a.properties.type = a.properties.type || i.layername; a.properties.name = a.properties.name || a.properties.Name || a.properties.stName || a.properties.pointNumber || a.properties.sewageName || a.properties.sectionName || a.properties.address || a.properties.pumpName || a.properties.projectAbbreviation; }) ); let types = {}; list .map((i) => i.data && i.data.features) .filter(Boolean) .flat(Infinity) .forEach((feature) => { if (!!!feature || !!!feature.properties) return; feature.properties.geometry = WKT.convert(feature.geometry); let type = feature.geometry.type.toLocaleLowerCase(); let flag = type.includes('multi'); type = type.replaceAll('multi', ''); let features = null; if (flag) features = turf.flatten(feature).features; !!!types[type] && (types[type] = []); types[type].push(...(features ? features : [feature])); }); Object.keys(types).forEach((key) => geojson[key].features.push(...types[key])); refreshGeoJSON(); }; const refreshGeoJSON = () => { Object.keys(geojson).forEach((key) => map.getSource(key) && map.getSource(key).setData(geojson[key])); }; const setGeoJSON = ({ json, key }) => { // geojson[key] = json; let layer = newfiberMap.getLayers().filter((i) => i.newfiberId == key)[0]; if (!!!layer) { layer = newfiberMap.unLoadLayers.filter((i) => i.newfiberId == key)[0]; layer && newfiberMap.addLayer(layer); } if (layer) layer.setData(json); setLegendData([{ data: json, layername: key, type: 'point' }]); }; const setLayerOrder = (sourceLayer, targetLayer) => { map.moveLayer(sourceLayer, targetLayer); }; const getLayerIdByClick = () => { map.getStyle().layers.forEach((i) => map.on('click', i.id, (a, b, c, d) => { console.log('layer-id', a.features[0].layer.id); console.log(a.features[0]); }) ); }; watch( () => props.PostionValue, (newVal, oldVal) => { console.log(`地图中接手到的最新坐标位置`, newVal); console.log('地图渲染轨迹----飞哥'); }, { deep: true, } ); //添加河流标注 const addWaterLabel = () => { !!!map.getSource('kaifengWaterLabel1') && map.addSource('kaifengWaterLabel1', { type: 'geojson', data: kaifengWaterLabel1 }); !!!map.getLayer('kaifengWaterLabel1') && map.addLayer({ id: 'kaifengWaterLabel1', type: 'symbol', source: 'kaifengWaterLabel1', layout: { 'text-field': ['get', 'name'], 'text-font': ['KlokanTech Noto Sans Regular'], 'text-transform': 'uppercase', 'text-size': 12, }, paint: { 'text-halo-color': 'rgba(238, 251, 255,1)', 'text-color': 'rgba(30, 30, 30,1)', 'icon-opacity': 1, 'text-halo-width': 1, }, }); !!!map.getSource('kaifengWaterLabel2') && map.addSource('kaifengWaterLabel2', { type: 'geojson', data: kaifengWater }); !!!map.getLayer('kaifengWaterLabel2') && map.addLayer({ id: 'kaifengWaterLabel2', type: 'symbol', source: 'kaifengWaterLabel2', layout: { 'symbol-placement': 'line', 'text-field': ['get', 'name'], 'text-font': ['KlokanTech Noto Sans Regular'], 'text-letter-spacing': 0.1, 'text-rotation-alignment': 'map', 'text-size': 12, 'text-transform': 'uppercase', }, paint: { 'text-halo-color': 'rgba(238, 251, 255,1)', 'text-color': 'rgba(30, 30, 30,1)', 'icon-opacity': 1, 'text-halo-width': 1, 'text-allow-overlap': true, }, }); }; onMounted(() => { initeMap(); bus.on('setLayerVisible', setLayerVisible); bus.on('setLegendData', setLegendData); bus.on('setGeoJSON', setGeoJSON); bus.on('getGeojsonByType', getGeojsonByType); bus.on('removeLayers', removeLayers); bus.on('removeMapDatas', removeMapDatas); bus.on('setHighlight', setHighlight); }); onBeforeUnmount(() => { bus.off('setLayerVisible'); bus.off('setLegendData'); bus.off('setGeoJSON'); bus.off('getGeojsonByType'); bus.off('removeMapDatas'); bus.off('setHighlight'); newfiberMap.destroy(); newfiberMap = null; }); </script> <style lang="less" scoped> .mapPage { width: 100%; height: 100%; position: absolute; left: 0px; top: 0px; z-index: 10; background: lavender; } #cesiumContainer { width: 100%; height: 100%; position: absolute; } .l7-control-mouse-location { background: none; } .l7-control-mouse-location { color: #ffffff; } </style>