赞
踩
用户需求:需要在填写表单信息时,在地图上标绘自己房屋的位置信息。
这个问题处理了很久,在网上也没有找到全面的相关案例,所以我将我的思路分享给大家,希望可以解决大家遇到的问题。如果大家有更好的思路,欢迎评论区留言,大家一起学习,共同进步!
实现最终界面:
由于我上一次写过一篇关于在uniapp微信小程序上如何加载控件的文章,在这里我不在赘述,大家可以先看这一篇:uniapp微信小程序实现地图展示控件
关于绘制面的知识点,我将分为以下几点为大家讲解:
目录
在页面加载的时候,创建map对象
- onLoad(data) {
- this.initMap();
- },
- methods:{
- initMap(){
- this.mapCtx = wx.createMapContext('mymap');
- },
- }
设置加载地图的中心点和缩放等级
- <map id="mymap" class="myMap_map" @tap="mapAction" :longitude="mapData.longitude" :latitude="mapData.latitude" :scale="mapData.scale">
- <cover-view class="myMap_map__cover-view">
- <cover-view class="myMap_map__cover-view_mapControls">
- <!-- 显示绘制的控件-->
- <cover-view class="myMap_map__cover-view_mapControls_drawControl" @click="drawPolygon">
- <cover-image class="myMap_map__cover-view_mapControls_drawControl_drawicon" :src="mapData.drawIconPath"></cover-image>
- <cover-view class="myMap_map__cover-view_mapControls_drawControl_drawText">标绘位置</cover-view>
- </cover-view>
- </cover-view>
- </cover-view>
- </map>
在data中声明变量
- // 地图的相关操作
- mapData:{
- //设置地图中心点 lon经度y、lat纬度x
- longitude:'119.965238',
- latitude:'35.916325',
- scale:18,
- polygon:[],
- marker:[],
-
- },
绘制面数据需要先明白,polygon是由多个点绘制而成的。也就是说我们需要先获取在地图上点击的point,将这个数据存储起来。
我的实现思路是点击标绘位置之后开始在地图上绘制,点击地图获取在地图上的定位点,存储这些定位点,最后结束的时候,需要双击地图。然后将point数据组赋值给polygon,生成一个polygon数据。在这里需要注意:用户点击两个点的时候,需要将这两个点进行连接,成poline,所以地图上需要加载point、poline和polygon。
这里我用了一个变量做判断,点击标绘位置的时候,说明开始标绘,这个时候我再点击地图,获取定位点的坐标,然后push到markers数组中。
HTML部分:
- <!-- 展示地图信息 标绘位置情况 -->
- <view class="myMap">
- <u-divider text="地图展示"></u-divider>
- <map id="mymap" class="myMap_map" @tap="mapAction" :longitude="mapData.longitude" :latitude="mapData.latitude" :scale="mapData.scale" :polygons="mapData.polygons"
- :markers="mapData.markers">
- <cover-view class="myMap_map__cover-view">
- <cover-view class="myMap_map__cover-view_mapControls">
- <!-- 显示绘制的控件-->
- <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">
- <cover-image class="myMap_map__cover-view_mapControls_drawControl_drawicon" :src="item.icon"></cover-image>
- <cover-view class="myMap_map__cover-view_mapControls_drawControl_drawText">{{ item.label }}</cover-view>
- </cover-view>
- </cover-view>
- </cover-view>
- </map>
- </view>
data变量:
- data(){
- return{
- // 地图的相关操作
- mapData:{
- //设置地图中心点 lon经度y、lat纬度x
- longitude:'119.965238',
- latitude:'35.916325',
- infowidth:6,
- infoheight:6,
- scale:18,
- markers:[],
- polyline:[],
- polygons:[],
-
- },
- //地图控件
- mapControls:[
- // 标绘位置
- {
- id:'drawPolygon',
- check:false,
- icon:'/static/mapview/drawIcon.png',
- method:'drawPolygons',
- label:'标绘位置'
- },
- //清除
- {
- id:'cleanPolygon',
- check:false,
- icon:'/static/mapview/cleanPolygon.png',
- method:'cleanPolygons',
- label:'清除'
- }
- ],
- }
- }
methods方法
- mapEdit(item){
- item.check = !item.check;
- switch(item.id){
- // 绘制面
- case 'drawPolygon':
- this.drawPolygons();
- break;
- //清除
- case 'cleanPolygon':
- this.cleanPolygons();
- break;
- default:
- break;
- }
- },
- //绘制面
- drawPolygons(){
- uni.$u.toast('点击地图开始绘制!');
- },
- cleanPolygons(){
- uni.$u.toast('清除')
- },
- //点击地图事件
- mapAction(e){
- //判断是否已经点击标绘位置,如果点击标绘位置后开始定位
- if(this.mapControls[0].check){
- this.mapData.markers.push({
- id:this.mapData.markers.length+1,
- longitude:e.detail.longitude,
- latitude:e.detail.latitude,
- iconPath:'/static/mapview/square.png',
- height:this.mapData.infoheight,
- width:this.mapData.infowidth
- })
- }
- },
写到此处,地图上已经实现可以标记点位信息
下边我们需要实现当用户点击两个点的时候,让这两个点连成线。
需要判断当marker数组中的长度大于等于2的时候,才开始生成线段
- //点击地图事件
- mapAction(e){
- //判断是否已经点击标绘位置,如果点击标绘位置后开始定位
- if(this.mapControls[0].check){
- this.mapData.markers.push({
- id:this.mapData.markers.length+1,
- longitude:e.detail.longitude,
- latitude:e.detail.latitude,
- iconPath:'/static/mapview/square.png',
- height:this.mapData.infoheight,
- width:this.mapData.infowidth
- })
- if(this.mapData.markers.length >=2){
- this.pointsData = [];
- for(let i=0;i<this.mapData.markers.length;i++){
- this.pointsData.push({
- latitude:this.mapData.markers[i].latitude,
- longitude:this.mapData.markers[i].longitude
- })
- }
- this.mapData.polyline.push({
- points:this.pointsData,
- color:'#00AF99',
- width:3,
- })
- }
- console.log(this.mapData.polyline)
- }
- },
此时,polyline数组中的存储结构是这样的
每两个点组成一条线段,界面中一共是三条线段。
在这里我们需要注意,两个点形成一条线,而三条线段才能形成一个polygon,所以我们需要先判断polyline的长度必须要大于等于3,才能结束标绘。
由于我并没有再官网上找到地图的双击事件,所以在这里我模拟了地图的双击事件。通过两次单击事件的时间差来判断。
首先,需要在data中定义两个变量存储点击的时间
- //单击事件时间差
- taptimestame:{
- firsttime:null,
- lasttime:null
- },
然后在单击地图的方法中进行时间的存储与判断
- //点击地图事件
- mapAction(e){
- if(this.taptimestame.firsttime == null){
- //第一次定位,给firsttime赋值
- this.taptimestame.firsttime = e.timeStamp;
- }else if(this.taptimestame.lasttime == null){
- //第二次定位,给lasttime赋值
- this.taptimestame.lasttime = e.timeStamp;
- }else{
- this.taptimestame.firsttime = this.taptimestame.lasttime;
- this.taptimestame.lasttime = e.timeStamp;
- }
- //判断是否已经点击标绘位置,如果点击标绘位置后开始定位
- if(this.mapControls[0].check){
- this.mapData.markers.push({
- id:this.mapData.markers.length+1,
- longitude:e.detail.longitude,
- latitude:e.detail.latitude,
- iconPath:'/static/mapview/square.png',
- height:this.mapData.infoheight,
- width:this.mapData.infowidth
- })
- if(this.mapData.markers.length >=2){
- this.pointsData = [];
- for(let i=0;i<this.mapData.markers.length;i++){
- this.pointsData.push({
- latitude:this.mapData.markers[i].latitude,
- longitude:this.mapData.markers[i].longitude
- })
- }
- this.mapData.polyline.push({
- points:this.pointsData,
- color:'#00AF99',
- width:3,
- })
-
- if(this.mapData.polyline.length >=3){
- //判断两次单击事件的时间差
- if(this.taptimestame.lasttime - this.taptimestame.firsttime < 500){
- uni.$u.toast('这是个双击事件')
- }
-
- }
- }
- }
- },
目前实现效果:
最后,在双击事件中,新增polygon面图层,如果不需要的话可以将点和线的数据进行清空操作
- //点击地图事件
- mapAction(e){
- if(this.taptimestame.firsttime == null){
- //第一次定位,给firsttime赋值
- this.taptimestame.firsttime = e.timeStamp;
- }else if(this.taptimestame.lasttime == null){
- //第二次定位,给lasttime赋值
- this.taptimestame.lasttime = e.timeStamp;
- }else{
- this.taptimestame.firsttime = this.taptimestame.lasttime;
- this.taptimestame.lasttime = e.timeStamp;
- }
- //判断是否已经点击标绘位置,如果点击标绘位置后开始定位
- if(this.mapControls[0].check){
- this.mapData.markers.push({
- id:this.mapData.markers.length+1,
- longitude:e.detail.longitude,
- latitude:e.detail.latitude,
- iconPath:'/static/mapview/square.png',
- height:this.mapData.infoheight,
- width:this.mapData.infowidth
- })
- if(this.mapData.markers.length >=2){
- this.pointsData = [];
- for(let i=0;i<this.mapData.markers.length;i++){
- this.pointsData.push({
- latitude:this.mapData.markers[i].latitude,
- longitude:this.mapData.markers[i].longitude
- })
- }
- this.mapData.polyline.push({
- points:this.pointsData,
- color:'#00AF99',
- width:2,
- })
-
- if(this.mapData.polyline.length >=3){
- //判断两次单击事件的时间差
- if(this.taptimestame.lasttime - this.taptimestame.firsttime < 500){
- this.pointsData = [];
- //在双击事件中 生成polygon
- for(let i=0;i<this.mapData.markers.length;i++){
- this.pointsData.push({
- latitude:this.mapData.markers[i].latitude,
- longitude:this.mapData.markers[i].longitude
- })
- }
- this.mapData.polygons.push({
- points:this.pointsData,
- strokeWidth:2,
- strokeColor:'#00AF99',
- fillColor:'#00AF9930'
- })
-
- //最后将点、线段的数据清空
- this.mapData.markers = [];
- this.mapData.polyline = [];
- this.mapControls[0].check = false;
- }
-
- }
- }
- }
- },
最终实现效果:
最后:这里有个bug哦,最后双击的时候会触发地图等级别缩放。这个地方需要判断以下,如果用户正在标绘位置,可以把这个事件禁用掉。
写到最后,如果大家觉得写的不错,一键三连白,点赞、收藏加关注。大家的点赞就是我不断分享的动力!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。