DiKongGanZhiPingTai/src/views/demo/system/mediaLibrary/path/pathMap.vue

733 lines
24 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<!-- <div class="map-out-container"> -->
<!-- <div class="map-inner-container"> -->
<div ref="vChartRef" id="mars3d-container" class="mars3d-container"> </div>
<!-- </div> -->
<!-- </div> -->
</template>
<script lang="ts" setup>
import { ref, watch, onMounted, defineEmits } from 'vue';
import * as mars3d from 'mars3d';
import * as Cesium from 'mars3d-cesium';
import {
CheckOutlined,
AntDesignOutlined,
ExpandAltOutlined,
BorderOutlined,
LogoutOutlined,
} from '@ant-design/icons-vue';
import {
AddAnnotation,
UpdateAnnotation,
AddWorkArea,
UpdateWorkArea,
} from '@/api/demo/mediaLibrary';
import * as turf from '@turf/turf';
import { WktToGeojson, GeojsonToWkt } from '@/components/MapboxMaps/src/WktGeojsonTransform';
import dayjs from 'dayjs';
const props = defineProps([
'allImageDataList',
'nowShowImageData',
'updateDisplayOrShowOnMapData',
]);
const emits = defineEmits(['setNowShowImageData', 'setAllImageData']);
const vChartRef: any = ref<HTMLElement>();
let map: mars3d.Map; // 地图对象
let graphicLayers = new mars3d.layer.GraphicLayer({
isAutoEditing: true,
});
// 地图照片
// 地图照片-地面点
let bottomPointGraphicData: any = [];
// 地图照片-飞行点
let flightointGraphicData: any = [];
// 地图照片-地面点到展示图片的线
let bottomImagePolylineGraphicData: any = [];
// 地图照片-展示图片
let imageGraphicData: any = [];
onMounted(() => {
initMap();
});
const initMap = () => {
map = new mars3d.Map(vChartRef.value, {
scene: {
center: {
lat: 35.134608,
lng: 118.29853,
alt: 8306.3,
heading: 360,
pitch: -45,
},
scene3DOnly: false,
shadows: false,
removeDblClick: true,
sceneMode: 3,
showSun: true,
showMoon: true,
showSkyBox: true,
showSkyAtmosphere: true,
fog: true,
fxaa: true,
requestRenderMode: true,
contextOptions: {
requestWebgl1: false,
webgl: {
preserveDrawingBuffer: true,
alpha: false,
stencil: true,
powerPreference: 'high-performance',
},
},
globe: {
depthTestAgainstTerrain: false,
baseColor: '#546a53',
showGroundAtmosphere: true,
enableLighting: false,
},
cameraController: {
zoomFactor: 3,
minimumZoomDistance: 1,
maximumZoomDistance: 50000000,
enableRotate: true,
enableTranslate: true,
enableTilt: true,
enableZoom: true,
enableCollisionDetection: true,
minimumCollisionTerrainHeight: 15000,
},
},
control: {
homeButton: true,
baseLayerPicker: false,
sceneModePicker: true,
vrButton: false,
fullscreenButton: true,
navigationHelpButton: true,
animation: false,
timeline: false,
infoBox: false,
geocoder: false,
selectionIndicator: false,
showRenderLoopErrors: true,
contextmenu: {
hasDefault: true,
},
mouseDownView: true,
zoom: {
insertIndex: 1,
},
compass: {
bottom: 'toolbar',
left: '5px',
rotation: true,
},
distanceLegend: {
left: '10px',
bottom: '2px',
},
locationBar: {
crs: 'CGCS2000_GK_Zone_3',
crsDecimal: 0,
template:
"<div>经度:{lng}</div> <div>纬度:{lat}</div> <div class='hide1000'>横{crsx} 纵{crsy}</div> <div>海拔:{alt}米</div> <div class='hide700'>层级:{level}</div><div>方向:{heading}°</div> <div>俯仰角:{pitch}°</div><div class='hide700'>视高:{cameraHeight}米</div>",
cacheTime: 50,
},
},
method: {
templateValues: {
dataServer: '//data.mars3d.cn',
gltfServerUrl: '//data.mars3d.cn/gltf',
},
},
terrain: {
url: '//data.mars3d.cn/terrain',
show: true,
clip: true,
},
basemaps: [
{
id: 10,
name: '地图底图',
type: 'group',
opacity: 1,
},
{
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
eventParent: {
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
show: true,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
show: true,
},
],
show: true,
},
private: false,
id: 'm-770c35e7-9054-4259-b5ee-c15f108becd0',
opacity: 1,
pid: 2021,
parent: {
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
show: true,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
show: true,
},
],
show: true,
},
zIndex: 1,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
eventParent: {
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
show: true,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
show: true,
},
],
show: true,
},
private: false,
id: 'm-3b881368-574b-48a5-88b2-8b3c2c48fd62',
opacity: 1,
pid: 2021,
parent: {
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
show: true,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
show: true,
},
],
show: true,
},
zIndex: 2,
},
],
show: true,
opacity: 1,
},
],
layers: [],
});
if (map) {
map.addLayer(graphicLayers);
// 图层
showAllImageDataList();
handlerLocation([118.2958779, 35.1342553]);
}
};
watch(
() => props.updateDisplayOrShowOnMapData,
(newValue) => {
if (newValue) {
// 地图照片-地面点
bottomPointGraphicData.forEach((graphicLayer) => {
if (graphicLayer.options.id == newValue.id + '_bottom') {
if (newValue.showOnMap == 1) {
graphicLayer.show = newValue.display == 1 ? true : false;
} else {
graphicLayers.removeGraphic(graphicLayer);
}
}
});
// 地图照片-飞行点
flightointGraphicData.forEach((graphicLayer) => {
if (graphicLayer.options.id == newValue.id + '_flight') {
if (newValue.showOnMap == 1) {
if (newValue.id == props.nowShowImageData.id) {
graphicLayer.show = newValue.display == 1 ? true : false;
}
} else {
graphicLayers.removeGraphic(graphicLayer);
}
}
});
// 地图照片-地面点到展示图片的线
bottomImagePolylineGraphicData.forEach((graphicLayer) => {
if (graphicLayer.options.id == newValue.id + '_polyline') {
if (newValue.showOnMap == 1) {
graphicLayer.show = newValue.display == 1 ? true : false;
} else {
graphicLayers.removeGraphic(graphicLayer);
}
}
});
// 地图照片-展示图片
imageGraphicData.forEach((graphicLayer) => {
if (graphicLayer.options.id == newValue.id + '_image') {
if (newValue.showOnMap == 1) {
graphicLayer.show = newValue.display == 1 ? true : false;
graphicLayer.setStyle({
label: {
text: `${newValue.name}`,
},
});
} else {
graphicLayers.removeGraphic(graphicLayer);
}
}
});
}
},
{
deep: true,
},
);
// watch(
// () => props.nowShowImageData,
// (newValue) => {
// if (newValue) {
// // 地图照片-地面点
// bottomPointGraphicData.forEach((graphicLayer) => {
// if (graphicLayer.options.id == newValue.id + '_bottom') {
// graphicLayer.show = newValue.display == 1 ? true : false;
// }
// });
// // 地图照片-飞行点
// // flightointGraphicData.forEach((graphicLayer) => {
// // if (graphicLayer.options.id == newValue.id + '_flight') {
// // }
// // });
// // 地图照片-地面点到展示图片的线
// bottomImagePolylineGraphicData.forEach((graphicLayer) => {
// if (graphicLayer.options.id == newValue.id + '_polyline') {
// graphicLayer.show = newValue.display == 1 ? true : false;
// }
// });
// // 地图照片-展示图片
// imageGraphicData.forEach((graphicLayer) => {
// if (graphicLayer.options.id == newValue.id + '_image') {
// graphicLayer.show = newValue.display == 1 ? true : false;
// graphicLayer.setStyle({
// label: {
// text: `${newValue.name}`,
// },
// });
// }
// });
// }
// },
// {
// deep: true,
// },
// );
// 地图照片--------------------------------------------------------------------
// 地图照片-初始化-遍历展示
const showAllImageDataList = async () => {
// 删除旧数据
bottomPointGraphicData?.forEach((graphicLayer) => {
graphicLayers.removeGraphic(graphicLayer);
});
flightointGraphicData?.forEach((graphicLayer) => {
graphicLayers.removeGraphic(graphicLayer);
});
bottomImagePolylineGraphicData?.forEach((graphicLayer) => {
graphicLayers.removeGraphic(graphicLayer);
});
imageGraphicData?.forEach((graphicLayer) => {
graphicLayers.removeGraphic(graphicLayer);
});
// 图层数据
bottomPointGraphicData = [];
flightointGraphicData = [];
bottomImagePolylineGraphicData = [];
imageGraphicData = [];
// 地图照片-遍历
let rotation = 0;
props.allImageDataList.forEach((item, index) => {
if (item.lng && item.lat && item.absoluteAltitude && item.showOnMap == 1) {
const image = new Image();
image.crossOrigin = 'Anonymous';
// image.src = item.preview_url;
// image.src = getImgurl(item.objectKey);
image.src =
'https://m.tuniucdn.com/fb2/t1/G5/M00/44/52/Cii-s1soezyIF2UxABn76u-yKl8AAIwBgB34jAAGfwC3020871';
image.onload = () => {
// 创建Canvas元素
const canvas = document.createElement('canvas');
canvas.width = 34;
canvas.height = 29;
// 获取Canvas绘图上下文
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'white';
ctx?.fillRect(0, 0, canvas.width, canvas.height);
// 在Canvas上绘制图片
ctx.drawImage(image, 2, 2, 30, 25);
// 将Canvas内容转换为图片的数据URL
const dataURL1 = canvas.toDataURL('image/png');
// 在Canvas上绘制图片假设image变量已经定义并且是一个有效的Image对象
ctx.drawImage(image, 2, 2, 30, 25);
// 设置边框颜色和宽度
ctx.strokeStyle = '#2d8cef'; // 蓝色边框
ctx.lineWidth = 1; // 边框宽度
// 绘制边框
ctx.strokeRect(0.5, 0.5, canvas.width - 1, canvas.height - 1); // 调整坐标和尺寸以适应边框宽度
// 将Canvas内容转换为图片的数据URL
const dataURL2 = canvas.toDataURL('image/png');
// 位置
let position = [
parseFloat(item.lng),
parseFloat(item.lat),
parseFloat(item.absoluteAltitude),
];
// 地形高度
mars3d.PointUtil.getSurfaceHeight(
map.scene,
Cesium.Cartesian3.fromDegrees(position[0], position[1]),
).then((point) => {
// 地面点
let bottomPointGraphic = new mars3d.graphic.BillboardEntity({
id: item.id + '_bottom',
position: [position[0], position[1], point.height],
style: {
image: '/src/assets/images/flightoperation/mediaLibraryPoint.png',
clampToGround: true,
scale: 1,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
},
hasEdit: false,
show: item.display == 1 ? true : false,
});
if (index + 1 < props.allImageDataList.length) {
const afterItem = props.allImageDataList[index + 1];
let lng = afterItem.lng - item.lng;
let lat = afterItem.lat - item.lat;
let angleARad = Math.atan(lng / lat);
let angleA = (angleARad * 180) / Math.PI;
rotation = angleA;
}
// 飞行点
let flightointGraphic = new mars3d.graphic.BillboardEntity({
id: item.id + '_flight',
position: [position[0], position[1], position[2] * 2],
style: {
image: '/src/assets/images/flightoperation/mediaLibraryFlight.png',
clampToGround: false,
scale: 1,
verticalOrigin: Cesium.VerticalOrigin.CENTER,
rotation: rotation,
},
hasEdit: false,
show: false,
});
// 地面点到展示图片的线
let bottomImagePolylineGraphic = new mars3d.graphic.PolylineEntity({
id: item.id + '_polyline',
positions: [
Cesium.Cartesian3.fromDegrees(position[0], position[1], point.height),
Cesium.Cartesian3.fromDegrees(position[0], position[1], position[2]),
],
style: {
color: '#ffffff',
width: 1, // 线宽
clampToGround: false,
},
hasEdit: false,
show: item.display == 1 ? true : false,
// 用于恢复默认
defaultPosition: position,
// 地形高度
surfaceHeight: point.height,
});
// 展示图片
let imageGraphic = new mars3d.graphic.BillboardEntity({
id: item.id + '_image',
position: [position[0], position[1], position[2]],
style: {
image: dataURL1,
clampToGround: false,
scale: 1,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
label: {
text: `${item.name}`,
font_size: 14,
color: '#2d8cf0',
outline: true,
outlineColor: '#ffffff',
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
pixelOffset: [25, -5],
show: false,
},
},
hasEdit: false,
show: item.display == 1 ? true : false,
// 用于恢复默认
defaultImage: dataURL1,
// 用于外侧修改图片
chooseImage: dataURL2,
});
// 监听mouseover事件
imageGraphic.on(mars3d.EventType.mouseOver, function () {
if (!props.nowShowImageData || props.nowShowImageData.id !== item.id) {
// 鼠标悬停时更改图片、图片变大
imageGraphic.setStyle({
image: dataURL2,
scale: 1.1,
label: {
show: true,
},
});
}
});
// 监听mouseout事件
imageGraphic.on(mars3d.EventType.mouseOut, function () {
if (!props.nowShowImageData || props.nowShowImageData.id !== item.id) {
// 鼠标移出时恢复默认图片、图片恢复大小
imageGraphic.setStyle({
image: dataURL1,
scale: 1,
label: {
show: false,
},
});
}
});
// 监听点击事件
imageGraphic.on(mars3d.EventType.click, function () {
// 点击当前展示的图片
if (props.nowShowImageData && props.nowShowImageData.id == item.id) {
// 全部恢复默认
imageRestoreDefault();
emits('setNowShowImageData', {});
} else if (!props.nowShowImageData || props.nowShowImageData.id !== item.id) {
// 当前展示图片为空 或者 点击与当前展示不同
// 全部恢复默认
imageRestoreDefault();
// 鼠标点击
// 更新 PolylineEntity 的位置
bottomImagePolylineGraphic.positions = [
Cesium.Cartesian3.fromDegrees(position[0], position[1], point.height),
Cesium.Cartesian3.fromDegrees(position[0], position[1], position[2] * 2),
];
// 更新 PolylineEntity 的颜色
bottomImagePolylineGraphic.setStyle({
color: '#2d8cf0',
});
// 飞行点显示
flightointGraphic.show = true;
// 鼠标更改图片
imageGraphic.setStyle({
image: dataURL2,
label: {
show: true,
},
});
emits('setNowShowImageData', item);
}
});
// 将地面点 添加到图层中
graphicLayers.addGraphic(bottomPointGraphic);
// 将飞行点 添加到图层中
graphicLayers.addGraphic(flightointGraphic);
// 地面点到展示图片的线 添加到图层中
graphicLayers.addGraphic(bottomImagePolylineGraphic);
// 展示图片 添加到图层中
graphicLayers.addGraphic(imageGraphic);
// 数据
bottomPointGraphicData.push(bottomPointGraphic);
flightointGraphicData.push(flightointGraphic);
bottomImagePolylineGraphicData.push(bottomImagePolylineGraphic);
imageGraphicData.push(imageGraphic);
});
};
}
});
};
// 图片获取路径
function getImgurl(url) {
return 'http://175.27.168.120:6014/api/v1/buckets/test/objects/download?prefix=' + url;
}
// 地图照片-恢复默认
function imageRestoreDefault() {
// 飞行点
for (let i = 0; i < flightointGraphicData.length; i++) {
let flightointGraphic = flightointGraphicData[i];
flightointGraphic.show = false;
}
// 地面点到展示图片的线
for (let i = 0; i < bottomImagePolylineGraphicData.length; i++) {
let bottomImagePolylineGraphic = bottomImagePolylineGraphicData[i];
let defaultPosition = bottomImagePolylineGraphic.options.defaultPosition;
let surfaceHeight = bottomImagePolylineGraphic.options.surfaceHeight;
bottomImagePolylineGraphic.setStyle({
color: '#ffffff',
});
bottomImagePolylineGraphic.positions = [
Cesium.Cartesian3.fromDegrees(defaultPosition[0], defaultPosition[1], surfaceHeight),
Cesium.Cartesian3.fromDegrees(defaultPosition[0], defaultPosition[1], defaultPosition[2]),
];
}
// 展示图片
for (let i = 0; i < imageGraphicData.length; i++) {
let imageGraphic = imageGraphicData[i];
let defaultImage = imageGraphic.options.defaultImage;
imageGraphic.setStyle({
image: defaultImage,
scale: 1,
label: {
show: false,
},
});
}
}
// 地图照片-右侧图片模块修改当前显示图片
function setNowShowImageByRight() {
setTimeout(() => {
// 全部恢复默认
imageRestoreDefault();
// 飞行点
for (let i = 0; i < flightointGraphicData.length; i++) {
if (flightointGraphicData[i].options.id.includes(props.nowShowImageData.id)) {
let flightointGraphic = flightointGraphicData[i];
flightointGraphic.show = true;
}
}
// 地面点到展示图片的线
for (let i = 0; i < bottomImagePolylineGraphicData.length; i++) {
if (bottomImagePolylineGraphicData[i].options.id.includes(props.nowShowImageData.id)) {
let bottomImagePolylineGraphic = bottomImagePolylineGraphicData[i];
let defaultPosition = bottomImagePolylineGraphic.options.defaultPosition;
let surfaceHeight = bottomImagePolylineGraphic.options.surfaceHeight;
bottomImagePolylineGraphic.setStyle({
color: '#2d8cf0',
});
bottomImagePolylineGraphic.positions = [
Cesium.Cartesian3.fromDegrees(defaultPosition[0], defaultPosition[1], surfaceHeight),
Cesium.Cartesian3.fromDegrees(
defaultPosition[0],
defaultPosition[1],
defaultPosition[2] * 2,
),
];
}
}
// 展示图片
for (let i = 0; i < imageGraphicData.length; i++) {
if (imageGraphicData[i].options.id.includes(props.nowShowImageData.id)) {
let imageGraphic = imageGraphicData[i];
let chooseImage = imageGraphic.options.chooseImage;
imageGraphic.setStyle({
image: chooseImage,
label: {
show: true,
},
});
}
}
}, 500);
}
// 图斑定位
const handlerLocation = (lngLat) => {
const position = Cesium.Cartesian3.fromDegrees(lngLat[0], lngLat[1]);
map.flyToPoint(position);
};
defineExpose({
setNowShowImageByRight,
handlerLocation,
});
onMounted(() => {
// let element = window.document.getElementsByClassName('mars3d-locationbar')[0] as HTMLElement;
// element.style.bottom = '40px';
});
</script>
<style lang="less" scoped>
// .map-out-container {
// width: 100%;
// height: calc(100vh - 80px);
// overflow: hidden;
// }
// .map-inner-container {
// width: calc(100% + 80px);
// height: calc(100% + 80px);
// position: relative;
// top: -40px;
// left: -40px;
// }
.mars3d-container {
position: relative;
width: 100%;
height: 100%;
}
</style>