当前位置:   article > 正文

uniapp微信小程序地图实现绘制polygon(保姆级教程 全网最全!!!)_小程序地图 定点绘制

小程序地图 定点绘制

用户需求:需要在填写表单信息时,在地图上标绘自己房屋的位置信息。

这个问题处理了很久,在网上也没有找到全面的相关案例,所以我将我的思路分享给大家,希望可以解决大家遇到的问题。如果大家有更好的思路,欢迎评论区留言,大家一起学习,共同进步!

实现最终界面:

由于我上一次写过一篇关于在uniapp微信小程序上如何加载控件的文章,在这里我不在赘述,大家可以先看这一篇:uniapp微信小程序实现地图展示控件

关于绘制面的知识点,我将分为以下几点为大家讲解:

目录

一、创建context 对象

二、开始绘制面图层

1.使用地图的tap点击事件,获取当前点击位置的坐标点

2.使用polyline将两个点连接成线

3.获取点击地图的双击事件,双击后结束标绘


一、创建context 对象

在页面加载的时候,创建map对象

  1. onLoad(data) {
  2. this.initMap();
  3. },
  4. methods:{
  5. initMap(){
  6. this.mapCtx = wx.createMapContext('mymap');
  7. },
  8. }

设置加载地图的中心点和缩放等级

  1. <map id="mymap" class="myMap_map" @tap="mapAction" :longitude="mapData.longitude" :latitude="mapData.latitude" :scale="mapData.scale">
  2. <cover-view class="myMap_map__cover-view">
  3. <cover-view class="myMap_map__cover-view_mapControls">
  4. <!-- 显示绘制的控件-->
  5. <cover-view class="myMap_map__cover-view_mapControls_drawControl" @click="drawPolygon">
  6. <cover-image class="myMap_map__cover-view_mapControls_drawControl_drawicon" :src="mapData.drawIconPath"></cover-image>
  7. <cover-view class="myMap_map__cover-view_mapControls_drawControl_drawText">标绘位置</cover-view>
  8. </cover-view>
  9. </cover-view>
  10. </cover-view>
  11. </map>

在data中声明变量

  1. // 地图的相关操作
  2. mapData:{
  3. //设置地图中心点 lon经度y、lat纬度x
  4. longitude:'119.965238',
  5. latitude:'35.916325',
  6. scale:18,
  7. polygon:[],
  8. marker:[],
  9. },

二、开始绘制面图层

绘制面数据需要先明白,polygon是由多个点绘制而成的。也就是说我们需要先获取在地图上点击的point,将这个数据存储起来。

我的实现思路是点击标绘位置之后开始在地图上绘制,点击地图获取在地图上的定位点,存储这些定位点,最后结束的时候,需要双击地图。然后将point数据组赋值给polygon,生成一个polygon数据。在这里需要注意:用户点击两个点的时候,需要将这两个点进行连接,成poline,所以地图上需要加载point、poline和polygon。

1.使用地图的tap点击事件,获取当前点击位置的坐标点

这里我用了一个变量做判断,点击标绘位置的时候,说明开始标绘,这个时候我再点击地图,获取定位点的坐标,然后push到markers数组中。

HTML部分:

  1. <!-- 展示地图信息 标绘位置情况 -->
  2. <view class="myMap">
  3. <u-divider text="地图展示"></u-divider>
  4. <map id="mymap" class="myMap_map" @tap="mapAction" :longitude="mapData.longitude" :latitude="mapData.latitude" :scale="mapData.scale" :polygons="mapData.polygons"
  5. :markers="mapData.markers">
  6. <cover-view class="myMap_map__cover-view">
  7. <cover-view class="myMap_map__cover-view_mapControls">
  8. <!-- 显示绘制的控件-->
  9. <cover-view class="myMap_map__cover-view_mapControls_drawControl" :class="item.check ? 'myMap_map__cover-view_mapControls_checkdrawControl' : '' " @click="mapEdit(item)" v-for="(item,index) in mapControls" :key="index">
  10. <cover-image class="myMap_map__cover-view_mapControls_drawControl_drawicon" :src="item.icon"></cover-image>
  11. <cover-view class="myMap_map__cover-view_mapControls_drawControl_drawText">{{ item.label }}</cover-view>
  12. </cover-view>
  13. </cover-view>
  14. </cover-view>
  15. </map>
  16. </view>

