2023-11-22 17:09:22 +08:00

716 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="map-content" id="map-content">
<div id="mars3dContainer" class="mars3d-container"></div>
<div class="layer-config" v-if="props.type == '底图'">
<div class="property-column-item">
<span>饱和度{{ formData.saturation ? formData.saturation : 0 }}</span>
<el-slider v-model="formData.saturation" :step="0.5" :max="5" :min="-5" @change="e => layerOperate(e, 'saturation')" />
</div>
<div class="property-column-item">
<span>亮度{{ formData.brightness ? formData.brightness : 0 }}</span>
<el-slider v-model="formData.brightness" :step="0.5" :max="10" :min="-10" @change="e => layerOperate(e, 'brightness')" />
</div>
<div class="property-column-item">
<span>对比度{{ formData.contrast ? formData.contrast : 0 }}</span>
<el-slider v-model="formData.contrast" :step="0.5" :max="10" :min="-10" @change="e => layerOperate(e, 'contrast')" />
</div>
<div class="property-column-item">
<span>色调{{ formData.hue ? formData.hue : 0 }}</span>
<el-slider v-model="formData.hue" :step="0.5" :max="2" :min="-2" @change="e => layerOperate(e, 'hue')" />
</div>
<div class="property-column-item">
<span>伽马校正{{ formData.gamma ? formData.gamma : 0 }}</span>
<el-slider v-model="formData.gamma" :step="0.5" :max="5" :min="-5" @change="e => layerOperate(e, 'gamma')" />
</div>
<div class="property-row-item">
<span>是否反色</span>
<el-switch v-model="formData.invertColor" @change="e => layerOperate(e, 'invertColor')" />
</div>
<div class="property-row-item">
<span>滤镜颜色{{ formData.filterColor ? formData.filterColor : "" }}</span>
<el-color-picker v-model="formData.filterColor" @change="e => layerOperate(e, 'filterColor')" />
</div>
<div class="operate-btn">
<el-button @click="editBaseMapsConfig">保存当前配置</el-button>
</div>
</div>
<div class="layer-config" v-if="props.type == '白膜'">
<div class="property-column-item">
<span>经度</span>
<el-input-number
v-model="formData.lng"
:step="0.0001"
controls-position="right"
style="margin: 5px 0"
@change="e => albugineaOperate(e, 'lng')"
/>
</div>
<div class="property-column-item">
<span>纬度</span>
<el-input-number
v-model="formData.lat"
:step="0.0001"
controls-position="right"
style="margin: 5px 0"
@change="e => albugineaOperate(e, 'lat')"
/>
</div>
<div class="property-column-item">
<span>高度()</span>
<el-input-number
v-model="formData.alt"
:step="10"
controls-position="right"
style="margin: 5px 0"
@change="e => albugineaOperate(e, 'alt')"
/>
</div>
<!-- <div class="property-row-item">
<span>是否反色</span>
<el-switch v-model="formData.invertColor" @change="e => layerOperate(e, 'invertColor')" />
</div> -->
<div class="property-row-item">
<span>白膜颜色{{ formData.color ? formData.color : "" }}</span>
<el-color-picker v-model="formData.color" @change="e => albugineaOperate(e, 'color')" />
</div>
<div class="operate-btn">
<el-button @click="editAlbugineaConfig">保存当前配置</el-button>
</div>
</div>
<div class="layer-config" v-if="props.type == '点坐标效果'">
<div class="property-row-item">
<span>效果颜色{{ formData.color ? formData.color : "" }}</span>
<el-color-picker v-model="formData.color" @change="e => pointPositionOperate(e, 'color')" />
</div>
<div class="property-column-item">
<span>半径{{ formData.radius ? formData.radius : 0 }}</span>
<el-slider
v-model.number="formData.radius"
:step="200"
:max="10000"
:min="200"
@change="e => pointPositionOperate(e, 'radius')"
/>
</div>
<div class="property-column-item" v-if="formData.type != 'CircleScan'">
<span>速度值{{ formData.speed ? formData.speed : 0 }}</span>
<el-slider
v-model.number="formData.speed"
:step="1"
:max="100"
:min="1"
@change="e => pointPositionOperate(e, 'speed')"
/>
</div>
<div class="operate-btn">
<el-button @click="editPointPositionConfig">保存当前配置</el-button>
</div>
</div>
<div class="layer-config" v-if="props.type == '线效果'">
<div class="property-column-item">
<span>宽度{{ formData.width ? formData.width : 0 }}</span>
<el-slider v-model.number="formData.width" :step="1" :max="100" :min="1" @change="e => lineEffectOperate(e, 'width')" />
</div>
<div class="property-row-item">
<span>颜色{{ formData.color ? formData.color : "" }}</span>
<el-color-picker v-model="formData.color" @change="e => lineEffectOperate(e, 'color')" />
</div>
<div class="property-row-item" v-if="formData.type == 'ODLine'">
<span>线的背景颜色{{ formData.bgColor ? formData.bgColor : "" }}</span>
<el-color-picker v-model="formData.bgColor" @change="e => lineEffectOperate(e, 'bgColor')" />
</div>
<div class="property-column-item">
<span>速度值{{ formData.speed ? formData.speed : 0 }}</span>
<el-slider v-model.number="formData.speed" :step="1" :max="100" :min="1" @change="e => lineEffectOperate(e, 'speed')" />
</div>
<div class="operate-btn">
<el-button @click="editLineEffectConfig">保存当前配置</el-button>
</div>
</div>
<div class="layer-config" v-if="props.type == '模型'">
<div class="property-column-item">
<span>比例{{ formData.scale ? formData.scale : 0 }}</span>
<el-slider v-model.number="formData.scale" :step="1" :max="100" :min="1" @change="e => modelOperate(e, 'scale')" />
</div>
<div class="property-column-item">
<span>方向角{{ formData.heading ? formData.heading : 0 }}</span>
<el-slider v-model.number="formData.heading" :step="1" :max="360" :min="0" @change="e => modelOperate(e, 'heading')" />
</div>
<div class="property-column-item">
<span>俯仰角{{ formData.pitch ? formData.pitch : 0 }}</span>
<el-slider v-model.number="formData.pitch" :step="1" :max="360" :min="0" @change="e => modelOperate(e, 'pitch')" />
</div>
<div class="property-column-item">
<span>翻滚角{{ formData.roll ? formData.roll : 0 }}</span>
<el-slider v-model.number="formData.roll" :step="1" :max="360" :min="0" @change="e => modelOperate(e, 'roll')" />
</div>
<div class="property-row-item" v-if="formData.silhouette">
<span>轮廓颜色{{ formData.silhouetteColor ? formData.silhouetteColor : "" }}</span>
<el-color-picker v-model="formData.silhouetteColor" @change="e => modelOperate(e, 'silhouetteColor')" />
</div>
<div class="property-column-item" v-if="formData.silhouette">
<span>轮廓宽度{{ formData.silhouetteSize ? formData.silhouetteSize : 0 }}</span>
<el-slider
v-model.number="formData.silhouetteSize"
:step="1"
:max="100"
:min="1"
@change="e => modelOperate(e, 'silhouetteSize')"
/>
</div>
<div class="operate-btn">
<el-button @click="editModelConfig">保存当前配置</el-button>
</div>
</div>
<div class="close-btn" @click="$emit('confirm')">
<el-icon color="#fff" size="18"><CircleClose /></el-icon>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onUnmounted, onBeforeUnmount, watch } from "vue";
//引入cesium基础库
import "mars3d-cesium/Build/Cesium/Widgets/widgets.css";
import * as Cesium from "mars3d-cesium";
//导入mars3d主库
import "mars3d/dist/mars3d.css";
import * as mars3d from "mars3d";
import {
baseMapDetails,
baseMapEdit,
albugineaMapDetails,
albugineaMapEdit,
diffuseWallDetails,
diffuseWallEdit,
polylineCombineDetails,
polylineCombineEdit,
gltfModelDetails,
gltfModelEdit
} from "@/api/modules/mapCommon";
import { ElMessage } from "element-plus";
import { form } from "@/views/project/supervision/ProjectSupervision/overview";
const props = defineProps({
testMapVisible: Boolean,
relativeId: String,
type: String
});
const emits = defineEmits(["confirm"]);
const formData: any = ref({});
const configJson = ref<any>({
scene: {
center: { lat: 14.029537, lng: 105.94238, alt: 4879779, heading: 0, pitch: -66 }
},
control: {
baseLayerPicker: false, // basemaps底图切换按钮
homeButton: true, // 视角复位按钮
sceneModePicker: true, // 二三维切换按钮
navigationHelpButton: true, // 帮助按钮
fullscreenButton: true, // 全屏按钮
contextmenu: { hasDefault: true } // 右键菜单
},
basemaps: [
{
name: "天地图影像",
icon: "img/basemaps/tdt_img.png",
type: "tdt",
layer: "img_d",
show: true
}
]
});
let map: any;
let graphicLayer: any;
let thisLayer: any; // 选中的图层
let thisAlbuginea: any; // 选中的白膜
let tiles3dLayer: any;
// 修改模型当前配置
const editModelConfig = async () => {
let requestData = {
id: props.relativeId,
...formData.value
};
const res: any = await gltfModelEdit(requestData);
if (res.code == 200) {
ElMessage.success("操作成功");
}
};
// 修改线效果当前配置
const editLineEffectConfig = async () => {
let requestData = {
id: props.relativeId,
...formData.value
};
const res: any = await polylineCombineEdit(requestData);
if (res.code == 200) {
ElMessage.success("操作成功");
}
};
// 修改点坐标当前配置
const editPointPositionConfig = async () => {
let requestData = {
id: props.relativeId,
...formData.value
};
const res: any = await diffuseWallEdit(requestData);
if (res.code == 200) {
ElMessage.success("操作成功");
}
};
// 修改白膜当前配置
const editAlbugineaConfig = async () => {
let requestData = {
id: props.relativeId,
...formData.value
};
const res: any = await albugineaMapEdit(requestData);
if (res.code == 200) {
ElMessage.success("操作成功");
}
};
// 修改底图当前配置
const editBaseMapsConfig = async () => {
let requestData = {
id: props.relativeId,
...formData.value
};
const res: any = await baseMapEdit(requestData);
if (res.code == 200) {
ElMessage.success("操作成功");
}
};
// 模型操作
const modelOperate = (e: any, label: any) => {
console.log(e);
console.log(formData.value);
if (graphicLayer) {
let graphic = graphicLayer.getGraphicById(formData.value.id);
let loadJson = {
scale: formData.value.scale,
heading: formData.value.heading,
pitch: formData.value.pitch,
roll: formData.value.roll,
silhouette: formData.value.silhouette,
silhouetteColor: formData.value.silhouetteColor,
silhouetteSize: formData.value.silhouetteSize,
hasShadows: formData.value.hasShadows,
clampToGround: formData.value.clampToGround
};
graphic.setStyle(loadJson);
// layer.style = loadJson;
}
};
// 线效果操作
const lineEffectOperate = (e: any, label: any) => {
console.log(e);
console.log(formData.value.width);
console.log(graphicLayer);
if (graphicLayer) {
let graphic = graphicLayer.getGraphicById(formData.value.id);
console.log(graphic);
let loadJson = {
width: formData.value.width,
materialType: mars3d.MaterialType[formData.value.type],
materialOptions: {
color: formData.value.color,
speed: formData.value.speed,
startTime: random(1000, 3000),
percent: 0.1,
alpha: 0.01
}
};
if (formData.value.type == "ODLine") {
loadJson.materialOptions.bgColor = formData.value.bgColor;
}
// graphic.redraw(loadJson);
graphic.setStyle(loadJson);
}
};
// 点坐标效果操作
const pointPositionOperate = (e: any, label: any) => {
console.log(formData.value);
if (graphicLayer) {
console.log(666);
let graphic = graphicLayer.getGraphicById(formData.value.id);
console.log(graphic);
let loadJson = {
radius: formData.value.radius,
materialOptions: {
// 扫描材质
color: formData.value.color,
speed: formData.value.speed
},
clampToGround: true // 是否贴地
};
graphic.setStyle(loadJson);
}
console.log(777);
};
// 白膜图层操作
const albugineaOperate = (e: any, label: any) => {
console.log(formData.value);
thisAlbuginea = map.getLayerById(formData.value.id);
console.log(thisAlbuginea);
if (label == "color") {
console.log(e, label);
if (e) {
thisAlbuginea.style = {
color: {
conditions: [["true", "color('" + e + "')"]]
}
};
} else {
thisAlbuginea.style = {
color: {
conditions: [["true", "color('#fff')"]]
}
};
}
} else {
thisAlbuginea.position = {
lng: formData.value.lng,
lat: formData.value.lat,
alt: formData.value.alt
};
console.log(thisAlbuginea);
}
};
// 底图图层操作
const layerOperate = (e: any, label: any) => {
thisLayer = map.getLayerById(formData.value.id);
console.log(thisLayer);
if (thisLayer) {
if (label == "filterColor") {
console.log(e, label);
if (e) {
thisLayer.layer[label] = Cesium.Color.fromCssColorString(e);
// thisLayer.layer[label] = e;
} else {
thisLayer.layer[label] = Cesium.Color.fromCssColorString("#FBFBFB");
// thisLayer.layer[label] = "#FBFBFB";
}
} else if (label == "invertColor") {
thisLayer.layer[label] = e;
} else {
thisLayer[label] = e;
}
}
};
// 获取模型数据详情
const getModelInfo = async () => {
let requestData = {
id: props.relativeId
};
const { result }: { result: any } = await gltfModelDetails(requestData);
console.log(result, "--------gltf模型");
if (result) {
formData.value = {
...result
};
await initMars3d(configJson.value);
}
};
// 获取线效果数据详情
const getLineEffectInfo = async () => {
let requestData = {
id: props.relativeId
};
const { result }: { result: any } = await polylineCombineDetails(requestData);
console.log(result, "--------线效果");
if (result) {
formData.value = {
...result
};
await initMars3d(configJson.value);
}
};
// 获取点坐标数据详情
const getPointPositionInfo = async () => {
let requestData = {
id: props.relativeId
};
const { result }: { result: any } = await diffuseWallDetails(requestData);
console.log(result, "--------点坐标");
if (result) {
formData.value = {
...result
};
await initMars3d(configJson.value);
}
};
// 获取白膜数据详情
const getAlbugineaInfo = async () => {
let requestData = {
id: props.relativeId
};
const { result }: { result: any } = await albugineaMapDetails(requestData);
console.log(result, "--------白膜");
await initMars3d(configJson.value);
if (result) {
formData.value = {
...result
};
let showObj = {
id: result.id,
name: result.name,
url: result.url,
maximumScreenSpaceError: 16,
cacheBytes: 1073741824, // 1024MB = 1024*1024*1024
maximumCacheOverflowBytes: 2147483648, // 2048MB = 2048*1024*1024
position: { lng: result.lng, lat: result.lat, alt: result.alt },
popup: "all",
flyTo: true
};
if (+result.lng || +result.lat || +result.alt) {
showObj.position = { lng: +result.lng, lat: +result.lat, alt: +result.alt };
}
tiles3dLayer = new mars3d.layer.TilesetLayer(showObj);
map.addLayer(tiles3dLayer);
// configJson.value.layers = [
// {
// id: result.id,
// name: result.name,
// type: "3dtiles",
// url: result.url,
// position: { lng: formData.value.lng, lat: formData.value.lat, alt: formData.value.alt },
// maximumScreenSpaceError: 1,
// style: {
// color: {
// conditions: [["true", "color('" + result.color + "')"]]
// }
// },
// show: true,
// flyTo: true
// }
// ];
}
};
// 获取底图数据详情
const getBaseMapsInfo = async () => {
let requestData = {
id: props.relativeId
};
const { result }: { result: any } = await baseMapDetails(requestData);
if (result) {
formData.value = { ...result };
configJson.value.basemaps = [
{
id: result.id,
name: result.name,
...JSON.parse(result.layer),
show: true
}
];
initMars3d(configJson.value);
}
};
// 取区域内的随机点
const randomPoint = (position: any) => {
const jd = random(position[0].lng * 1000, position[1].lng * 1000) / 1000;
const wd = random(position[0].lat * 1000, position[1].lat * 1000) / 1000;
return new mars3d.LngLatPoint(jd, wd, 100);
};
// 取随机数字
const random = (min: any, max: any) => {
return Math.floor(Math.random() * (max - min + 1) + min);
};
const initMars3d = async (option: any) => {
console.log(666);
map = new mars3d.Map("mars3dContainer", option);
// 创建矢量数据图层
graphicLayer = new mars3d.layer.GraphicLayer();
map.addLayer(graphicLayer);
if (props.type == "点坐标效果") {
let _rotation = Math.random();
let loadJson = {
id: formData.value.id,
position: new mars3d.LngLatPoint(formData.value.lng, formData.value.lat, formData.value.alt),
style: {
radius: formData.value.radius,
materialType: mars3d.MaterialType[formData.value.type],
materialOptions: {
// 扫描材质
image: formData.value.type == "CircleScan" ? formData.value.image : "",
color: formData.value.color,
speed: formData.value.speed
},
// stRotation: new Cesium.CallbackProperty(function (e) {
// _rotation += 0.1;
// return _rotation;
// }, false),
// classificationType: Cesium.ClassificationType.BOTH,
clampToGround: true // 是否贴地
},
attr: { remark: "展示" }
};
if (formData.value.type == "CircleScan") {
loadJson.style.stRotation = new Cesium.CallbackProperty(function (e) {
_rotation += 0.1;
return _rotation;
}, false);
loadJson.style.classificationType = Cesium.ClassificationType.BOTH;
}
const graphic = new mars3d.graphic.CircleEntity(loadJson);
graphicLayer.addGraphic(graphic);
graphic.flyTo();
//绑定经纬度监听事件
graphic.on(mars3d.EventType.editMovePoint, function (event) {
console.log("移动改变了矢量数据对象", event);
let graphic = graphicLayer.getGraphicById(formData.value.id);
formData.value.lng = event.target.point.lng;
formData.value.lat = event.target.point.lat;
formData.value.alt = event.target.point.alt;
formData.value.radius = event.target.radius;
let loadJson = {
position: new mars3d.LngLatPoint(formData.value.lng, formData.value.lat, formData.value.alt),
style: {
radius: formData.value.radius
}
};
graphic.setStyle(loadJson);
});
// 开启编辑状态
graphic.startEditing();
}
if (props.type == "线效果") {
const arrData: any = [];
if (formData.value.type == "LineFlowColor") {
const linePositions = JSON.parse(formData.value.positions);
for (let j = 0; j < 100; ++j) {
const startPt = randomPoint(linePositions);
const endPt = startPt.clone();
endPt.alt = random(linePositions[0].alt, linePositions[1].alt);
arrData.push({
positions: [startPt, endPt],
style: {
width: formData.value.width,
materialType: mars3d.MaterialType.LineFlowColor,
materialOptions: {
color: formData.value.color,
speed: formData.value.speed,
startTime: random(1000, 3000),
percent: 0.1,
alpha: 0.01
}
}
});
}
} else {
mars3d.Util.fetchJson({ url: JSON.parse(formData.value.jsonFile).url }).then(function (data) {
const busLines: any = [];
data.forEach(function (busLine: any, idx: any) {
let prevPt: any;
const points = [];
for (let i = 0; i < busLine.length; i += 2) {
let pt = [busLine[i], busLine[i + 1]];
if (i > 0) {
pt = [prevPt[0] + pt[0], prevPt[1] + pt[1]];
}
prevPt = pt;
const longitude = pt[0] / 1e4;
const latitude = pt[1] / 1e4;
const cart = Cesium.Cartesian3.fromDegrees(longitude, latitude, 100.0);
points.push(cart);
}
busLines.push({
positions: points,
color: new Cesium.Color(Math.random() * 0.5 + 0.5, Math.random() * 0.8 + 0.2, 0.0, 1.0),
speed: 2 + 1.0 * Math.random()
});
});
busLines.forEach(function (item: any, index: any) {
arrData.push({
positions: item.positions,
style: {
width: formData.value.width,
materialType: mars3d.MaterialType.ODLine,
materialOptions: {
color: formData.value.color,
speed: formData.value.speed,
bgColor: formData.value.bgColor,
startTime: Math.random()
}
},
attr: { index: index }
});
});
});
}
setTimeout(function () {
// 多个线对象的合并渲染。
const graphic = new mars3d.graphic.PolylineCombine({
id: formData.value.id,
instances: arrData
});
console.log(graphic);
graphicLayer.addGraphic(graphic);
graphic.flyTo();
}, 200);
}
if (props.type == "模型") {
// 创建gltf模型
const model = new mars3d.graphic.ModelPrimitive({
id: formData.value.id,
name: formData.value.name,
position: [formData.value.lng, formData.value.lat, formData.value.alt],
style: {
url: formData.value.url,
scale: formData.value.scale,
heading: formData.value.heading,
pitch: formData.value.pitch,
roll: formData.value.roll,
silhouette: formData.value.silhouette,
silhouetteColor: formData.value.silhouetteColor,
silhouetteSize: formData.value.silhouetteSize,
hasShadows: formData.value.hasShadows,
clampToGround: formData.value.clampToGround
}
});
console.log(model);
graphicLayer.addGraphic(model);
model.flyTo({ maxHeight: 200 });
}
};
onBeforeUnmount(async () => {
// if (props.type == "底图") {
// await getBaseMapsInfo();
// } else if (props.type == "白膜") {
// await getAlbugineaInfo();
// } else if (props.type == "点坐标效果") {
// await getPointPositionInfo();
// } else if (props.type == "线效果") {
// await getLineEffectInfo();
// } else if (props.type == "模型") {
// await getModelInfo();
// }
});
onMounted(async () => {
if (props.type == "底图") {
await getBaseMapsInfo();
} else if (props.type == "白膜") {
await getAlbugineaInfo();
} else if (props.type == "点坐标效果") {
await getPointPositionInfo();
} else if (props.type == "线效果") {
await getLineEffectInfo();
} else if (props.type == "模型") {
await getModelInfo();
}
});
onUnmounted(() => {
map = null;
thisLayer = null;
graphicLayer = null;
});
</script>
<style lang="scss" scoped>
@import "./index.scss";
</style>