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

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

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

实现最终界面:

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

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

目录

一、创建context 对象

二、开始绘制面图层

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

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

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


一、创建context 对象

在页面加载的时候,创建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。

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

这里我用了一个变量做判断,点击标绘位置的时候,说明开始标绘,这个时候我再点击地图,获取定位点的坐标,然后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
    	})
    }
},

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

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

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

需要判断当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数组中的存储结构是这样的

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

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

在这里我们需要注意,两个点形成一条线,而三条线段才能形成一个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哦,最后双击的时候会触发地图等级别缩放。这个地方需要判断以下,如果用户正在标绘位置,可以把这个事件禁用掉。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/207329.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分享几种 Java8 中通过 Stream 对列表进行去重的方法

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 1. Stream 的 distinct…

java商城系统选型技巧

近期有很多网友在知乎、百度上咨询如何选择java商城系统&#xff0c;本文我们介绍目前有哪些java商城系统&#xff0c;如何选择商城系统&#xff0c;希望有所帮助。 我们之前做过调研&#xff0c;目前java语言开发的商城系统主要有shop、javashop、ejavashop、远丰、mall4j、li…

重测序项目文章 | Fungal Diversity(IF:20.3)发表杯伞科真菌系统分类和毒蝇碱进化的研究

Clitocybaceae&#xff08;杯伞科&#xff09;是近期建立的真菌家族。目前&#xff0c;由于取样和用于系统发育分析的基因有限&#xff0c;该家族内的亚科分化和关系尚不清晰。该家族的一些蘑菇含有神经毒性毒蕈碱&#xff0c;导致全球范围内许多严重甚至致命的中毒事件。然而&…

vue2使用ElementUI

elementui官网&#xff1a;组件 | Element 1、全部引入 下载&#xff1a;npm i element-ui 在 main.js 中写入以下内容&#xff1a;import Vue from vue; import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css; import App from ./App.vue;Vue.use(…

『Fiddler数据抓包功攻略』| 如何使用Fiddler进行数据抓包与分析?

『Fiddler数据抓包功攻略』| 如何使用Fiddler进行数据抓包与分析&#xff1f; 1 关于Fiddler2 Fiddler安装3 Fiddler信息查看3.1 查看请求信息3.2 查看响应信息3.3 查看会话信息统计 4 Fiddler暂停抓包5 Fiddler清除抓包数据6 Fiddler设置Filters过滤6.1 关于Actions6.2 关于Us…

c++ day 4

代码整理&#xff0c; 将学过的三种运算符重载&#xff0c;每个至少实现一个运算符的重载:分别是-&#xff0c;-&#xff0c;<。 #include <iostream>using namespace std; class Stu {friend const Stu operator-(const Stu &L,const Stu &R);friend bool o…

picgo配置又拍云

又拍云控制台配置操作员账号 添加操作员账号 进入又拍云的控制台 又拍云控制台 (upyun.com) 右上角选择账号下拉框&#xff0c;选择账户管理 在账户管理中&#xff0c;选择操作员&#xff0c;添加操作员 输入操作员名字&#xff0c;点击生成密码&#xff0c;填入操作员备注…

音频修复和增强软件iZotope RX 10 mac特点介绍

iZotope RX 10 mac是一款音频修复和增强软件&#xff0c;主要特点包括&#xff1a; 声音修复&#xff1a;iZotope RX 10可以去除不良噪音、杂音、吱吱声等&#xff0c;使音频变得更加清晰干净。 音频增强&#xff1a;iZotope RX 10支持对音频进行音量调节、均衡器、压缩器、限…

Jinja2使用Layui报 “d is not defined“

问题出现场景在使用Jinja2渲染Layui的表格时候&#xff0c;要做自定义templte的传入 Jinja2这块本来就是支持 {{ }} 插值的模板语言&#xff0c;所以这块的第一种渲染方式会冲突 所以只能用函数返回代码块进行填充&#xff0c;不能使用插值&#xff0c;只能拼接字符串 templt…

web项目添加防调试