data变量:

  1. data(){
  2. return{
  3. // 地图的相关操作
  4. mapData:{
  5. //设置地图中心点 lon经度y、lat纬度x
  6. longitude:'119.965238',
  7. latitude:'35.916325',
  8. infowidth:6,
  9. infoheight:6,
  10. scale:18,
  11. markers:[],
  12. polyline:[],
  13. polygons:[],
  14. },
  15. //地图控件
  16. mapControls:[
  17. // 标绘位置
  18. {
  19. id:'drawPolygon',
  20. check:false,
  21. icon:'/static/mapview/drawIcon.png',
  22. method:'drawPolygons',
  23. label:'标绘位置'
  24. },
  25. //清除
  26. {
  27. id:'cleanPolygon',
  28. check:false,
  29. icon:'/static/mapview/cleanPolygon.png',
  30. method:'cleanPolygons',
  31. label:'清除'
  32. }
  33. ],
  34. }
  35. }

methods方法

  1. mapEdit(item){
  2. item.check = !item.check;
  3. switch(item.id){
  4. // 绘制面
  5. case 'drawPolygon':
  6. this.drawPolygons();
  7. break;
  8. //清除
  9. case 'cleanPolygon':
  10. this.cleanPolygons();
  11. break;
  12. default:
  13. break;
  14. }
  15. },
  16. //绘制面
  17. drawPolygons(){
  18. uni.$u.toast('点击地图开始绘制!');
  19. },
  20. cleanPolygons(){
  21. uni.$u.toast('清除')
  22. },
  23. //点击地图事件
  24. mapAction(e){
  25. //判断是否已经点击标绘位置,如果点击标绘位置后开始定位
  26. if(this.mapControls[0].check){
  27. this.mapData.markers.push({
  28. id:this.mapData.markers.length+1,
  29. longitude:e.detail.longitude,
  30. latitude:e.detail.latitude,
  31. iconPath:'/static/mapview/square.png',
  32. height:this.mapData.infoheight,
  33. width:this.mapData.infowidth
  34. })
  35. }
  36. },

写到此处,地图上已经实现可以标记点位信息

下边我们需要实现当用户点击两个点的时候,让这两个点连成线。

2.使用polyline将两个点连接成线

需要判断当marker数组中的长度大于等于2的时候,才开始生成线段

  1. //点击地图事件
  2. mapAction(e){
  3. //判断是否已经点击标绘位置,如果点击标绘位置后开始定位
  4. if(this.mapControls[0].check){
  5. this.mapData.markers.push({
  6. id:this.mapData.markers.length+1,
  7. longitude:e.detail.longitude,
  8. latitude:e.detail.latitude,
  9. iconPath:'/static/mapview/square.png',
  10. height:this.mapData.infoheight,
  11. width:this.mapData.infowidth
  12. })
  13. if(this.mapData.markers.length >=2){
  14. this.pointsData = [];
  15. for(let i=0;i<this.mapData.markers.length;i++){
  16. this.pointsData.push({
  17. latitude:this.mapData.markers[i].latitude,
  18. longitude:this.mapData.markers[i].longitude
  19. })
  20. }
  21. this.mapData.polyline.push({
  22. points:this.pointsData,
  23. color:'#00AF99',
  24. width:3,
  25. })
  26. }
  27. console.log(this.mapData.polyline)
  28. }
  29. },

此时,polyline数组中的存储结构是这样的

每两个点组成一条线段,界面中一共是三条线段。

3.获取点击地图的双击事件,双击后结束标绘

在这里我们需要注意,两个点形成一条线,而三条线段才能形成一个polygon,所以我们需要先判断polyline的长度必须要大于等于3,才能结束标绘。

由于我并没有再官网上找到地图的双击事件,所以在这里我模拟了地图的双击事件。通过两次单击事件的时间差来判断。

首先,需要在data中定义两个变量存储点击的时间

  1. //单击事件时间差
  2. taptimestame:{
  3. firsttime:null,
  4. lasttime:null
  5. },

