<template> <div class="mapPage"> <div id="cesiumContainer"></div> </div> </template> <script> import { reactive, toRefs, onBeforeMount, onMounted, nextTick, onBeforeUnmount, } from "vue"; import bus from "@/bus"; import axios from "axios"; import buildingGeojson from "@/assets/yanAnBuilding.json"; import yanAnRoad from "@/assets/yanAnRoad.json"; import yanAnWater from "@/assets/yanAnWater.json"; import { buffer } from "ol/size"; export default { components: {}, props: { initJson: { type: String, default: () => "/static/libs/mapbox/style/floodOneMap.json", }, loadCallback: { type: Function, default: () => function () {}, }, }, setup(props, event) { 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; const { basemap } = config.params; const { style, localStyle } = config.params.init; let styleJson = ( await axios.get( localStyle ? localStyle : (style.includes("http") ? "" : location.origin + basemap) + config.params.init.style ) ).data; styleJson.glyphs = styleJson.glyphs.includes("http") ? styleJson.glyphs : location.origin + styleJson.glyphs; styleJson.sprite = styleJson.sprite.includes("http") ? styleJson.sprite : location.origin + styleJson.sprite; window.newfiberMapbox = new mapboxL7.Scene({ id: "cesiumContainer", map: new mapboxL7.Mapbox({ style: styleJson, // style: localStyle?localStyle:(style.includes('http')?'':location.origin + config.params.basemap) + config.params.init.style, center: config.params.init.center, zoom: config.params.init.zoom, }), }); map = newfiberMapbox.map; map.ogcLayers = []; newfiberMapbox.unLoadLayers = []; map.on("load", async () => { const mouseLocation = new mapboxL7.MouseLocation({ transform: (position) => { return position; }, }); newfiberMapbox.addControl(mouseLocation); let { sprites, l7 } = config.params; (sprites || []).forEach((url) => map.style._loadSprite( url.includes("http") ? url : window.location.origin.split("#")[0] + url ) ); ((l7 || []).images || []).forEach((item) => newfiberMapbox.addImage( item.name, item.url.includes("http") ? item.url : window.location.origin.split("#")[0] + item.url ) ); addYanAnBuilding(); addYanAnRiverFlow(); // addYanAnRoad(); await getGeoJSON(); await loadData(); props.loadCallback && props.loadCallback(); // getLayerIdByClick(); newfiberMapbox .getLayers() .filter( (i) => highlightLayers[i.newfiberId] && (highlightLayers[i.newfiberId] = i) ); let timeout = setTimeout(() => { let { pitch, center } = config.params.init; pitch && newfiberMapbox.map.setPitch(pitch); center && newfiberMapbox.map.setCenter(center); (config.orders || []).forEach((item) => setLayerOrder(...item)); clearTimeout(timeout); }, 1000); // three(); // getLayerIdByClick(); }); 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]; setHighlight(feature); event.emit( "map-click", Object.values(e.lngLat), (feature || {}).properties, ((feature || {}).layer || {}).id ); }); async function getGeoJSON() { config.geojsonMvts = {}; let url = config.mapbox .filter((i) => i.mType == "geojsonMvt") .map((item) => { let { mType, columns, geom_column, id, key } = item; let sourceID = geom_column ? key + "_" + (geom_column || "") : key; let params = []; if (columns) params.push(`columns=${columns}`); if (geom_column) params.push(`geom_column=${geom_column}`); return config.params.mvt + `/v1/geojson/${key}?` + params.join("&"); }); url = Array.from(new Set(url)); let fetchs = url.map((url) => axios.get(url)); let results = await Promise.all(fetchs); url.forEach((url, index) => (config.geojsonMvts[url] = results[index].data)); } }; const loadData = async () => { let { mapbox, l7, ogc } = config; if (mapbox) initMapBoxLayer(); if (l7) l7.forEach((item) => { let { id, columns, filter } = item; let params = []; if (columns) params.push(`columns=${columns}`); if (filter) params.push(`filter=${filter}`); id ? axios .get(config.params.mvt + `/v1/geojson/${id}?` + params.join("&")) .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) => (params[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 newfiberMapbox.unLoadLayers.push(layer); newfiberMapbox.addLayer(layer); allData.layerIds.push(key); } function initMapBoxLayer() { mapbox.forEach((item) => { let { mType, columns, geom_column, id, key } = item; let sourceID = geom_column ? key + "_" + (geom_column || "") : key; let params = []; if (columns) params.push(`columns=${columns}`); if (geom_column) params.push(`geom_column=${geom_column}`); if (!!!map.getSource(sourceID)) { let flag = mType == "geojson"; flag ? map.addSource(sourceID, { type: mType, data: geojson[key] }) : map.addSource(sourceID, { ...(mType == "mvt" ? { type: "vector", tiles: [ config.params.mvt + `/v1/${mType}/${key}/{z}/{x}/{y}?` + params.join("&"), ], tileSize: 512, scheme: "xyz", maxzoom: 14, minzoom: 1, } : { type: "geojson", data: config.geojsonMvts[ config.params.mvt + `/v1/geojson/${key}?` + params.join("&") ], }), }); } map.addLayer({ ...item, source: sourceID }); map.moveLayer(id, undefined); allData.layerIds.push(id); }); } }; const setLayerVisible = ({ layername, isCheck, values = [] }) => { if (!!!layername) return; if (((config || {}).filter || [])[layername]) { config.filter[layername].layerName.forEach((name, index) => { let layer = newfiberMapbox.getLayers().filter((i) => i.newfiberId == name)[0]; let fValues = config.filter[layername].filter[index]; if (layer) { let geojson = layer.getSource().originData; geojson.features.forEach( (i) => fValues.includes(i.properties.type) && (i.properties.visible = isCheck) ); layer.setData(geojson); } if (map.getLayer(name)) { fValues = fValues.filter(Boolean); let filter = map.getFilter(name); if (!fValues.length) fValues = values; if (filter[0] == "in") { isCheck ? filter.push(...fValues) : (filter = filter.filter((i) => !fValues.includes(i))); } else { let _filter = filter[filter.length - 1][filter[filter.length - 1].length - 1][ filter[filter.length - 1][filter[filter.length - 1].length - 1].length - 1 ]; isCheck ? filter[filter.length - 1][filter[filter.length - 1].length - 1][ filter[filter.length - 1][filter[filter.length - 1].length - 1] .length - 1 ].push(...fValues) : (filter[filter.length - 1][filter[filter.length - 1].length - 1][ filter[filter.length - 1][filter[filter.length - 1].length - 1] .length - 1 ] = _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); if (filter[0] == "in") { isCheck ? filter.push(layername) : (filter = filter.filter((i) => i != layername)); } else { let _filter = filter[filter.length - 1][filter[filter.length - 1].length - 1][ filter[filter.length - 1][filter[filter.length - 1].length - 1].length - 1 ]; isCheck ? filter[filter.length - 1][filter[filter.length - 1].length - 1][ filter[filter.length - 1][filter[filter.length - 1].length - 1].length - 1 ].push(layername) : (filter[filter.length - 1][filter[filter.length - 1].length - 1][ filter[filter.length - 1][filter[filter.length - 1].length - 1].length - 1 ] = _filter.filter((i) => i != layername)); } map.setFilter(type1, filter); }); } let layer = newfiberMapbox.getLayers().filter((i) => i.newfiberId == layername)[0]; if (!!!layer) { layer = newfiberMapbox.unLoadLayers.filter((i) => i.newfiberId == layername)[0]; isCheck && layer && newfiberMapbox.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 + "_text", "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 } = newfiberMapbox; 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) => { let points = []; if (!i.data) return; i.data.features.forEach((a) => { if (!!!a || !!!a.properties) return; (a.properties.minzoom = a.properties.minzoom || 0), (a.properties.color = a.properties.color || "rgba(0,0,0,1)"), (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.pumpName; if ( a.properties.name && !turf.getType(a).toLocaleLowerCase().includes("point") ) { let center = turf.pointOnFeature(a); center.properties = { ...a.properties, minzoom: 10 }; center.properties.geometry = Terraformer.WKT.convert(center.geometry); points.push(center); } }); i.data.features = i.data.features.concat(points); }); let types = {}; list .map((i) => i.data && i.data.features) .filter(Boolean) .flat(Infinity) .forEach((feature) => { if (!!!feature || !!!feature.properties) return; feature.properties.geometry = Terraformer.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]) ); map.triggerRepaint(); }; const setGeoJSON = ({ json, key }) => { let layer = newfiberMapbox.getLayers().filter((i) => i.newfiberId == key)[0]; console.log("layer----", layer); if (!!!layer) { layer = newfiberMapbox.unLoadLayers.filter((i) => i.newfiberId == key)[0]; layer && layer.setData(json); layer && newfiberMapbox.addLayer(layer); } if (layer) return layer.setData(json); setLegendData([{ data: json, layername: key, type: "point" }]); }; const beansToMap = ({ beans, fields = { geometry: "geometry", lng: "lng", lat: "lat", name: "name" }, type, isConvert, }) => { let geojson = turf.featureCollection( beans .filter( (i) => i[fields.geometry] || (Boolean(Number(i[fields.lng])) && Boolean(Number(i[fields.lat]))) ) .map((i) => { let feature = null; if (i[fields.geometry]) feature = turf.feature(Terraformer.WKT.parse(i[fields.geometry]), { ...i, name: i[fields.name], }); if (i[fields.lng]) feature = turf.point([i[fields.lng], i[fields.lat]].map(Number), { ...i, name: i[fields.name], }); return feature; }) .filter(Boolean) ); isConvert && (geojson = gcoord.transform(geojson, gcoord.AMap, gcoord.WGS84)); setGeoJSON({ json: geojson, key: type }); }; 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 = Terraformer.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 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); }) ); }; const updateStyle = (styleJson) => { styleJson.glyphs = styleJson.glyphs.includes("http") ? styleJson.glyphs : location.origin + styleJson.glyphs; styleJson.sprite = styleJson.sprite.includes("http") ? styleJson.sprite : location.origin + styleJson.sprite; const currentStyle = map.getStyle(); styleJson.sources = Object.assign({}, currentStyle.sources, styleJson.sources); let labelIndex = styleJson.layers.findIndex((el) => { return el.id == "waterway-label"; }); if (labelIndex === -1) { labelIndex = styleJson.layers.length; } const appLayers = currentStyle.layers.filter((el) => { return ( el.source && el.source != "mapbox://mapbox.satellite" && el.source != "mapbox" && el.source != "composite" ); }); styleJson.layers = [ ...styleJson.layers.slice(0, labelIndex), ...appLayers, ...styleJson.layers.slice(labelIndex, -1), ]; map.setStyle(styleJson); }; //添加延安建筑白膜 const addYanAnBuilding = () => { map.addLayer({ id: "buildingLayer", type: "fill-extrusion", source: { type: "geojson", data: buildingGeojson, }, // //绘画功能 paint: { // Get the fill-extrusion-color from the source 'color' property. 从source 'color'属性获取fill- extrusive -color。 // 'fill-extrusion-color':'rgba(200, 100, 240, 0.4)', // "fill-extrusion-color":['get','color'],//加载数据中的颜色 "fill-extrusion-color": { //根据数值中加载相对应颜色 property: "height_3", // this will be your density property form you geojson stops: [ [10, "#009bdd"], [20, "#009bdd"], [30, "#009bdd"], [80, "#00a8de"], [100, "#24edff"], [125, "#24edff"], [300, "#24edff"], ], }, // 从source 'height'属性获取填充-挤出-高度。 "fill-extrusion-height": ["get", "height_3"], "fill-extrusion-opacity": 1, }, }); }; //添加延安水系 const addYanAnRiverFlow = () => { let layer = new mapboxL7.LineLayer({ name: "waterLake", }) .source(yanAnWater) .size(4) .shape("line") .texture("arrow") .color("aqua") .animate({ interval: 2, // 间隔 duration: 3, // 持续时间,延时 trailLength: 3, // 流线长度 }) .style({ opacity: 0.8, lineTexture: true, // 开启线的贴图功能 iconStep: 200, // 设置贴图纹理的间距 borderWidth: 0.4, // 默认文 0,最大有效值为 0.5 borderColor: "#fff", // 默认为 #ccc }); newfiberMapbox.addLayer(layer); }; //添加延安路网 const addYanAnRoad = () => { let layer = new mapboxL7.LineLayer({ name: "dynamicRoad", }) .source(yanAnRoad) .size(1.3) .shape("line") .color("rgb(184, 184, 184)") .animate({ interval: 1, // 间隔 duration: 1.5, // 持续时间,延时 trailLength: 2, // 流线长度 }) .style({ opacity: 0.6, }); newfiberMapbox.addLayer(layer); }; onMounted(() => { initeMap(); bus.on("beansToMap", beansToMap); 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); bus.on("updateStyle", updateStyle); }); onBeforeUnmount(() => { bus.off("beansToMap"); bus.off("setLayerVisible"); bus.off("setLegendData"); bus.off("setGeoJSON"); bus.off("getGeojsonByType"); bus.off("removeMapDatas"); bus.off("setHighlight"); bus.off("updateStyle"); if (newfiberMapbox) { newfiberMapbox.destroy(); newfiberMapbox = null; } }); return { ...toRefs(allData), }; }, }; </script> <style> .mapPage { width: 100%; height: 100%; position: absolute; left: 0px; top: 0px; z-index: 0; background: lavender; } #cesiumContainer { width: 100%; height: 100%; position: absolute; } .l7-control-mouse-location { background: none; } .l7-control-mouse-location { color: #ffffff; } </style>