新建js文件debug-vconsole.js /**防止非法调试*/ (function () {function getLocationHrefParams(name) {var reg new RegExp("(^|&)" name "([^&]*)(&|$)");var r window.location.search.substr(1).match(reg);if (r ! null) return un…

docker部署elasticsearch+kibana+head

前言 最近&#xff0c;项目需要使用elasticsearch&#xff0c;所以就想快速安装一个使用&#xff0c;最开始是docker安装了7.10.1版本。 后面计划使用Java开发&#xff0c;发现有 RestHighLevelClient 和 Elasticsearch Java API Client两种客户端连接方式。 然后网上查阅了一…

【微服务 SpringCloudAlibaba】实用篇 · Nacos配置中心

微服务&#xff08;6&#xff09; 文章目录 微服务&#xff08;6&#xff09;1. 统一配置管理1.1 在nacos中添加配置文件1.2 从微服务拉取配置 2. 配置热更新2.1 方式一2.2 方式二 3. 配置共享1&#xff09;添加一个环境共享配置2&#xff09;在user-service中读取共享配置3&am…

数字人可以为文化传播带来什么?

近日&#xff0c;由哈萨克斯坦驻华大使馆、中国外文局文化传播中心、中关村科幻产业创新中心联合发起的中哈青年友谊数字人怡漾和苏路&#xff08;Сұлу&#xff09;正式发布。其中&#xff0c;代表中方形象的数字人怡漾&#xff0c;不仅将成为中哈青年文化交流的标志与代言…

seq2seq:中英文翻译

文章目录 一、完整代码二、论文解读2.1 RNN模型2.2 Attention-based ModelsGlobal attentional modelLocal attentional model 2.3 Input-feeding Approach2.4 模型效果 三、过程实现3.1 导包3.2 数据准备3.3 构建相关类3.4 模型配置3.5 模型推理 四、整体总结 论文&#xff1a…

Facebook公共主页受限、被封?一文教你排雷解决

一、Facebook公共主页是什么&#xff1f; 现在人们的生活已经离不开各种社交媒体&#xff0c;只要有智能手机&#xff0c;或多或少会使用一些社交平台&#xff0c;而Facebook是一个拥有大量用户的社交平台。这对于各种企业而言&#xff0c;也是一个十分优秀的营销平台&#xf…

使用Docker安装部署Swagger Editor并远程访问编辑API文档

文章目录 Swagger Editor本地接口文档公网远程访问1. 部署Swagger Editor2. Linux安装Cpolar3. 配置Swagger Editor公网地址4. 远程访问Swagger Editor5. 固定Swagger Editor公网地址 Swagger Editor本地接口文档公网远程访问 Swagger Editor是一个用于编写OpenAPI规范的开源编…

四、虚拟机网络配置

目录 1、VMware网卡配置模式 1.1 桥接模式 1.2 NAT模式 1.3 仅主机模式 ​​​​​​​2、编辑虚拟机的网络编辑器 ​​​​​​​3、编辑Window的虚拟网卡 ​​​​​​​4、修改IP地址为静态 4.1 查看网卡名字 4.2 编辑修改网卡IP地址的配置文件 4.3 重启网络: 4.…

如何选择靠谱的安防监控系统?优秀的安防智能系统应该具备哪些特点?

随着科技的不断进步&#xff0c;安防智能系统变得越来越重要。当前的安防监控市场系统五花八门&#xff0c;用户该如何选择性比价高、功能又靠谱的平台&#xff1f;一个优秀的安防智能系统应该具备哪些特点&#xff1f;今天我们来针对这个话题讨论和分享一下。 1、高效性&…

Flutter页面刷新失败?看看是不是这个原因

文章目录 问题描述解决办法在控件A中定义回调函数在页面中使用控件A 原因分析回顾问题原因分析 setState使用注意事项上下文正确性异步更新避免深层嵌套避免频繁调用避免在 build 方法中调用避免在 dispose 方法中调用 问题描述 我用flutter开发了一个页面&#xff0c;页面上有…

java操作windows系统功能案例(三)

以下是一些 Java 操作 Windows 系统功能的案例&#xff1a; 打开 Windows 计算器 public class Calculator {public static void main(String[] args) throws Exception {Runtime.getRuntime().exec("calc.exe");} }打开 Windows 默认浏览器 public class Browser…