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;
|
}
|