445 lines
13 KiB
Vue
445 lines
13 KiB
Vue
<template>
|
||
<div ref="vChartRef" :id="'mars3d-container-' + name"></div>
|
||
<EditModal @register="editModal" @success="editSuccess" />
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, onMounted } from 'vue';
|
||
import { isArray } from '@/utils';
|
||
import * as mars3d from 'mars3d';
|
||
import { EditModal } from './index';
|
||
import { useModal } from '@/components/Modal';
|
||
|
||
const [editModal, { openModal: openEidtModal }] = useModal();
|
||
|
||
let map: mars3d.Map; // 地图对象
|
||
|
||
let mapIns: any = null;
|
||
let markers: any = [];
|
||
let AMapIns: any = null;
|
||
|
||
const vChartRef = ref<HTMLElement>();
|
||
const props = defineProps({
|
||
name: {
|
||
type: String,
|
||
default: '',
|
||
},
|
||
});
|
||
onMounted(() => {
|
||
let options = {
|
||
scene: {
|
||
center: {
|
||
lat: 35.362625,
|
||
lng: 118.033886,
|
||
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: false,
|
||
baseLayerPicker: false,
|
||
sceneModePicker: false,
|
||
vrButton: false,
|
||
fullscreenButton: false,
|
||
navigationHelpButton: false,
|
||
animation: false,
|
||
timeline: false,
|
||
infoBox: false,
|
||
geocoder: false,
|
||
selectionIndicator: false,
|
||
showRenderLoopErrors: true,
|
||
contextmenu: {
|
||
hasDefault: true,
|
||
},
|
||
mouseDownView: true,
|
||
zoom: {
|
||
insertIndex: 1,
|
||
},
|
||
},
|
||
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-a57ecb7d-ba05-47a3-b1be-2e28411a5954',
|
||
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-671f9d42-dda7-45ec-9d0f-4259c915b2cb',
|
||
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: [],
|
||
};
|
||
initMap(options);
|
||
});
|
||
|
||
const isFirstLoad = ref(true);
|
||
const initMap = (newData: any) => {
|
||
// 第一次加载
|
||
if (isFirstLoad.value) {
|
||
map = new mars3d.Map(vChartRef.value, newData);
|
||
} else {
|
||
// 之后更新
|
||
// map.setOptions(newData);
|
||
map.setSceneOptions(newData.scene);
|
||
}
|
||
isFirstLoad.value = false;
|
||
// 初始化矢量图层
|
||
handlerInitEntityLayer();
|
||
const mapContextmenuItems = [
|
||
{
|
||
text: '在此处添加打卡点',
|
||
icon: `<svg class="iconsvg" aria-hidden="true">
|
||
<use xlink:href="#marsgis-qjsjdb"></use>
|
||
</svg>`, // 支持iconfont的symbol方式图标(svg)
|
||
callback: (e) => {
|
||
const mpt = mars3d.LngLatPoint.fromCartesian(e.cartesian);
|
||
openEidtModal(true, {
|
||
isUpdate: false,
|
||
lat: mpt.lat,
|
||
lng: mpt.lng,
|
||
});
|
||
},
|
||
},
|
||
];
|
||
map.bindContextMenu(mapContextmenuItems);
|
||
};
|
||
|
||
const dataHandle = (newData: any) => {
|
||
if (!mapIns && !AMapIns) {
|
||
// initMap(props.chartConfig.option)
|
||
return;
|
||
}
|
||
if (isArray(newData.markers)) {
|
||
// 先清除旧标记
|
||
mapIns.remove(markers);
|
||
markers = [];
|
||
// 记录新标记
|
||
if (mapMarkerType.value === 'Marker') {
|
||
newData.markers.forEach((markerItem: any) => {
|
||
const markerInstance = new AMapIns.Marker({
|
||
position: [markerItem.position[0], markerItem.position[1]],
|
||
offset: new AMapIns.Pixel(-13, -30),
|
||
});
|
||
markers.push(markerInstance);
|
||
markerInstance.setMap(mapIns);
|
||
});
|
||
} else if (mapMarkerType.value === 'CircleMarker') {
|
||
newData.markers.forEach((markerItem: any) => {
|
||
const markerInstance = new AMapIns.CircleMarker({
|
||
center: [markerItem.position[0], markerItem.position[1]],
|
||
radius: markerItem.value,
|
||
...marker.value,
|
||
});
|
||
markers.push(markerInstance);
|
||
markerInstance.setMap(mapIns);
|
||
});
|
||
}
|
||
}
|
||
};
|
||
|
||
let graphicLayer = null;
|
||
// 地球创建完成后默认加载矢量数据图层
|
||
const handlerInitEntityLayer = () => {
|
||
if (graphicLayer == null) {
|
||
graphicLayer = new mars3d.layer.GraphicLayer({ id: 999 });
|
||
}
|
||
};
|
||
|
||
// 点击获取点击位置点位信息 用于常见的下发火点、下发任务点等使用
|
||
|
||
const handlerDrawPoint = async () => {
|
||
const graphic = await graphicLayer.startDraw({
|
||
type: 'point',
|
||
});
|
||
|
||
let position = graphic.toJSON().position;
|
||
|
||
let res = {
|
||
lng: position[0],
|
||
lat: position[1],
|
||
alt: position[0],
|
||
};
|
||
|
||
graphicLayer.removeGraphic(graphic);
|
||
|
||
return res;
|
||
};
|
||
|
||
// 添加Entity
|
||
const handlerAddEntity = (data) => {
|
||
let graphicOptions = {
|
||
id: data.id,
|
||
position: [parseFloat(data.position.lng), parseFloat(data.position.lat)],
|
||
style: {
|
||
image: data.image.generalIcon,
|
||
clampToGround: true,
|
||
scale: 0.5,
|
||
label: {
|
||
text: data.attribute.label,
|
||
font_size: 14,
|
||
color: '#ffffff',
|
||
pixelOffsetY: 10,
|
||
distanceDisplayCondition: true,
|
||
distanceDisplayCondition_far: 500000,
|
||
distanceDisplayCondition_near: 0,
|
||
},
|
||
},
|
||
popup: `<div class="marsTiltPanel marsTiltPanel-theme-red" style="font-size:12px;">
|
||
<div class="marsTiltPanel-wrap">
|
||
<div class="area">
|
||
<div class="arrow-lt"></div>
|
||
<div class="b-t"></div>
|
||
<div class="b-r"></div>
|
||
<div class="b-b"></div>
|
||
<div class="b-l"></div>
|
||
<div class="arrow-rb"></div>
|
||
<div class="label-wrap">
|
||
<div class="title">火点信息</div>
|
||
<div class="label-content">
|
||
<div class="data-li">
|
||
<div class="data-label">火点地址:${data.attribute.address}</div>
|
||
</div>
|
||
<div class="data-li">
|
||
<div class="data-label">上报时间:</div>
|
||
<div class="data-value"><span id="lablYeWei" class="label-num">2025-2-11 12:00:00</span><span class="label-unit"></span>
|
||
</div>
|
||
</div>
|
||
<div class="data-li">
|
||
<div class="data-value">
|
||
<span id="lablCSFM3" onclick="aroundYuAn([${data.position.lng},${data.position.lat}])" class="label-tag data-value-status-2" >防灭火资源</span>
|
||
<span id="lablCSFM2" onclick="delFirePoint(${data.id})" class="label-tag data-value-status-3" title="删除火点">删除火点</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="b-t-l"></div>
|
||
<div class="b-b-r"></div>
|
||
</div>
|
||
<div class="arrow" ></div>
|
||
</div>`,
|
||
popupOptions: {
|
||
offsetY: -30,
|
||
template: '{content}',
|
||
horizontalOrigin: 'Cesium.HorizontalOrigin.LEFT',
|
||
verticalOrigin: 'Cesium.VerticalOrigin.CENTER',
|
||
},
|
||
};
|
||
|
||
let graphic = graphicLayer.getGraphicById(data.id);
|
||
|
||
if (graphic) {
|
||
graphic.setStyleOptions(graphicOptions);
|
||
} else {
|
||
graphic = new mars3d.graphic.BillboardEntity(graphicOptions);
|
||
graphicLayer.addGraphic(graphic);
|
||
}
|
||
};
|
||
|
||
const handlerHiddenEntity = (data) => {
|
||
let graphic = graphicLayer.getGraphicById(data.id);
|
||
if (graphic) {
|
||
graphic.show = false;
|
||
}
|
||
};
|
||
|
||
const handlerRemoveEntity = (data) => {
|
||
let graphic = graphicLayer.getGraphicById(data.id);
|
||
if (graphic) {
|
||
graphicLayer.removeGraphic(graphic);
|
||
}
|
||
};
|
||
|
||
const handlerFlyToEntity = (data) => {
|
||
let graphic = graphicLayer.getGraphicById(data.id);
|
||
|
||
if (graphic) {
|
||
if (data.image.activeIcon) {
|
||
grasphic.setStyle({
|
||
image: data.image.activeIcon,
|
||
});
|
||
}
|
||
|
||
window.globalMap.flyToGraphic(graphic);
|
||
}
|
||
};
|
||
|
||
// 清空所有适量图标
|
||
const handlerClearEntityLayer = () => {
|
||
graphicLayer.clear();
|
||
};
|
||
|
||
// 隐藏所有矢量图标
|
||
const handlerHiddenEntityLayer = () => {
|
||
graphicLayer.show = false;
|
||
};
|
||
|
||
// yi
|
||
</script>
|
||
<style lang="less" scoped></style>
|