irpas技术客

小程序Map组件点聚合功能详细接入步骤和ios、Android真机环境以及开发者工具各种样式差异的适配过程_我们是最后一代_微信小程序map组件点聚合

网络投稿 5081

效果图 ios效果图

Android效果图

开发者工具效果图

业务场景

需要将很多的小区根据经纬度在地图上进行标注,随着业务的推进,小区标注点越来越多,如何将所有的小区合理的分布在有限的地图空间上便于管理者全局的观察成了一个亟待解决的问题! 首先当然是小程序刚更新没多久的组件map的点聚合功能了,有了点聚合还不够,如何合理的定义地图中心点也非常重要! 接下来就是小程序Api MapContext.includePoints缩放视野展示所有经纬度! 最后一个就是标记点markers的callout气泡窗口属性了。当我们点击标记点的时候就会自动弹出弹窗显示该标记点的一些详细信息

开始接入 点聚合功能

1、wxml中创建地图容器

<map enable-3D id="mapId" class="map" scale="11" latitude="{{latitude}}" longitude="{{longitude}}" subkey="JO3BZ-2FAKD-QTG4N-HPCPP-I7L2H-HDBOR" ></map>

subkey是自己的个性化地图,上述代码中的参数都可以在markers文档中找到详细的说明,可以自行去查看 2、拼接地图map展示的数据 这种拼接数据的操作肯定最好是在我们的后台获取到数据之后直接进行拼接比较好!毕竟要尊重也要遵守腾讯极致简约的文化传统。 代码就补贴了毕竟每个人的业务需求数据都是不一样的,这里我就给一组测试数据供大家参考吧

markers: [ { id: 1, iconPath: "../../images/yikaifa.png", latitude: '30.321877', longitude: '120.132039', width: 30, height: 30, joinCluster: true, callout: { "content": "小区名称:拱墅区**大院(**街北)\n状态:已**\n业务员:康**", "borderRadius": 5, "padding": 10, "bgColor": "#E3E3E3", "borderColor": "#1AA034", "borderWidth": 2, "anchorX": 12, "anchorY": 1 } }, { id: 2, iconPath: "../../images/yikaifa.png", latitude: '30.296532', longitude: '120.136135', width: 30, height: 30, joinCluster: true, callout: { "content": "小区名称:**新村(**西路)\n状态:正在**\n业务员:刘**", "borderRadius": 5, "padding": 10, "bgColor": "#E3E3E3", "borderColor": "#1AA034", "borderWidth": 2, "anchorX": 12, "anchorY": 1 } } ]

这里就开始就有坑了,不注意的话直接人都得崩溃! iconPath的路径图片一定要存在哦,可能你的数据直接在后台拼接返回来的时候数据大很可能就没注意导致个别数据的路径不存在这个时候由于数据是后台动态渲染的小程序端也不会报错但是地图上是不会显示这个标记点的!一定要注意! latitude和longitude的值一定要注意不能是字符串带""或者单引号格式的哦!一般很有可能后台经纬度采用varchar保存的话返回来的就是字符串,这个需要和后台沟通好!如果带引号了在开发者工具和Android真机能正常显示但是到了ios真机就会在点聚合的时候出现问题! 3、开始实现点聚合功能 具体要用的方法小程序文档点聚合这个板块讲的非常粗糙,光看这个是接不成功的,接之前还需要看Api地图文档 在js中代码如下:

this.mapCtx = wx.createMapContext('mapId') this.bindEvent()//此函数主要是自定义聚合后的聚合簇样式的 bindEvent() { this.mapCtx.initMarkerCluster({ enableDefaultStyle: false, zoomOnClick: true, gridSize: 20, complete(res) { } }) // enableDefaultStyle 为 true 时不会触发改事件 this.mapCtx.on('markerClusterCreate', res => { const clusters = res.clusters const markers = clusters.map(cluster => { const { center, clusterId, markerIds } = cluster return { ...center, width: 0, height: 0, clusterId, label: { content: markerIds.length + '', fontSize: 15, width: 30, height: 30, borderWidth:2, borderColor:"#E1B368", bgColor:"#fff", borderRadius:20, textAlign: 'center', anchorX: 0, anchorY: -18, } } }) this.mapCtx.addMarkers({ markers, clear: false, }) }) },

