CaiYuanYiTiHua/src/components/MapboxMaps/MapComponent.vue

543 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="map-container">
<div id="mapContainer" class="map-box"></div>
<!-- 图层控制 -->
<div class="layer-control-center">
<p v-for="(item,index) in props.layers" >
<a-checkbox v-model:checked="item.checked" @change="handlerCheckboxChange(item)" >{{item.name}}</a-checkbox>
</p>
</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>
</template>
<script lang="ts" setup>
import { onMounted, onUnmounted, defineProps,defineEmits, reactive, ref,defineExpose } from 'vue';
import { useMessage } from '@/hooks/web/useMessage';
import mapboxgl, { Map,Popup } from 'mapbox-gl';
// 图形绘制工具类
import MapboxDraw from "@mapbox/mapbox-gl-draw";
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';
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'
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(
{
layers:{
type:Array,
default:[],
},
location:{
type:Array,
default:[],
},
type:{
type:String,
default:"",
},
feature:{
type:String,
default:"",
}
}
);
let nextMapControl: Array<any> = reactive([]);
nextMapControl = props.control
? props.control.map((item) => {
console.log('item::: ', item);
return MapControlConfig[item];
})
: [];
console.log('nextMapControl::: ', nextMapControl);
// 定义地图容器
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:{}
})
const { createConfirm, createMessage } = useMessage();
// 定义地图回调emit
// 地图加载完成回调
const emit = defineEmits(['mapOnLoad', 'mapDraw','handlerDrawComplete']);
onMounted(() => {
mapboxgl.accessToken = MapboxConfig.ACCESS_TOKEN;
map = initMap();
map.on('load', () => {
// 初始化绘图空间
// handlerInitDrawTool(null);
map.on("click",(e)=>{
// handlerPreviewFeatureInfo(e);
clickPoisition = e.lngLat
})
map.on("draw.selectionchange",(e)=>{
// handlerCopyToTargetLayer(e);
})
// 设置绘图监听事件
map.on("draw.create", function (e) {
console.log(e);
drawGeojson.geojson = e.features[0]
});
map.on("draw.update", function (e) {
console.log(e);
drawGeojson.geojson = e.features[0]
});
window.handlerCopyFeature = handlerCopyFeature;
});
});
// 销毁地图
// 移除地图实例
onUnmounted(() => {
map ? map.remove() : null;
});
// 初始化地图 返回地图实例
const initMap = () => {
return new mapboxgl.Map({
container: 'mapContainer',
language: 'zh-cmn',
projection: 'equirectangular', // wgs84参考系
style: MapboxDefaultStyle,
maxZoom: 22,
minZoom: 6,
zoom:14,
center:props.location
});
};
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);
});
};
//绘制线
const handlerDrawLineString = () => {
mp.draw('LineString');
mp.on('LineString', function (e) {
emit('mapDraw', 'LineString', e);
});
};
//绘制面
const handlerDrawPolygon = () => {
mp.draw('Polygon');
mp.on('Polygon', function (e) {
emit('mapDraw', 'Polygon', e);
});
};
//删除标记
const handlerUnDraw = () => {
mp.deleteDraw();
emit('mapDraw', 'cancel');
};
// 初始化绘图空间
const handlerInitDrawTool = (feature) => {
geojson.geojson = feature;
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");
drawTool.set(geojson.geojson);
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 = () => {
console.log("selectFeature",selectFeature);
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) => {
handlerPreviewLayer(item)
}
// 控制图层是否显示
const handlerPreviewLayer = (layer) => {
handlerLayerControler(layer)
}
// 图层控制中心
const handlerLayerControler = (layerInfo)=>{
console.log("layerinfoinfo",layerInfo)
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){
console.log("EEEEEEE",e.features[0].layer.id,e.features[0].properties);
isOpen.value = true;
}
}
const handlerClose = (e) => {
isOpen.value = e;
}
// 图斑定位
const handlerLocation = (lngLat) => {
map.flyTo({
center: lngLat,
zoom: 16,
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 = () => {
emit("handlerDrawComplete",GeojsonToWkt(drawGeojson.geojson.geometry))
}
const handlerCancleDraw = () => {
map.removeControl(drawTool)
drawing.value = false;
// drawTool.set(geojson.geojson)
}
const handlerDraw = (feature=null) =>{
let featureTemp = WktToGeojson(feature);
console.log("传入的WKT",featureTemp);
let geo = {
type: "FeatureCollection",
features: [
{
"id": "cd1d93c0e4a6747ff597f190c311d0e3",
"type": "Feature",
"properties": {},
"geometry": featureTemp
}
],
}
console.log("geo",geo);
handlerInitDrawTool(geo)
}
defineExpose({
handlerDraw,
handlerLocation
});
</script>
<style>
.layer-control-center{
position:absolute;
padding:10px;
top:15px;
left:15px;
background:#ffffff;
border-radius: 12px;
}
.layer-control-center p{
margin:0px;
}
.draw-control-center{
position:absolute;
padding:7px;
top:15px;
right:15px;
background:#ffffff;
border-radius: 12px;
}
.draw-control-center .draw-btn{
float:left;
margin:0px 6px;
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:10px;
border-radius: 12px;
position:relative;
right:140px;
top:5px;
}
.mapbox-gl-draw_ctrl-draw-btn{
width:20px!important;
height:20px!important;
float:left;
}
.mapboxgl-ctrl-top-right{
}
.mapboxgl-ctrl-group button+button{
border:0px;
margin:0px 10px;
}
.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 10px;
}
.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;
}
</style>