在 React 中接入 Google Map
业务需求,正好对接了 google map 。初次使用,碰到了很多细节问题,于是总结整理,也算是学习过程自己踩过的坑吧。
一、React 中如何引入
1.使用 google-map-react ;1
npm install --save google-map-react
使用示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
const AnyReactComponent = ({ text }) => <div>{text}</div>;
class SimpleMap extends Component {
static defaultProps = {
center: {lat: 59.95, lng: 30.33},
zoom: 11
};
render() {
return (
<GoogleMapReact
defaultCenter={this.props.center}
defaultZoom={this.props.zoom}
>
<AnyReactComponent
lat={59.955413}
lng={30.337844}
text={'Kreyser Avrora'}
/>
</GoogleMapReact>
);
}
}
2.使用 react-google-maps ;1
2npm install --save react-google-maps # or
yarn add react-google-maps
简单代码示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import {
withGoogleMap,
GoogleMap,
Marker,
} from "react-google-maps";
const MapWithAMarker = withGoogleMap(props =>
<GoogleMap
defaultZoom={8}
defaultCenter={{ lat: -34.397, lng: 150.644 }}
>
<Marker
position={{ lat: -34.397, lng: 150.644 }}
/>
</GoogleMap>
);
<MapWithAMarker
containerElement={<div style={{ height: `400px` }} />}
mapElement={<div style={{ height: `100%` }} />}
/>
友情提示,记得提前引入 Google Map API
:1
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"
二、API 调用次数限制:
Google Map
虽然是免费的,但是也是有调用次数限制,这里列举几条计数的规则:
- 重新加载;
- 调用地图;
- 切换卫星模式;
- 切换全景模式;
三、经纬度查询:
处理地图业务,可能会用到一个经纬度检测工具: GPS SPG
四、地图个性化
如果你不想局限于默认的地图,可以在这里找到答案:个性化地图样式:
首先,我们需要下载一个 JSON
类型的样式文件
其次,引入文件:1
const demoFancyMapStyles = require("./demoFancyMapStyles.json");
最后,在 Map
初始化的时候应用定义样式:1
2
3
4
5
6<GoogleMap
defaultZoom={5}
defaultCenter={props.center}
defaultOptions={{ styles: demoFancyMapStyles }}
>
</GoogleMap>
OK,大功告成,可以刷新页面查看新的地图样式了。此外,这里推荐两款样式相关的工具:
五、关于 DrawingManager
1.DrawingManager undefined
处理方式:
遇到这个问题,需要在加载 Map API
的时候初始化 libraries=drawing
,如下:1
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB8Qspe99idJxy7QlEi_VIH2Bcl9y5Mlqk&libraries=drawing"></script>
2.DrawingManagerOption
说明文档:
3.DrawManager
画图按键监听:
当我们使用 DrawManager
的时候,可能会有按键监听的需求,那么只需要这么写:1
2
3
4
5
6
7google.maps.event.addDomListener(document, 'keyup', function (e) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code === 27) {
drawingManager.setDrawingMode(null);
polygon.setMap(null);
}
});
更多内容,请查看:参考示例
4.对于 DrawManager
来说,清除地图时需要调用 setDrawingMode(null)
:1
2this._drawingManager.setDrawingMode(null);
clearFlag.setMap && clearFlag.setMap(null);
此处参考:
how-to-remove-previous-shape-when-drawing-new-shape-is-started-on-google-map
5.Draw Manage
如果要拖动图形,需要把 Clickable
设置为 True
1
2clickable: true,
draggable: true,
6.扩展 Google Draw Manager Toolbar
我们可以发现,Draw Manager
只支持给定的配置,如果我们有扩展的需求呢?此处,我们需要清除 Map
上绘制的图形,所以只能自行扩展,思路如下:
添加一个与 Draw Manager
相似的按钮,控制显示位置即可。
1 | .clearbtn{ |
7.如何给 Draw Manager
添加修改监听事件?
绘制图形最难的就是对其添加事件监听,我们需要注意两个事件 set_at
和 insert_at
1 | // Add an event listener that selects the newly-drawn shape when the user |
此处参考:
六、地图事件监听
上述例子只是列举了个别监听事件,详细请查看文档:事件监听 API
示例代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31handleOverlayComplete(event) {
let newShape = event.overlay;
clearFlag = event.overlay;
newShape.type = event.type;
shapes.push(newShape);
if (this._drawingManager.getDrawingMode()) {
this._drawingManager.setDrawingMode(null);
}
if (newShape.type === 'polygon') {
google.maps.event.addListener(newShape.getPath(), 'set_at', () => {
console.log(newShape.getPaths(), 'polygon_set_at');
});
google.maps.event.addListener(newShape.getPath(), 'insert_at', () => {
console.log(newShape.getPaths(), 'polygon_insert_at');
});
} else if (newShape.type === 'rectangle') {
google.maps.event.addListener(newShape, 'bounds_changed', () => {
console.log(newShape.getBounds(), 'rectangle_changed');
});
} else if (newShape.type === 'circle') {
google.maps.event.addListener(newShape, 'radius_changed', () => {
console.log(newShape.getRadius(), 'circle_radius_changed');
});
google.maps.event.addListener(newShape, 'center_changed', () => {
console.log(newShape.getCenter().lat(), newShape.getCenter().lng(), 'circle_center_changed');
});
}
}
七、引入多个 Map Lib
多个 Map Lib
需要在引入 API
的时候,需要用 &
连接起来,如: libraries=geometry,places&sensor=false
,示例如下:1
2<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?libraries=geometry,places&sensor=false">
此处容易出现的问题,如:
1.this api project is not authorized to use this API 如何解决:1
2
3
4
5From the picture you posted, it say it's disabled...
Go to Developer Console -> APIs & auth -> APIs
Search for Geocoding and click on Google Maps Geocoding API -> Enable API. Do the same thing for Geolocating
八、如何更改 Marker
图标:
1 | const image = { |
1.为标记添加动画:1
2
3
4
5
6marker = new google.maps.Marker({
map: map,
draggable: true,
animation: google.maps.Animation.DROP,
position: {lat: 59.327, lng: 18.067}
});
2.标记如何全部显示在可见区域:
Marker
适配示例1
2
3
4
5
6
7var markers = [];//some array
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers.length; i++) {
bounds.extend(markers[i].getPosition());
}
map.fitBounds(bounds);Circle
适配示例1
2
3
4
5
6
7
8var bounds = circle.getBounds();
bounds.union(rectangle.getBounds();
for (var aa=0; aa < arrayLatitude.length; aa++) {
var points = new google.maps.LatLng(arrayLatitude[aa], arrayLongitude[aa]);
bounds.extend(points);
}
map.fitBounds(bounds);
更多详情,请参考如下:
Marker
Circle
Shape
LatLngBounds