234 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <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>
 | ||
|     </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']),
 | ||
|   },
 | ||
|   data() {
 | ||
|     return {
 | ||
|       map: null,
 | ||
|       polyEditor: null,
 | ||
|       placeSearch: null,
 | ||
|       searchAddress: "",
 | ||
|       overlays: [],
 | ||
|       points: [],
 | ||
|       dialog: false
 | ||
|     }
 | ||
|   },
 | ||
|   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.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;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   :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>
 |