dianlixunjian
徐景良 2024-08-31 17:41:03 +08:00
parent f1f6c4025c
commit cc6034a042
3 changed files with 332 additions and 86 deletions

View File

@ -10,6 +10,7 @@
<div>云查询</div>
</div>
</div>
<!-- 图层控制 -->
<div class="layer-control-center" v-if="false">
<a-collapse v-model:activeKey="activeKey" accordion expandIconPosition="end" expandIcon="">
@ -46,9 +47,28 @@
<div class="draw-polygon" @click="LocationShow = true"></div>
</a-tooltip>
<a-popover placement="bottom" v-if="props.splitPlugin" v-model:visible="splitPanelVisible">
<template #content>
<div class="split-panel">
<p class="split-panel-item" @click="handlerDrawLineString()">线</p>
<p class="split-panel-item" @click="handlerDrawPolygon()"></p>
<a-upload
name="file"
:before-upload="handleImportCoorinateChange"
:showUploadList="false"
>
<p class="split-panel-item">导入图层分割</p>
</a-upload>
</div>
</template>
<div class="split-line" ></div>
</a-popover>
<a-tooltip>
<template #title>线分割图斑</template>
<div class="split-line" @click="handlerDrawLineString()" v-if="props.splitPlugin"></div>
</a-tooltip>
<a-tooltip>
@ -84,6 +104,7 @@
<a-button type="default" size="small" @click="handlerClearLocationItem"
><ClearOutlined />清空</a-button
>
&nbsp;
<a-button
type="default"
@ -91,18 +112,57 @@
v-if="props.splitPlugin"
@click="onHandlerSplitPolygon"
><SplitCellsOutlined />分割图斑</a-button>
<span style="float: right">
<CloseOutlined @click="handlerLocationClose" />
</span>
</div>
<a-empty v-if="locationArrays.length == 0" />
<!-- <a-empty v-if="locationArrays.length == 0" /> -->
<div class="location-item-list-coantienr">
<div class="location-item" v-for="(item, index) in locationArrays" :key="index">
<a-table :dataSource="locationArrays" size="small" :pagination="false" >
<a-table-column-group>
<a-table-column key="lng" title="经度(Y)" data-index="lng">
<template #default="{ record }">
<a-input
v-model:value="record.lng"
@chagne="handlerLocationChange"
size="small"
/>
</template>
</a-table-column>
<a-table-column key="lat" title="纬度(X)" data-index="lat">
<template #default="{record}">
<a-input
v-model:value="record.lat"
@chagne="handlerLocationChange"
size="small"
/>
</template>
</a-table-column>
<a-table-column key="operation" title="操作" data-index="operation" width="100px">
<template #default="{record,index}">
<a-button type="default" size="small" @click="handlerLocationFlyTo(index)"
><EnvironmentOutlined
/></a-button>
&nbsp;
<a-button type="default" size="small" @click="handlerLocationRemove(index)"
><DeleteOutlined
/></a-button>
</template>
</a-table-column>
</a-table-column-group>
</a-table>
<!-- <div class="location-item" v-for="(item, index) in locationArrays" :key="index">
<a-button type="default" size="small" @click="handlerLocationFlyTo(item)"
><EnvironmentOutlined
/></a-button>
@ -123,7 +183,7 @@
<a-button type="default" size="small" @click="handlerLocationRemove(index)"
><DeleteOutlined
/></a-button>
</div>
</div> -->
</div>
</div>
</div>
@ -204,25 +264,29 @@
//
function GkToCGCS2000(lngLat){
try{
// CGCS2000 / 3-degree Gauss-Kruger zone 39
let from_system = "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=39500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs"
try{ //
let from_system = "";
if(lngLat[0]>=37000000 && lngLat[0] < 38000000){
from_system = "+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs"
}if(lngLat[0]>=38000000 && lngLat[0] < 39000000){
from_system = "+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=38500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs"
}if(lngLat[0]>=39000000 && lngLat[0] < 40000000){ // CGCS2000 / 3-degree Gauss-Kruger zone 39
from_system = "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=39500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs"
}else if(lngLat[0] >= 40000000){ // CGCS2000 / 3-degree Gauss-Kruger zone 40
from_system = "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs"
}
// China Geodetic Coordinate System 2000
// let to_system = "+proj=longlat +ellps=GRS80 +no_defs +type=crs";
// WGS 84 -- WGS84 - World Geodetic System 1984,
let to_system = "+proj=longlat +datum=WGS84 +no_defs +type=crs";
// transform
let trasnformLnglat = proj4(from_system,to_system,lngLat);
return trasnformLnglat;
}catch(e){
return null;
}
}
@ -698,8 +762,10 @@
emit('mapDraw', 'Point', e);
});
};
const splitPanelVisible = ref<Boolean>(false);
//线
const handlerDrawLineString = () => {
splitPanelVisible.value = false;
mp.draw('LineString');
mp.on('LineString', function (e) {
Modal.confirm({
@ -721,6 +787,7 @@
//
const handlerDrawPolygon = () => {
splitPanelVisible.value = false;
mp.draw('Polygon');
mp.on('Polygon', function (e) {
let coordinates = [];
@ -1081,9 +1148,9 @@
console.log('currentGeoJson', geojson);
//
let coordinates = null;
if (geojson.features[0].geometry.type == 'MultiPolygon') {
if (geojson.features.length>0 && geojson.features[0].geometry.type == 'MultiPolygon') {
coordinates = geojson.features[0].geometry.coordinates[0];
} else if (geojson.features[0].geometry.type == 'Polygon') {
} else if (geojson.features.length>0 && geojson.features[0].geometry.type == 'Polygon') {
coordinates = geojson.features[0].geometry.coordinates;
}
if (coordinates) {
@ -1145,46 +1212,31 @@
}
const LocationShow = ref<Boolean>(false);
const locationArrays = ref<LocationItem[]>([
// {"lat":3876411.9272,"lng":39624337.6595},
// {"lat":3876419.7281,"lng":39624444.1571},
// {"lat":3876419.8852,"lng":39624446.3011},
// {"lat":3876425.1275,"lng":39624517.8687},
// {"lat":3876425.2918,"lng":39624520.1122},
// {"lat":3876431.6438,"lng":39624606.8289},
// {"lat":3876412.7832,"lng":39624632.9065},
// {"lat":3876365.7135,"lng":39624644.6931},
// {"lat":3876325.9298,"lng":39624654.7128},
// {"lat":3876316.1075,"lng":39624657.1746},
// {"lat":3876246.0573,"lng":39624674.5737},
// {"lat":3876243.9623,"lng":39624675.0987},
// {"lat":3876243.8703,"lng":39624674.5037},
// {"lat":3876240.4283,"lng":39624652.4797},
// {"lat":3876233.6843,"lng":39624607.2316},
// {"lat":3876232.2352,"lng":39624597.5126},
// {"lat":3876222.6982,"lng":39624540.8865},
// {"lat":3876221.3592,"lng":39624531.5094},
// {"lat":3876215.2311,"lng":39624497.0364},
// {"lat":3876206.5951,"lng":39624498.5794},
// {"lat":3876189.579,"lng":39624390.1352},
// {"lat":3876189.002,"lng":39624386.4602},
// {"lat":3876186.4209,"lng":39624370.0092},
// {"lat":3876195.956,"lng":39624367.6201},
// {"lat":3876198.685,"lng":39624385.0072},
// {"lat":3876199.261,"lng":39624388.6822},
// {"lat":3876207.5961,"lng":39624441.8023},
// {"lat":3876209.7341,"lng":39624441.5433},
// {"lat":3876253.1836,"lng":39624436.2662},
// {"lat":3876258.4453,"lng":39624435.6273},
// {"lat":3876290.5054,"lng":39624431.7412},
// {"lat":3876299.4224,"lng":39624430.675},
// {"lat":3876303.8533,"lng":39624430.1453},
// {"lat":3876297.7186,"lng":39624342.1213},
// {"lat":3876299.3188,"lng":39624341.7203},
// {"lat":3876305.1635,"lng":39624340.2558},
// {"lat":3876387.1195,"lng":39624319.7203},
// {"lat":3876411.9272,"lng":39624337.6595}
]);
const locationColumns = ref([
{
title: '定位',
dataIndex: 'position',
key: 'position',
},
{
title: '经度',
dataIndex: 'lng',
key: 'lng',
},
{
title: '纬度',
dataIndex: 'lat',
key: 'lat',
},
{
title: '操作',
dataIndex: 'operation',
key: 'operation',
},
])
const locationArrays = ref<LocationItem[]>([]);
const locationDrawArrays = ref<LocationItem[]>();
const locationGeoJson = reactive({
point: {
type: 'FeatureCollection',
@ -1211,7 +1263,6 @@
// txt
const handleImportCoorinateChange = (e)=>{
console.log("woligehoulai",e);
const reader = new FileReader();
reader.readAsText(e);
reader.onload = function(text){
@ -1231,7 +1282,6 @@
}
locationArrays.value?.push(obj);
}
})
}
const handlerClearLocationItem = () => {
@ -1247,24 +1297,35 @@
};
const handlerLocationRemove = (index: number) => {
locationArrays.value.splice(index, 1);
locationDrawArrays.value.splice(index, 1);
handlerLocationGeoJson();
};
const handlerLocationChange = (e) => {};
//
const handlerLocationFlyTo = (item: LocationItem) => {
if(item.lng > 180){
let coor = GkToCGCS2000([parseFloat(item.lng),parseFloat(item.lat)]);
item.lng = coor[0];
item.lat = coor[1];
}
if (item.lng && item.lat) {
handlerLocation([item.lng, item.lat]);
handlerLocationGeoJson();
}
const handlerLocationFlyTo = (clickIndex:number) => {
locationDrawArrays.value = [];
locationArrays.value?.forEach((location)=>{
let obj={...location}
console.log(obj);
locationDrawArrays.value?.push(obj)
})
locationDrawArrays.value?.forEach((item,index)=>{
//
if(item.lng > 180){
let coor = GkToCGCS2000([parseFloat(item.lng),parseFloat(item.lat)]);
item.lng = coor[0];
item.lat = coor[1];
}
if (item.lng && item.lat) {
handlerLocationGeoJson();
}
})
//
handlerLocation([locationDrawArrays.value[clickIndex].lng, locationDrawArrays.value[clickIndex].lat]);
};
// geojson
@ -1273,7 +1334,7 @@
locationGeoJson.polyline.features = [];
locationGeoJson.polygon.features = [];
locationArrays.value?.forEach((item, index) => {
locationDrawArrays.value?.forEach((item, index) => {
if (item.lng && item.lat) {
let feature = {
type: 'Feature',
@ -1285,7 +1346,8 @@
locationGeoJson.point.features.push(feature);
}
});
if (locationArrays.value?.length >= 2) {
if (locationDrawArrays.value?.length >= 2) {
let feature = {
type: 'Feature',
geometry: {
@ -1294,19 +1356,22 @@
},
};
locationArrays.value?.forEach((item, index) => {
locationDrawArrays.value?.forEach((item, index) => {
if (item.lng && item.lat) {
let coor = [parseFloat(item.lng), parseFloat(item.lat)];
feature.geometry.coordinates.push(coor);
}
});
feature.geometry.coordinates.push([
parseFloat(locationArrays.value[0].lng),
parseFloat(locationArrays.value[0].lat),
parseFloat(locationDrawArrays.value[0].lng),
parseFloat(locationDrawArrays.value[0].lat),
]);
locationGeoJson.polyline.features[0] = feature;
}
if (locationArrays.value?.length >= 3) {
if (locationDrawArrays.value?.length >= 3) {
let feature = {
type: 'Feature',
geometry: {
@ -1314,15 +1379,15 @@
coordinates: [[]],
},
};
locationArrays.value?.forEach((item, index) => {
locationDrawArrays.value?.forEach((item, index) => {
if (item.lng && item.lat) {
let coor = [parseFloat(item.lng), parseFloat(item.lat)];
feature.geometry.coordinates[0].push(coor);
}
});
feature.geometry.coordinates[0].push([
parseFloat(locationArrays.value[0].lng),
parseFloat(locationArrays.value[0].lat),
parseFloat(locationDrawArrays.value[0].lng),
parseFloat(locationDrawArrays.value[0].lat),
]);
locationGeoJson.polygon.features[0] = feature;
}
@ -1776,6 +1841,7 @@
position: absolute;
top: 48px;
right: 10px;
z-index:999999;
border-radius: 5px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
.location-operation {
@ -1794,4 +1860,10 @@
}
}
}
.split-panel-item:hover{
cursor:pointer;
color:#999;
}
</style>

View File

@ -37,14 +37,26 @@ export function splitPolygonByLine(line, outerPolygon) {
let innerPolygons = polygonCollection.features.filter((polygon) => {
// 获取多边形质心 多边形不规则时有问题
// let center = turf.centroid(polygon);
// 获取多边形表面一点
let newcenter = turf.pointOnFeature(polygon);
// 求多边形内一点
// let innerCenter =
return turf.booleanWithin(newcenter, outerPolygon);
// 判断点是否在被分割图斑内
// 图斑中心点
let centerPoint = turf.point(newcenter.geometry.coordinates);
// 图斑面
let outPolygon = turf.polygon(outerPolygon.geometry.coordinates)
// return turf.booleanPointInPolygon(centerPoint, outPolygon);
// let innerPoint = getRandomPointInPolygon(outPolygon);
// 获取多边形边界
// let bbox = turf.bbox(outPolygon); // 获取多边形的边界框
// return turf.booleanPointInPolygon(randomPoint.features[0], outPolygon);
return turf.booleanWithin(centerPoint, outerPolygon);
});
// let innerPolygons = polygonCollection.features;
//处理镂空数据多处镂空数据会导致计算错误因为polygonize方法无法正常的返回数据
@ -69,6 +81,18 @@ export function splitPolygonByLine(line, outerPolygon) {
return innerPolygons;
}
function getRandomPointInPolygon(polygon) {
const bbox = turf.bbox(polygon); // 获取多边形的边界框
let point;
do {
point = turf.randomPoint(1, {bbox: bbox}).features[0]; // 从边界框中生成一个随机点
} while (!turf.booleanPointInPolygon(point, polygon)); // 检查点是否在多边形内部
return point;
}
export function splitPolygonByFill(fill, outerPolygon) {
var polygon1 = turf.polygon(fill.geometry.coordinates);
// var polygon1 = turf.polygon(

View File

@ -274,6 +274,9 @@
:style="{ 'border-color': currentPolygon == index ? '#408eff' : '#fff' }"
>
<div class="data-list-layout-div">
<div class="data-list-checked">
<a-checkbox v-model:checked="item.checked"></a-checkbox>
</div>
<div class="data-list-title-div">
<img
src="/positioning.png"
@ -369,7 +372,12 @@
/>
</div>
<div class="split-operation">
<a-button type="primary" :disabled="isSpliting" @click="reductionSplit"></a-button>
<a-button type="primary" :disabled="isSpliting" @click="mergeSplitResult"></a-button>
&nbsp;
<a-button type="error" :disabled="isSpliting" @click="deleteSplitResult"></a-button>
&nbsp;
<a-button type="primary" :disabled="isSpliting" @click="reductionSplit"></a-button>
&nbsp;
<a-button type="primary" :disabled="isSpliting" @click="saveSplitResult"></a-button>
</div>
@ -733,7 +741,9 @@
};
const splitPolygonForm = ref([]);
const splitAfterPolygon = ref({});
const handlerSplitPolygon = (e) => {
splitAfterPolygon.value = e;
splitPolygonForm.value = [];
e?.forEach((item, index) => {
let form = {
@ -751,6 +761,7 @@
guotukongjianguihua_area: null,
area: null,
geom: item,
checked:false,
};
splitPolygonForm.value?.push(form);
});
@ -830,6 +841,138 @@
splitPolygonForm.value = [];
};
//
const deleteSplitResult = ()=>{
//
let deleteIndexs = [];
splitPolygonForm.value?.forEach((item,index)=>{
if(item.checked){
deleteIndexs.push(index);
}
})
if(deleteIndexs.length<1){
createMessage.error("请选择需要删除的图斑!");
return;
}
removeElementsByIndexes(splitAfterPolygon.value,deleteIndexs);
removeElementsByIndexes(splitPolygonForm.value,deleteIndexs);
//
let geoms = {
type: 'FeatureCollection',
features:splitAfterPolygon.value?splitAfterPolygon.value : [],
};
console.log("geoms123",geoms);
MapboxComponent.value.handlerDetails(geoms, 'detailsSource', 'detailsLayer', {
lineStyle: { 'line-color': '#fcf003', 'line-width': 3 },
fillStyle: { 'fill-color': '#fcf003', 'fill-opacity': 0.1 },
});
let checkedGeoms = {
type: 'FeatureCollection',
features: [],
};
console.log("geoms12345",checkedGeoms);
MapboxComponent.value.handlerDetails(checkedGeoms, 'splitPolygonSource', 'splitPolygonLayer', {
lineStyle: { 'line-color': '#408eff', 'line-width': 3 },
fillStyle: { 'fill-color': '#408eff', 'fill-opacity': 0.1 },
});
}
//
function removeElementsByIndexes(arr, indexes) {
//
indexes.sort((a, b) => b - a);
//
for (const index of indexes) {
arr.splice(index, 1);
}
}
//
const mergeSplitResult = ()=>{
let mergeArr = []
let deleteIndexs = [];
splitPolygonForm.value?.forEach((item,index)=>{
if(item.checked){
let turfPolygon = turf.polygon(splitAfterPolygon.value[index].geometry.coordinates);
mergeArr.push(turfPolygon);
deleteIndexs.push(index);
}
})
if(deleteIndexs.length<=1){
createMessage.error("请选择至少两个图斑进行合并!");
return;
}
removeElementsByIndexes(splitAfterPolygon.value,deleteIndexs);
removeElementsByIndexes(splitPolygonForm.value,deleteIndexs);
//
let union = turf.union(mergeArr[0],mergeArr[1]);
let polygon = {
fid: null,
unitname: '',
createdate: createtime,
caseno: case_no + ' 分割图斑',
countyname: countyname,
streetname: streetname,
isbuildname: '',
nongyongdi_area: null,
gengdi_area: null,
yongjiujibennongtian_area: null,
shengtaibaohuhongxian_area: null,
guotukongjianguihua_area: null,
area: null,
geom: union,
checked:false,
}
splitAfterPolygon.value?.push(union);
splitPolygonForm.value?.push(polygon);
//
let geoms = {
type: 'FeatureCollection',
features:splitAfterPolygon.value?splitAfterPolygon.value : [],
};
MapboxComponent.value.handlerDetails(geoms, 'detailsSource', 'detailsLayer', {
lineStyle: { 'line-color': '#fcf003', 'line-width': 3 },
fillStyle: { 'fill-color': '#fcf003', 'fill-opacity': 0.1 },
});
let checkedGeoms = {
type: 'FeatureCollection',
features: [],
};
MapboxComponent.value.handlerDetails(checkedGeoms, 'splitPolygonSource', 'splitPolygonLayer', {
lineStyle: { 'line-color': '#408eff', 'line-width': 3 },
fillStyle: { 'fill-color': '#408eff', 'fill-opacity': 0.1 },
});
}
//
const saveSplitResult = () => {
isSpliting.value = true;
@ -1006,7 +1149,14 @@
padding-bottom: 8px;
border-bottom: 1px solid #e5e5e5;
height: 45px;
gap:20px;
.data-list-checked{
width:28px;
height:28px;
margin-top:8px;
}
.data-list-title-div {
flex:auto;
display: flex;
align-items: center;
.map-mark {