Mapbox绘图工具、图斑复制
parent
ccd0308958
commit
9fef8986d2
@ -0,0 +1,7 @@
|
||||
{
|
||||
"i18n-ally.localesPaths": [
|
||||
"src/locales",
|
||||
"src/locales/lang",
|
||||
"public/resource/tinymce/langs"
|
||||
]
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
@ -0,0 +1,274 @@
|
||||
<template>
|
||||
<div class="map-container">
|
||||
<div id="mapContainer" class="map-box"></div>
|
||||
<!-- <div class="map-control">
|
||||
<img
|
||||
v-for="(item, index) in nextMapControl"
|
||||
:key="index"
|
||||
:src="item.icon"
|
||||
:title="item.title"
|
||||
@click="handlerMapControlClick(item.handler)"
|
||||
/>
|
||||
<img v-show="nextMapControl.length > 0" @click="handlerUnDraw" src="/del.png" title="清除" />
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, defineProps, reactive } 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";
|
||||
|
||||
// map参数类型
|
||||
interface MapboxOptionsInterface {
|
||||
mapOptions: mapboxgl.MapboxOptions;
|
||||
control: DrawingType[];
|
||||
}
|
||||
const props = defineProps<MapboxOptionsInterface>();
|
||||
|
||||
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 popup:Popup;
|
||||
let clickPoisition:Array<number> = [];
|
||||
let selectFeature:Object = {};
|
||||
let mp: any = null;
|
||||
|
||||
const { createConfirm, createMessage } = useMessage();
|
||||
|
||||
// 定义地图回调emit
|
||||
// 地图加载完成回调
|
||||
const emit = defineEmits(['mapOnLoad', 'mapDraw']);
|
||||
|
||||
onMounted(() => {
|
||||
mapboxgl.accessToken = MapboxConfig.ACCESS_TOKEN;
|
||||
map = initMap();
|
||||
map.on('load', () => {
|
||||
//挂载mapbox-gl-utils
|
||||
// U.init(map);
|
||||
// mp = new MP(map);
|
||||
// emit('mapOnLoad', map);
|
||||
|
||||
// 初始化绘图空间
|
||||
handlerInitDrawTool();
|
||||
|
||||
map.on("click",(e)=>{
|
||||
clickPoisition = e.lngLat
|
||||
})
|
||||
|
||||
map.on("draw.selectionchange",(e)=>{
|
||||
handlerCopyToTargetLayer(e);
|
||||
})
|
||||
|
||||
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,
|
||||
...props.mapOptions,
|
||||
});
|
||||
};
|
||||
|
||||
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 = () => {
|
||||
|
||||
let drawTool = new MapboxDraw({
|
||||
modes: {
|
||||
...MapboxDraw.modes,
|
||||
draw_point: SnapPointMode,
|
||||
draw_polygon: SnapPolygonMode,
|
||||
draw_line_string: SnapLineMode,
|
||||
direct_select: SnapDirectSelect,
|
||||
},
|
||||
// Styling guides
|
||||
styles: SnapModeDrawStyles,
|
||||
userProperties: true,
|
||||
// Config snapping features
|
||||
snap: true,
|
||||
snapOptions: {
|
||||
snapPx: 15, // defaults to 15
|
||||
snapToMidPoints: true, // defaults to false
|
||||
snapVertexPriorityDistance: 0.0025, // defaults to 1.25
|
||||
},
|
||||
guides: true,
|
||||
});
|
||||
|
||||
map.addControl(drawTool, "top-right");
|
||||
}
|
||||
|
||||
// 将图斑复制到指定图层
|
||||
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)
|
||||
popup.remove();
|
||||
createMessage.success("复制成功!")
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.mapboxgl-ctrl-group:not(:empty){
|
||||
box-shadow: none;
|
||||
}
|
||||
.mapboxgl-ctrl-group{
|
||||
background:none!important;
|
||||
}
|
||||
.mapbox-gl-draw_ctrl-draw-btn{
|
||||
width:40px!important;
|
||||
height:40px!important;
|
||||
float:left;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.mapboxgl-ctrl-top-right{
|
||||
}
|
||||
|
||||
.mapboxgl-ctrl-group button+button{
|
||||
border:0px;
|
||||
margin:0px 3px;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.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>
|
||||
|
Loading…
Reference in New Issue