盗采点添加及编辑设置为绘制图斑

main
zhufu 2026-02-10 14:13:56 +08:00
parent 338d9181b6
commit ecf78eb57a
4 changed files with 132 additions and 45 deletions

View File

@ -79,6 +79,7 @@
"@originjs/vite-plugin-commonjs": "^1.0.3",
"@terraformer/wkt": "2.1.2",
"@turf/turf": "^7.0.0",
"@turf/helpers": "^7.2.0",
"@vben/hooks": "workspace:*",
"@vue/shared": "^3.4.5",
"@vueuse/core": "^10.7.1",

View File

@ -1,15 +1,27 @@
<template>
<div style="position: relative; height: 100%" ref="vChartRef" id="mars3d-container"></div>
<div style="position: relative; height: 100%" ref="vChartRef" id="mars3d-container">
<div class="control-button-div" v-if="props.page=='miningSiteManagement'">
<a-button style="margin-right: 10px;n" type="primary" @click="startDraw"></a-button>
<a-button type="error" @click="clearDraw"></a-button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import * as mars3d from 'mars3d';
import { point, polygon as trfPolygon } from '@turf/helpers';
import { wktToGeoJSON,geojsonToWKT } from "@terraformer/wkt"
const props = defineProps(['page','data'])
const emits = defineEmits(['getAddress'])
let map: mars3d.Map; //
const vChartRef = ref<HTMLElement>();
const drawLayer = new mars3d.layer.GraphicLayer({
isAutoEditing: true,
});
let graphic
onMounted(() => {
console.log(111111,)
let options = {
scene: {
center: {
@ -84,11 +96,11 @@
gltfServerUrl: '//data.mars3d.cn/gltf',
},
},
terrain: {
url: '//data.mars3d.cn/terrain',
show: true,
clip: true,
},
// terrain: {
// url: '//data.mars3d.cn/terrain',
// show: true,
// clip: true,
// },
basemaps: [
{
id: 10,
@ -245,36 +257,59 @@
isAutoEditing: false,
});
map.addLayer(pointLayer);
map.on(mars3d.EventType.click, async (event) => {
const cartesian = map.camera.pickEllipsoid(
event.position,
map.scene.globe.ellipsoid
);
if (!cartesian) return;
const point = mars3d.LngLatPoint.fromCartesian(cartesian);
point.format();
const { lng, lat } = point;
const address = await getAddressByLngLat(lng, lat);
emits('getAddress', lng, lat, address)
pointData.value = {
lng,
lat,
address
}
if (pointGraphic.value) {
pointLayer.removeGraphic(pointGraphic.value);
}
pointGraphic.value = new mars3d.graphic.BillboardEntity({
position: [lng, lat, 10],
style: {
image: '/positioning.png',
scale: 0.6,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
verticalOrigin: mars3d.Cesium.VerticalOrigin.BOTTOM,
},
map.addLayer(drawLayer);
if(props.page == 'parkinglot'){
map.on(mars3d.EventType.click, async (event) => {
const cartesian = map.camera.pickEllipsoid(
event.position,
map.scene.globe.ellipsoid
);
if (!cartesian) return;
const point = mars3d.LngLatPoint.fromCartesian(cartesian);
point.format();
const { lng, lat } = point;
const address = await getAddressByLngLat(lng, lat);
emits('getAddress', lng, lat, address)
pointData.value = {
lng,
lat,
address
}
if (pointGraphic.value) {
pointLayer.removeGraphic(pointGraphic.value);
}
pointGraphic.value = new mars3d.graphic.BillboardEntity({
position: [lng, lat, 10],
style: {
image: '/positioning.png',
scale: 0.6,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
verticalOrigin: mars3d.Cesium.VerticalOrigin.BOTTOM,
},
});
pointLayer.addGraphic(pointGraphic.value);
});
pointLayer.addGraphic(pointGraphic.value);
});
}
if(props.page == 'miningSiteManagement'){
console.log('props.data',props.data)
console.log('props.data.geom',props.data.geom)
if(props.data && props.data.geom){
const geojson = wktToGeoJSON(props.data.geom);
console.log('geojson', geojson);
graphic = new mars3d.graphic.PolygonEntity({
positions: geojson.coordinates[0],
style: {
color: "#00B569",
opacity: 0.2,
outline: true,
outlineColor: "#00B569",
outlineWidth: 2,
},
});
drawLayer.addGraphic(graphic);
drawLayer.flyTo()
}
}
};
async function getAddressByLngLat(lng: number, lat: number) {
const GAODE_KEY = "6af6a87038f44c8c793aa70331f2b7ca";
@ -297,8 +332,58 @@
const getPosition = () => {
return pointData.value;
};
const startDraw = async () => {
graphic = await drawLayer.startDraw({
type: 'polygon',
style: {
color: "#00B569",
opacity: 0.2,
outline: true,
outlineColor: "#00B569",
outlineWidth: 2,
clampToGround: true,
height: 0
},
});
console.log('graphic', graphic);
}
const clearDraw = async () => {
drawLayer.clear();
}
const getGraphic = (addOrUpdate = 'add') => {
if (graphic) {
let graphicJson = graphic.toJSON();
let coordinates = graphicJson.position || graphicJson.positions;
// Z
const filteredCoordinates = coordinates.map((coord: [number, number, number]) => [
coord[0], //
coord[1], //
// coord[2]Z
]);
let polygonData: any = [];
let geom = '';
filteredCoordinates.push(filteredCoordinates[0]);
if (addOrUpdate == 'add') {
polygonData.push(filteredCoordinates);
} else {
polygonData = filteredCoordinates;
}
geom = geojsonToWKT(trfPolygon(polygonData).geometry);
return geom
}
return null;
}
defineExpose({
getPosition,
getGraphic
});
</script>
<style lang="less" scoped></style>
<style lang="less" scoped>
.control-button-div{
position: absolute;
top: 10px;
left: 10px;
z-index: 2;
}
</style>

View File

@ -30,9 +30,11 @@
<a-select v-model:value="props.modalData.communityId" :options="communityOptions" @change="changeCommunity"/>
</a-form-item>
<a-form-item
label="经纬度"
name="geom"
label="图斑"
:rules="[{ required: true, message: '请绘制图斑' }]"
>
<a-button style="margin-right: 10px;" @click="mapVisible = true">选择经纬度</a-button>
<a-button style="margin-right: 10px;" @click="mapVisible = true">绘制图斑</a-button>
<span v-if="props.modalData.lng && props.modalData.lat">{{ `${props.modalData.lng}, ${props.modalData.lat}` }}</span>
</a-form-item>
@ -45,11 +47,11 @@
<a-modal
width="60%"
v-model:open="mapVisible"
title="选择位置"
title="绘制图斑"
@ok="handlePostionOk"
:destroyOnClose="true"
>
<Map ref="PostionRef" @getAddress="getAddress"/>
<Map ref="PostionRef" :page="'miningSiteManagement'" :data="props.modalData" @getAddress="getAddress"/>
</a-modal>
</template>
@ -134,11 +136,10 @@ const changeCommunity = (value, record) => {
props.modalData.communityName = record.label
}
const handlePostionOk = () => {
const data = PostionRef.value.getPosition();
const data = PostionRef.value.getGraphic();
console.log(data);
if(data){
props.modalData.lng = data.lng
props.modalData.lat = data.lat
props.modalData.geom = data
}
mapVisible.value = false;
};

View File

@ -53,7 +53,7 @@
@ok="handlePostionOk"
:destroyOnClose="true"
>
<Map ref="PostionRef" @getAddress="getAddress"/>
<Map ref="PostionRef" :page="'parkinglot'" @getAddress="getAddress"/>
</a-modal>
</template>