This commit is contained in:
yanran200730
2023-04-14 17:42:43 +08:00
parent 42eff40f48
commit e553c9c758
4 changed files with 1053 additions and 0 deletions

View File

@@ -0,0 +1,327 @@
<template>
<section class="mapPlotting">
<div class="clicker" @click="dialog=true,$emit('open')">
<slot v-if="$slots.default"/>
<el-button v-else type="text">标绘</el-button>
</div>
<ai-dialog :title="title" class="fullscreenMap"
:visible.sync="dialog"
:destroyOnClose="true"
@close="points=[]"
border fullscreen
@open="initMap" :modal="false"
@onConfirm="$emit('change',points.flat()),dialog=false">
<div class="mapPanel">
<div class="tipinput">
<el-input
v-model="searchAddress"
@change="addressChange"
clearable
placeholder="请输入关键字"
id="tipinput"
size="medium"/>
</div>
<div id="panel"/>
<div class="container fill" id="container"/>
<div class="operationBtns" v-if="map">
<el-alert type="success" title="操作说明:" :closable="false">
<li>1.双击覆盖物即可编辑</li>
<li>2.编辑状态,对点双击可删除该点</li>
<li>3.绘制状态,右键结束绘制</li>
<li>4.结束编辑才能保存绘制的覆盖物信息</li>
</el-alert>
<el-button-group>
<el-button type="primary" @click="handleAdd">新建</el-button>
<el-button @click="polyEditor.close()">结束编辑</el-button>
<el-button @click="clear()">清除绘制</el-button>
</el-button-group>
</div>
<div class="mapLayerSwitcher" flex>
<div class="item" :class="{current:mapType=='vector'}" @click="mapType='vector'"/>
<div class="item satellite" :class="{current:mapType=='satellite'}" @click="mapType='satellite'"/>
</div>
</div>
</ai-dialog>
</section>
</template>
<script>
import AMapLoader from "@amap/amap-jsapi-loader";
import {mapState} from "vuex";
export default {
name: "mapPlotting",
model: {
prop: "value",
event: "change"
},
props: {
title: {default: "地图标绘"},
value: Array
},
computed: {
...mapState(['user']),
},
watch: {
mapType(v) {
if (v == 'satellite') {
for (const k in this.layers) {
this.layers[k].show()
}
} else {
for (const k in this.layers) {
this.layers[k].hide()
}
}
}
},
data() {
return {
map: null,
polyEditor: null,
placeSearch: null,
searchAddress: "",
overlays: [],
points: [],
dialog: false,
mapType: "vector",
layers: {},
}
},
methods: {
addressChange(val) {
this.placeSearch.search(val);
},
clear() {
this.map.remove(this.overlays);
this.overlays = [];
this.points = []
},
handleAdd() {
if (this.points?.length == 0) {
let {polyEditor} = this
polyEditor.close();
polyEditor.setTarget();
polyEditor.open();
} else this.$message.error("请先清除已标绘图形!")
},
initMap() {
setTimeout(() => AMapLoader.load({
key: "b553334ba34f7ac3cd09df9bc8b539dc", // 申请好的Web端开发者Key首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: ["AMap.PlaceSearch", "AMap.PolygonEditor"], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
AMapUI: {
// 是否加载 AMapUI缺省不加载
version: "1.1", // AMapUI 缺省 1.1
plugins: [], // 需要加载的 AMapUI ui插件
},
}).then((AMap) => {
this.map = new AMap.Map("container", {
resizeEnable: true,
});
/* 添加卫星图层*/
this.layers.roadNet = new AMap.TileLayer.RoadNet({zIndex: 11})
this.layers.satellite = new AMap.TileLayer.Satellite({zIndex: 10})
this.map.addLayer(this.layers.roadNet)
this.map.addLayer(this.layers.satellite)
this.layers.roadNet.hide()
this.layers.satellite.hide()
/*end*/
this.placeSearch = new AMap.PlaceSearch({
pageSize: 5, // 单页显示结果条数
pageIndex: 1, // 页码
city: this.user.info.areaId?.substring(0, 6), // 兴趣点城市
citylimit: true, //是否强制限制在设置的城市内搜索
map: this.map, // 展现结果的地图实例
panel: "panel", // 结果列表将在此容器中进行展示。
autoFitView: true, // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
});
this.polyEditor = new AMap.PolygonEditor(this.map).on('add', ({target}) => {
this.polyEditor.addAdsorbPolygons(target)
target.on("dblclick", () => {
this.polyEditor.setTarget(target);
this.polyEditor.open()
})
})
this.polyEditor.on('end', ({target}) => {
if (target) {
this.overlays.push(target);
this.points = target.getPath().map(e => ({lat: e.getLat(), lng: e.getLng()}))
}
});
if (this.value?.length > 0) {
let path = this.value.map(e => [e.lng, e.lat]);
let polygon = new AMap.Polygon({
path,
strokeColor: "#FF33FF",
strokeWeight: 6,
strokeOpacity: 0.2,
fillOpacity: 0.4,
fillColor: "#1791fc",
})
this.map.add([polygon]);
this.map.setFitView();
this.polyEditor.addAdsorbPolygons(polygon)
polygon.on('dblclick', () => {
this.polyEditor.setTarget(polygon);
this.polyEditor.open()
});
this.polyEditor.setTarget(polygon);
this.polyEditor.open()
} else {
this.map.setCity(this.user.info.areaId?.substring(0, 6))
this.map.setZoom(14, false, 600)
}
}), 500)
}
}
}
</script>
<style lang="scss" scoped>
.mapPlotting {
display: inline-block;
text-align: left;
.clicker {
display: inline-block;
}
.mapPanel {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
.container {
width: inherit;
}
#panel {
position: absolute;
height: 400px;
right: 30px;
top: 20px;
width: 280px;
overflow: hidden;
z-index: 10000;
}
.tipinput {
position: absolute;
width: 300px;
height: 38px;
left: 20px;
top: 20px;
z-index: 10000;
}
.operationBtns {
position: absolute;
left: 20px;
bottom: 20px;
z-index: 10000;
}
.mapLayerSwitcher {
position: absolute;
z-index: 202304061607;
bottom: 20px;
right: 12px;
background-color: #fff;
padding: 5px;
width: fit-content;
height: 56px;
box-sizing: content-box;
overflow: hidden;
transition: width 2s ease;
gap: 10px;
&:hover {
.item {
display: block;
}
}
.item {
position: relative;
width: 80px;
height: 56px;
border: 1px dashed #ddd;
cursor: pointer;
flex-shrink: 0;
background-image: url("https://cdn.cunwuyun.cn/map/defaultMap.png");
box-sizing: border-box;
color: #fff;
background-size: 100%;
display: none;
&.current {
border: 1px solid #366FFF;
display: block !important;
&:before {
background-color: #366FFF;
}
}
&:hover {
border-color: #333;
}
&:before {
font-size: 12px;
line-height: 18px;
padding: 0 3px;
position: absolute;
bottom: 0;
right: 0;
content: "地图";
user-select: none;
}
&.satellite {
background-image: url("https://cdn.cunwuyun.cn/map/satelliteMap.png");
&:before {
content: "卫星"
}
}
}
}
}
:deep(.fullscreenMap ) {
.el-dialog {
display: flex;
flex-direction: column;
.el-dialog__body {
padding: 0;
flex: 1;
min-height: 0;
.ai-dialog__content {
max-height: unset !important;
padding-bottom: 0;
height: 100%;
.ai-dialog__content--wrapper {
padding-right: 0 !important;
}
}
}
}
}
:deep( .amap-copyright ) {
display: none !important;
}
:deep( .amap-logo ) {
display: none !important;
}
}
</style>