import { showDeviceDetail, deviceDetail, className, dialogPositon } from "@/store"; import { useSimStore } from '@/store/simulation' export function addTerrain(url) { // console.log("加载地形"); var terrainProvider = new Cesium.CesiumTerrainProvider({ // 切片地址 // url: `${process.env.VUE_APP_MAP_API}/DEM/`, // url: `{MAP_API}/dixing/切片/`, // url: `{MAP_API}/QJDEM/`, url, // 地形服务源自SuperMap iServer发布时需设置isSct为true isSct: false, invisibility: true, }); viewer.terrainProvider = terrainProvider; } export function addImageLayer(url) { const imageLayer = viewer.scene.imageryLayers.addImageryProvider( new Cesium.UrlTemplateImageryProvider({ url, // url: `{MAP_API}/yingxiang/切片/{z}/{x}/{y}.png`, // url: `{MAP_API}/QJZXSQYX/{z}/{x}/{y}.png`, // maximumLevel: 16, }) ); } export async function addTileset(url) { const tileset = await Cesium.Cesium3DTileset.fromUrl(url); viewer.scene.primitives.add(tileset); console.log("palaceTileset", tileset); // Cesium Cesium3DTileset 贴地 tileset.heightReference = Cesium.HeightReference.RELATIVE_TO_GROUND; tileset.clampToGround = true; //高度偏差,正数为向上偏,负数为向下偏,根据真实的模型位置不断进行调整 var heightOffset = 0; let name = tileset._url || ""; //计算tileset的绑定范围 var boundingSphere = tileset.boundingSphere; //计算中心点位置 var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center); //计算中心点位置坐标 var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0); //偏移后的三维坐标 var offset = Cesium.Cartesian3.fromRadians( cartographic.longitude, cartographic.latitude, heightOffset ); var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3()); //tileset.modelMatrix转换 if (heightOffset) { tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); } return tileset; } let entities = []; const pointEntityMap = new Map(); // key: id, value: entity export function createPoint(option) { const { id, type = "", deviceTypeName = "", name = "默认名称", view, latitude, longitude, height, callback, imgWidth = 56, imgHeight = 67, showBillboard = true, showLabel = true, className = "device" } = option; const realType = type || deviceTypeName; // 如果已经存在该 id 的 entity,则跳过创建 if (pointEntityMap.has(id)) { clearAllPoints() console.log(`点 ${id} 已存在,已清除重建`); } let position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height || 50); let model = { id, name: name, position: position, type: realType, view: view, attrs: option, className: className, label: { text: name || "默认标签", font: "14pt Source Han Sans CN", fillColor: (typeof realType === 'string' && realType.includes("active")) ? Cesium.Color.AQUA : Cesium.Color.WHITE, // fillColor: Cesium.Color.WHITE, backgroundColor: showBillboard ? Cesium.Color.BLACK.withAlpha(0.5) : Cesium.Color.SKYBLUE, showBackground: true, outline: false, outlineColor: Cesium.Color.WHITE, outlineWidth: 0, scale: 1.0, scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 1.5e7, 0.5), style: Cesium.LabelStyle.FILL_AND_OUTLINE, verticalOrigin: Cesium.VerticalOrigin.CENTER, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, pixelOffset: new Cesium.Cartesian2(0, -40), distanceDisplayCondition: (typeof realType === 'string' && realType.includes("河流")) ? new Cesium.DistanceDisplayCondition(0, 5000000) : new Cesium.DistanceDisplayCondition(0, 50000), // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 50000), heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, show: showLabel, }, }; model.billboard = { image: type ? `/images/poi/${type}.png` : `/images/poi/村庄.png`, height: imgHeight || 20, width: imgWidth || 20, sizeInMeters: false, verticalOrigin: Cesium.VerticalOrigin.CENTER, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, pixelOffset: new Cesium.Cartesian2(0, 3), scale: 0.8, scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 1.5e7, 0.5), distanceDisplayCondition: (typeof realType === 'string' && realType.includes("河流")) ? new Cesium.DistanceDisplayCondition(0, 5000000) : new Cesium.DistanceDisplayCondition(0, 50000), distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 50000), show: showBillboard, heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, backgroundColor: showBillboard ? Cesium.Color.BLACK.withAlpha(0.8) : Cesium.Color.SKYBLUE, }; // 创建新实体并添加到地图中 const entity = viewer.entities.add(model); pointEntityMap.set(id, entity); // 存入 map return entity; } /** * 删除所有已创建的点 */ export function clearAllPoints() { for (let [id, entity] of pointEntityMap.entries()) { viewer.entities.remove(entity); } pointEntityMap.clear(); } export function removeEntities(id) { pointEntityMap.forEach((entity, index) => { if (entity.id === id) { viewer.entities.remove(entity); } }); } function removeHandler() { if (interativeHandler != null && Cesium.defined(interativeHandler)) { //清除添加的楼栋包围盒 entities.forEach(entity => { viewer.entities.remove(entity); }); entities = []; this.interativeHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); this.interativeHandler = null; const highlightedFeature = this.highlightedFeature; if (Cesium.defined(highlightedFeature.feature)) { highlightedFeature.feature.color = new Cesium.Color(); this.highlightedFeature.feature = null; } } } export function initHandler() { const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); handler.setInputAction(movement => { const position = getPickPositon(movement.position); console.log("getPickPositon", position); const picked = viewer.scene.pick(movement.position); const id = picked?.id?.id; console.log("picked", picked); if (Cesium.defined(picked) && id) { const entity = picked?.id; const simStore = useSimStore() if (entity && entity.attrs && !simStore.openDia && entity.attrs.type && entity.attrs.type == '泥位计') { let obj = { deviceName: entity.attrs.deviceName, latitude: entity.attrs.latitude, longitude: entity.attrs.longitude } simStore.selectNWJ = obj showDeviceDetail.value = false; console.log(simStore.selectNWJ, 'map.js点击泥位计') } if (entity && entity.className && simStore.openDia) { showDeviceDetail.value = true; deviceDetail.value = entity.attrs; className.value = entity.className; dialogPositon.value = entity.position._value; } // const callback = this.eventMap.get(id) // if (callback && typeof callback === "function") { // callback(picked.id) // } // this.resetAllPointColor(picked.id.id) } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); } export function dbClickHandler() { const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); handler.setInputAction(movement => { const picked = viewer.scene.pick(movement.position); const id = picked?.id?.id; if (Cesium.defined(picked) && id) { const type = picked?.id?.type; const view = picked?.id?.view; if (view) { view.duration = 5; // view.easingFunction = Cesium.EasingFunction.QUADRATIC_IN_OUT, viewer.scene.camera.flyTo(view); } else { viewer.flyTo(picked.id); } } }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); } window.getCameraPosition = function getCameraPosition() { const camera = viewer.scene.camera; const position = camera.position; const cartographic = Cesium.Cartographic.fromCartesian(position); const longitude = Cesium.Math.toDegrees(cartographic.longitude); const latitude = Cesium.Math.toDegrees(cartographic.latitude); const height = cartographic.height; const pitch = camera.pitch; const roll = camera.roll; const heading = camera.heading; return { destination: position, orientation: { pitch, roll, heading, }, }; }; export function calcPosition(positionArray) { if (!Array.isArray(positionArray)) { return []; } const result = positionArray.map(item => { const position = cartesianToXY(item); return [position.longitude, position.latitude, position.height]; }); console.log("calcPosition", result); return result; } window.calcPosition = calcPosition; export function cartesianToXY(cartesian) { var scene = viewer.scene; var ellipsoid = scene.globe.ellipsoid; if (cartesian) { var cartographic = ellipsoid.cartesianToCartographic(cartesian); var longitude = Cesium.Math.toDegrees(cartographic.longitude).toFixed(7); var latitude = Cesium.Math.toDegrees(cartographic.latitude).toFixed(7); // 地理高度 var height = (cartographic.height + 1).toFixed(2); // 相机高度 // var height = viewer.camera.positionCartographic.height.toFixed(0); // 方向 围绕Z轴旋转 var heading = Cesium.Math.toDegrees(viewer.camera.heading); // 倾斜角度 围绕Y轴旋转 var pitch = Cesium.Math.toDegrees(viewer.camera.pitch); // 围绕X轴旋转 var roll = Cesium.Math.toDegrees(viewer.camera.roll); return { longitude: Number(longitude), latitude: Number(latitude), height: Number(height), heading: Number(heading), pitch: Number(pitch), roll: Number(roll), }; } } export function initView(option) { let view = { destination: { x: -2256394.3617862244, y: 4620836.918376569, z: 4049368.785453873, }, orientation: { pitch: -0.7862789841268825, roll: 0.00003453626288862921, heading: 0.18702357350897447, }, }; viewer.scene.camera.flyTo(view); } //获取点击坐标 export function getPickPositon(position) { let cartesianCoordinate = viewer.scene.pickPosition(position); if (!cartesianCoordinate) { return null; } let cartographic = Cesium.Cartographic.fromCartesian(cartesianCoordinate); let longitude = Cesium.Math.toDegrees(cartographic.longitude); let latitude = Cesium.Math.toDegrees(cartographic.latitude); let height = cartographic.height; let result = { longitude: Number(longitude.toFixed(6)), latitude: Number(latitude.toFixed(6)), altitude: Number(height.toFixed(2)), }; return result; } // 坐标转换函数 function transformCoordinates(coordinates) { return coordinates.map(ring => ring.map(point => { const [lon, lat] = utmToWgs84(point[0], point[1]); return [lon, lat, point[2]]; // 保留高程 }) ); } function utmToWgs84(x, y) { return proj4("EPSG:32650", "EPSG:4326", [x, y]); } export function geomToGeoJSON(geomString) { const geom = JSON.parse(geomString); // 定义 UTM Zone 50N 投影 // proj4.defs("EPSG:32650", "+proj=utm +zone=40 +datum=WGS84 +units=m +no_defs") // 生成 GeoJSON const geoJson = { type: "Feature", properties: {}, geometry: { type: geom.type, coordinates: geom.coordinates, }, }; return geoJson; }