1802 lines
48 KiB
Vue
1802 lines
48 KiB
Vue
<template>
|
||
<div class="map-container">
|
||
<div :id="mapContainerName" @mouseover="mapmouseover" class="map-box"></div>
|
||
<div class="cloud-query-div" v-if="props.geomsList" @click="initiateCloudQuery">
|
||
<div>
|
||
<div class="cloud-query-icon">
|
||
<Icon icon="gis:globe-poi" :size="20" />
|
||
|
||
</div>
|
||
<div>云查询</div>
|
||
</div>
|
||
</div>
|
||
<!-- 图层控制 -->
|
||
<div class="layer-control-center" v-if="false">
|
||
<a-collapse v-model:activeKey="activeKey" accordion expandIconPosition="end" expandIcon="">
|
||
<a-collapse-panel key="1" header="图层">
|
||
<p v-for="(item, index) in props.mapConfig.layers" class="layer-item">
|
||
<a-checkbox v-model:checked="item.checked" @change="handlerCheckboxChange(item)">{{
|
||
item.name
|
||
}}</a-checkbox>
|
||
</p>
|
||
<p v-for="(item, index) in props.mapConfig.baseLayers" class="layer-item">
|
||
<a-checkbox v-model:checked="item.checked" @change="handlerCheckboxChange(item)">{{
|
||
item.name
|
||
}}</a-checkbox>
|
||
</p>
|
||
</a-collapse-panel>
|
||
</a-collapse>
|
||
</div>
|
||
|
||
<!-- 绘图控制 -->
|
||
<div class="draw-control-center" v-show="drawing">
|
||
<div class="draw-btn" @click="handlerCancleDraw"> 取消 </div>
|
||
<div class="draw-btn" @click="handlerDrawComplete"> 保存 </div>
|
||
</div>
|
||
|
||
<!-- 根据输入坐标定位 -->
|
||
<div class="position-by-lnglat">
|
||
<a-tooltip>
|
||
<template #title>图斑定位</template>
|
||
<div class="to-location" @click="handlerToPosition()"></div>
|
||
</a-tooltip>
|
||
|
||
<a-tooltip>
|
||
<template #title>坐标定位</template>
|
||
<div class="draw-polygon" @click="LocationShow = true"></div>
|
||
</a-tooltip>
|
||
|
||
<a-tooltip>
|
||
<template #title>线分割图斑</template>
|
||
<div class="split-line" @click="handlerDrawLineString()" v-if="props.splitPlugin"></div>
|
||
</a-tooltip>
|
||
|
||
<a-tooltip>
|
||
<template #title>{{isShowPicture?'显示选中图片方位角':'显示全部图片方位角'}}</template>
|
||
<div :class="isShowPicture?'picture-azimuth':'picture-azimuth-active'" @click="handlerChangePictureVisible()"></div>
|
||
</a-tooltip>
|
||
|
||
<div class="split-polygon" @click="handlerDrawPolygon()" v-if="false"> </div>
|
||
</div>
|
||
|
||
<!-- 坐标输入框 -->
|
||
<div class="to-location-input" v-if="LocationShow">
|
||
<div class="location-operation">
|
||
<a-button type="default" size="small" @click="handlerPushLocationItem"
|
||
><PlusOutlined />添加</a-button
|
||
>
|
||
|
||
|
||
<a-upload
|
||
name="file"
|
||
:before-upload="handleImportCoorinateChange"
|
||
:showUploadList="false"
|
||
>
|
||
<a-button
|
||
type="default"
|
||
size="small"
|
||
><CloudUploadOutlined />导入
|
||
</a-button>
|
||
</a-upload>
|
||
|
||
|
||
|
||
<a-button type="default" size="small" @click="handlerClearLocationItem"
|
||
><ClearOutlined />清空</a-button
|
||
>
|
||
|
||
<a-button
|
||
type="default"
|
||
size="small"
|
||
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" />
|
||
|
||
<div class="location-item-list-coantienr">
|
||
<div class="location-item" v-for="(item, index) in locationArrays" :key="index">
|
||
<a-button type="default" size="small" @click="handlerLocationFlyTo(item)"
|
||
><EnvironmentOutlined
|
||
/></a-button>
|
||
<a-input
|
||
v-model:value="item.lng"
|
||
@chagne="handlerLocationChange"
|
||
addon-before="经度"
|
||
size="small"
|
||
style="width: 140px; margin: 0px 12px"
|
||
/>
|
||
<a-input
|
||
v-model:value="item.lat"
|
||
@chagne="handlerLocationChange"
|
||
addon-before="纬度"
|
||
size="small"
|
||
style="width: 140px; margin-right: 12px"
|
||
/>
|
||
<a-button type="default" size="small" @click="handlerLocationRemove(index)"
|
||
><DeleteOutlined
|
||
/></a-button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import {
|
||
onMounted,
|
||
onUnmounted,
|
||
defineProps,
|
||
defineEmits,
|
||
reactive,
|
||
ref,
|
||
defineExpose,
|
||
watch,
|
||
inject,
|
||
} from 'vue';
|
||
|
||
import { useMessage } from '@/hooks/web/useMessage';
|
||
import {
|
||
CloseOutlined,
|
||
EnvironmentOutlined,
|
||
DeleteOutlined,
|
||
CopyOutlined,
|
||
PlusOutlined,
|
||
ClearOutlined,
|
||
SplitCellsOutlined,
|
||
CloudUploadOutlined
|
||
} from '@ant-design/icons-vue';
|
||
import mapboxgl, { Map, Popup } from 'mapbox-gl';
|
||
import Icon from '@/components/Icon/Icon.vue';
|
||
|
||
// 图形绘制工具类
|
||
import MapboxDraw from '@mapbox/mapbox-gl-draw';
|
||
|
||
import { generateUUID, getGeometryCenter } from './src/tool';
|
||
|
||
// 测量工具
|
||
import { SwitchLayerControl, MeasureControl } from 'mapbox-extensions';
|
||
import 'mapbox-extensions/dist/index.css';
|
||
|
||
import U from 'mapbox-gl-utils';
|
||
import 'mapbox-gl/dist/mapbox-gl.css';
|
||
|
||
import './src/index.less';
|
||
import { MapboxConfig, MapboxDefaultStyle, MapControlConfig } from './src/config';
|
||
import { MP } from './src/MP';
|
||
import { DrawingType } from '@/enums/mapEnum';
|
||
|
||
// POLYGON分割函数
|
||
import { polygonCut } from './lib/segmentation';
|
||
import { splitPolygonByLine, splitPolygonByFill } from './lib/splitpolygon';
|
||
|
||
// 图片切换
|
||
import { userFormFileStore } from '@/store/modules/formFileUrl';
|
||
import { storeToRefs } from 'pinia';
|
||
|
||
import {
|
||
SnapPolygonMode,
|
||
SnapPointMode,
|
||
SnapLineMode,
|
||
SnapModeDrawStyles,
|
||
SnapDirectSelect,
|
||
} from 'mapbox-gl-draw-snap-mode';
|
||
|
||
import { customDrawStyles } from './Styles/Styles';
|
||
import Drawtool from '@/views/datamaintenance/components/drawtool.vue';
|
||
import { WktToGeojson, GeojsonToWkt } from './src/WktGeojsonTransform';
|
||
import { features } from 'process';
|
||
|
||
import { getAppEnvConfig } from '@/utils/env';
|
||
|
||
import { message, Modal } from 'ant-design-vue';
|
||
import { useCloudQueryStore } from '@/store/modules/cloudquery';
|
||
import { AddDroneTask } from '@/api/demo/cloudQuery.ts';
|
||
|
||
import proj4 from 'proj4'
|
||
|
||
// 投影转地理坐标系
|
||
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"
|
||
|
||
// 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;
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
const useCloudQuery = useCloudQueryStore();
|
||
|
||
const { VITE_GLOB_API_URL } = getAppEnvConfig();
|
||
const VITE_GLOB_API_URL_VAR = ref<String>(VITE_GLOB_API_URL + '/');
|
||
|
||
const mapContainerName = ref<String>();
|
||
|
||
mapContainerName.value = 'mapContainer-' + generateUUID();
|
||
|
||
const openModal = ref(false);
|
||
const insertShpModal = ref(false);
|
||
const changeOpenModal = (value) => {
|
||
openModal.value = value;
|
||
};
|
||
|
||
const changeOpenInsertShpModal = (value) => {
|
||
insertShpModal.value = value;
|
||
};
|
||
|
||
// map参数类型
|
||
interface MapboxOptionsInterface {
|
||
mapOptions: mapboxgl.MapboxOptions;
|
||
control: DrawingType[];
|
||
}
|
||
|
||
const props = defineProps({
|
||
mapConfig: {
|
||
type: Object,
|
||
default: {},
|
||
},
|
||
layers: {
|
||
type: Array,
|
||
default: [],
|
||
},
|
||
location: {
|
||
type: Array,
|
||
default: [],
|
||
},
|
||
type: {
|
||
type: String,
|
||
default: '',
|
||
},
|
||
feature: {
|
||
type: String,
|
||
default: '',
|
||
},
|
||
splitPlugin: {
|
||
type: Boolean,
|
||
default: false,
|
||
},
|
||
geomsList: {
|
||
type: Array,
|
||
default: null,
|
||
},
|
||
caseno: {
|
||
type: String,
|
||
default: '',
|
||
}
|
||
});
|
||
|
||
let nextMapControl: Array<any> = reactive([]);
|
||
nextMapControl = props.control
|
||
? props.control.map((item) => {
|
||
return MapControlConfig[item];
|
||
})
|
||
: [];
|
||
|
||
// 定义地图容器
|
||
let map: Map;
|
||
let drawTool: any;
|
||
let popup: Popup;
|
||
let clickPoisition: Array<number> = [];
|
||
let selectFeature: Object = {};
|
||
let mp: any = null;
|
||
let geojson = reactive({
|
||
geojson: {},
|
||
});
|
||
let drawing = ref(false);
|
||
|
||
let drawGeojson = reactive({
|
||
geojson: {
|
||
type: 'FeatureCollection',
|
||
features: [],
|
||
},
|
||
});
|
||
|
||
let switchLayerControler;
|
||
|
||
const { createConfirm, createMessage } = useMessage();
|
||
|
||
// 定义地图回调emit
|
||
// 地图加载完成回调
|
||
const emit = defineEmits([
|
||
'mapOnLoad',
|
||
'mapDraw',
|
||
'handlerDrawComplete',
|
||
'handlerGetFormDetail',
|
||
'handlerSplitPolygon',
|
||
'onFeatureClick',
|
||
]);
|
||
|
||
watch(
|
||
() => props.mapConfig,
|
||
(newVal, oldVal) => {
|
||
handlerLoadMapLayer();
|
||
},
|
||
);
|
||
|
||
const formFileStore = userFormFileStore();
|
||
const formFileState = storeToRefs(formFileStore);
|
||
|
||
watch(formFileState.url, (newValue, oldValue) => {});
|
||
|
||
function mapmouseover(e) {}
|
||
onMounted(() => {
|
||
// let mapDiv = window.document.getElementById(mapContainerName.value);
|
||
// mapDiv?.onmouseover = function(e){
|
||
// alert(e);
|
||
// }
|
||
|
||
mapboxgl.accessToken = MapboxConfig.ACCESS_TOKEN;
|
||
map = initMap();
|
||
map.on('load', () => {
|
||
//挂载mapbox-gl-utils
|
||
U.init(map);
|
||
mp = new MP(map);
|
||
|
||
// 根据地图配置信息加载地形数据
|
||
if (props.mapConfig.mode == '3D') {
|
||
// handlerLoadTerrain();
|
||
}
|
||
|
||
// 初始化绘图空间
|
||
// handlerInitDrawTool(null);
|
||
|
||
map.on('click', (e) => {
|
||
// handlerPreviewFeatureInfo(e);
|
||
clickPoisition = e.lngLat;
|
||
});
|
||
|
||
map.on('draw.selectionchange', (e) => {
|
||
// handlerCopyToTargetLayer(e);
|
||
});
|
||
|
||
emit('mapOnLoad', map);
|
||
|
||
// 设置绘图监听事件
|
||
map.on('draw.create', function (e) {
|
||
drawGeojson.geojson.features = e.features;
|
||
handlerDealFeature(e.features[0]);
|
||
});
|
||
|
||
map.on('draw.update', function (e) {
|
||
drawGeojson.geojson = e.features;
|
||
handlerDealFeature(e.features[0]);
|
||
});
|
||
|
||
map.on('draw.delete', function (e) {
|
||
handlerDeleteFeature(e.features[0]);
|
||
});
|
||
|
||
window.handlerCopyFeature = handlerCopyFeature;
|
||
|
||
// 测量工具
|
||
map.addControl(
|
||
new MeasureControl({
|
||
horizontal: true, //default false
|
||
btnBgColor: '#ffffff', //default '#ffffff'
|
||
btnActiveColor: '#ddd', //default '#ddd'
|
||
geometryClick: true, //defualt false
|
||
enableModes: ['Point', 'LineString', 'Polygon'], //default all
|
||
onStart: () => {},
|
||
onStop: () => {},
|
||
measurePointOptions: {},
|
||
measureLineStringOptions: {},
|
||
measurePolygonOptions: {},
|
||
}),
|
||
'top-right',
|
||
);
|
||
|
||
// 加载图层
|
||
handlerLoadMapLayer();
|
||
// 应用图层绑定点击事件
|
||
// applicationLayers.forEach((item,index)=>{
|
||
// map.on("click",item.layer.id,(e)=>{
|
||
// let state = findLayerAttributeInfo(applicationLayers,e.features[0].layer.id);
|
||
// if(state){
|
||
|
||
// let formDetailParams = {
|
||
// attributeTable:state.attributeTable,
|
||
// attributeField:state.attributeField,
|
||
// value:e.features[0].properties.gid
|
||
// }
|
||
|
||
// // 调用父组件查询表单详情信息
|
||
// emit("handlerGetFormDetail",formDetailParams)
|
||
|
||
// createMessage.success("数据表:"+state.attributeTable+";查询字段:"+state.attributeField+"字段值:"+e.features[0].properties.gid)
|
||
|
||
// }else{
|
||
// createMessage.warning("当前点击图层未绑定信息");
|
||
// }
|
||
|
||
// })
|
||
// })
|
||
|
||
// 分割多边形
|
||
// splitFeature();
|
||
});
|
||
});
|
||
|
||
function handlerLayerChange() {
|
||
var allLayers = map.getStyle().layers;
|
||
if (map.getLayer('detailsLayerLine'))
|
||
map.moveLayer('detailsLayerLine', allLayers[allLayers.length - 1].id);
|
||
allLayers.forEach(function (layer) {});
|
||
// allLayers.forEach(function(layer){
|
||
// console.log("layersssss",layer.id);
|
||
// // map.moveLayer('detailsLayer', layer.id);
|
||
// });
|
||
}
|
||
// 地图图层控制
|
||
const handlerLoadMapLayer = () => {
|
||
if (switchLayerControler) {
|
||
// var allLayers = map.getStyle().layers;
|
||
// allLayers.forEach(function(layer){
|
||
// console.log("layerEEEEEE",layer);
|
||
// console.log(layer.id);
|
||
// // map.removeLayer(layer.id);
|
||
// });
|
||
// var allSources = Object.keys(map.style.sourceCaches);
|
||
// allSources.forEach(function(sourceId){
|
||
// map.removeSource(sourceId);
|
||
// });
|
||
map.removeControl(switchLayerControler);
|
||
}
|
||
let configlayers = {};
|
||
let baseLayers = [];
|
||
props.mapConfig.layers?.forEach((item, index) => {
|
||
let applicationLayers = [];
|
||
item?.layers?.forEach((it, idx) => {
|
||
let style = JSON.parse(it.style);
|
||
let layers = {
|
||
name: it.name,
|
||
layer: style,
|
||
fixed: true,
|
||
zoom: 18,
|
||
easeToOptions: {},
|
||
mutex: false,
|
||
mutexIdentity: generateUUID(),
|
||
active: it.checked,
|
||
backgroundImage: '',
|
||
backgroundImageActive: '',
|
||
selectAndClearAll: true,
|
||
selectAllLabel: 'select all',
|
||
clearAllLabel: 'clear all',
|
||
onVisibleChange: (visible: boolean) => {},
|
||
};
|
||
applicationLayers.push(layers);
|
||
});
|
||
configlayers[item.name] = {
|
||
uiType: 'SwitchBtn',
|
||
collapse: !0,
|
||
defaultCollapsed: !0,
|
||
layers: applicationLayers,
|
||
};
|
||
});
|
||
props.mapConfig.baseLayers?.forEach((item, index) => {
|
||
console.log('baselayers', item);
|
||
let layer = JSON.parse(item.style);
|
||
let image = item.image.replace('\\', '/');
|
||
let layers = {
|
||
name: item.name,
|
||
layer: layer,
|
||
fixed: false,
|
||
// zoom:0,
|
||
easeToOptions: {},
|
||
active: item.checked,
|
||
backgroundImage: VITE_GLOB_API_URL_VAR.value + image,
|
||
backgroundImageActive: '',
|
||
onVisibleChange: (visible: boolean) => {
|
||
handlerLayerChange();
|
||
},
|
||
};
|
||
console.log('layersssss', layers);
|
||
baseLayers.push(layers);
|
||
});
|
||
configlayers['地图底图'] = {
|
||
collapse: !0,
|
||
defaultCollapsed: !0,
|
||
uiType: 'ImgTxtBtn',
|
||
layers: baseLayers,
|
||
};
|
||
|
||
if (props?.mapConfig) {
|
||
if (props?.mapConfig?.baseLayers?.length > 0 && props?.mapConfig?.layers?.length > 0) {
|
||
// 图层管理工具
|
||
switchLayerControler = new SwitchLayerControl({
|
||
name: '图层管理',
|
||
position: 'top-left',
|
||
showToTop: true,
|
||
layerGroups: configlayers,
|
||
});
|
||
map.addControl(switchLayerControler, 'top-left');
|
||
}
|
||
}
|
||
|
||
handlerLayerChange();
|
||
};
|
||
// 销毁地图
|
||
|
||
const findLayerAttributeInfo = (layers, id) => {
|
||
let layer = layers?.find((itme, index) => {
|
||
return itme.layer.id == id;
|
||
});
|
||
if (layer) {
|
||
if (layer.layer.state) {
|
||
return layer.layer.state;
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
};
|
||
// 加载地形
|
||
const handlerLoadTerrain = () => {
|
||
map.addSource('mapbox-dem', {
|
||
type: 'raster-dem',
|
||
url: 'mapbox://mapbox.mapbox-terrain-dem-v1',
|
||
tileSize: 512,
|
||
maxzoom: 14,
|
||
});
|
||
map.setTerrain({ source: 'mapbox-dem', exaggeration: 1.5 });
|
||
};
|
||
// 移除地图实例
|
||
onUnmounted(() => {
|
||
map ? map.remove() : null;
|
||
});
|
||
|
||
// 数据绘制完成判断
|
||
const handlerDealFeature = (feature) => {
|
||
let existFeature = geojson.geojson.features.find((item, index) => {
|
||
return item.id == feature.id;
|
||
});
|
||
|
||
if (existFeature) {
|
||
// 如果查找到了 则替换数据
|
||
for (let i = 0; i < geojson.geojson.features.length; i++) {
|
||
if (geojson.geojson.features[i].id == feature.id) {
|
||
geojson.geojson.features[i] = feature;
|
||
}
|
||
}
|
||
} else {
|
||
// 如果没找到数据则添加到数组
|
||
geojson.geojson.features.push(feature);
|
||
}
|
||
// 自动将数据返回给父组件
|
||
handlerDrawComplete();
|
||
};
|
||
|
||
// 删除数据
|
||
const handlerDeleteFeature = (feature) => {
|
||
for (let i = 0; i < geojson.geojson.features.length; i++) {
|
||
if (geojson.geojson.features[i].id == feature.id) {
|
||
geojson.geojson.features.splice(i, 1);
|
||
}
|
||
}
|
||
// handlerDrawComplete();
|
||
};
|
||
|
||
// 初始化地图 返回地图实例
|
||
const initMap = () => {
|
||
return new mapboxgl.Map({
|
||
container: mapContainerName.value,
|
||
language: 'zh-cmn',
|
||
projection: 'equirectangular', // wgs84参考系
|
||
style: MapboxDefaultStyle,
|
||
// maxZoom: props.mapConfig.maxZoom ? props.mapConfig.maxZoom:18,
|
||
minZoom: props.mapConfig.minZoom ? props.mapConfig.minZoom : 1,
|
||
zoom: props.mapConfig.zoom ? props.mapConfig.zoom : 10,
|
||
pitch: props.mapConfig.angle ? props.mapConfig.angle : 0,
|
||
center: props.mapConfig.center?.split(',')
|
||
? props.mapConfig.center?.split(',')
|
||
: [118.340253, 35.092481],
|
||
});
|
||
};
|
||
|
||
const handlerMapControlClick = (handler: string) => {
|
||
handler === 'handlerDrawPoint' && handlerDrawPoint();
|
||
handler === 'handlerDrawLineString' && handlerDrawLineString();
|
||
handler === 'handlerDrawPolygon' && handlerDrawPolygon();
|
||
};
|
||
// 使用坐标点分割图斑
|
||
const onHandlerSplitPolygon = () => {
|
||
if (locationArrays.value.length < 2) {
|
||
createMessage.warning('必须绘制2个以上点!');
|
||
} else {
|
||
let feature = {
|
||
type: 'Feature',
|
||
geometry: {
|
||
type: 'LineString',
|
||
coordinates: [],
|
||
},
|
||
};
|
||
|
||
locationArrays.value?.forEach((item, index) => {
|
||
if (item.lng && item.lat) {
|
||
let coor = [parseFloat(item.lng), parseFloat(item.lat)];
|
||
feature.geometry.coordinates.push(coor);
|
||
}
|
||
});
|
||
|
||
splitFeature(feature.geometry.coordinates);
|
||
}
|
||
};
|
||
// 分割图斑
|
||
const splitFeature = (line) => {
|
||
|
||
let splitLineString = {
|
||
type: 'Feature',
|
||
properties: {},
|
||
geometry: {
|
||
coordinates: line,
|
||
type: 'LineString',
|
||
},
|
||
};
|
||
let splitPolygon = currentGeoJson.value;
|
||
try {
|
||
// let features = polygonCut(splitPolygon,splitLineString,0.1,"meters");
|
||
let features = splitPolygonByLine(splitLineString, splitPolygon);
|
||
|
||
let splitAfterFeatures = {
|
||
type: 'FeatureCollection',
|
||
features: [],
|
||
};
|
||
splitAfterFeatures.features = features;
|
||
|
||
emit('handlerSplitPolygon', features);
|
||
handlerDetails(splitAfterFeatures);
|
||
handlerUnDraw();
|
||
} catch (e) {
|
||
createMessage.warning('分割线起点、终点需要在图斑外');
|
||
handlerUnDraw();
|
||
}
|
||
};
|
||
|
||
// 根据面分割
|
||
const splitFeatureByFill = (fill) => {
|
||
let splitLineString = {
|
||
type: 'Feature',
|
||
properties: {},
|
||
geometry: {
|
||
coordinates: [fill],
|
||
type: 'Polygon',
|
||
},
|
||
};
|
||
let splitPolygon = currentGeoJson.value;
|
||
// let features = polygonCut(splitPolygon,splitLineString,0.1,"meters");
|
||
let features = splitPolygonByFill(splitLineString, splitPolygon);
|
||
|
||
let splitAfterFeatures = {
|
||
type: 'FeatureCollection',
|
||
features: [],
|
||
};
|
||
splitAfterFeatures.features = [features];
|
||
handlerDetails(splitAfterFeatures);
|
||
handlerUnDraw();
|
||
};
|
||
//绘制点
|
||
const handlerDrawPoint = () => {
|
||
mp.draw('Point');
|
||
mp.on('Point', function (e) {
|
||
emit('mapDraw', 'Point', e);
|
||
});
|
||
};
|
||
//绘制线
|
||
const handlerDrawLineString = () => {
|
||
mp.draw('LineString');
|
||
mp.on('LineString', function (e) {
|
||
Modal.confirm({
|
||
title: '是否确认分割图斑?',
|
||
onCancel() {
|
||
handlerUnDraw();
|
||
},
|
||
async onOk() {
|
||
let coordinates = [];
|
||
e?.forEach((item, index) => {
|
||
coordinates?.push([item.lng, item.lat]);
|
||
});
|
||
splitFeature(coordinates);
|
||
},
|
||
});
|
||
emit('mapDraw', 'LineString', e);
|
||
});
|
||
};
|
||
|
||
//绘制面
|
||
const handlerDrawPolygon = () => {
|
||
mp.draw('Polygon');
|
||
mp.on('Polygon', function (e) {
|
||
let coordinates = [];
|
||
e?.forEach((item, index) => {
|
||
coordinates?.push([item.lng, item.lat]);
|
||
});
|
||
splitFeatureByFill(coordinates);
|
||
emit('mapDraw', 'Polygon', e);
|
||
});
|
||
};
|
||
|
||
//删除标记
|
||
const handlerUnDraw = () => {
|
||
mp.deleteDraw();
|
||
emit('mapDraw', 'cancel');
|
||
};
|
||
|
||
// 初始化绘图空间
|
||
const handlerInitDrawTool = (feature, bool) => {
|
||
// if (feature.features.length > 0) {
|
||
|
||
// feature.features.forEach((item) => {
|
||
|
||
// if (item.geometry.type == 'MultiPolygon') {
|
||
// let arr: any = ref([]);
|
||
// item.geometry.coordinates.forEach((val) => {
|
||
// arr.value.push(val[0]);
|
||
// });
|
||
// item.geometry.coordinates = arr.value;
|
||
// item.geometry.type = 'Polygon';
|
||
// }
|
||
// });
|
||
|
||
// }
|
||
geojson.geojson = feature;
|
||
|
||
if (drawTool) {
|
||
drawTool.deleteAll();
|
||
if (feature.features) {
|
||
drawTool.set(geojson.geojson);
|
||
}
|
||
} else {
|
||
drawTool = new MapboxDraw({
|
||
modes: {
|
||
...MapboxDraw.modes,
|
||
draw_point: SnapPointMode,
|
||
draw_polygon: SnapPolygonMode,
|
||
draw_line_string: SnapLineMode,
|
||
direct_select: SnapDirectSelect,
|
||
},
|
||
styles: customDrawStyles,
|
||
userProperties: true,
|
||
snap: true,
|
||
snapOptions: {
|
||
snapPx: 12, // defaults to 15
|
||
snapToMidPoints: true, // defaults to false
|
||
snapVertexPriorityDistance: 0.0025, // defaults to 1.25
|
||
},
|
||
guides: false,
|
||
});
|
||
|
||
map.addControl(drawTool, 'top-right');
|
||
|
||
if (feature.features) {
|
||
drawTool.set(geojson.geojson);
|
||
}
|
||
}
|
||
|
||
// 正在绘制
|
||
// if (bool) {
|
||
// drawing.value = true;
|
||
// } else {
|
||
// drawing.value = false;
|
||
// }
|
||
|
||
drawing.value = true;
|
||
};
|
||
|
||
// 将图斑复制到指定图层
|
||
const handlerCopyToTargetLayer = (e) => {
|
||
if (e.features.length > 0) {
|
||
if (popup) {
|
||
popup.remove();
|
||
popup = null;
|
||
}
|
||
|
||
selectFeature = e.features[0];
|
||
|
||
popup = new mapboxgl.Popup({
|
||
closeButton: false,
|
||
closeOnClick: false,
|
||
});
|
||
|
||
// 设置 popup 的位置和内容
|
||
popup
|
||
.setLngLat(clickPoisition)
|
||
.setHTML(
|
||
`
|
||
<div style="color:#333;padding:3px 12px;cursor:pointer;" type="primary" icon="el-icon-search" onclick="handlerCopyFeature();">复制当前图斑</div>`,
|
||
)
|
||
.addTo(map);
|
||
} else {
|
||
popup.remove();
|
||
}
|
||
};
|
||
|
||
const handlerCopyFeature = () => {
|
||
popup.remove();
|
||
createMessage.success('复制成功!');
|
||
};
|
||
|
||
// 添加到图层
|
||
const handlerAddToLayerList = (layer) => {
|
||
handlerCheckLayerExist(layer);
|
||
};
|
||
|
||
// 判断图层列表中是否一定添加
|
||
const handlerCheckLayerExist = (layer) => {
|
||
for (let i = 0; i < layerList.length; i++) {
|
||
if (layerList[i] == layer.id) {
|
||
return;
|
||
}
|
||
}
|
||
layerList.push(layer);
|
||
};
|
||
|
||
const handlerCheckboxChange = (item) => {
|
||
console.log('itemitemitem', item);
|
||
handlerPreviewLayer(item);
|
||
};
|
||
|
||
// 控制图层是否显示
|
||
const handlerPreviewLayer = (layer) => {
|
||
console.log('layersss', layer);
|
||
handlerLayerControler(layer);
|
||
};
|
||
|
||
// 图层控制中心
|
||
const handlerLayerControler = (layerInfo) => {
|
||
layerInfo.layer = layerInfo.layer ? layerInfo.layer : JSON.parse(layerInfo.style);
|
||
|
||
if (map.getSource(layerInfo.layer.id)) {
|
||
if (layerInfo.checked) {
|
||
map.setLayoutProperty(layerInfo.layer.id, 'visibility', 'visible');
|
||
} else {
|
||
map.setLayoutProperty(layerInfo.layer.id, 'visibility', 'none');
|
||
}
|
||
} else {
|
||
map.addLayer(layerInfo.layer);
|
||
map.on('click', layerInfo.layer.id, function (e) {
|
||
handlerPreviewFeatureInfo(e);
|
||
});
|
||
}
|
||
};
|
||
|
||
// 查看列表数据
|
||
const handlerDataList = () => {};
|
||
|
||
// 图斑属性查看
|
||
const handlerPreviewFeatureInfo = (e) => {
|
||
if (e.features) {
|
||
isOpen.value = true;
|
||
}
|
||
};
|
||
|
||
const handlerClose = (e) => {
|
||
isOpen.value = e;
|
||
};
|
||
|
||
const currentPosition = ref(null);
|
||
// 图斑定位
|
||
const handlerLocation = (lngLat) => {
|
||
map.flyTo({
|
||
center: lngLat,
|
||
zoom: 17,
|
||
speed: 10, // 飞行速度
|
||
curve: 1, // 飞行曲线
|
||
easing(t) {
|
||
// 飞行动画函数
|
||
return t;
|
||
},
|
||
});
|
||
};
|
||
// 定位
|
||
const handlerToPosition = () => {
|
||
if (currentPosition.value) {
|
||
map.flyTo({
|
||
center: currentPosition.value,
|
||
zoom: 17,
|
||
speed: 10, // 飞行速度
|
||
curve: 1, // 飞行曲线
|
||
easing(t) {
|
||
// 飞行动画函数
|
||
return t;
|
||
},
|
||
});
|
||
}
|
||
};
|
||
|
||
// 编辑图斑
|
||
const handlerEdit = (info) => {
|
||
initDraw(info);
|
||
};
|
||
|
||
const initDraw = (layerInfo) => {
|
||
// 实例化绘图工具
|
||
drawTool = new MapboxDraw({
|
||
modes: {
|
||
...MapboxDraw.modes,
|
||
draw_point: SnapPointMode,
|
||
// draw_polygon: SnapPolygonMode,
|
||
// draw_line_string: SnapLineMode,
|
||
direct_select: SnapDirectSelect,
|
||
},
|
||
styles: customDrawStyles,
|
||
userProperties: true,
|
||
snap: true,
|
||
snapOptions: {
|
||
snapPx: 15, // defaults to 15
|
||
snapToMidPoints: true, // defaults to false
|
||
snapVertexPriorityDistance: 0.0025, // defaults to 1.25
|
||
},
|
||
guides: false,
|
||
});
|
||
|
||
map.addControl(drawTool, 'top-right');
|
||
|
||
// let geojson:Object = {};
|
||
// if (layerInfo.dataType == "面") {
|
||
// geojson.type = "Polygon";
|
||
// geojson.coordinates = geojson.coordinates[0];
|
||
// } else if (layerInfo.dataType == "点") {
|
||
// geojson.type = "Point";
|
||
// geojson.coordinates = geojson.coordinates;
|
||
// } else if (layerInfo.dataType == "线") {
|
||
// geojson.type = "LineString";
|
||
// geojson.coordinates = geojson.coordinates[0];
|
||
// }
|
||
// if (formData.lat && formData.lng) {
|
||
// formData.lat = geojson.coordinates[1];
|
||
// formData.lng = geojson.coordinates[0];
|
||
// }
|
||
// geojson = {
|
||
// type: "FeatureCollection",
|
||
// features: [
|
||
// {
|
||
// type: "Feature",
|
||
// geometry: geojson,
|
||
// },
|
||
// ],
|
||
// };
|
||
// map.setLayoutProperty("pbfLayer", "visibility", "none");
|
||
// drawTool.set(geojson);
|
||
};
|
||
|
||
const handlerDrawComplete = () => {
|
||
let arr = [];
|
||
geojson.geojson.features.forEach((item, index) => {
|
||
let wktStr = GeojsonToWkt(item.geometry);
|
||
let obj = {
|
||
columnName: 'mapgeom',
|
||
value: wktStr,
|
||
};
|
||
arr.push(obj);
|
||
});
|
||
console.log('aaaa', arr);
|
||
emit('handlerDrawComplete', arr);
|
||
};
|
||
|
||
const handlerCancleDraw = () => {
|
||
if (drawTool) {
|
||
map.removeControl(drawTool);
|
||
drawTool = null;
|
||
drawing.value = false;
|
||
}
|
||
|
||
// 清空详情图层
|
||
if (map.getSource('detailsSource')) {
|
||
map.getSource('detailsSource').setData({
|
||
type: 'FeatureCollection',
|
||
features: [],
|
||
});
|
||
}
|
||
};
|
||
|
||
const handlerDraw = (status: string, features = null, bool = false) => {
|
||
let geo = {
|
||
type: 'FeatureCollection',
|
||
features: [],
|
||
};
|
||
// 清空详情图斑
|
||
if (map.getSource('detailsSource')) {
|
||
map.getSource('detailsSource').setData({
|
||
type: 'FeatureCollection',
|
||
features: [],
|
||
});
|
||
}
|
||
if (features == null) {
|
||
bool = true;
|
||
} else {
|
||
if (features.length > 0) {
|
||
for (let i = 0; i < features.length; i++) {
|
||
try {
|
||
let featureTemp = WktToGeojson(features[i]?.mapgeom);
|
||
|
||
let feature = {
|
||
id: generateUUID(),
|
||
type: 'Feature',
|
||
properties: {},
|
||
geometry: featureTemp,
|
||
};
|
||
geo.features.push(feature);
|
||
// 获取第一个图斑的中心点跳转定位
|
||
if (i == 0) {
|
||
let lngLat = getGeometryCenter(feature);
|
||
// let lngLat = getGeometryCenter(geo.features[0]);
|
||
currentPosition.value = lngLat;
|
||
handlerLocation(lngLat);
|
||
}
|
||
} catch (e) {
|
||
console.error('wktParse', e);
|
||
createMessage.error('WKT数据格式解析错误,请检查WKT数据格式是否有误!');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
switch (status) {
|
||
case 'Add':
|
||
handlerInitDrawTool(geo, bool);
|
||
break;
|
||
case 'Edit':
|
||
handlerInitDrawTool(geo, bool);
|
||
break;
|
||
case 'Details':
|
||
handlerDetails(geo);
|
||
break;
|
||
default:
|
||
createMessage.error('请传入操作类型!');
|
||
}
|
||
};
|
||
|
||
const currentGeoJson = ref({});
|
||
|
||
const handlerDetails = (
|
||
geojson,
|
||
source = 'detailsSource',
|
||
layer = 'detailsLayer',
|
||
style = {
|
||
lineStyle: { 'line-color': '#fcf003', 'line-width': 3 },
|
||
fillStyle: { 'fill-color': '#fcf003', 'fill-opacity': 0.1 },
|
||
},
|
||
) => {
|
||
let fillLayerName = layer + 'Fill';
|
||
let lineLayerName = layer + 'Line';
|
||
|
||
if (source == 'detailsSource') {
|
||
console.log('currentGeoJson', geojson);
|
||
// 判断是单面还是多面
|
||
let coordinates = null;
|
||
if (geojson.features[0].geometry.type == 'MultiPolygon') {
|
||
coordinates = geojson.features[0].geometry.coordinates[0];
|
||
} else if (geojson.features[0].geometry.type == 'Polygon') {
|
||
coordinates = geojson.features[0].geometry.coordinates;
|
||
}
|
||
if (coordinates) {
|
||
if(
|
||
coordinates[0][coordinates[0].length - 1][0] ==
|
||
coordinates[0][coordinates[0].length - 2][0]
|
||
) {
|
||
coordinates[0]?.pop();
|
||
}
|
||
}
|
||
let singleFeature = {
|
||
type: 'Feature',
|
||
properties: {},
|
||
geometry: {
|
||
coordinates: coordinates,
|
||
type: 'Polygon',
|
||
},
|
||
};
|
||
currentGeoJson.value = singleFeature;
|
||
console.log('currentGeoJson', currentGeoJson.value);
|
||
}
|
||
|
||
if (map.getSource(source)) {
|
||
map.getSource(source).setData(geojson);
|
||
} else {
|
||
map.addSource(source, {
|
||
type: 'geojson',
|
||
data: geojson,
|
||
});
|
||
map.addLayer({
|
||
id: fillLayerName,
|
||
type: 'fill',
|
||
source: source,
|
||
layout: {},
|
||
paint: style.fillStyle,
|
||
});
|
||
map.addLayer({
|
||
id: lineLayerName,
|
||
type: 'line',
|
||
source: source,
|
||
layout: {},
|
||
paint: style.lineStyle,
|
||
});
|
||
map.on('click', fillLayerName, function (e) {
|
||
if (e.features.length > 0) {
|
||
var feature = e.features[0];
|
||
emit('onFeatureClick', feature);
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
// 创建查看图斑图层
|
||
|
||
// 粘贴坐标实现定位、绘图相关
|
||
interface LocationItem {
|
||
lng: string;
|
||
lat: string;
|
||
}
|
||
|
||
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 locationGeoJson = reactive({
|
||
point: {
|
||
type: 'FeatureCollection',
|
||
features: [],
|
||
},
|
||
polyline: {
|
||
type: 'FeatureCollection',
|
||
features: [],
|
||
},
|
||
polygon: {
|
||
type: 'FeatureCollection',
|
||
features: [],
|
||
},
|
||
});
|
||
|
||
const handlerPushLocationItem = () => {
|
||
let item: LocationItem = {
|
||
lng: '',
|
||
lat: '',
|
||
};
|
||
locationArrays.value.push(item);
|
||
};
|
||
|
||
|
||
// 通过上传txt文件方式导入坐标数据
|
||
const handleImportCoorinateChange = (e)=>{
|
||
console.log("woligehoulai",e);
|
||
const reader = new FileReader();
|
||
reader.readAsText(e);
|
||
reader.onload = function(text){
|
||
console.log(text.target?.result?.split("\r\n"))
|
||
handlerImportCoor(text.target?.result?.split("\r\n"));
|
||
}
|
||
}
|
||
|
||
const handlerImportCoor = (arr)=>{
|
||
|
||
arr?.forEach((item,index)=>{
|
||
let coor = item.split(",");
|
||
if(coor[0] && coor[1]){
|
||
let obj = {
|
||
lng:parseFloat(coor[1]),
|
||
lat:parseFloat(coor[0])
|
||
}
|
||
locationArrays.value?.push(obj);
|
||
}
|
||
|
||
})
|
||
}
|
||
const handlerClearLocationItem = () => {
|
||
locationArrays.value = [];
|
||
locationGeoJson.point.features = [];
|
||
locationGeoJson.polygon.features = [];
|
||
locationGeoJson.polyline.features = [];
|
||
handlerLocationLoadLayer();
|
||
};
|
||
|
||
const handlerLocationClose = () => {
|
||
LocationShow.value = false;
|
||
};
|
||
const handlerLocationRemove = (index: number) => {
|
||
locationArrays.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();
|
||
}
|
||
};
|
||
|
||
// 处理生成geojson数据
|
||
const handlerLocationGeoJson = () => {
|
||
locationGeoJson.point.features = [];
|
||
locationGeoJson.polyline.features = [];
|
||
locationGeoJson.polygon.features = [];
|
||
|
||
locationArrays.value?.forEach((item, index) => {
|
||
if (item.lng && item.lat) {
|
||
let feature = {
|
||
type: 'Feature',
|
||
geometry: {
|
||
type: 'Point',
|
||
coordinates: [parseFloat(item.lng), parseFloat(item.lat)],
|
||
},
|
||
};
|
||
locationGeoJson.point.features.push(feature);
|
||
}
|
||
});
|
||
if (locationArrays.value?.length >= 2) {
|
||
let feature = {
|
||
type: 'Feature',
|
||
geometry: {
|
||
type: 'LineString',
|
||
coordinates: [],
|
||
},
|
||
};
|
||
|
||
locationArrays.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),
|
||
]);
|
||
locationGeoJson.polyline.features[0] = feature;
|
||
}
|
||
if (locationArrays.value?.length >= 3) {
|
||
let feature = {
|
||
type: 'Feature',
|
||
geometry: {
|
||
type: 'Polygon',
|
||
coordinates: [[]],
|
||
},
|
||
};
|
||
locationArrays.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),
|
||
]);
|
||
locationGeoJson.polygon.features[0] = feature;
|
||
}
|
||
handlerLocationLoadLayer();
|
||
console.log('locationGeoJson', locationGeoJson);
|
||
};
|
||
|
||
// 加载点、线、面图层
|
||
const handlerLocationLoadLayer = () => {
|
||
|
||
console.log("locationGeoJson123",locationGeoJson);
|
||
// 绘制点
|
||
if (map.getSource('LocationPointSource')) {
|
||
map.getSource('LocationPointSource').setData(locationGeoJson.point);
|
||
} else {
|
||
map.addSource('LocationPointSource', {
|
||
type: 'geojson',
|
||
data: locationGeoJson.point,
|
||
});
|
||
map.addLayer({
|
||
id: 'LocationPointLayer',
|
||
type: 'circle',
|
||
source: 'LocationPointSource',
|
||
paint: {
|
||
'circle-radius': 5,
|
||
'circle-color': '#408eff', // 设置点的颜色
|
||
},
|
||
});
|
||
}
|
||
|
||
// 绘制线
|
||
if (map.getSource('LocationPolylineSource')) {
|
||
map.getSource('LocationPolylineSource').setData(locationGeoJson.polyline);
|
||
} else {
|
||
map.addSource('LocationPolylineSource', {
|
||
type: 'geojson',
|
||
data: locationGeoJson.polyline,
|
||
});
|
||
map.addLayer({
|
||
id: 'LocationLineLayer',
|
||
type: 'line',
|
||
source: 'LocationPolylineSource',
|
||
paint: {
|
||
'line-color': '#408eff', // 设置线的颜色
|
||
'line-width': 2, // 设置线的宽度
|
||
},
|
||
});
|
||
}
|
||
|
||
// 绘制面
|
||
if (map.getSource('LocationPolygonSource')) {
|
||
map.getSource('LocationPolygonSource').setData(locationGeoJson.polygon);
|
||
} else {
|
||
map.addSource('LocationPolygonSource', {
|
||
type: 'geojson',
|
||
data: locationGeoJson.polygon,
|
||
});
|
||
map.addLayer({
|
||
id: 'LocationPolygonLayer',
|
||
type: 'fill',
|
||
source: 'LocationPolygonSource',
|
||
paint: {
|
||
'fill-color': '#408eff', // 设置填充颜色
|
||
'fill-opacity': 0.5, // 设置填充透明度
|
||
},
|
||
});
|
||
}
|
||
};
|
||
|
||
// 绘制图片方位角
|
||
|
||
// 是否显示全部方位角
|
||
const isShowPicture = ref<Boolean>(true);
|
||
const imageList = ref<Array>([]);
|
||
const pictureArrowElementArray = ref([]);
|
||
const pictureParentArrowElementArray = ref([]);
|
||
const currentPictureIndex = ref(null);
|
||
const currentPictureZIndex = ref(0);
|
||
function handlerLoadPictureAzimuth(list) {
|
||
imageList.value = list;
|
||
pictureArrowElementArray.value = [];
|
||
list.forEach((item, index) => {
|
||
if (item.lng && item.lat) {
|
||
let arrowElement = document.createElement('div');
|
||
arrowElement.className = 'picArrow';
|
||
arrowElement.style.width = '43px';
|
||
arrowElement.style.height = '57px';
|
||
let childElement = document.createElement('div');
|
||
childElement.className = 'childArrow';
|
||
childElement.style.width = '43px';
|
||
childElement.style.height = '57px';
|
||
childElement.style.transform = 'rotate(' + item.orientation + 'deg)';
|
||
childElement.style.backgroundImage = 'url(/map/arrow.png)';
|
||
childElement.style.backgroundSize = '43px 57px';
|
||
childElement.style.position = "relative";
|
||
arrowElement.appendChild(childElement);
|
||
pictureArrowElementArray.value?.push(childElement);
|
||
pictureParentArrowElementArray.value?.push(arrowElement);
|
||
let arrowMark = new mapboxgl.Marker(arrowElement)
|
||
.setLngLat([item.lng, item.lat])
|
||
.addTo(map);
|
||
}
|
||
});
|
||
|
||
currentPictureZIndex.value = list?.length;
|
||
|
||
// setTimeout(function(){
|
||
// handlerCurrentImageChange(0);
|
||
// },10000)
|
||
}
|
||
|
||
function handlerCurrentImageChange(fileName) {
|
||
// 根据图片名检索标签
|
||
let currentIndex = null;
|
||
imageList.value?.forEach((item, index) => {
|
||
if (item.filePath?.match(fileName)) {
|
||
currentIndex = index;
|
||
currentPictureIndex.value = index;
|
||
}
|
||
});
|
||
try {
|
||
pictureArrowElementArray.value?.forEach((itme, index) => {
|
||
pictureArrowElementArray.value[index].style.backgroundImage = 'url(/map/arrow.png)';
|
||
if(isShowPicture.value){
|
||
pictureArrowElementArray.value[index].style.display = 'block';
|
||
}else{
|
||
pictureArrowElementArray.value[index].style.display = 'none';
|
||
}
|
||
});
|
||
|
||
pictureArrowElementArray.value[currentIndex].style.backgroundImage = 'url(/map/arrow-a.png)';
|
||
pictureArrowElementArray.value[currentIndex].style.display = 'block';
|
||
// 设置显示在最上层
|
||
currentPictureZIndex.value = currentPictureZIndex.value + 1;
|
||
pictureParentArrowElementArray.value[currentIndex].style.zIndex = currentPictureZIndex.value;
|
||
} catch (e) {}
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
function handlerChangePictureVisible(){
|
||
isShowPicture.value = !isShowPicture.value;
|
||
// 展示全部
|
||
if(isShowPicture.value){
|
||
pictureArrowElementArray.value?.forEach((itme, index) => {
|
||
pictureArrowElementArray.value[index].style.display = 'block';
|
||
});
|
||
}else{
|
||
pictureArrowElementArray.value?.forEach((itme, index) => {
|
||
pictureArrowElementArray.value[index].style.display = 'none';
|
||
});
|
||
if(pictureArrowElementArray.value?.length){
|
||
pictureArrowElementArray.value[currentPictureIndex.value].style.display = 'block';
|
||
}
|
||
}
|
||
|
||
// 展示选中
|
||
|
||
}
|
||
|
||
// 绘制点
|
||
const handlerLocationDrawPoint = () => {};
|
||
|
||
// 绘制线
|
||
const handlerLocationDrawLine = () => {};
|
||
|
||
// 绘制面
|
||
const handlerLocationDrawPolygon = () => {};
|
||
const initiateCloudQuery = () => {
|
||
if (useCloudQuery.getIdentification) {
|
||
message.warning('已有云查询运行,不能再次提交');
|
||
} else {
|
||
let geomidStr = props.geomsList.map((item) => item.key).join(',');
|
||
AddDroneTask({ geomid: geomidStr, caseno: props.caseno }).then((res) => {
|
||
message.success('成功提交云查询');
|
||
useCloudQuery.setIdentification(true);
|
||
});
|
||
}
|
||
};
|
||
|
||
defineExpose({
|
||
handlerDraw,
|
||
handlerDetails,
|
||
handlerLocation,
|
||
handlerCancleDraw,
|
||
handlerLoadPictureAzimuth,
|
||
handlerCurrentImageChange,
|
||
});
|
||
</script>
|
||
|
||
<style scoped>
|
||
.cloud-query-div {
|
||
position: absolute;
|
||
top: 50px;
|
||
left: 10px;
|
||
width: 52px;
|
||
height: 60px;
|
||
background: #fff;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 5px;
|
||
border-radius: 5px;
|
||
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
|
||
user-select: none;
|
||
cursor: pointer;
|
||
}
|
||
.cloud-query-icon {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-bottom: 8px;
|
||
}
|
||
.map-container {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.map-box {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.layer-control-center {
|
||
position: absolute;
|
||
top: 15px;
|
||
left: 15px;
|
||
background: #fff;
|
||
border-radius: 8px;
|
||
}
|
||
|
||
.layer-control-center p {
|
||
margin: 0px;
|
||
}
|
||
|
||
.layer-control-center .ant-checkbox-wrapper {
|
||
}
|
||
|
||
.draw-control-center {
|
||
position: absolute;
|
||
padding: 8px;
|
||
top: 15px;
|
||
right: 15px;
|
||
background: #ffffff;
|
||
border-radius: 12px;
|
||
}
|
||
|
||
.draw-control-center .draw-btn {
|
||
float: left;
|
||
margin: 0px 7px;
|
||
padding: 5px;
|
||
border-radius: 5px;
|
||
}
|
||
|
||
.draw-control-center .draw-btn:hover {
|
||
background-color: rgb(0 0 0/5%);
|
||
cursor: pointer;
|
||
}
|
||
|
||
.mapboxgl-ctrl-group:not(:empty) {
|
||
box-shadow: none;
|
||
}
|
||
|
||
.mapboxgl-ctrl-group {
|
||
padding: 6px;
|
||
border-radius: 12px;
|
||
top: 5px;
|
||
right: 0px;
|
||
}
|
||
.mapbox-gl-draw_ctrl-draw-btn {
|
||
width: 20px !important;
|
||
height: 20px !important;
|
||
float: left;
|
||
}
|
||
|
||
.mapboxgl-ctrl-top-right {
|
||
width: 360px;
|
||
}
|
||
|
||
.mapboxgl-ctrl-group button + button {
|
||
border: 0px;
|
||
margin: 0px 6px;
|
||
}
|
||
|
||
.mapbox-gl-draw_ctrl-draw-btn:hover {
|
||
transform: scale(1.2);
|
||
}
|
||
|
||
.mapbox-gl-draw_polygon {
|
||
background-image: url(/polygon.png);
|
||
background-size: 100% 100%;
|
||
width: 100px;
|
||
height: 100px;
|
||
}
|
||
.mapbox-gl-draw_point {
|
||
background-image: url(/point.png);
|
||
background-size: 100% 100%;
|
||
width: 100px;
|
||
height: 100px;
|
||
}
|
||
.mapbox-gl-draw_line {
|
||
background-image: url(/line.png);
|
||
background-size: 100% 100%;
|
||
width: 100px;
|
||
height: 100px;
|
||
margin: 0px 6px;
|
||
}
|
||
|
||
.mapbox-gl-draw_trash {
|
||
background-image: url(/del.png);
|
||
background-size: 100% 100%;
|
||
width: 100px;
|
||
height: 100px;
|
||
}
|
||
|
||
.mapbox-gl-draw_combine {
|
||
background-image: url(/combine.png);
|
||
background-size: 100% 100%;
|
||
width: 100px;
|
||
height: 100px;
|
||
}
|
||
|
||
.mapbox-gl-draw_uncombine {
|
||
background-image: url(/uncombine.png);
|
||
background-size: 100% 100%;
|
||
width: 100px;
|
||
height: 100px;
|
||
}
|
||
|
||
.jas-ctrl-measure {
|
||
position: relative;
|
||
top: 6px;
|
||
right: 10px;
|
||
}
|
||
|
||
.jas-ctrl-measure-item {
|
||
height: 22px;
|
||
color: rgb(255, 255, 255);
|
||
}
|
||
|
||
.layer-item {
|
||
padding: 8px 16px;
|
||
}
|
||
|
||
.layer-item:hover {
|
||
background: #c7dcf580;
|
||
}
|
||
|
||
::v-deep .ant-collapse-content-box {
|
||
padding: 0px !important;
|
||
}
|
||
|
||
::v-deep .jas-ctrl-extend-desktop-container {
|
||
width: 320px !important;
|
||
}
|
||
|
||
.position-by-lnglat {
|
||
height: 29px;
|
||
background: #fff;
|
||
position: absolute;
|
||
top: 10px;
|
||
right: 131px;
|
||
border-radius: 3px;
|
||
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
|
||
.to-location {
|
||
width: 29px;
|
||
height: 29px;
|
||
float: left;
|
||
background: url(/map/location.png);
|
||
background-size: 20px 20px;
|
||
background-repeat: no-repeat;
|
||
background-position: 4px 5px;
|
||
&:hover {
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
|
||
.picture-azimuth{
|
||
width: 29px;
|
||
height: 29px;
|
||
float: left;
|
||
background: url(/map/is_show_picture.png);
|
||
background-size: 20px 20px;
|
||
background-repeat: no-repeat;
|
||
background-position: 4px 5px;
|
||
&:hover {
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
|
||
.picture-azimuth-active{
|
||
width: 29px;
|
||
height: 29px;
|
||
float: left;
|
||
background: url(/map/not_show_picture.png);
|
||
background-size: 20px 20px;
|
||
background-repeat: no-repeat;
|
||
background-position: 4px 5px;
|
||
&:hover {
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
|
||
.draw-polygon {
|
||
width: 29px;
|
||
height: 29px;
|
||
float: left;
|
||
background: url(/map/draw_polygon.png);
|
||
background-size: 20px 20px;
|
||
background-repeat: no-repeat;
|
||
background-position: 4px 5px;
|
||
&:hover {
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
|
||
.split-line {
|
||
width: 29px;
|
||
height: 29px;
|
||
float: left;
|
||
background: url(/map/split_polygon.png);
|
||
background-size: 20px 20px;
|
||
background-repeat: no-repeat;
|
||
background-position: 4px 5px;
|
||
&:hover {
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
|
||
.split-polygon {
|
||
width: 29px;
|
||
height: 29px;
|
||
float: left;
|
||
background: url(/map/split_polygon_polygon.png);
|
||
background-size: 20px 20px;
|
||
background-repeat: no-repeat;
|
||
background-position: 4px 5px;
|
||
&:hover {
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
}
|
||
|
||
.to-location-input {
|
||
padding: 16px;
|
||
padding-right:4px;
|
||
width: 418px;
|
||
min-height: 60px;
|
||
background: #fff;
|
||
position: absolute;
|
||
top: 48px;
|
||
right: 10px;
|
||
border-radius: 5px;
|
||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
|
||
.location-operation {
|
||
width: 100%;
|
||
height: 40px;
|
||
border-bottom: 1px solid #f1f1f1;
|
||
margin-bottom: 12px;
|
||
}
|
||
.location-item-list-coantienr{
|
||
width:100%;
|
||
max-height:400px;
|
||
overflow-y:auto;
|
||
.location-item {
|
||
line-height: 20px;
|
||
margin-bottom: 6px;
|
||
}
|
||
}
|
||
}
|
||
</style>
|