補充說明:
當參與層級控制的元素是點型元素時,是無法參與ZIndex層級控制的,此時可以換個解決方案
1.給不同的高度值實現,元素間的層級控制覆蓋
import * as mars3d from "mars3d"export let map // mars3d.Map三維地圖對象
export let graphicLayer // 矢量圖層對象// 需要覆蓋config.json中地圖屬性參數(當前示例框架中自動處理合并)
export const mapOptions = {scene: {center: { lat: 24.688611, lng: 119.260277, alt: 1673759, heading: 348, pitch: -69 }}
}// 初始化地圖業務,生命周期鉤子函數(必須),框架在地圖初始化完成后自動調用該函數
export function onMounted(mapInstance) {map = mapInstance // 記錄mapaddDemoLayer1()addDemoLayer2()
}async function addDemoLayer1() {graphicLayer1 = new mars3d.layer.GraphicLayer({})map.addLayer(graphicLayer1)const res = await mars3d.Util.fetchJson({ url: "https://data.mars3d.cn/file/apidemo/mudi.json" })for (let i = 0; i < 50; i++) {const item = res.data[i]const label = new mars3d.graphic.CircleEntity({position: [item.lng, item.lat,200],style: {radius: 480.0,materialType: mars3d.MaterialType.Water,materialOptions: {normalMap: "https://data.mars3d.cn/img/textures/waterNormals.jpg", // 水正常擾動的法線圖frequency: 80.0, // 控制波數的數字。animationSpeed: 0.02, // 控制水的動畫速度的數字。amplitude: 5.0, // 控制水波振幅的數字。specularIntensity: 0.8, // 控制鏡面反射強度的數字。baseWaterColor: "#006ab4", // rgba顏色對象基礎顏色的水。#00ffff,#00baff,#006ab4blendColor: "#006ab4" // 從水中混合到非水域時使用的rgba顏色對象。}},attr: item,flyTo: true})graphicLayer1.addGraphic(label)}
}function addDemoLayer2() {const singleDigitPins = {}// 創建矢量數據圖層(業務數據圖層)graphicLayer = new mars3d.layer.BusineDataLayer({url: "https://data.mars3d.cn/file/apidemo/mudi.json",dataColumn: "data", // 數據接口中對應列表所在的取值字段名lngColumn: "lng",latColumn: "lat",altColumn: "z",// 點的聚合配置cluster: {enabled: true,pixelRange: 20,image: async function (count, result) {const key = "type1-" + count // 唯一標識,不同圖層需要設置不一樣let image = singleDigitPins[key]if (image) {return image // 當前頁面變量有記錄}image = await localforage.getItem(key)if (image) {singleDigitPins[key] = imagereturn image // 瀏覽器客戶端緩存有記錄}image = await getClusterImage(count) // 生成圖片singleDigitPins[key] = image // 記錄到當前頁面變量,未刷新頁面時可直接使用localforage.setItem(key, image) // 記錄到瀏覽器客戶端緩存,刷新頁面后也可以繼續復用return image}},symbol: {type: "billboard",styleOptions: {image: "https://data.mars3d.cn/img/marker/mark-blue.png",width: 25,height: 34, // billboard聚合必須有width、heighthorizontalOrigin: Cesium.HorizontalOrigin.CENTER,verticalOrigin: Cesium.VerticalOrigin.BOTTOM,scaleByDistance: new Cesium.NearFarScalar(1000, 0.7, 5000000, 0.3),label: {text: "{text}",font_size: 19,color: Cesium.Color.AZURE,outline: true,outlineColor: Cesium.Color.BLACK,outlineWidth: 2,horizontalOrigin: Cesium.HorizontalOrigin.LEFT,verticalOrigin: Cesium.VerticalOrigin.BOTTOM,pixelOffset: new Cesium.Cartesian2(10, 0), // 偏移量distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0.0, 80000)}}}})map.addLayer(graphicLayer)bindLayerEvent(graphicLayer)
}
function bindLayerEvent() {graphicLayer.on(mars3d.EventType.clusterStop, function (event) {console.log("聚合發生了變化,并渲染完成", event)})// 單擊事件graphicLayer.on(mars3d.EventType.click, function (event) {console.log("你單擊了", event)if (map.camera.positionCartographic.height > 90000) {const graphic = event.graphic// graphic.closePopup()if (graphic?.cluster) {// 單擊了聚合的點console.log("單擊了聚合的點", graphic.graphics)} else {// 單擊了具體的點對象const position = graphic.positionShowmap.flyToPoint(position, {radius: 5000, // 距離目標點的距離duration: 4,complete: function (e) {// 飛行完成回調方法// graphic.openPopup()}})}}})graphicLayer.bindPopup(function (event) {if (event.graphic?.cluster) {const graphics = event.graphic.graphics // 對應的grpahic數組,可以自定義顯示if (graphics) {const names = []for (let index = 0; index < graphics.length; index++) {names.push(graphics[index].attr.text)}const inthtml = `單擊了聚合點(${graphics.length}個):<br/>${names.join(",")}`return inthtml}}const item = event.graphic?.attrif (!item) {return false}const inthtml = `<table style="width: auto;"><tr><th scope="col" colspan="2" style="text-align:center;font-size:15px;">${item.text} </th></tr><tr><td>省:</td><td>${item.province}</td></tr><tr><td>市:</td> <td>${item.city}</td></tr><tr><td>縣/區:</td> <td>${item.district}</td></tr><tr><td>地址:</td> <td>${item.address}</td></tr><tr><td>視頻:</td> <td><video src='http://data.mars3d.cn/file/video/lukou.mp4' controls autoplay style="width: 300px;" ></video></td></tr></table>`return inthtml})
}// 生成聚合圖標,支持異步
async function getClusterImage(count) {let colorInif (count < 10) {colorIn = "rgba(110, 204, 57, 0.6)"} else if (count < 100) {colorIn = "rgba(240, 194, 12, 0.6)"} else {colorIn = "rgba(241, 128, 23, 0.6)"}const radius = 40const thisSize = radius * 2const circleCanvas = document.createElement("canvas")circleCanvas.width = thisSizecircleCanvas.height = thisSizeconst circleCtx = circleCanvas.getContext("2d", { willReadFrequently: true })circleCtx.fillStyle = "#ffffff00"circleCtx.globalAlpha = 0.0circleCtx.fillRect(0, 0, thisSize, thisSize)// 圓形底色circleCtx.globalAlpha = 1.0circleCtx.beginPath()circleCtx.arc(radius, radius, radius, 0, Math.PI * 2, true)circleCtx.closePath()circleCtx.fillStyle = colorIncircleCtx.fill()// 數字文字const text = count + "個"circleCtx.font = radius * 0.6 + "px bold normal" // 設置字體circleCtx.fillStyle = "#ffffff" // 設置顏色circleCtx.textAlign = "center" // 設置水平對齊方式circleCtx.textBaseline = "middle" // 設置垂直對齊方式circleCtx.fillText(text, radius, radius) // 繪制文字(參數:要寫的字,x坐標,y坐標)return circleCanvas.toDataURL("image/png") // getImage方法返回任意canvas的圖片即可
}// 釋放當前地圖業務的生命周期函數,具體項目中時必須寫onMounted的反向操作(如解綁事件、對象銷毀、變量置空)
export function onUnmounted() {graphicLayer.remove()graphicLayer = nullmap = null
}// 計算貼地高度示例代碼,可以將獲取到的高度更新到數據庫內,后續不用重復計算。
export function getDataSurfaceHeight() {if (graphicLayer.length === 0) {globalMsg("數據尚未加載成功!")return}showLoading()// 對圖層內的數據做貼地運算,自動得到貼地高度graphicLayer.autoSurfaceHeight({ exact: true }).then((graphics) => {hideLoading()const arr = []for (let i = 0, len = graphics.length; i < len; i++) {const graphic = graphics[i]const point = graphic.pointarr.push({...graphic.attr,lat: point.lat,lng: point.lng,z: point.alt})}mars3d.Util.downloadFile("point.json", JSON.stringify({ data: arr }))})
}export function enabledAggressive(val) {graphicLayer.clusterEnabled = val
}export function layerShowChange(val) {graphicLayer.show = val
}
覆蓋效果