<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"; const baseUrl = import.meta.env.VITE_APP_MAP_BASE_API || ""; 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, }; let isMvtCache = null; let isGeojsonCache = null; const initeMap = async () => { console.log("baseUrl", baseUrl); config = (await axios.get(baseUrl + props.initJson)).data; isMvtCache = config.params.mvt.includes("/v1/mvt"); isGeojsonCache = config.params.geojson.includes("/v1/geojson"); const { basemap } = config.params; const { style, localStyle } = config.params.init; let styleJson = ( await axios.get( localStyle ? baseUrl + localStyle : (style.includes("http") ? "" : location.origin + basemap) + config.params.init.style ) ).data; styleJson.glyphs = styleJson.glyphs.includes("http") ? styleJson.glyphs : location.origin + baseUrl + styleJson.glyphs; styleJson.sprite = styleJson.sprite.includes("http") ? styleJson.sprite : location.origin + baseUrl + styleJson.sprite; window.newfiberMap = new mapboxL7.Scene({ id: "cesiumContainer", map: new mapboxL7.Mapbox({ // style: localStyle?localStyle:(style.includes('http')?'':location.origin + config.params.basemap) + config.params.init.style, ...config.params.init, style: styleJson, }), }); newfiberMap.config_ = config; map = newfiberMap.map; map.ogcLayers = []; newfiberMap.unLoadLayers = []; map.on("load", async () => { /* const mouseLocation = new mapboxL7.MouseLocation({ transform: position => { return position; }, }); newfiberMap.addControl(mouseLocation);*/ let { sprites, l7, mapbox } = config.params; (sprites || []).forEach((url) => map.style._loadSprite( url.includes("http") ? baseUrl + url : window.location.origin.split("#")[0] + url ) ); ((l7 || []).images || []).forEach((item) => newfiberMap.addImage( item.name, item.url.includes("http") ? baseUrl + item.url : window.location.origin.split("#")[0] + item.url ) ); ((mapbox || []).images || []).forEach((item) => item.url.includes("gif") ? setGifImage(item) : newfiberMap.map.loadImage( item.url.includes("http") ? baseUrl + item.url : window.location.origin.split("#")[0] + item.url, (error, image) => newfiberMap.map.addImage(item.name, image) ) ); await getGeoJSON(); await loadData(); newfiberMap .getLayers() .filter( (i) => highlightLayers[i.newfiberId] && (highlightLayers[i.newfiberId] = i) ); props.loadCallback && props.loadCallback(); getLayerIdByClick(); let timeout = setTimeout(() => { let { pitch, center } = config.params.init; pitch && newfiberMap.map.setPitch(pitch); center && newfiberMap.map.setCenter(center); (config.orders || []).forEach((item) => setLayerOrder(...item)); clearTimeout(timeout); }, 2000); // 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]; if (feature && feature.properties.geometry) setHighlight( turf.feature( Terraformer.WKT.parse(feature.properties.geometry), feature.properties ) ); 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.geojson + `/${key}${ !isGeojsonCache ? "_" + (geom_column || "geometrys") + ".geojson" : "" }?` + 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, features: results[index].data.features && results[index].data.features.map((i) => ({ ...i, properties: { ...i.properties, name: i.properties.name ? i.properties.name.replaceAll("\\n", "\n") : undefined, }, })), }) ); } async function setGifImage(item) { const arrayBuffer = await fetchImageAsArrayBuffer(item.url); const canvasIcon = new mapboxgl1.CanvasIcon( item.width || 512, item.height || 512, { autoPixelRatio: true, onAdd(ctx) { ctx.gif = mapboxgl1.AnimatedGIF.fromBuffer(arrayBuffer, ctx.context, {}); }, renderCallback(ctx) { ctx.gif.update(performance.now() / 1000); ctx.gif.updateFrame(); }, postRender(ctx) { map.triggerRepaint(); }, } ); if (!map.hasImage(item.name)) map.addImage(item.name, canvasIcon); async function fetchImageAsArrayBuffer(url) { try { const response = await fetch(url); if (!response.ok) { throw new Error("Network response was not ok"); } const arrayBuffer = await response.arrayBuffer(); return arrayBuffer; } catch (error) { console.error("There has been a problem with your fetch operation:", error); } } } }; const loadData = async () => { let { mapbox, l7, ogc } = config; 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); }); if (l7) l7.forEach((item) => { let { id, columns, filter } = item; let params = []; if (columns) params.push(`columns=${columns}`); if (filter) params.push(`filter=${filter}`); let urlKey = config.params.geojson + `/${id}${!isGeojsonCache ? "_" + "geometrys" + ".geojson" : ""}?` + params.join("&"); let _geojson = config.geojsonMvts[urlKey]; id ? _geojson ? initMapBoxL7Class(item, _geojson) : axios .get(urlKey) .then(({ data: geojson }) => initMapBoxL7Class(item, geojson)) : initMapBoxL7Class(item, geojson[item.key] || turf.featureCollection([])); }); if (mapbox) initMapBoxLayer(); 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; newfiberMap.addLayer(layer); if (!show) layer.hide(); 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 + `/${key}/{z}/{x}/{y}${!isMvtCache ? ".pbf" : ""}?` + params.join("&"), ], tileSize: 512, scheme: "xyz", maxzoom: 14, minzoom: 1, } : { type: "geojson", data: config.geojsonMvts[ config.params.geojson + `/${key}${ !isGeojsonCache ? "_" + (geom_column || "geometrys") + ".geojson" : "" }?` + params.join("&") ], }), }); } map.addLayer({ ...item, source: sourceID }); map.moveLayer(id); 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 = newfiberMap.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 (filter) { 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); } } }); config.filter[layername].easeTo && isCheck && map.easeTo({ ...config.filter[layername].easeTo, pitch: 51 }); } 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 = 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 + "_text", "visibility", isCheck ? "visible" : "none" ); layer = map.getLayer(layername + "_top"); layer && map.setLayoutProperty( layername + "_top", "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 closeAllLayer = () => { if (newfiberMap.getLayerByName("dynamicLine")) { newfiberMap.removeLayer(newfiberMap.getLayerByName("dynamicLine")); } if (newfiberMap && newfiberMap.RainsLayer) { newfiberMap.RainsLayer.destroy(); } if (newfiberMap.popup) newfiberMap.popup.remove(); let point = (newfiberMap.map.getFilter("point") || []).flat(Infinity); let line = (newfiberMap.map.getFilter("linestring") || []).flat(Infinity); let polygon = (newfiberMap.map.getFilter("polygon") || []).flat(Infinity); if (point.concat(line).concat(polygon).length == 0) return; config.ogc .map((i) => i.id) .concat(config.l7.filter((i) => i.id).map((i) => i.key)) .concat(Object.keys(config.filter)) .concat( Array.from( new Set( [point, line, polygon] .map((i) => _.slice(i, i.indexOf(""))) .flat() .filter(Boolean) ) ) ) .forEach((i) => setLayerVisible({ layername: i, isCheck: false })); bus.emit("openMapPopup", {}); bus.emit("setHighlight", []); bus.emit("clearTuLiCheck", false); }; const removeMapDatas = (types) => { types = types.map(i => i+'_text').concat(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.center(a); center.properties = { ...a.properties, minzoom: 10,type:a.properties.type +"_text" }; 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 = newfiberMap.getLayers().filter((i) => i.newfiberId == key)[0]; if (!!!layer) { layer = newfiberMap.unLoadLayers.filter((i) => i.newfiberId == key)[0]; layer && layer.setData(json); layer && newfiberMap.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],}); feature.properties.visible = false; 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)) return; let geometry = feature.geometry; 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(feature); }); 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 addDynamicLine = ({ c_layer, c_layer1 }) => { if (newfiberMap.getLayerByName("dynamicLine")) { newfiberMap.removeLayer(newfiberMap.getLayerByName("dynamicLine")); } let dynamicLineJson = turf.featureCollection( newfiberMap.map .getSource("sx_wn_hm_merge") ._data.features.filter( (feature) => feature.properties.c_layer.includes(c_layer) && feature.properties.c_layer.includes(c_layer1) ) ); console.log(c_layer, dynamicLineJson); let layer = new mapboxL7.LineLayer({ name: "dynamicLine", }) .source(dynamicLineJson) .size(3) .shape("line") .color("color") .animate({ interval: 1, duration: 2, trailLength: 0.8, }); newfiberMap.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); bus.on("closeAllLayer", closeAllLayer); bus.on("addDynamicLine", addDynamicLine); }); 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"); bus.off("closeAllLayer"); bus.off("addDynamicLine"); if (newfiberMap) { if (newfiberMap.RainsLayer) newfiberMap.RainsLayer.destroy(); newfiberMap.destroy(); newfiberMap = 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>