ly-front/src/components/myMarsmap.vue

619 lines
17 KiB
Vue
Raw Normal View History

2025-03-31 15:26:29 +00:00
<template>
<div class="ditu">
<div id="marsContainer-map" ref="marsMaps" class="mars3d-container"></div>
<div class="btns" v-if="!disabled">
<div class="toolbar" v-if="typeOf === 'polygon'">
<div
:class="{ drawPolygon: true, disabled: isDisabled }"
@click="lineClick('polygon')"
>
<div class="drawPolygonIcon"></div>
</div>
2025-04-05 10:58:49 +00:00
<div class="drawPolygon" @click="lineClick('circle')">
2025-03-31 15:26:29 +00:00
<div class="drawCircularIcon"></div>
2025-04-05 10:58:49 +00:00
</div>
2025-03-31 15:26:29 +00:00
<!-- <div class="drawPolygon">
<el-upload
action=""
class="upload-demo"
:before-upload="beforeUpload"
:on-change="handleChange"
:file-list="fileList"
:show-file-list="false"
accept=".json"
:auto-upload="false"
ref="upLoad"
>
<i class="el-icon-upload2"></i>
</el-upload>
</div> -->
</div>
<div class="toolbar" v-if="typeOf === 'pointP'">
2025-04-05 11:56:13 +00:00
<div class="drawPolygon" @click="lineClicks('pointP')">
2025-03-31 15:26:29 +00:00
<div class="drawpointIcon"></div>
</div>
</div>
<div class="topbtns">
<el-input
2025-04-13 08:23:44 +00:00
v-model="lonData"
:disabled="isinputDisabled"
placeholder="请输入经度"
2025-03-31 15:26:29 +00:00
></el-input>
2025-04-13 08:23:44 +00:00
<el-input
v-model="latData"
:disabled="isinputDisabled"
placeholder="请输入纬度"
></el-input>
<el-button @click="handleSearchClick()">定位</el-button>
2025-03-31 15:26:29 +00:00
<el-button class="btns" @click="clearDraw">清空</el-button>
</div>
</div>
</div>
</template>
<script>
"use script";
import { Drawarectangle } from "./map.js";
2025-04-13 08:23:44 +00:00
import iconimg from "@/assets/img/dianweidingweiqizi.png";
2025-03-31 15:26:29 +00:00
export default {
name: "myMarsmap",
props: {
mapData: {
type: Object,
default: () => {}
},
mapgeoJson: {
type: String,
default: ""
},
typeOf: {
type: String
},
disabled: {
type: Boolean,
default: false
}
},
data() {
return {
jsonData: [],
lon: "",
lat: "",
num: 0,
attrType: "",
fileList: [],
2025-04-13 08:23:44 +00:00
lonData: "",
latData: "",
2025-03-31 15:26:29 +00:00
fileContent: "",
2025-04-13 08:23:44 +00:00
isDisabled: false,
isinputDisabled: false
2025-03-31 15:26:29 +00:00
};
},
components: {},
mounted() {
this.getMapJson();
console.log(this.typeOf, "this.typeOf");
},
watch: {
mapgeoJson: {
deep: true,
immediate: true,
handler(newVal) {
console.log("newVal1111", newVal);
2025-03-31 15:26:29 +00:00
if (newVal) {
this.jsonData = JSON.parse(newVal);
if (this.jsonData) {
this.showRegion(this.jsonData, "geojson");
2025-03-31 15:26:29 +00:00
}
}
}
},
mapData: {
deep: true,
immediate: true,
handler(newVal) {
if (newVal) {
2025-04-13 08:23:44 +00:00
if (newVal.lon && newVal.lat) {
this.lonData = newVal.lon;
this.latData = newVal.lat;
} else {
this.lonData = "";
this.latData = "";
}
if (this.lonData && this.latData) {
if (this.lonData && this.latData) {
this.isinputDisabled = true;
2025-04-13 08:23:44 +00:00
this.deviceDrid(this.lonData, this.latData);
2025-03-31 15:26:29 +00:00
}
}
}
}
}
},
methods: {
handleSearchClick() {
2025-04-13 08:23:44 +00:00
this.map.setCameraView(
{ lat: this.latData, lng: this.lonData, alt: 4607, pitch: -50 },
{ duration: 0 }
);
if (this.lonData && this.latData) {
this.isinputDisabled = true;
this.deviceDrid(this.lonData, this.latData);
2025-03-31 15:26:29 +00:00
}
},
getMapJson() {
// eslint-disable-next-line no-undef
mars3d.Util.fetchJson({
url: "/configJson/mapArea.json"
}).then((res) => {
this.initMarsMap({
// 合并配置项
...res.map3d
});
});
},
initMarsMap(options) {
// eslint-disable-next-line no-undef
this.map = new mars3d.Map(this.$refs.marsMaps, options);
// eslint-disable-next-line no-undef
this.graphicLayer = new mars3d.layer.GraphicLayer();
this.map.addLayer(this.graphicLayer);
// 设备点位
// eslint-disable-next-line no-undef
this.graphicDevice = new mars3d.layer.GraphicLayer();
this.map.addLayer(this.graphicDevice);
// 禁止右键菜单
this.map.unbindContextMenu();
this.map.setCameraView(
{
lat: "43.895464",
lng: "109.10559",
alt: 3269697,
pitch: -90,
heading: 360
},
{ duration: 0 }
);
// 针对不同终端的优化配置
// eslint-disable-next-line no-undef
if (mars3d.Util.isPCBroswer()) {
this.map.zoomFactor = 2.0; // 鼠标滚轮放大的步长参数
// IE浏览器优化
if (navigator.userAgent.toLowerCase().includes("msie")) {
this.map.viewer.targetFrameRate = 20; // 限制帧率
this.map.scene.requestRenderMode = false; // 取消实时渲染
}
} else {
this.map.zoomFactor = 5.0; // 鼠标滚轮放大的步长参数
// 移动设备上禁掉以下几个选项,可以相对更加流畅
this.map.scene.requestRenderMode = false; // 取消实时渲染
this.map.scene.fog.enabled = false;
this.map.scene.skyAtmosphere.show = false;
this.map.scene.globe.showGroundAtmosphere = false;
}
// map构造完成后的一些处理
this.onMapLoad();
// this.map.on(
// // eslint-disable-next-line no-undef
// mars3d.EventType.click,
// this.map_dblClickHandler,
// this.graphicLayer
// );
// this.map.on(mars3d.EventType.dblClick, map_clickHandler, graphicLayer)
},
// map_dblClickHandler() {},
onMapLoad() {
console.log("地图加载完成", this.graphicLayer);
// 设置鼠标操作习惯,更换中键和右键
this.map.changeMouseModel(true);
if (this.jsonData.length !== 0) {
this.showRegion(this.jsonData, "geojson");
}
2025-04-13 08:23:44 +00:00
if (this.lonData && this.latData) {
this.deviceDrid(this.lonData, this.latData);
this.isinputDisabled = true;
2025-03-31 15:26:29 +00:00
}
},
2025-04-05 11:56:13 +00:00
lineClicks(val) {
this.clearDraw();
this.graphicLayer.eachGraphic((item) => {
if (item.id === "pointP") {
this.graphicLayer.removeGraphic(item);
}
});
let style = {};
style = {
color: "#ffff00",
pixelSize: 10,
clampToGround: true,
outlineWidth: 0
};
Drawarectangle(val, this.graphicLayer, style);
},
2025-03-31 15:26:29 +00:00
lineClick(val) {
2025-04-05 11:56:13 +00:00
if (this.typeOf === "polygon") {
2025-03-31 15:26:29 +00:00
this.attrType = val;
2025-04-05 11:56:13 +00:00
// 检查 graphicLayer 中的图形
const graphicsArray = this.graphicLayer._graphicList._array || [];
let hasPolygon = false;
let hasCircle = false;
// 遍历检查是否有 polygon 或 circle
graphicsArray.forEach((graphic) => {
if (graphic.type === "polygon") {
hasPolygon = true;
} else if (graphic.type === "circle") {
hasCircle = true;
}
});
2025-03-31 15:26:29 +00:00
let style = {};
if (val === "polygon") {
2025-04-05 11:56:13 +00:00
// 如果已有 polygon 或 circle限制只能绘制一个 polygon
if (hasPolygon) {
this.$message.error("已存在,请先清空");
return; // 阻止继续执行
}
if (hasCircle) {
// 清除已有 circle
this.graphicLayer.eachGraphic((item) => {
if (item.type === "circle") {
this.graphicLayer.removeGraphic(item);
}
});
}
2025-03-31 15:26:29 +00:00
style = {
materialType: mars3d.MaterialType.PolyGradient,
materialOptions: {
color: "#3388cc",
opacity: 0.7,
alphaPower: 1.3
}
};
} else if (val === "pointP") {
2025-04-05 11:56:13 +00:00
// pointP 可以与 polygon 或 circle 共存,仅清除已有 pointP
2025-03-31 15:26:29 +00:00
this.graphicLayer.eachGraphic((item) => {
if (item.id === "pointP") {
this.graphicLayer.removeGraphic(item);
}
});
style = {
color: "#ffff00",
pixelSize: 10,
clampToGround: true,
outlineWidth: 0
};
} else if (val === "circle") {
2025-04-05 11:56:13 +00:00
// 如果已有 circle 或 polygon限制只能绘制一个 circle
if (hasCircle) {
this.$message.error("已存在,请先清空");
return; // 阻止继续执行
}
if (hasPolygon) {
// 清除已有 polygon
this.graphicLayer.eachGraphic((item) => {
if (item.type === "polygon") {
this.graphicLayer.removeGraphic(item);
}
});
}
2025-03-31 15:26:29 +00:00
style = {
materialType: mars3d.MaterialType.PolyGradient,
materialOptions: {
2025-04-05 10:58:49 +00:00
color: "#3388cc",
2025-03-31 15:26:29 +00:00
opacity: 0.7,
alphaPower: 1.3
}
};
}
2025-04-05 11:56:13 +00:00
// 如果 val 是 polygon 或 circle且已有另一种类型则提示并阻止
if (
(hasPolygon && val === "circle") ||
(hasCircle && val === "polygon")
) {
this.$message.error("只能显示一种类型,已清空");
return; // 阻止继续执行
}
// 绘制新图形
2025-03-31 15:26:29 +00:00
Drawarectangle(val, this.graphicLayer, style);
}
},
clearDraw() {
console.log(111);
2025-04-13 08:23:44 +00:00
this.isinputDisabled = false;
2025-03-31 15:26:29 +00:00
if (this.graphicLayer) {
this.graphicLayer.clear();
}
},
toGeoJSON() {
2025-04-05 11:56:13 +00:00
if (this.typeOf === "pointP") {
// return this.graphicLayer.toGeoJSON({ noAlt: true });
2025-04-05 11:56:13 +00:00
} else {
this.graphicLayer._graphicList._array.forEach((item) => {
2025-04-13 08:23:44 +00:00
if (item.type === "billboard") {
2025-04-05 11:56:13 +00:00
this.graphicLayer.removeGraphic(item);
}
});
return this.graphicLayer.toGeoJSON({ noAlt: true });
}
2025-03-31 15:26:29 +00:00
},
showRegion(value, type) {
this.clearDraw();
2025-03-31 15:26:29 +00:00
let geojson = {};
if (type === "uploadGeojson") {
if (this.graphicLayer._graphicList.length === 0) {
geojson = value;
} else {
this.$message.error("请先清空数据在添加");
}
} else {
geojson = {
type: "Feature",
geometry: value,
properties: {
name: ""
}
};
this.clearDraw();
}
if (this.graphicLayer) {
this.graphicLayer.loadGeoJSON(geojson, {
style: {
type: "polygon",
// eslint-disable-next-line no-undef
materialType: mars3d.MaterialType.PolyGradient,
materialOptions: {
color: "#3388cc",
opacity: 0.7,
alphaPower: 1.3
}
},
flyTo: true
});
let _this = this;
// eslint-disable-next-line no-undef
this.graphicLayer.on(mars3d.EventType.click, function (event) {
_this.attrType = "";
console.log("单击了图层", event);
});
}
},
deviceDrid(lon, lat) {
2025-04-13 11:05:15 +00:00
console.log(this.graphicLayer, "this.graphicLayer");
if (this.graphicLayer) {
this.graphicLayer.eachGraphic((item) => {
if (item.name === "贴地点") {
this.graphicLayer.removeGraphic(item);
}
});
}
2025-04-13 08:23:44 +00:00
const graphic = new mars3d.graphic.BillboardEntity({
2025-03-31 15:26:29 +00:00
position: new mars3d.LngLatPoint(lon, lat),
style: {
2025-04-13 08:23:44 +00:00
image: iconimg,
scale: 1,
width: 30,
height: 50,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM
2025-03-31 15:26:29 +00:00
},
flyTo: true
});
2025-04-13 08:23:44 +00:00
2025-03-31 15:26:29 +00:00
if (this.graphicLayer) {
this.graphicLayer.addGraphic(graphic);
}
2025-04-13 08:23:44 +00:00
console.log(this.graphicLayer, "this.graphicLayer");
2025-03-31 15:26:29 +00:00
},
// 地图跳转
mapJump(lon, lat, alt) {
if (lon !== 0 && lat !== 0) {
this.map.setCameraView({
lat: lat,
lng: lon,
alt: alt || 10000,
pitch: -90
});
}
},
clearDevice() {
if (this.graphicDevice) {
this.graphicDevice.clear();
}
},
// 设备点位
mapDevice(lon, lat) {
if (lon !== null && lat !== null) {
this.clearDevice();
// eslint-disable-next-line no-undef
const graphic = new mars3d.graphic.PointPrimitive({
name: "设备点位",
// eslint-disable-next-line no-undef
position: new mars3d.LngLatPoint(lon, lat),
style: {
color: "#ff0000",
pixelSize: 10,
clampToGround: true,
outlineWidth: 0
},
flyTo: true
});
if (this.graphicDevice) {
this.graphicDevice.addGraphic(graphic);
}
} else {
this.clearDevice();
}
},
beforeUpload(file) {
console.log(file);
// const isJson = file.type === "json/geojson";
// if (!isJson) {
// this.$message.error("只能上传 JSON 或 GeoJSON 文件");
// }
// return isJson;
const isJPG = file.type === "image/jpeg";
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error("上传头像图片只能是 JPG 格式!");
}
if (!isLt2M) {
this.$message.error("上传头像图片大小不能超过 2MB!");
}
return isJPG && isLt2M;
},
handleChange(file) {
console.log(file);
const reader = new FileReader();
reader.onload = (e) => {
const content = e.target.result;
this.fileContent = JSON.parse(content);
console.log(this.fileContent);
this.showRegion(this.fileContent, "uploadGeojson");
};
reader.readAsText(file.raw);
// this.$refs.upLoad.submit();
},
isGeoJSON(content) {
try {
// eslint-disable-next-line no-undef
const multiPolygon = turf.multiPolygon(content);
console.log("MultiPolygon is valid:", multiPolygon);
} catch (error) {
console.error("Error processing MultiPolygon:", error);
}
}
}
};
</script>
<style lang="scss" scoped>
.ditu {
width: 100%;
height: 100%;
position: relative;
#marsContainer-map {
width: 100%;
height: 250px;
}
.topbtns {
width: 100%;
height: 45px;
position: absolute;
top: 0;
display: flex;
align-items: center;
justify-content: flex-start;
background-color: rgba(30, 93, 160, 0.5);
.el-input {
2025-04-13 08:23:44 +00:00
width: 30%;
2025-03-31 15:26:29 +00:00
margin-left: 1%;
// transform: translateX(-50%);
}
.el-button--small {
margin-left: 10px;
}
}
.toolbar {
position: absolute;
right: 0%;
2025-04-13 08:23:44 +00:00
top: 20%;
2025-03-31 15:26:29 +00:00
z-index: 999;
height: auto;
display: flex;
align-items: center;
.disabled {
pointer-events: none;
opacity: 0.5;
}
.drawPolygon {
width: 40px;
height: 40px;
margin-top: 3px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
background: rgba(15, 24, 41, 0.5);
border-radius: 8px;
margin-right: 5px;
.drawPolygonIcon {
width: 20px;
height: 20px;
background: url(@/assets/img/wbx.png);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
}
.drawPolygonIcon:hover {
width: 20px;
height: 20px;
background: url(@/assets/img/wbxH.png);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
}
.drawCircularIcon {
width: 20px;
height: 20px;
background: url(@/assets/img/y.png);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
}
.drawCircularIcon:hover {
width: 20px;
height: 20px;
background: url(@/assets/img/yh.png);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
}
.drawpointIcon {
width: 20px;
height: 20px;
background: url(@/assets/img/point.png);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
}
.drawpointIcon:hover {
width: 20px;
height: 20px;
background: url(@/assets/img/pointh.png);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
}
.el-icon-upload2 {
color: #fff;
font-size: 16px;
cursor: pointer;
}
.el-icon-upload2:hover {
color: #1e5da0;
font-size: 16px;
cursor: pointer;
}
}
}
}
</style>