uniapp绘制marker,点击marker将其移至地图中心并缩放

背景

最近产品要在地图上显示出来各个点位的经纬度和名称信息,点击后将 marker 移动至地图中心,同时缩放地图。

知识点

属性 说明
id 地图组件的id,必填,在这里主要是用来获取地图上下文 mapContext 对象
scale 缩放级别,在这里主要是用来点击callout后缩放级别
show-location 显示带有方向的当前定位点, 和将地图中心移动到当前定位点 moveToLocation 方法结合使用
longitude 中心经度,点击 callout 变更为选中 marker 的经度
latitude 中心纬度,点击 callout 变更为选中 marker 的纬度
markers 标记点
markertap marker 的点击事件,和下方 calloutTap 事件一致
calloutTap callout 的点击事件,点击之后 marker 移动至地图中心,并缩放地图

createMapContext

使用 createMapContext 获取 map 上下文,第一个参数就是该地图组件的 id ,第二个参数传入组件实例this ,以操作组件内 <map> 组件,详情可查看

那这里为什么需要 this 呢?毕竟微信小程序中的 createMapContext 不需要

这是因为在 uni-app 中,组件实例的生命周期和小程序页面的生命周期是不同的。在小程序中,一个页面是一个独立的 JavaScript 文件,而在 uni-app 中,一个页面可能包含多个组件,这些组件有自己的数据和生命周期。因此,如果要在组件中使用 createMapContext 方法来创建地图上下文,就需要将组件实例作为第二个参数传递给该方法,以便在组件内部访问到地图上下文对象。

因此,将组件实例作为第二个参数传递给 uni.createMapContext 方法,可以确保在组件内部正确地创建和管理地图上下文对象,并且可以避免不同组件之间的地图上下文对象混淆的问题。同时,也方便了组件内部对地图上下文对象的调用和管理。

moveToLocation

moveToLocation会获取定位权限,并且需要在 show-location 配合使用,也就是设置为true

移动至地图中心

两种方式

  • 动态设置 map 组件上的 longitudelatitude ,缺点是没有移动的动画,很生硬
  • 使用 moveToLocation 方法继续进行移动,动画很流畅

所以这里采用了第二种方案

设置地图scale

iOS 上设置 scale ,它会根据当前的经纬度进行缩放,也就是 map组件 上的 longitudelatitude ,由于动态设置经纬度会导致失去移动的动画,所以我们这里先调用 moveToLocation 方法将 marker 移动至地图中心,300ms (这里的300ms是我多次尝试出来的,并不是官方的,这里的时间按需设置) 之后移动动画完成再去设置经纬度,这样既有移动的动画,又可以进行正常缩放了

安卓一切正常

实现

<template>
<map id="myMap" :scale="scale" :show-location="true" :longitude="longitude" :latitude="latitude" :markers="markers" @markertap="calloutTap" @callouttap="calloutTap" />
</template>
<script>
export default {
data() {
return {
longitude: 116.397428, //中心点经度
latitude: 39.90923, //中心点纬度
markers: [] ,//所有点位信息
mapContext: null, //map上下文
scale: 10, //默认缩放级别
};
},
mounted() {
//获取map上下文
const mapContext = uni.createMapContext('myMap', this);
this.mapContext = mapContext;
//模拟请求
setTimeout(() => {
//对markers进行赋值
this.markers = [
{
id: 1,
longitude: 116.397428,
latitude: 39.90923,
callout: {
content: '标记1',
color: '#ffffff',
fontSize: 14,
borderRadius: 4,
bgColor: '#3cc51f',
padding: 8,
display: 'ALWAYS',
},
},
{
id: 2,
longitude: 116.407428,
latitude: 39.90923,
callout: {
content: '标记2',
color: '#ffffff',
fontSize: 14,
borderRadius: 4,
bgColor: '#3cc51f',
padding: 8,
display: 'ALWAYS',
},
},
{
id: 3,
longitude: 116.397428,
latitude: 39.91923,
callout: {
content: '标记3',
color: '#ffffff',
fontSize: 14,
borderRadius: 4,
bgColor: '#3cc51f',
padding: 8,
display: 'ALWAYS',
},
},
];
//将中心点经纬度设置成第一个点位的经纬度
this.longitude = this.markers[0].longitude;
this.latitude = this.markers[0].latitude;
//获取所有点的经纬度
const points = this.markers.map((marker) => ({ latitude: marker.latitude, longitude: marker.longitude }));
// 缩放视野展示所有经纬度 [上,右,下,左]
this.mapContext.includePoints({
points,
padding: [150, 150, 150, 150], // 设置地图边缘与 marker 的间距
});
}, 2000);
},
methods: {
//点击气泡,找到被点击的marker
calloutTap(e) {
const { markerId } = e.detail;
const marker = this.markers.find((m) => m.id === markerId);
marker && this.moveMarkerToCenter(marker);
},
moveMarkerToCenter(marker) {
//将marker移动至中心点
this.mapContext.moveToLocation({
longitude: marker.longitude,
latitude: marker.latitude,
success: (res) => {
//这里加300ms的延时是为了防止和moveToLocation功能冲突,保留地图移动的动画
const timer = setTimeout(() => {
this.longitude = marker.longitude;
this.latitude = marker.latitude;
clearTimeout(timer);
//进行缩放,设置为16
this.scale = 16;
}, 300);
},
});
},
},
};
</script>
<style lang="scss" scoped>
#myMap {
width: 100vw;
height: 100vh;
}
</style>

在上述代码中,我们在 mounted 钩子函数中获取了地图的上下文对象 mapContext,发起请求为markers赋值,调用includePoints方法来缩放视野展示点位等

calloutTap 方法中,通过 e.markerId 获取到当前点击的标记点的 id,然后在 markers 数组中查找该标记点,获取它的经纬度,将其作为参数传递给 moveToLocation 方法,以使地图移动到该标记点的位置并缩放地图

最终效果如下图所示

uniapp绘制marker,点击marker将其移至地图中心并缩放

结语

到这里,我们已经完成了在 Uniapp 微信小程序中绘制标记点和气泡,并实现标记点和气泡的点击事件,以及点击后将标记点移动到地图中心的功能。

都已经看到了这里了,麻烦各位大佬点个赞咯,谢谢!

祝大家都变得更强!

原文链接:https://juejin.cn/post/7237514744479219767 作者:道宁

(1)
上一篇 2023年5月28日 上午10:41
下一篇 2023年5月28日 上午10:51

相关推荐

发表回复

登录后才能评论