2024-05-27 08:25:43 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div class="map-container">
|
2024-07-02 16:34:19 +08:00
|
|
|
|
|
|
|
|
|
|
<div :id="mapContainerName" class="map-box"></div>
|
2024-05-27 08:25:43 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 图层控制 -->
|
2024-06-13 18:02:33 +08:00
|
|
|
|
<div class="layer-control-center" v-if="false">
|
2024-06-12 17:28:10 +08:00
|
|
|
|
<a-collapse v-model:activeKey="activeKey" accordion expandIconPosition="end" expandIcon="">
|
|
|
|
|
|
<a-collapse-panel key="1" header="图层">
|
2024-06-13 18:02:33 +08:00
|
|
|
|
<p v-for="(item, index) in props.mapConfig.layers" class="layer-item">
|
2024-06-12 17:28:10 +08:00
|
|
|
|
<a-checkbox v-model:checked="item.checked" @change="handlerCheckboxChange(item)">{{
|
|
|
|
|
|
item.name
|
|
|
|
|
|
}}</a-checkbox>
|
|
|
|
|
|
</p>
|
2024-06-13 18:02:33 +08:00
|
|
|
|
<p v-for="(item, index) in props.mapConfig.baseLayers" class="layer-item">
|
2024-06-12 17:28:10 +08:00
|
|
|
|
<a-checkbox v-model:checked="item.checked" @change="handlerCheckboxChange(item)">{{
|
|
|
|
|
|
item.name
|
|
|
|
|
|
}}</a-checkbox>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
</a-collapse-panel>
|
|
|
|
|
|
</a-collapse>
|
2024-05-27 08:25:43 +08:00
|
|
|
|
</div>
|
2024-05-30 10:13:56 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
<!-- 绘图控制 -->
|
|
|
|
|
|
<div class="draw-control-center" v-show="drawing">
|
|
|
|
|
|
<div class="draw-btn" @click="handlerCancleDraw"> 取消 </div>
|
|
|
|
|
|
<div class="draw-btn" @click="handlerDrawComplete"> 保存 </div>
|
|
|
|
|
|
</div>
|
2024-07-02 08:57:18 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 根据输入坐标定位 -->
|
|
|
|
|
|
<div class="position-by-lnglat">
|
2024-07-04 15:53:59 +08:00
|
|
|
|
<div class="to-location" @click="handlerToPosition">
|
2024-07-02 08:57:18 +08:00
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="draw-polygon" @click="LocationShow = true">
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2024-07-02 19:32:01 +08:00
|
|
|
|
<!-- 坐标输入框 -->
|
2024-07-02 08:57:18 +08:00
|
|
|
|
<div class="to-location-input" v-if="LocationShow">
|
|
|
|
|
|
<div class="location-operation">
|
|
|
|
|
|
<a-button type="default" size="small" @click="handlerPushLocationItem"><PlusOutlined />添加</a-button>
|
|
|
|
|
|
|
|
|
|
|
|
<a-button type="default" size="small" @click="handlerClearLocationItem"><ClearOutlined />清空</a-button>
|
|
|
|
|
|
|
|
|
|
|
|
<span style="float:right;">
|
|
|
|
|
|
<CloseOutlined @click="handlerLocationClose" />
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<a-empty v-if="locationArrays.length==0" />
|
|
|
|
|
|
|
|
|
|
|
|
<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>
|
2024-06-13 09:02:01 +08:00
|
|
|
|
</div>
|
2024-06-14 08:37:42 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
|
|
import {
|
|
|
|
|
|
onMounted,
|
|
|
|
|
|
onUnmounted,
|
|
|
|
|
|
defineProps,
|
|
|
|
|
|
defineEmits,
|
|
|
|
|
|
reactive,
|
|
|
|
|
|
ref,
|
|
|
|
|
|
defineExpose,
|
2024-07-03 15:35:14 +08:00
|
|
|
|
watch
|
2024-06-14 08:37:42 +08:00
|
|
|
|
} from 'vue';
|
|
|
|
|
|
|
|
|
|
|
|
import { useMessage } from '@/hooks/web/useMessage';
|
2024-07-02 08:57:18 +08:00
|
|
|
|
import {CloseOutlined,EnvironmentOutlined,DeleteOutlined,CopyOutlined,PlusOutlined,ClearOutlined} from "@ant-design/icons-vue"
|
|
|
|
|
|
import mapboxgl,{ Map, Popup } from 'mapbox-gl';
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
|
|
|
|
|
// 图形绘制工具类
|
|
|
|
|
|
import MapboxDraw from '@mapbox/mapbox-gl-draw';
|
|
|
|
|
|
|
|
|
|
|
|
import { generateUUID,getGeometryCenter } from './src/tool'
|
|
|
|
|
|
|
2024-05-30 10:13:56 +08:00
|
|
|
|
// 测量工具
|
2024-07-03 15:35:14 +08:00
|
|
|
|
import { SwitchLayerControl,MeasureControl } from 'mapbox-extensions'
|
2024-05-30 10:13:56 +08:00
|
|
|
|
import 'mapbox-extensions/dist/index.css'
|
2024-06-08 08:34:52 +08:00
|
|
|
|
|
2024-07-03 15:35:14 +08:00
|
|
|
|
// import U from 'mapbox-gl-utils';
|
2024-06-14 08:37:42 +08:00
|
|
|
|
import 'mapbox-gl/dist/mapbox-gl.css';
|
2024-07-02 19:32:01 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
import './src/index.less';
|
|
|
|
|
|
import { MapboxConfig, MapboxDefaultStyle, MapControlConfig } from './src/config';
|
|
|
|
|
|
import { MP } from './src/MP';
|
|
|
|
|
|
import { DrawingType } from '@/enums/mapEnum';
|
|
|
|
|
|
|
|
|
|
|
|
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';
|
2024-07-04 13:32:08 +08:00
|
|
|
|
|
|
|
|
|
|
import { getAppEnvConfig } from '@/utils/env';
|
|
|
|
|
|
const { VITE_GLOB_API_URL } = getAppEnvConfig();
|
|
|
|
|
|
const VITE_GLOB_API_URL_VAR = ref<String>(VITE_GLOB_API_URL+"/");
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
2024-07-02 16:34:19 +08:00
|
|
|
|
const mapContainerName = ref<String>()
|
|
|
|
|
|
mapContainerName.value = "mapContainer"+generateUUID();
|
|
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
const openModal = ref(false);
|
|
|
|
|
|
const insertShpModal = ref(false);
|
|
|
|
|
|
const changeOpenModal = (value) => {
|
|
|
|
|
|
openModal.value = value;
|
|
|
|
|
|
};
|
2024-07-02 16:34:19 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
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: '',
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
2024-07-03 15:35:14 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
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: [],
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
2024-07-03 15:35:14 +08:00
|
|
|
|
|
|
|
|
|
|
let switchLayerControler;
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
|
|
|
|
|
const { createConfirm, createMessage } = useMessage();
|
|
|
|
|
|
|
|
|
|
|
|
// 定义地图回调emit
|
|
|
|
|
|
// 地图加载完成回调
|
2024-06-24 17:33:05 +08:00
|
|
|
|
const emit = defineEmits(['mapOnLoad', 'mapDraw', 'handlerDrawComplete','handlerGetFormDetail']);
|
2024-07-03 15:35:14 +08:00
|
|
|
|
|
|
|
|
|
|
watch(
|
|
|
|
|
|
()=>props.mapConfig,
|
|
|
|
|
|
(newVal,oldVal)=>{
|
2024-07-04 15:53:59 +08:00
|
|
|
|
handlerLoadMapLayer();
|
2024-07-03 15:35:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
mapboxgl.accessToken = MapboxConfig.ACCESS_TOKEN;
|
|
|
|
|
|
map = initMap();
|
2024-07-02 18:59:27 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
map.on('load', () => {
|
|
|
|
|
|
|
|
|
|
|
|
// 根据地图配置信息加载地形数据
|
|
|
|
|
|
if(props.mapConfig.mode == "3D"){
|
2024-07-02 18:59:27 +08:00
|
|
|
|
// handlerLoadTerrain();
|
2024-06-14 08:37:42 +08:00
|
|
|
|
}
|
2024-06-13 09:02:01 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
// 初始化绘图空间
|
|
|
|
|
|
// handlerInitDrawTool(null);
|
|
|
|
|
|
|
|
|
|
|
|
map.on('click', (e) => {
|
|
|
|
|
|
// handlerPreviewFeatureInfo(e);
|
|
|
|
|
|
clickPoisition = e.lngLat;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
map.on('draw.selectionchange', (e) => {
|
|
|
|
|
|
// handlerCopyToTargetLayer(e);
|
|
|
|
|
|
});
|
2024-07-02 18:59:27 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
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:{
|
2024-06-11 08:29:53 +08:00
|
|
|
|
|
2024-05-30 10:13:56 +08:00
|
|
|
|
},
|
|
|
|
|
|
measureLineStringOptions:{
|
|
|
|
|
|
},
|
|
|
|
|
|
measurePolygonOptions:{
|
|
|
|
|
|
}
|
2024-06-12 13:37:35 +08:00
|
|
|
|
}),"top-right")
|
2024-06-13 18:02:33 +08:00
|
|
|
|
|
2024-07-03 15:35:14 +08:00
|
|
|
|
// 加载图层
|
|
|
|
|
|
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("当前点击图层未绑定信息");
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// })
|
|
|
|
|
|
// })
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 地图图层控制
|
|
|
|
|
|
const handlerLoadMapLayer = ()=>{
|
|
|
|
|
|
if(switchLayerControler){
|
2024-07-04 15:53:59 +08:00
|
|
|
|
// var allLayers = map.getStyle().layers;
|
|
|
|
|
|
// allLayers.forEach(function(layer){
|
|
|
|
|
|
// console.log("layerEEEEEE",layer);
|
|
|
|
|
|
// console.log(layer.id);
|
|
|
|
|
|
// // map.removeLayer(layer.id);
|
|
|
|
|
|
// });
|
2024-07-03 15:35:14 +08:00
|
|
|
|
// var allSources = Object.keys(map.style.sourceCaches);
|
|
|
|
|
|
// allSources.forEach(function(sourceId){
|
|
|
|
|
|
// map.removeSource(sourceId);
|
|
|
|
|
|
// });
|
2024-07-04 15:53:59 +08:00
|
|
|
|
map.removeControl(switchLayerControler);
|
2024-07-03 15:35:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
let configlayers = {};
|
2024-06-13 18:02:33 +08:00
|
|
|
|
let baseLayers = [];
|
|
|
|
|
|
props.mapConfig.layers?.forEach((item,index)=>{
|
2024-07-03 15:35:14 +08:00
|
|
|
|
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:false,
|
|
|
|
|
|
backgroundImage:"",
|
|
|
|
|
|
backgroundImageActive:"",
|
|
|
|
|
|
selectAndClearAll:true,
|
|
|
|
|
|
selectAllLabel:"select all",
|
|
|
|
|
|
clearAllLabel:"clear all",
|
|
|
|
|
|
onVisibleChange:(visible:boolean)=>{}
|
|
|
|
|
|
}
|
|
|
|
|
|
applicationLayers.push(layers);
|
|
|
|
|
|
})
|
|
|
|
|
|
configlayers[item.name] = {
|
|
|
|
|
|
mutex:true,
|
|
|
|
|
|
collapse:true,
|
|
|
|
|
|
selectAndClearAll:true,
|
|
|
|
|
|
selectAllLabel:"select all",
|
|
|
|
|
|
clearAllLabel:"clear all",
|
|
|
|
|
|
uiType:"SwitchBtn",
|
|
|
|
|
|
layers:applicationLayers
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2024-06-13 18:02:33 +08:00
|
|
|
|
})
|
|
|
|
|
|
props.mapConfig.baseLayers?.forEach((item,index)=>{
|
2024-07-04 13:32:08 +08:00
|
|
|
|
let layer = JSON.parse(item.style);
|
|
|
|
|
|
let image = item.image.replace('\\','/');
|
2024-06-13 18:02:33 +08:00
|
|
|
|
let layers = {
|
|
|
|
|
|
name:item.name,
|
2024-07-04 13:32:08 +08:00
|
|
|
|
layer: layer,
|
2024-06-13 18:02:33 +08:00
|
|
|
|
fixed:true,
|
|
|
|
|
|
zoom:-100,
|
|
|
|
|
|
easeToOptions:{},
|
2024-07-03 15:35:14 +08:00
|
|
|
|
mutex:false,
|
|
|
|
|
|
mutexIdentity:generateUUID(),
|
|
|
|
|
|
active:false,
|
2024-07-04 13:32:08 +08:00
|
|
|
|
backgroundImage:VITE_GLOB_API_URL_VAR.value+image,
|
2024-06-13 18:02:33 +08:00
|
|
|
|
backgroundImageActive:"",
|
|
|
|
|
|
onVisibleChange:(visible:boolean)=>{}
|
|
|
|
|
|
}
|
|
|
|
|
|
baseLayers.push(layers)
|
|
|
|
|
|
})
|
2024-07-03 15:35:14 +08:00
|
|
|
|
configlayers["地图底图"] = {
|
|
|
|
|
|
mutex:true,
|
|
|
|
|
|
collapse:true,
|
|
|
|
|
|
uiType:"ImgTxtBtn",
|
|
|
|
|
|
layers:baseLayers
|
|
|
|
|
|
};
|
2024-07-02 18:59:27 +08:00
|
|
|
|
// 图层管理工具
|
2024-07-03 15:35:14 +08:00
|
|
|
|
|
|
|
|
|
|
switchLayerControler = new SwitchLayerControl({
|
2024-06-13 18:02:33 +08:00
|
|
|
|
name:"图层管理" ,
|
|
|
|
|
|
position:"top-left",
|
|
|
|
|
|
selectAndClearAll:true,
|
2024-07-03 15:35:14 +08:00
|
|
|
|
selectAllLabel:"select all",
|
|
|
|
|
|
clearAllLabel:"clear all",
|
|
|
|
|
|
showToTop:false,
|
2024-06-13 18:02:33 +08:00
|
|
|
|
topLayerId:"",
|
2024-07-03 15:35:14 +08:00
|
|
|
|
layerGroups:configlayers
|
|
|
|
|
|
});
|
|
|
|
|
|
map.addControl(switchLayerControler,"top-left");
|
|
|
|
|
|
}
|
2024-05-27 08:25:43 +08:00
|
|
|
|
// 销毁地图
|
2024-06-08 08:34:52 +08:00
|
|
|
|
|
2024-06-21 17:47:17 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-06-14 08:37:42 +08:00
|
|
|
|
// 加载地形
|
|
|
|
|
|
const handlerLoadTerrain = () => {
|
|
|
|
|
|
map.addSource('mapbox-dem', {
|
|
|
|
|
|
'type': 'raster-dem',
|
|
|
|
|
|
'url': 'mapbox://mapbox.mapbox-terrain-dem-v1',
|
|
|
|
|
|
'tileSize': 512,
|
|
|
|
|
|
'maxzoom': 14
|
|
|
|
|
|
});
|
2024-06-08 08:34:52 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
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;
|
2024-05-27 08:25:43 +08:00
|
|
|
|
});
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
|
|
|
|
|
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({
|
2024-07-02 16:34:19 +08:00
|
|
|
|
container:mapContainerName.value,
|
2024-06-14 08:37:42 +08:00
|
|
|
|
language: 'zh-cmn',
|
|
|
|
|
|
projection: 'equirectangular', // wgs84参考系
|
|
|
|
|
|
style: MapboxDefaultStyle,
|
2024-07-02 08:57:18 +08:00
|
|
|
|
// maxZoom: props.mapConfig.maxZoom ? props.mapConfig.maxZoom:18,
|
2024-06-14 08:37:42 +08:00
|
|
|
|
minZoom: props.mapConfig.minZoom ? props.mapConfig.minZoom:1,
|
2024-07-02 17:42:09 +08:00
|
|
|
|
zoom: props.mapConfig.zoom ? props.mapConfig.zoom:10,
|
2024-06-14 08:37:42 +08:00
|
|
|
|
pitch:props.mapConfig.angle ? props.mapConfig.angle:0,
|
2024-07-02 17:42:09 +08:00
|
|
|
|
center: props.mapConfig.center?.split(",") ? props.mapConfig.center?.split(",") : [117.984425,35.270654],
|
2024-05-27 08:25:43 +08:00
|
|
|
|
});
|
2024-06-14 08:37:42 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handlerMapControlClick = (handler: string) => {
|
|
|
|
|
|
handler === 'handlerDrawPoint' && handlerDrawPoint();
|
|
|
|
|
|
handler === 'handlerDrawLineString' && handlerDrawLineString();
|
|
|
|
|
|
handler === 'handlerDrawPolygon' && handlerDrawPolygon();
|
|
|
|
|
|
};
|
|
|
|
|
|
//绘制点
|
|
|
|
|
|
const handlerDrawPoint = () => {
|
|
|
|
|
|
mp.draw('Point');
|
|
|
|
|
|
mp.on('Point', function (e) {
|
|
|
|
|
|
emit('mapDraw', 'Point', e);
|
2024-05-27 08:25:43 +08:00
|
|
|
|
});
|
2024-06-14 08:37:42 +08:00
|
|
|
|
};
|
|
|
|
|
|
//绘制线
|
|
|
|
|
|
const handlerDrawLineString = () => {
|
|
|
|
|
|
mp.draw('LineString');
|
|
|
|
|
|
mp.on('LineString', function (e) {
|
|
|
|
|
|
emit('mapDraw', 'LineString', e);
|
2024-05-27 08:25:43 +08:00
|
|
|
|
});
|
2024-06-14 08:37:42 +08:00
|
|
|
|
};
|
|
|
|
|
|
//绘制面
|
|
|
|
|
|
const handlerDrawPolygon = () => {
|
|
|
|
|
|
mp.draw('Polygon');
|
|
|
|
|
|
mp.on('Polygon', function (e) {
|
|
|
|
|
|
emit('mapDraw', 'Polygon', e);
|
2024-06-13 09:02:01 +08:00
|
|
|
|
});
|
2024-06-14 08:37:42 +08:00
|
|
|
|
};
|
|
|
|
|
|
//删除标记
|
|
|
|
|
|
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;
|
2024-05-30 10:13:56 +08:00
|
|
|
|
|
|
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-05-30 10:13:56 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
// 正在绘制
|
|
|
|
|
|
// 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;
|
2024-05-27 08:25:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-06-14 08:37:42 +08:00
|
|
|
|
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);
|
|
|
|
|
|
});
|
2024-05-27 08:25:43 +08:00
|
|
|
|
}
|
2024-06-14 08:37:42 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 查看列表数据
|
|
|
|
|
|
const handlerDataList = () => {};
|
|
|
|
|
|
|
|
|
|
|
|
// 图斑属性查看
|
|
|
|
|
|
const handlerPreviewFeatureInfo = (e) => {
|
|
|
|
|
|
if (e.features) {
|
|
|
|
|
|
isOpen.value = true;
|
2024-05-27 08:25:43 +08:00
|
|
|
|
}
|
2024-06-14 08:37:42 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handlerClose = (e) => {
|
|
|
|
|
|
isOpen.value = e;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2024-07-04 15:53:59 +08:00
|
|
|
|
const currentPosition = ref(null);
|
2024-06-14 08:37:42 +08:00
|
|
|
|
// 图斑定位
|
|
|
|
|
|
const handlerLocation = (lngLat) => {
|
2024-07-04 15:53:59 +08:00
|
|
|
|
currentPosition.value = lngLat
|
2024-06-14 08:37:42 +08:00
|
|
|
|
map.flyTo({
|
|
|
|
|
|
center: lngLat,
|
|
|
|
|
|
zoom: 17,
|
|
|
|
|
|
speed: 10, // 飞行速度
|
|
|
|
|
|
curve: 1, // 飞行曲线
|
|
|
|
|
|
easing(t) {
|
|
|
|
|
|
// 飞行动画函数
|
|
|
|
|
|
return t;
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
2024-07-04 15:53:59 +08:00
|
|
|
|
// 定位
|
|
|
|
|
|
const handlerToPosition = ()=>{
|
|
|
|
|
|
if(currentPosition.value){
|
|
|
|
|
|
map.flyTo({
|
|
|
|
|
|
center: currentPosition.value,
|
|
|
|
|
|
zoom: 17,
|
|
|
|
|
|
speed: 10, // 飞行速度
|
|
|
|
|
|
curve: 1, // 飞行曲线
|
|
|
|
|
|
easing(t) {
|
|
|
|
|
|
// 飞行动画函数
|
|
|
|
|
|
return t;
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
|
|
|
|
|
// 编辑图斑
|
|
|
|
|
|
const handlerEdit = (info) => {
|
|
|
|
|
|
initDraw(info);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const initDraw = (layerInfo) => {
|
|
|
|
|
|
|
|
|
|
|
|
// 实例化绘图工具
|
2024-05-27 08:25:43 +08:00
|
|
|
|
drawTool = new MapboxDraw({
|
|
|
|
|
|
modes: {
|
|
|
|
|
|
...MapboxDraw.modes,
|
|
|
|
|
|
draw_point: SnapPointMode,
|
2024-06-14 08:37:42 +08:00
|
|
|
|
// draw_polygon: SnapPolygonMode,
|
|
|
|
|
|
// draw_line_string: SnapLineMode,
|
2024-05-27 08:25:43 +08:00
|
|
|
|
direct_select: SnapDirectSelect,
|
|
|
|
|
|
},
|
|
|
|
|
|
styles: customDrawStyles,
|
|
|
|
|
|
userProperties: true,
|
|
|
|
|
|
snap: true,
|
|
|
|
|
|
snapOptions: {
|
2024-06-14 08:37:42 +08:00
|
|
|
|
snapPx: 15, // defaults to 15
|
2024-05-27 08:25:43 +08:00
|
|
|
|
snapToMidPoints: true, // defaults to false
|
|
|
|
|
|
snapVertexPriorityDistance: 0.0025, // defaults to 1.25
|
|
|
|
|
|
},
|
|
|
|
|
|
guides: false,
|
|
|
|
|
|
});
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
2024-06-13 09:02:01 +08:00
|
|
|
|
map.addControl(drawTool, 'top-right');
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
|
|
|
|
|
// 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 = () => {
|
2024-06-11 08:29:53 +08:00
|
|
|
|
|
2024-06-14 08:41:20 +08:00
|
|
|
|
if(drawTool){
|
|
|
|
|
|
map.removeControl(drawTool);
|
|
|
|
|
|
drawTool = null;
|
|
|
|
|
|
drawing.value = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
// 清空详情图层
|
|
|
|
|
|
if(map.getSource("detailsSource")){
|
|
|
|
|
|
map.getSource("detailsSource").setData({
|
|
|
|
|
|
type: 'FeatureCollection',
|
|
|
|
|
|
features: [],
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
2024-06-11 08:29:53 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
*
|
|
|
|
|
|
* 查看图斑
|
|
|
|
|
|
*
|
|
|
|
|
|
* 添加图斑
|
|
|
|
|
|
*
|
|
|
|
|
|
* 编辑图斑
|
|
|
|
|
|
*
|
|
|
|
|
|
* status 操作类型
|
|
|
|
|
|
*
|
|
|
|
|
|
* features 空间数据
|
|
|
|
|
|
*
|
|
|
|
|
|
* [
|
|
|
|
|
|
* {id:"8448048304dofhaofh0af0q4",geom:""}
|
|
|
|
|
|
* ]
|
2024-06-15 14:33:23 +08:00
|
|
|
|
*
|
2024-06-14 08:37:42 +08:00
|
|
|
|
* */
|
|
|
|
|
|
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);
|
|
|
|
|
|
handlerLocation(lngLat);
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {
|
2024-06-17 11:37:36 +08:00
|
|
|
|
console.error("wktParse",e);
|
2024-06-14 08:37:42 +08:00
|
|
|
|
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("请传入操作类型!");
|
2024-06-11 08:29:53 +08:00
|
|
|
|
}
|
2024-06-14 08:37:42 +08:00
|
|
|
|
};
|
2024-05-30 10:13:56 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
// 查看图斑详情
|
|
|
|
|
|
const handlerDetails = (geojson) => {
|
|
|
|
|
|
if(map.getSource("detailsSource")){
|
|
|
|
|
|
map.getSource("detailsSource").setData(geojson);
|
|
|
|
|
|
}else{
|
|
|
|
|
|
map.addSource("detailsSource",{
|
|
|
|
|
|
type:"geojson",
|
|
|
|
|
|
data:geojson
|
|
|
|
|
|
})
|
|
|
|
|
|
map.addLayer(
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "detailsLayer",
|
|
|
|
|
|
"type": "fill",
|
|
|
|
|
|
"source": "detailsSource",
|
|
|
|
|
|
'layout':{
|
2024-06-11 08:29:53 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
},
|
|
|
|
|
|
'paint': {
|
|
|
|
|
|
//填充颜色
|
|
|
|
|
|
'fill-color': '#3badc9',
|
|
|
|
|
|
//透明度设置
|
|
|
|
|
|
"fill-opacity": 0.4,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
map.addLayer(
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "detailsLayerLine",
|
|
|
|
|
|
"type": "line",
|
|
|
|
|
|
"source": "detailsSource",
|
|
|
|
|
|
'layout':{
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
'paint': {
|
|
|
|
|
|
'line-color': '#3badc9',
|
|
|
|
|
|
'line-width': 2
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-06-13 09:02:01 +08:00
|
|
|
|
)
|
|
|
|
|
|
}
|
2024-05-27 08:25:43 +08:00
|
|
|
|
}
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
|
|
|
|
|
// 创建查看图斑图层
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-07-02 08:57:18 +08:00
|
|
|
|
// 粘贴坐标实现定位、绘图相关
|
|
|
|
|
|
interface LocationItem {
|
|
|
|
|
|
lng:string;
|
|
|
|
|
|
lat:string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const LocationShow = ref<Boolean>(false);
|
|
|
|
|
|
const locationArrays = ref<LocationItem[]>([]);
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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&&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": "MultiLineString",
|
|
|
|
|
|
"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 = ()=>{
|
|
|
|
|
|
// 绘制点
|
|
|
|
|
|
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 handlerLocationDrawPoint = ()=>{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 绘制线
|
|
|
|
|
|
const handlerLocationDrawLine = ()=>{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 绘制面
|
|
|
|
|
|
const handlerLocationDrawPolygon = ()=>{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
|
|
|
|
|
defineExpose({
|
|
|
|
|
|
handlerDraw,
|
|
|
|
|
|
handlerLocation,
|
|
|
|
|
|
handlerCancleDraw,
|
|
|
|
|
|
});
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
2024-06-18 09:59:49 +08:00
|
|
|
|
<style scoped>
|
2024-06-14 08:37:42 +08:00
|
|
|
|
.map-container {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
2024-06-12 13:37:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
.map-box {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
}
|
2024-06-12 17:28:10 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
.layer-control-center {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 15px;
|
|
|
|
|
|
left: 15px;
|
|
|
|
|
|
background:#fff;
|
|
|
|
|
|
border-radius: 8px;
|
2024-05-27 08:25:43 +08:00
|
|
|
|
}
|
2024-05-30 10:13:56 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
.layer-control-center p {
|
|
|
|
|
|
margin: 0px;
|
2024-05-27 08:25:43 +08:00
|
|
|
|
}
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
|
|
|
|
|
.layer-control-center .ant-checkbox-wrapper{
|
|
|
|
|
|
|
2024-05-27 08:25:43 +08:00
|
|
|
|
}
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
|
|
|
|
|
.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;
|
2024-05-27 08:25:43 +08:00
|
|
|
|
}
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
|
|
|
|
|
.draw-control-center .draw-btn:hover {
|
|
|
|
|
|
background-color: rgb(0 0 0/5%);
|
|
|
|
|
|
cursor: pointer;
|
2024-05-27 08:25:43 +08:00
|
|
|
|
}
|
2024-05-30 10:13:56 +08:00
|
|
|
|
|
2024-06-14 08:37:42 +08:00
|
|
|
|
.mapboxgl-ctrl-group:not(:empty) {
|
|
|
|
|
|
box-shadow: none;
|
2024-05-30 10:13:56 +08:00
|
|
|
|
}
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
2024-05-27 08:25:43 +08:00
|
|
|
|
.mapboxgl-ctrl-group {
|
2024-06-13 18:02:33 +08:00
|
|
|
|
padding: 6px;
|
2024-05-27 08:25:43 +08:00
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
top: 5px;
|
2024-06-18 09:59:49 +08:00
|
|
|
|
right:0px;
|
2024-05-27 08:25:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
.mapbox-gl-draw_ctrl-draw-btn {
|
|
|
|
|
|
width: 20px !important;
|
|
|
|
|
|
height: 20px !important;
|
|
|
|
|
|
float: left;
|
|
|
|
|
|
}
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|
|
|
|
|
|
.mapboxgl-ctrl-top-right {
|
2024-06-18 09:59:49 +08:00
|
|
|
|
width:360px;
|
2024-06-14 08:37:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-30 10:13:56 +08:00
|
|
|
|
.jas-ctrl-measure-item{
|
|
|
|
|
|
height:22px;
|
2024-06-13 18:02:33 +08:00
|
|
|
|
color: rgb(255, 255, 255);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.layer-item{
|
|
|
|
|
|
padding:8px 16px;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.layer-item:hover{
|
|
|
|
|
|
background:#c7dcf580;
|
|
|
|
|
|
|
2024-05-30 10:13:56 +08:00
|
|
|
|
}
|
2024-06-12 17:28:10 +08:00
|
|
|
|
|
2024-06-13 18:02:33 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
::v-deep .ant-collapse-content-box{
|
|
|
|
|
|
padding:0px!important;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-18 09:59:49 +08:00
|
|
|
|
::v-deep .jas-ctrl-extend-desktop-container {
|
|
|
|
|
|
width:320px!important;
|
|
|
|
|
|
}
|
2024-07-02 08:57:18 +08:00
|
|
|
|
|
|
|
|
|
|
.position-by-lnglat{
|
2024-07-04 15:53:59 +08:00
|
|
|
|
width:58px;
|
2024-07-02 08:57:18 +08:00
|
|
|
|
height:29px;
|
|
|
|
|
|
background:#fff;
|
|
|
|
|
|
position:absolute;
|
|
|
|
|
|
top:10px;
|
|
|
|
|
|
right:131px;
|
|
|
|
|
|
border-radius:3px;
|
|
|
|
|
|
.to-location{
|
|
|
|
|
|
width:29px;
|
|
|
|
|
|
height:29px;
|
|
|
|
|
|
float:left;
|
|
|
|
|
|
background:url(/public/map/location.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(/public/map/draw_polygon.png);
|
|
|
|
|
|
background-size:20px 20px;
|
|
|
|
|
|
background-repeat: no-repeat;
|
|
|
|
|
|
background-position: 4px 5px;
|
|
|
|
|
|
&:hover{
|
|
|
|
|
|
cursor:pointer;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.to-location-input{
|
|
|
|
|
|
padding:16px;
|
|
|
|
|
|
width:408px;
|
|
|
|
|
|
min-height:60px;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
position:absolute;
|
|
|
|
|
|
top:48px;
|
|
|
|
|
|
right:10px;
|
2024-07-02 16:34:19 +08:00
|
|
|
|
border-radius:5px;
|
2024-07-02 08:57:18 +08:00
|
|
|
|
.location-operation{
|
|
|
|
|
|
width:100%;
|
|
|
|
|
|
height:40px;
|
|
|
|
|
|
border-bottom:1px solid #f1f1f1;
|
|
|
|
|
|
margin-bottom:12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.location-item{
|
2024-07-02 15:47:48 +08:00
|
|
|
|
line-height:20px;
|
2024-07-02 08:57:18 +08:00
|
|
|
|
margin-bottom:6px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-05-27 08:25:43 +08:00
|
|
|
|
</style>
|
2024-06-14 08:37:42 +08:00
|
|
|
|
|