前言
我们常说的uniapp或者原生微信小程序框架使用高德地图,并不是ui就是高德地图,而是api用的高德地图,ui仍然是框架内置的地图,也就是说,地图和api是分开,微信小程序的内置地图自然是腾讯地图。
高德地图
高德地图的api包含服务端和客户端两部分,经常用到的api方法有经纬度地址解析及逆解析、获取POI(Point of Interest),POI指的是兴趣点,常见的POI有关键字搜索、周边搜索、多边形区域搜索、路线规划等,如果客户端用高德,那有pc web版的、有安卓版的、有IOS版的、有微信小程序版的,各个版本之间有差异,比如微信小程序版的api方法很少,pc web版的api方法很多。
原生微信小程序 map组件
原生微信小程序的地图控件,提供了路径规划、标记点、标签、气泡等属性。
<map
id="map"
longitude="{{longitude}}"
latitude="{{latitude}}"
scale="14"
show-location="true"
markers="{{markers}}"
bindmarkertap="makertap"></map>
举几个map组件常用的属性
- markers,标记点
- 它是一个marker数组,marker对象格式{id,latitude,longitude,title…}
- polyline,路线
- 它是一个路线数组,路线对象{points:[{longitude,latitude}],color}
- include-points,缩放视野以包含所有给定的坐标点
- 它是一个坐标点数组,坐标点格式{longitude,latitude}
uniapp的map组件跟微信小程序的map组件,特别相似,可认为是一样的。
- 它是一个坐标点数组,坐标点格式{longitude,latitude}
标记点 vs 标签 vs 气泡
地图中有3个常用的概念,标记点marker,标签label、气泡callout,这三者是不一样的,可看下图,红色的是marker、气泡、标签分别用文本做了标记。
这里以微信原生小程序举例,以下代码基于高德微信小程序插件样例进行了改造,关键代码如下,代码中用到了getPoiAround方法,
var that = this;
var myAmapFun = new amapFile.AMapWX({key:'高德key'});
myAmapFun.getPoiAround({
success: function(data){
markersData = data.markers;
markersData.forEach(marker=>{
marker.label={content:"标签:"+marker.name,bgColor:"#d3cd9c",padding:5,borderWidth:1,borderRadius:4}
marker.callout={content:"气泡:"+marker.name,bgColor:"#ebc3c3",display:"ALWAYS",padding:5,borderWidth:2,borderRadius:4}
})
that.setData({
markers: markersData
});
}
},
常见的需求及实现原理
标记点
标记点的原理就是将目标点的坐标组装成markers的结构,然后赋值给它就可以了。
路线规划
路线规划的原理很简单,通过高德getDrivingRoute方法(当然了,还有骑行、步行、公交等方法),然后组装成polyline的数据格式,顺便提一下,高德api方法的坐标参数,格式都是经度,纬度
,经度在前,纬度在后,中间有逗号隔开。
路线附近标记点
这个的应用场景通常是,从A---->B规划出路径后,需要展示路径附近的加油站(或者旅游景区)等等之类的。它实现原理是,路径是一系列坐标点组成的,通过过滤计算所有加油站到坐标连起来的线的距离(mysql有对应的地理函数),获取到目标加油站的坐标,然后返回到前端,通过地图的标记点api标记到地图上。
- 前端,获取到A->B的路径规划一系列坐标
- 通过高德getDrivingRoute方法将坐标组装成字符串,参考下边StationsNearbyLineQuery中的points格式。
- 后端接口,接收一系列坐标,以java举例
/**
* @description: 获取路线沿途的站点
*/
@Data
public class StationsNearbyLineQuery {
/**
* 坐标点,p1[,p2]...
* p1格式:经度 纬度
* 一言一概之,点与点之间逗号分隔,经纬度空格分隔
*/
@NotBlank
private String points;
/**
* 搜索范围(米)
*/
private Integer distance;
}
/**
* 获取路线沿途的站点
* @param query 查询条件
* @return
*/
@PostMapping("/getStationsNearbyLine")
public List<MerchantsVO> getStationsNearbyLine(@Valid @RequestBody StationsNearbyLineQuery query){
//执行sql查询目标站点
}
- mysql计算所有加油站到路径的距离,筛选出范围内站点
select * from 加油站 where ST_Distance( ST_GeomFromText(concat('LINESTRING(', #{points}, ')')), POINT(longitude, dimensionality) ) * 111195 <= #{distance}
- 这里要乘以111195是因为,
st_distance
计算的结果单位是度,需要乘111195(地球半径6371000*PI/180)是将值转化为米。
- 前端标注
自定义气泡
自定义气泡,就是利用marker对象中的customcallout属性,具体可参考marker 上的自定义气泡 customCallout
使用方式如下,map 组件下添加名为 callout 的 slot 节点,其内部的 cover-view 通过 marker-id 属性与
marker 绑定。当 marker 创建时,该 cover-view 显示的内容将作为 callout 显示在标记点上方。
<map>
<cover-view slot="callout">
//如果是动态的,则用wx:for之类的动态生成,因为map是较高层级组件,为了实现实现遮挡,
//必须要用cover-view,它的层级高过map
<cover-view marker-id="1"></cover-view>
<cover-view marker-id="2"></cover-view>
</cover-view>
</map>
相应的每个marker对象中要指定customCallout
marker:{
id:"",
customCallout: {
display: "ALWAYS"
},
}
除了以上几个,还提供了点击标记bindmarkertap、点击标签bindlabeltap、点击气泡bindcallouttap等方法,已实现自定义效果。
总结
做demo时,可用微信原生框架做测试,高德微信小程序插件提供了样例代码,因为少了uniapp翻译为原生微信小程序这一步,代码看起来直观一些,也方便调试,并且微信小程序的地图文档也得也更好一些。