然后在单击地图的方法中进行时间的存储与判断

  1. //点击地图事件
  2. mapAction(e){
  3. if(this.taptimestame.firsttime == null){
  4. //第一次定位,给firsttime赋值
  5. this.taptimestame.firsttime = e.timeStamp;
  6. }else if(this.taptimestame.lasttime == null){
  7. //第二次定位,给lasttime赋值
  8. this.taptimestame.lasttime = e.timeStamp;
  9. }else{
  10. this.taptimestame.firsttime = this.taptimestame.lasttime;
  11. this.taptimestame.lasttime = e.timeStamp;
  12. }
  13. //判断是否已经点击标绘位置,如果点击标绘位置后开始定位
  14. if(this.mapControls[0].check){
  15. this.mapData.markers.push({
  16. id:this.mapData.markers.length+1,
  17. longitude:e.detail.longitude,
  18. latitude:e.detail.latitude,
  19. iconPath:'/static/mapview/square.png',
  20. height:this.mapData.infoheight,
  21. width:this.mapData.infowidth
  22. })
  23. if(this.mapData.markers.length >=2){
  24. this.pointsData = [];
  25. for(let i=0;i<this.mapData.markers.length;i++){
  26. this.pointsData.push({
  27. latitude:this.mapData.markers[i].latitude,
  28. longitude:this.mapData.markers[i].longitude
  29. })
  30. }
  31. this.mapData.polyline.push({
  32. points:this.pointsData,
  33. color:'#00AF99',
  34. width:3,
  35. })
  36. if(this.mapData.polyline.length >=3){
  37. //判断两次单击事件的时间差
  38. if(this.taptimestame.lasttime - this.taptimestame.firsttime < 500){
  39. uni.$u.toast('这是个双击事件')
  40. }
  41. }
  42. }
  43. }
  44. },

目前实现效果:

最后,在双击事件中,新增polygon面图层,如果不需要的话可以将点和线的数据进行清空操作

  1. //点击地图事件
  2. mapAction(e){
  3. if(this.taptimestame.firsttime == null){
  4. //第一次定位,给firsttime赋值
  5. this.taptimestame.firsttime = e.timeStamp;
  6. }else if(this.taptimestame.lasttime == null){
  7. //第二次定位,给lasttime赋值
  8. this.taptimestame.lasttime = e.timeStamp;
  9. }else{
  10. this.taptimestame.firsttime = this.taptimestame.lasttime;
  11. this.taptimestame.lasttime = e.timeStamp;
  12. }
  13. //判断是否已经点击标绘位置,如果点击标绘位置后开始定位
  14. if(this.mapControls[0].check){
  15. this.mapData.markers.push({
  16. id:this.mapData.markers.length+1,
  17. longitude:e.detail.longitude,
  18. latitude:e.detail.latitude,
  19. iconPath:'/static/mapview/square.png',
  20. height:this.mapData.infoheight,
  21. width:this.mapData.infowidth
  22. })
  23. if(this.mapData.markers.length >=2){
  24. this.pointsData = [];
  25. for(let i=0;i<this.mapData.markers.length;i++){
  26. this.pointsData.push({
  27. latitude:this.mapData.markers[i].latitude,
  28. longitude:this.mapData.markers[i].longitude
  29. })
  30. }
  31. this.mapData.polyline.push({
  32. points:this.pointsData,
  33. color:'#00AF99',
  34. width:2,
  35. })
  36. if(this.mapData.polyline.length >=3){
  37. //判断两次单击事件的时间差
  38. if(this.taptimestame.lasttime - this.taptimestame.firsttime < 500){
  39. this.pointsData = [];
  40. //在双击事件中 生成polygon
  41. for(let i=0;i<this.mapData.markers.length;i++){
  42. this.pointsData.push({
  43. latitude:this.mapData.markers[i].latitude,
  44. longitude:this.mapData.markers[i].longitude
  45. })
  46. }
  47. this.mapData.polygons.push({
  48. points:this.pointsData,
  49. strokeWidth:2,
  50. strokeColor:'#00AF99',
  51. fillColor:'#00AF9930'
  52. })
  53. //最后将点、线段的数据清空
  54. this.mapData.markers = [];
  55. this.mapData.polyline = [];
  56. this.mapControls[0].check = false;
  57. }
  58. }
  59. }
  60. }
  61. },

最终实现效果:

最后:这里有个bug哦,最后双击的时候会触发地图等级别缩放。这个地方需要判断以下,如果用户正在标绘位置,可以把这个事件禁用掉。

写到最后,如果大家觉得写的不错,一键三连白,点赞、收藏加关注。大家的点赞就是我不断分享的动力!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/83259
推荐阅读
相关标签
  

闽ICP备14008679号