打卡添加电子围栏

src同级的index.html引入高德地图插件

<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=c57a0390d2e37350f319d6d170fac8f4&plugin=AMap.GeoJSON,AMap.Autocomplete,AMap.PlaceSearch,AMap.MouseTool,AMap.CircleEditor,AMap.ToolBar,AMap.Scale" ></script>
页面
页面内容
css地图内样式
初始化加载地图
位置搜索框
 1 startDraw(type) {
 2     let that = this;
 3     this.clearDraw();
 4     if(type == 'marker'){//绘制点
 5       this.mapInitialization.clearMap();
 6       if(entityMarker) this.mapInitialization.remove(entityMarker);
 7       mouseToolMarker = new AMap.MouseTool(this.mapInitialization);
 8       mouseToolMarker.marker({
 9         zoom: 16,
10         icon: 'https://files.xatasoft.com/Uploads/zhonghuan/icon/point12.png',
11         offset: new AMap.Pixel(-17, -56)
12       });
13       mouseToolMarker.on('draw',function(e){
14         entityMarker = e.obj;
15         if(mouseToolMarker) mouseToolMarker.close(false);
16       })
17       this.drawCircleDisabled = true//绘制圆时显示(项目中的逻辑,不用管)
18       this.circleShow = false//编辑时半径不显示(项目中的逻辑,不用管)
19     }
20     if(type == 'polygon'){//绘制多边形
21       if(mouseToolMarker) mouseToolMarker.close(false);
22       if(mouseTool) mouseTool.close(true);
23       mouseTool = new AMap.MouseTool(this.mapInitialization);
24       mouseTool.polygon({
25         strokeColor: "#FF33FF",
26         strokeOpacity: 1,
27         strokeWeight: 6,
28         strokeOpacity: 0.2,
29         fillColor: '#1791fc',
30         fillOpacity: 0.4,
31         strokeStyle: "dashed",
32       });
33       mouseTool.on('draw',function(e){
34         entity = e.obj;
35         if(mouseTool) mouseTool.close(false);
36       })
37     }
38   },
39 
40 //判断是否存在, 如果存在就关闭和清除
41 clearDraw(){
42     if(mouseTool) mouseTool.close(true);
43     if(entity) this.mapInitialization.remove(entity);
44   },
点击定位和绘制多边形
绘制圆形
 1  clearDraw(){
 2     if(mouseTool) mouseTool.close(true);
 3     if(entity) this.mapInitialization.remove(entity);
 4   },
 5   clearMarker(){
 6     if(entityMarker) this.mapInitialization.remove(entityMarker);
 7     if(mouseToolMarker) mouseToolMarker.close(true);
 8     entityMarker = undefined
 9     mouseToolMarker = undefined
10     this.drawCircleDisabled = true//绘制圆显示
11     this.circleShow = false//编辑半径不显示
12   },
清除所有绘制
 1 let myLngLat = new AMap.LngLat(this.location.lng,this.location.lat)
 2           let result = this.currentFenceInfo.some(item =>{
 3             let polygonOrCircle;
 4             if(item.radius){//圆形
 5               polygonOrCircle = new AMap.Circle({
 6                 center: new AMap.LngLat(item.setting[0].lng,item.setting[0].lat),
 7                 radius: item.radius
 8               });
 9             }else{//多边形
10               polygonOrCircle = new AMap.Polygon({
11                 path:item.setting
12               });
13             }
14             console.log("判断点是否在多边形和圆范围内",polygonOrCircle.contains(myLngLat)) 
判断点面关系

 

 整体页面代码内容

  1 <template lang='pug'>
  2   .boxCommon
  3     .header
  4       xt-search(:searchList="searchList" @submit="searchHandle" ref="formName" :hasResetBtn="true")
  5       .btn-group
  6         el-button(type="primary" size="small" @click="handleAddFun" icon="iconfont icon-icon_xinzeng") 新增
  7     .boxTable.boxTableStriped
  8       el-table(:data="tableData" stripe border v-loading="tableLoading" height="calc(100vh - 240px)")
  9         el-table-column(prop="serial_number" label="序号" align="center" width="80")
 10         el-table-column(prop="title" label="标题" align="center")
 11         el-table-column(prop="type" label="类型" align="center")
 12           template(slot-scope="scope")
 13             span {{ scope.row.type == '1'?'多边形':'圆形'}}
 14         el-table-column(prop="remark" label="备注" align="center")
 15         el-table-column(prop="user_name" label="创建人" align="center")
 16         el-table-column(prop="create_time" label="创建时间" align="center")
 17         el-table-column(label="操作" align="center" width="180")
 18           template(slot-scope="scope")
 19             .operateBtn
 20               i.iconfont.icon-bianji(@click="handleFun(1, scope.row)" title="编辑")
 21               i.iconfont.icon-shanchu(@click="handleFun(2,scope.row)" title="删除")
 22               i.iconfont.icon-chakan(@click="handleFun(3, scope.row)" title="查看")
 23     xt-pagination(:total="total" @change="changePage" :page="pageForm.page" :page-size="pageForm.page_size")
 24     xt-dialog.patrolDialog(
 25       ref="mapFenceDialog"
 26       :title="title"
 27       top="5vh"
 28       width="65%"
 29       :showfooter="title != '详情' ? true : false"
 30       @confirm="$refs.xtFormRef.submit()"
 31       :autoclose="false"
 32       @close="mapFenceClose"
 33     )
 34       xt-form(:formList="formList" ref="xtFormRef" :type="title" :label-width="120" @submit="handleSubmit")
 35       .mapBox
 36         #mapContainer(style="width: 100%;height: 100%;")
 37         .mapSearchWrap(v-show="title != '详情'")
 38           .searchBox
 39             .searchInput
 40               el-input(v-model="keyword" placeholder="请输入关键字:" size="mini" @keyup.enter.native="searchMap" style="width:80px")
 41               .searchList(v-show="showSearch")
 42                 ul(v-show="searchMapList.length")
 43                   li(v-for="item in searchMapList" :key="item.id" @click="checkPoint(item)") {{ item.name}}
 44                 .emptyBox(v-show="!searchMapList.length") 暂无数据
 45             el-button(type="primary" plain @click="searchMap" size="mini") 搜索
 46           .drawBtn(v-if='polygonShow')
 47             el-tooltip(effect="dark" content="定位" placement="top")
 48               el-button.iconfont.icon-techreport-(type="primary" plain @click="startDraw('marker')" size="mini")
 49             el-tooltip(effect="dark" content="开始绘制多边形" placement="top")
 50               el-button.iconfont.icon-duobianxing(type="primary" plain @click="startDraw('polygon')" size="mini")
 51           .drawBtn(v-else)
 52             el-tooltip(effect="dark" content="定位" placement="top")
 53               el-button.iconfont.icon-techreport-(type="primary" @click="startDraw('marker')" plain size="mini")
 54             el-tooltip(effect="dark" content="开始绘制圆形" placement="top")
 55               el-button.iconfont.icon-yuanquan(type="primary" plain @click="startDrawCircle('add')" size="mini" v-if="drawCircleDisabled")
 56             span(v-if="circleShow" style="margin-left:10px")
 57               el-tooltip(effect="dark" content="设置半径" placement="top")
 58                 el-button.iconfont.icon-lujing759(type="primary" plain @click="circleEditorOpen" size="mini")
 59               el-tooltip(effect="dark" content="完成设置" placement="top")
 60                 el-button.iconfont.icon-wanchenggouxuanxuanzhong(type="primary" plain @click="circleEditorClose" size="mini")
 61       .helpDescription(v-show="title != '详情'")
 62         .tip
 63           span(style="color:#000;font-weight:bold;width:80px;") 帮助说明:
 64           span(style="color:#666;margin-left:8px;") 1.类型为多边形时,点击绘图按钮, 单击地图开始绘制, 右键结束绘制。
 65           div(style="color:#666;margin-left:80px;") 2.类型为圆形时,点击定位按钮在地图上单击定位后, 点击绘制圆形按钮,默认半径300米的圆形绘制完成。
 66           div(style="color:#666;margin-left:90px;") 点击设置半径按钮, 鼠标在地图圆形边缘半径圆点处拖动可进行圆形大小设置。
 67 </template>
 68 
 69 <script>
 70 import { mapGetters } from 'vuex'
 71 let circleEditor, mouseTool, entity ,mouseToolMarker, entityMarker;
 72 export default {
 73 name: '',
 74 data() {
 75   let vm = this
 76   return {
 77     title: '新增',
 78     tableData: [],
 79     tableLoading: false,
 80     total: 0, //页码变量
 81     pageForm: { //页码
 82       page: 1,
 83       page_size: 20
 84     },
 85     searchForm: {},
 86     searchList: [
 87       {
 88         type: 'xt-form',
 89         children: [
 90           {
 91             title: '标题:',
 92             type: 'input',
 93             key: 'title',
 94             props: {
 95               placeholder: '请输入标题'
 96             }
 97           },
 98         ]
 99       }
100     ],
101     enclosureDetails:{},
102     rowObj:{},
103     formList:[
104       {
105         renderContent (h, item, form) {
106           return (<div style="font-size: 18px;color: #000;font-weight: bold;margin-left: -120px;">基本信息</div>)
107         }
108       },
109       {
110         title: '标题:',
111         type: 'input',
112         key: 'title',
113         defaultValue:"电子围栏设置",
114         rule: {required: true, message: '请输入标题', trigger: 'change'},
115         props: {
116           'placeholder': '请输入标题'
117         }
118       },
119       {
120         title: '类型:',
121         type: 'radio-group',
122         key: 'type',
123         defaultValue: 1,
124         options: [{
125             value: 1,
126             text:'多边形'
127         },{
128             value: 2,
129             text:'圆形'
130         }],
131         onInput(value, item, form) {
132           if (value == 1) {
133             vm.drawPolygon()
134           }else {
135             vm.drawCircle()
136           }
137         }
138       },
139       {
140         title: '半径:',
141         type: 'input',
142         key: 'radius',
143         isShow:false
144       },
145       {
146         title: '备注:',
147         type: 'input',
148         key: 'remark',
149         disabled: false,
150         props: {
151           placeholder: '请输入备注',
152           type: 'textarea',
153           rows: 3
154         }
155       },
156       {
157         renderContent (h, item, form) {
158           return (<div class="lastItem">围栏设置</div>)
159         }
160       },
161     ],
162     setting:null,//围栏设置
163     radius:"",//半径默认300
164     polygonShow:true,//多边形工具
165     mapInitialization:'',//地图
166     keyword: '', // 地图搜索关键字
167     searchMapList: [],
168     showSearch: false,
169     drawCircleDisabled:true,//绘制圆形
170     circleShow:false,//圆形编辑工具
171   }
172 },
173 computed: {},
174 watch: {},
175 methods: {
176   initMap(lon_lat){
177     this.mapInitialization = new AMap.Map("mapContainer", {
178       zoom: lon_lat ? 16 : 11,
179       resizeEnable: true,
180     });
181     var scale = new AMap.Scale()
182     this.mapInitialization.addControl(scale);
183     if(lon_lat){
184       let location = JSON.parse(lon_lat)
185       this.mapInitialization.setCenter([location.lng, location.lat])
186     }
187     this.searchMap(false)//搜索
188   },
189   async getDetails(data){
190     let res = await this.$api.electricFence_detail(data)
191     this.enclosureDetails = res.result
192     this.enclosureDetails.radius = res.result.radius + '(m)'
193     this.handleReset(this.enclosureDetails)
194     if(this.enclosureDetails.type == 2){
195       this.formList[3].radius = this.enclosureDetails.radius
196       this.formList[3].isShow = true
197     }else{
198       this.formList[3].isShow = false
199     }
200   },
201   checkPoint(item){ // 选中搜索项
202     this.showSearch = false
203     let map = this.mapInitialization
204     map.setCenter([item.location.lng, item.location.lat]); // 定位中心点
205     map.setZoom(16); // 设置缩放
206     //搜索完成后清空关键字
207     this.keyword = ''
208     this.searchMapList = []
209   },
210   handleAddFun(){
211     this.title = '新增'
212     this.$refs.mapFenceDialog.open()
213     this.formList[3].isShow = false
214     this.$nextTick(() => {
215       this.initMap()
216       this.drawPolygon()//默认绘制多边形
217       if(entity) entity = undefined
218     })
219   },
220   handleFun(index,row){
221     if(index == 1){
222       this.title = '编辑'
223       this.$refs.mapFenceDialog.open()
224       this.formList[3].isShow = false
225       this.rowObj = row
226       this.handleReset(this.rowObj)
227     }else if(index == 2){
228       this.handleDelete(row)
229     }else{
230       this.title = '详情'
231       this.$refs.mapFenceDialog.open()
232       this.getDetails({id:row.id})
233     }
234   },
235   handleReset(rowData){
236     if(rowData.type == 1){//多边形
237       this.polygonShow = true;
238       this.$nextTick(() => {
239         this.$refs.xtFormRef.setForm(rowData)
240         this.initMap()
241         if(rowData.setting && rowData.setting.length>0){
242           let path = [];
243           rowData.setting.forEach(element => {
244             let a = new AMap.LngLat(element.lng,element.lat);
245             path.push(a);
246           });
247           entity = new AMap.Polygon({
248               path: path,
249               strokeColor: "#FF33FF",
250               strokeOpacity: 1,
251               strokeWeight: 6,
252               strokeOpacity: 0.2,
253               fillColor: '#1791fc',
254               fillOpacity: 0.4,
255               strokeStyle: "dashed",
256               zIndex: 50,
257           });
258 
259           this.mapInitialization.add(entity);
260           this.mapInitialization.setFitView([ entity ])
261         }
262       })
263     }else{//圆形
264       if(rowData.setting && rowData.setting.length > 0){
265         let lng_lat = [rowData.setting[0].lng,rowData.setting[0].lat]
266         this.polygonShow = false;
267         this.$nextTick(() => {
268           this.$refs.xtFormRef.setForm(rowData)
269           this.initMap()
270           this.mapInitialization.clearMap();
271           var marker = new AMap.Marker({
272             position: lng_lat,
273             icon: 'https://files.xatasoft.com/Uploads/zhonghuan/icon/point12.png',
274             offset: new AMap.Pixel(-17, -56)
275           });
276           entityMarker = marker
277           this.mapInitialization.add(marker);
278           this.startDrawCircle('edit',rowData.radius,lng_lat)
279         })
280       }
281     }
282   },
283   searchHandle(row) {
284     this.searchForm = { ...row }
285     this.getData()
286   },
287   changePage (row) {
288     this.pageForm = { ...row }
289     this.getData()
290   },
291   async getData() {
292     this.tableLoading = true
293     let data = {
294       ...this.searchForm,
295       ...this.pageForm
296     }
297     let res = await this.$api.electricFence_index(data)
298     this.tableData = res.result.data
299     this.total = res.result.total
300     this.tableLoading = false
301   },
302   handleDelete(row) {
303     this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
304       confirmButtonText: '确定',
305       cancelButtonText: '取消',
306       type: 'warning'
307     }).then(async () => {
308       await this.$api.electricFence_remove({id: row.id})
309       this.$success('删除成功')
310       this.pageForm.page = 1
311       this.getData()
312     })
313   },
314   //切换至多边形
315   drawPolygon(){
316     this.clearDraw();
317     this.clearMarker()
318     this.polygonShow = true;
319     this.mapInitialization.clearMap();
320   },
321   //绘制多边形和定位
322   startDraw(type) {
323     let that = this;
324     this.clearDraw();
325     if(type == 'marker'){
326       this.mapInitialization.clearMap();
327       if(entityMarker) this.mapInitialization.remove(entityMarker);
328       mouseToolMarker = new AMap.MouseTool(this.mapInitialization);
329       mouseToolMarker.marker({
330         zoom: 16,
331         icon: 'https://files.xatasoft.com/Uploads/zhonghuan/icon/point12.png',
332         offset: new AMap.Pixel(-17, -56)
333       });
334       mouseToolMarker.on('draw',function(e){
335         entityMarker = e.obj;
336         if(mouseToolMarker) mouseToolMarker.close(false);
337       })
338       this.drawCircleDisabled = true//绘制圆显示
339       this.circleShow = false//编辑半径不显示
340     }
341     if(type == 'polygon'){
342       if(mouseToolMarker) mouseToolMarker.close(false);
343       if(mouseTool) mouseTool.close(true);
344       mouseTool = new AMap.MouseTool(this.mapInitialization);
345       mouseTool.polygon({
346         strokeColor: "#FF33FF",
347         strokeOpacity: 1,
348         strokeWeight: 6,
349         strokeOpacity: 0.2,
350         fillColor: '#1791fc',
351         fillOpacity: 0.4,
352         strokeStyle: "dashed",
353       });
354       mouseTool.on('draw',function(e){
355         entity = e.obj;
356         if(mouseTool) mouseTool.close(false);
357       })
358     }
359   },
360   //切换至圆形
361   drawCircle(){
362     this.clearDraw()
363     this.clearMarker()
364     this.polygonShow = false;
365   },
366   //绘制圆形
367   startDrawCircle(type,radius,lng_lat){
368     let that = this;
369     this.clearDraw();
370     if(type == 'add'){//新增
371       if(!entityMarker){
372         this.circleShow = false;
373         that.$message({message: '请先选择位置进行定位',type: 'warning'});
374       }else{
375         this.circleShow = true;
376         entity = new AMap.Circle({
377           center:[entityMarker.w.position.lng,entityMarker.w.position.lat],
378           radius:300, //半径
379           borderWeight: 3,
380           strokeColor: "#FF33FF",
381           strokeOpacity: 1,
382           strokeWeight: 6,
383           strokeOpacity: 0.2,
384           fillOpacity: 0.4,
385           strokeStyle: 'dashed',
386           strokeDasharray: [10, 10],
387           fillColor: '#1791fc',
388           zIndex: 50,
389         })
390         this.mapInitialization.add(entity);
391         this.mapInitialization.setFitView([ entity ])
392 
393         circleEditor = new AMap.CircleEditor(this.mapInitialization, entity)
394         circleEditor.on('move', function(event) {
395           entity = event.target;
396         })
397       }
398     }else{//编辑回显
399       this.circleShow = true;//编辑半径显示
400       this.drawCircleDisabled = false//绘制圆不显示
401       entity = new AMap.Circle({
402         center:lng_lat,
403         radius:radius, //半径
404         borderWeight: 3,
405         strokeColor: "#FF33FF",
406         strokeOpacity: 1,
407         strokeWeight: 6,
408         strokeOpacity: 0.2,
409         fillOpacity: 0.4,
410         strokeStyle: 'dashed',
411         strokeDasharray: [10, 10],
412         fillColor: '#1791fc',
413         zIndex: 50,
414       })
415       this.mapInitialization.add(entity);
416       this.mapInitialization.setFitView([ entity ])
417 
418       circleEditor = new AMap.CircleEditor(this.mapInitialization, entity)
419       circleEditor.on('move', function(event) {
420         entity = event.target;
421       })
422     }
423 
424   },
425   clearDraw(){
426     if(mouseTool) mouseTool.close(true);
427     if(entity) this.mapInitialization.remove(entity);
428   },
429   clearMarker(){
430     if(entityMarker) this.mapInitialization.remove(entityMarker);
431     if(mouseToolMarker) mouseToolMarker.close(true);
432     entityMarker = undefined
433     mouseToolMarker = undefined
434     this.drawCircleDisabled = true//绘制圆显示
435     this.circleShow = false//编辑半径不显示
436   },
437   circleEditorOpen(){
438     circleEditor.open()
439     this.drawCircleDisabled = false
440   },
441   circleEditorClose(){
442     circleEditor.close()
443     this.circleShow = false;
444     this.drawCircleDisabled = true
445   },
446   searchMap(bool=true){ // 地图搜索关键字
447     if(!this.keyword && bool) {
448       this.$message.warning('请先输入关键字!')
449       return
450     }
451     let _this = this
452     let keyword = this.keyword
453     AMap.plugin('AMap.PlaceSearch', function(){
454       var autoOptions = {
455         city: '浙江省',
456         citylimit: true,  //是否强制限制在设置的城市内搜索
457         pageSize: 20,
458       }
459       var placeSearch = new AMap.PlaceSearch(autoOptions);
460       placeSearch.search(keyword, function(status, result) { // 搜索成功时,result即是对应的匹配数据
461         if(status == 'complete'){ // 搜索成功时
462           let list = result.poiList.pois
463           _this.searchMapList = list
464           _this.showSearch = true // 显示搜索列表
465         }
466       })
467     })
468   },
469   async handleSubmit(form, valid) {
470     if (valid) {
471       if(!entity){
472         this.$message({message: '电子围栏未设置',type: 'warning'});
473       }else{
474         let result;
475         if(form.type === 1) {
476           this.radius = ""
477           this.setting = entity.getPath()
478         } else {
479           result = entity.getCenter()
480           this.radius = entity.getRadius()
481           this.setting = [{lat:result.lat,lng:result.lng}]
482         }
483         let data = {
484           title:form.title,    //标题
485           type:form.type,    //类型 1-多边形 2-圆
486           radius:this.radius,    //半径 (m)
487           remark:form.remark,    //备注
488           setting:this.setting,    //围栏设置
489         }
490         if (this.title == '编辑') {
491           data.id = this.rowObj.id
492         }
493         await this.$api.electricFence_createOrEdit(data)
494         this.$success(`${this.title == '新增' ? '新增' : '编辑'}成功!`)
495         this.$refs.mapFenceDialog.handleClose()
496         this.getData()
497 
498       }
499     }
500   },
501   mapFenceClose(){
502     this.$refs.xtFormRef.reset()
503     this.drawPolygon()
504   }
505 },
506 created() {},
507 mounted() {
508   this.getData()
509 },
510 }
511 </script>
512 <style scoped lang="scss">
513 .boxCommon {
514   .header {
515     display: flex;
516     justify-content: space-between;
517     width: 100%;
518   }
519 }
520 .patrolDialog {
521   /deep/ .el-form-item__content {
522     color: #666 !important;
523     margin-left: 120px !important;
524   }
525   /deep/ .el-input {
526     width: 100% !important;
527   }
528   /deep/ .el-textarea {
529     width: 100% !important;
530   }
531    /deep/ .el-select {
532     width: 100% !important;
533   }
534   /deep/ .el-form-item .lastItem {
535     margin-bottom: 0px;
536     font-size: 18px;color: #000;font-weight: bold;margin-left: -120px;
537   }
538   /deep/ .el-form-item--small.el-form-item{
539      margin-bottom: 8px;
540   }
541 }
542 .mapBox{
543   width: calc(100% - 120px);
544   height: 420px;
545   margin-left:120px;
546   position: relative;
547   .mapSearchWrap{
548     position: absolute; left: 0px; top:0px; z-index: 99;
549     padding: 8px;
550     background-color: rgba(206, 240, 248, 0.6);
551     display: flex;
552     justify-content: space-between;
553     align-items: flex-end;
554     .searchBox{
555       width: 240px; display: flex;
556       /deep/ .el-button{
557         margin: auto 10px;
558       }
559       .searchInput{
560         position: relative;
561         flex: 1; min-width: 0;
562         .searchList{
563           position: absolute; max-height: 200px; width: 100%; overflow-y: auto;
564           background-color: #fff;
565           .emptyBox{
566             line-height: 200px; text-align: center; color: #ccc;
567           }
568           ul{
569             padding: 10px 0;
570             li{
571               line-height: 20px; padding: 5px 15px;
572               cursor: pointer;
573               &:hover{
574                 background-color: #A0C5E8;
575               }
576             }
577           }
578         }
579       }
580     }
581   }
582   /deep/.amap-logo{
583     display: none !important;
584   }
585   /deep/ .amap-copyright{
586     display: none !important;
587   }
588   /deep/.amap-scalecontrol{
589     bottom: 0 !important;
590   }
591 }
592 .helpDescription{
593   width: calc(100% - 120px);
594   height: 80px;
595   margin-top: 10px;
596   line-height: 20px;
597   margin-left:120px;
598 }
599 
600 </style>
页面

 

 
 
 
 
posted @ 2022-08-17 11:23  爱听书的程序猿  阅读(122)  评论(0编辑  收藏  举报