本文将主要介绍一下关于google map的常用API,最后通过常用API实现一个自定义行程路线的小例子。
一、调用地图
1. 获取API密钥
要使用Google Map API,必须具有API密钥,具体信息请查看官网。
2. 初始化地图
2.1 引入地图
通过script
标签引入
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script>
通过jsonp
的方式调用地图api
jsonp('https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY', () => {
initMap()
})
不过呢,官网提供的API地址对于国内用户会存在梯子的问题,所幸,还有两个不需要梯子的API网址:
1. http://maps.google.cn/maps/api/js?key=${apiKey}
2. http://ditu.google.cn/maps/api/js?key=${apiKey}
2.2 创建地图
// 坐标点
let position = { lat: -25.344, lng: 131.036 }
// 创建地图
let map = new google.maps.Map(
// 绑定到指定DOM节点
el,
{
zoom: 7,
center: position
})
2.3 配置参数
google.maps.Map
的第二个参数即为地图的配置参数,常用参数如下:
{
// 地图缩放比例
zoom,
// 地图中心点位置
center,
// 是否显示街景控制按钮
streetViewControl,
// 常用控件位置
mapTypeControlOptions: {
position: google.maps.ControlPosition.TOP_RIGHT
},
zoomControlOptions: {
position: google.maps.ControlPosition.RIGHT_TOP
},
fullscreenControl: {
position: google.maps.ControlPosition.RIGHT_TOP
},
...
}
既然可以初始化配置参数,那,又该如何动态修改配置参数呢?对于zoom
和center
,我们可以通过直接调用相应的API进行修改:setZoom
和setCenter
。那对于其他参数可以通过setOptions
进行修改。控件的具体详情请查看官网。
this.map.setOptions({
zoom: 9
streetViewControl: false,
...
})
二、标记
标记可识别地图上的位置。默认情况下,标记使用标准图像。标记可以显示自定义图像,在这种情况下,它们通常称为“图标”。标记和图标是类型的对象 Marker。您可以在标记的构造函数中设置自定义图标,也可以通过调用标记来设置自定义图标setIcon()。
1. 添加标记
通过google.maps.Marker
构造函数生成指定的标记:
let marker = new google.maps.Marker({
// 标记位置
position: LatLng,
// 附加到指定地图,未指定时,不会添加到任何地方
map: map,
// 工具提示
title: 'ABC'
})
// 添加到指定地图
marker.setMap(map)
2. 删除标记
从地图上删除指定标记,同样需要调用setMap
方法:
marker.setMap(null)
不过此操作只是把指定地图上的标记删除了,依旧可以通过setMap(map)
添加到指定地图中,若想真正删除当前标记,需设置标记为null
:
marker.setMap(null)
marker = null
3. 自定义标记
如果只能显示默认的标记那肯定就不好玩了,那接下来我们可以通过icon设置指定的自定义图标:
let marker = new google.maps.Marker({
position: LanLng,
map: map,
// 自定义图像的url
icon: imageURL
})
如果说只是图像的url路径,肯定还是不过瘾的,接下来可以进行更加复杂的设置:
let marker = new google.maps.Marker({
position: LanLng,
map: map,
icon: {
url: 'icon路径',
// icon图片大小
size: new google.maps.Size(30, 46),
// 从icon图片起点坐标进行截取
origin: new google.maps.Point(0, 0),
// 偏移当前坐标点(LanLng)的位置大小
anchor: new google.maps.Point(0, 46)
}
})
4. 修改标记
通过setIcon
进行标记的动态修改:
marker.setIcon({
url,
size,
...
})
5. 完全自定义标记
具体可以通过下面的demo展示。
三、形状
形状是地图上的一个对象,与纬度/经度坐标相关联。可以使用以下形状: 线,多边形, 圆形和矩形。您还可以配置形状,以便用户可以编辑或拖动它们。
接下来,我们主要介绍一下折线的API,其他形状详情请查看官网。
1. 添加折线
通过 google.maps.Polyline
构造函数生成指定的折线,该函数常用参数如下:
strokeColor
指定格式的十六进制HTML颜色"#FFFFFF",不支持命名的颜色。strokeOpacity
取值范围:[0.0, 1.0],1.0以确定线条颜色的不透明度。默认值为1.0。strokeWeight
线条的宽度(以像素为单位)。
// 1. 初始化折线
let polyline = new google.maps.Polyline({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 5
})
// 2. 以现有坐标点生成折线
let latLng = [
{lat: 37.772, lng: -122.214},
{lat: 21.291, lng: -157.821}
]
let polyline = new google.maps.Polyline({
path: latLng,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 5
})
polyline.setMap(map)
2. 删除折线
折线的删除方式和上述标记的删除方式一样,通过setMap
进行添加和删除,同样也只是在地图中移除折线,只有将折线本身设置为null
才是真正的删除。
// 从地图中移除
polyline.setMap(null)
// 删除折线本身
polyline = null
3. 添加标记到折线中
想要在折线中添加标记,那我们不得不介绍一下getPath()
,其返回type数组MVCArray
。可以通过一下方法操作折线变化:
getAt(index)
返回索引值index
对应的LatLng对象(index
从0开始)。insertAt(index)
在索引值index
处插入一个Latlng对象(即插入标记),其后面标记点向后依次移动(类似数组splice
操作)。removeAt(index)
删除索引值index
处的Latlng对象。
// 在当前折线尾部添加一个坐标点
let path = poly.getPath()
path.push(latLng)
4. 将标记在折线中删除
// 获取删除项在折线的索引值index
let path = poly.getPath()
path.removeAt(index)
四、地图小例子(实现自定义行程路线规划)
下面,我们将实现一个小的例子:路线规划。
1. 生成城市标记
首先,将城市添加到地图中,生成标记。
// 定义存储标记的表
const ALL_MARKERS = new Map()
1.1 定义生成标记的方法
// 定义生成标记的方法
const addLatLngToMap = (lat, lng) => {
// 生成坐标点
let latLng = new google.maps.LatLng(lat, lng)
let marker = new google.maps.Marker({
position: latLng,
map: this.map,
icon: {
url: '默认图像',
// icon图片大小
size: new google.maps.Size(30, 42),
// 从图片起点坐标进行截取
origin: new google.maps.Point(0, 0)
}
})
// 添加到表中
ALL_MARKERS.set('城市名称', marker)
}
1.2 为生成标记绑定事件
// 绑定事件
const addClickEvengtToMarker = (marker) => {
let listener = marker.addListener('click', e => {
...
// 移除事件
google.maps.event.removeListener(listener)
})
}
有时候,我们可能想要通过自动触发标记的绑定事件,那我们可以通过trigger
方法来实现:
google.maps.event.trigger(marker, 'click')
看到这里,大家可能会想:一般地图上的标记不仅显示一个图像,同时还可以显示当前城市名称,那这个功能,我们就可以用上述提到的完全自定义标记
来实现。
1.3 完全自定义标记
首先官网给我们提供了一个简单的例子,通过自定义弹出层OverlayView
来实现,根据官网要求,在用户自定义弹出层时,必须实现以下三个方法:onAdd()
,draw()
和onRemove()
。优化代码如下:
// 自定义弹出层
const createPopupClass = () => {
/*
* A customized popup on the map.
* @param {!google.maps.LatLng} position
* @param {!Element} content The bubble div.
* @constructor
* @extends {google.maps.OverlayView}
*/
class Popup extends google.maps.OverlayView {
constructor(position, content) {
super()
// 坐标点位置
this.position = position
// 自定义弹出层内容
this.containerDiv = content
// 若想阻止地图中缩放,点击等事件冒泡到到弹出层上的,可以通过`preventMapHitsAndGesturesFrom`进行阻止
google.maps.OverlayView.preventMapHitsAndGesturesFrom(this.containerDiv)
}
onAdd () {
// 将弹出层添加到 MapPanes 界面
this.getPanes().floatPane.appendChild(this.containerDiv)
}
onRemove () {
// setMap(null) 时,清除当前弹出层
if (this.containerDiv.parentElement) {
this.containerDiv.parentElement.removeChild(this.containerDiv)
}
}
draw () {
// 地图缩放时,动态计算弹出层位置
let divPosition = this.getProjection().fromLatLngToDivPixel(this.position)
// Hide the popup when it is far out of view.
let display =
Math.abs(divPosition.x) < 4000 && Math.abs(divPosition.y) < 4000 ?
'block' :
'none'
if (display === 'block') {
this.containerDiv.style.left = divPosition.x + 'px'
this.containerDiv.style.top = divPosition.y + 'px'
}
if (this.containerDiv.style.display !== display) {
this.containerDiv.style.display = display
}
}
}
return Popup
}
使用自定义弹出层类,同时要注意,在创建弹出层时,一定为其增加position: absolute
,否则弹出层位置会出现偏差。
const addPopupToMap = (lat, lng) => {
let Popup = createPopupClass()
// 1. 创建弹出层
let content = document.createElement('div')
content.className = 'customize-map__popup-container'
content.innerHTML = name
let popup = new Popup(
new google.maps.LatLng(lat, lng),
content
)
popup.setMap(map)
}
.customize-map__popup-container{
cursor: grab;
position: absolute;
background-color: white;
padding: 2px 3px;
border-radius: 4px;
min-width: 30px;
max-width: 200px;
text-align: center;
border: 1px solid rgb(153, 153, 153);
user-select: none;
}
2. 将指定城市添加到路线中
通过Polyline
生成指定路线,同时点击城市标记进行添加。
2.1 初始化路线
let poly = new google.maps.Polyline({
strokeColor: 'rgb(251, 109, 72)',
strokeOpacity: 0.8,
strokeWeight: 5
})
直接点击想要添加的城市标记,便可以把当前城市添加到路线(即添加到地图折线中),同时,为了把添加和为添加的城市做区分,可以通过setIcon
进行修改标记图像。
3. 从路线中删除指定城市
若想删除城市,我们可以遍历获取当前城市在路线中的位置,然后通过removeAt
进行删除。
this.poly.getPath().removeAt(index)