- 地图瓦片/ Leaflet/自定义图层WMSLayer,小程序都不能用?来试试这个方法
需求 最近项目甲方想把PC端的地图线路绘制在手机上,并且还要在小程序上,听得我心里一惊,那么多线,那么多点符号,我该如何画啊,小程序最大setData也有1M的限制。但是需求来了就得想办法解决。 寻找方法 1、小程序方法[代码]polyline[代码]+[代码]marker[代码](适用普通的点位渲染) 小程序文档翻了翻,发现map组件文档有个 “聚合能力” 我似乎看见了新大陆,觉得肯定可以满足,经过一番研究,还是不能满足,因为这种方法只能用[代码]polyline[代码]来画线,而点或符号用[代码]marker[代码]来画,这种方法数据要处理大多了,因为我的项目线多,符号也多还不同形状的符号,PC端的显示是使用瓦片来渲染,没有分那么多符号和点位,这个方法以失败告终。有兴趣可以看下这个博客写的内容和我这里讲的差不多:微信小程序添加外部地图服务数据 2、自定义图层WMSLayer 上面方法不行,于是我找了gis,跟他讨论了我这个需求,看看有没有办法可以满足我的需求,他们就给我推荐了自定义图层WMSLayer,他说PC端就是用这种方式实现,导入一份数据就可以了。我就说好的,我自己回去研究了一番,发现是需要引入GL的包,但是小程序不支持dom操作,和普通web页面还是有区别,于是我就放弃了该方法。 3、Leaflet插件 这个方法也是gis那边介绍的一个插件库,我寻找了很多遍,发现没有支持小程序的插件库,只是支持web网页开发,还是无法使用到小程序中。传送门leaflet地址 4、小程序个性化图层 这个方法我研究过,就是可以直接导入图层瓦片,最终腾讯生成一个个性化地图id,然后小程序调用个性化图层id。该方法好像还行,但是我没有具体操作,因为我的数据不是固定的,随时会改变,如果每次改变又去改个性化地图就惨了,这种方法适用于景区景点类型。 腾讯地图个性化图层 看见社区有人发的web效果图地址 个性化地图使用指南 我使用的方法 思来索去既然瓦片是图,那能不能让gis那边直接返回一张图片呢?我这边就贴图就行?因为小程序刚好有个[代码]自定义图片图层[代码]可以跟着地图变大变小[图片] 感觉这个方法挺好的,联想了加入是一张张瓦片我也可以对准位置贴上去,连在一起就是我想要的效果了。于是找了gis那边的同事,发现他们有这种方法可以获取图片。addGroundOverlay文档地址 思路 先看下addGroundOverlay的参数 [图片] 单独一个参数抽出来 [图片] 由图可见,有一个很重要的参数[代码]bounds[代码]这个参数,这个参数就是获取地图的对角点,用来确定当前地图视野范围,有了这个参数,我们就叫gis那边生成一张图片,然后粘贴到我们小程序的地图上面就完成了渲染。这里需要注意几点: gis那边生成的图片需要几个参数, a、需要对角点即[代码]bounds[代码]一样的参数,可以通过小程序提供的MapContext.getRegion获取当前地图的视野范围 b、需要获取你当前手机全屏屏幕宽高(windowWidth这个),用这个宽高传给gis那边生成图片的宽高 c、使用地图map组件提供的方法[代码]bindregionchange[代码]来监听,当前缩放或者中心点移动,然后去请求最新视野的图片粘贴上去 d、这里有个不好的问题就是用[代码]MapContext.updateGroundOverlay[代码]方法,更新上一张的贴图会出现闪动问题(即更新最新的图片会发生显示原来图片位置、然后隐藏才显示最新的图片位置),为了解决这个问题,我使用了每次变动位置请求最新图片,都用增加方法[代码]MapContext.addGroundOverlay[代码]去添加贴图到地图,然后把旧的贴图全部删除,为了效果看起来像懒加载,等加载完最新的图片在去删除旧的图片,这样就不会出现闪动的问题 核心代码如下: [代码]onReady: function (options) { this.MapContext = wx.createMapContext('mapId', this) this.getSystemInfo = wx.getSystemInfo().then(res => { this.getSystemInfo = res }) this.indexId = 1 }, bindregionchange: function (e) { if (e.type === 'end') { const northeast = e.detail.region.northeast const southwest = e.detail.region.southwest if (mapTimer) clearTimeout(mapTimer) mapTimer = setTimeout(()=> { this.updataMap(southwest, northeast) }, 100) } }, updataMap(southwest, northeast) { const northeast1 = { longitude: CoordTransformUtil.GCJ02ToWGS84(northeast.longitude, northeast.latitude)[0], latitude: CoordTransformUtil.GCJ02ToWGS84(northeast.longitude, northeast.latitude)[1] } const southwest1 = { longitude: CoordTransformUtil.GCJ02ToWGS84(southwest.longitude, southwest.latitude)[0], latitude: CoordTransformUtil.GCJ02ToWGS84(southwest.longitude, southwest.latitude)[1] } overlayId.push(this.indexId) this.indexId = this.indexId + 1 this.MapContext.addGroundOverlay({ id: this.indexId, src: `https://xxx/export?bbox=${northeast1.longitude},${northeast1.latitude},${southwest1.longitude},${southwest1.latitude}&bboxSR=4490&layers=&layerDefs=&size=${this.getSystemInfo.windowWidth},${this.getSystemInfo.windowHeight}`, bounds: { southwest: southwest, northeast: northeast }, success: async (res) => { // 由于使用updata图层会出现每次闪图渲染问题,所以每次获取图层都是新增的,故这里需要把每次渲染的图层删除,只留最后一次 if (mapTimer2) clearTimeout(mapTimer2) mapTimer2 = setTimeout(async() => { await Promise.all(overlayId.map(async (item) => { await this.MapContext.removeGroundOverlay({ id: item }); overlayId = overlayId.filter(fil => fil != item) })); }, 500) }, fail: (err) => { console.error(err, 'fail...addGroundOverlay') } }) } [代码] 总结 抱歉了,其实我这是不讲武德,把技术点给gis那边处理了,我这边只需要把他们处理好的图片粘贴上去就好了,经过验证该方法确实可行的哦 解决问题才是王道 代码片段:https://developers.weixin.qq.com/s/taAR41mz7GHT
2023-03-27 - addGroundOverlay添加的手绘图在华为手机下很模糊,明显锯齿
小程序手绘地图,addGroundOverlay添加的图片,设置最大放大max-scale为18,将地图放大到最大,华为系统下很模糊,出现明显锯齿。(无论是鸿蒙还是安卓,只要是华为手机) 测试过7、8个手机,ios的iphone7、iphone11、iphone12都清晰正常,安卓系统的vivo x7、oppo A8、iqoo u3x也都清晰正常。 不正常的是几个华为手机:p40、Mate30、畅享9、荣耀9X、荣耀play3e,操作系统有些是鸿蒙2.0,有些是安卓,打开手绘地图后放大到最大后,很模糊、出现明显锯齿。 [图片] 具体可以通过这个小程序查看
2022-01-29 - 小程序开发起步
学习 5 节课程,从 0 至 1 做第一个属于你的小程序,深入浅出了解小程序开发。本系列视频,由腾讯课堂 NEXT 学院、微信学堂联合出品。
2022-03-24