然后在请求后台获取到我们上一步获取到的拼接数据之后进行如下操作:

const markers = this.data.markers; this.mapCtx.addMarkers({ markers, clear: false, })

至此基本缩放地图就可以看到标注点的聚合展开功能了,但是问题又出现了! 就是在放大地图展开聚合簇的时候如果操作比较快就会出现部分聚合簇没有展开,会出现尴尬的一个聚合簇显示在两个标注点之间!这个找了好久也没有发现原因!最终解决方案是找到了,但是原理还是没搞清楚!说白了还是腾讯那边组件底层的代码还未优化好 解决方案:地图容器中

<map enable-3D id="mapId" class="map" scale="11" latitude="{{latitude}}" longitude="{{longitude}}" subkey="JO3BZ-2FAKD-QTG4N-HPCPP-I7L2H-HDBOR" ></map>

scale的值必须小于等于13!!

地图中心点的确定

如何在地图有限的空间内十分合理的布局所有的标记点就关系到地图中心点的确定问题了 MapContext.includePoints(Object object)缩放视野展示所有经纬度,这个API可以完美的解决问题 includePoints所需要的参数也是最好在后台配置哦,这边也直接给一组测试数据吧

positions: { points: [ { "latitude": 30.321877, "longitude": 120.132039 }, { "latitude": 30.296532, "longitude": 120.136135 }], padding: [ 10, 10, 10, 10 ] }

后台需要拼接的就是把所有标注点的经纬度全部拼接到points这个参数里,不要觉得这样子不合理,就算是几千上万的标记点对于服务器来说这点计算量也是很小的,不要去心疼它!

this.mapCtx.includePoints(this.data.positions)

至此小程序就会根据所有标记点的经纬度采用合理的缩放比例把全部的点展示在有限的地图空间上了 这个步骤的话目前我是没有遇到特别坑的地方,只要参数的拼接没有问题这一步应该是很容易就出效果了!

重置缩放比例让地图回到初始状态

当我们点击某个聚合簇之后地图就会进行放大更精确的展示该聚合簇中点的周边信息,那么问题就来了,我们不可能每次都去手动的再去缩小地图来看其他的聚合簇,那么我们需要一个重置地图的功能 目前方法中我只能想到一个比较笨的方法就是直接刷新页面重新渲染一次页面,网上也有说可以计算聚合簇中心点的经纬度然后计算缩放比例去实现,这个方法我也试过了,会影响前面几个步骤的页面交互体验,而且逻辑都是要在小程序端来处理,我觉得这样子不好,很容易拖垮小程序的响应速度! 地图右下角新增一个重置按钮

<van-button type="primary" bindtap="resetMap" size="small">重置地图</van-button>

js代码:

resetMap() { this.onLoad(); },

这里问题出现了,当我们点击重置按钮的时候会发现地图上的某些没有参与聚合的点会在重置之后消失,这个时候我们需要在js文件的onload方法里面再去执行一次addmarkers方法

onLoad: function () { this.mapCtx = wx.createMapContext('mapId') this.mapCtx.addMarkers({ clear: true, markers: [] }) // 使用默认聚合效果时可注释下一句 this.bindEvent() },

还有一个问题也出现了,就是marker的callout气泡窗口在ios中是手风琴模式的,就是点击第一个弹窗后再去点击第二个点的弹窗则第一个弹窗会自动关闭,但是在Android真机中就不会,必须手动在点一次来关闭弹窗不然callout会一直存在!

总结(不管水平高低一定要做一个有思想有灵魂的开发者) 腾讯的文档一般属于国内比较上流的水准了!但是这个map点聚合的文档估计是临时工写的,确实不咋地。而且在接入过程中上述我所讲的很多差异明显就是在不同真机环境中适配的有问题!希望官方尽快更新一下吧最终的ios和Android真机环境的界面聚合簇的显示还是会存在一点点小的差异,在效果图中我已经贴出来了希望我的开发过程可以给大家一些参考,欢迎沟通交流15651712186


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #微信小程序map组件点聚合