React Amap 官方文档
最近做后台选址地图的更换,由百度地图换到高德地图。原有功能为用户先圈定城市范围,点击定位图标,打开弹窗,将用户原有的地图信息以经纬度的形式带入,地图中心点切换为当前经纬度,用户可以通过搜索选择地址,在右侧选择详细地址后点击确定,将选择的信息带出,关闭弹窗。
涉及到的高德地图API有地址编码与逆编码、poi选点,地图展示。
具体效果如下:
具体实现代码如下:
import React, { memo } from 'react';
import { Map, Markers } from 'react-amap';
import { debounce } from 'lodash';
import { AutoComplete, Spin, Cascader, Modal, Input } from 'antd';
import styles from './mapSelect.less';
import ManageForm from './ManageForm';
import activeIcon from './location_active.png';
import localIcon from './location.png';
let loading;
// 高德地图实例
let mapInstance = null
export default class MapSelect extends React.PureComponent {
state = {
loading: true,
searchResult: [],
current: null,
address: '',
city: '北京市',
point: null
};
// init after localSearch
doSearch = () => {};
async componentWillReceiveProps(props) {
if (props.visible) {
const city = props.city || '北京市';
this.setState(
{
address: props.address,
city,
loading: true,
},
() => {
if (Array.isArray(props.point)) {
console.info('from point', props.point)
this.setState({
point: props.point
})
} else {
console.info('from name', city)
}
}
);
}
}
emit = (key, item) => {
if (typeof this.props[key] === 'function') {
this.props[key](item);
}
};
onOk = () => {
const { current } = this.state;
if (!current) {
return Modal.error({
title: '提示',
content: '请选择一个地址',
});
}
this.emit('onChange', current);
this.clear();
};
onCancel = () => {
this.props.onCancel();
this.clear();
};
clear() {
this.setState({
searchResult: [],
current: null,
address: '',
city: '北京市',
});
}
onInputChange = e => {
const address = e.target.value;
this.setState(
{
address,
loading: true,
},
() => {
this.doSearch(address);
}
);
};
render() {
const { address, city } = this.state;
const { visible } = this.props;
const amapEvents = {
created: (el) => {
// react amap 自带的生命周期,在这里可以执行一些初始化操作
mapInstance = el
AMap.service(["AMap.PlaceSearch"], () => {
// 构造地点查询类
this.doSearch = debounce(doSearch.bind(this), 500);
let placeSearch = new AMap.PlaceSearch({
pageSize: 10, // 单页显示结果条数
pageIndex: 1, // 页码
city, // 兴趣点城市
citylimit: true, // 是否强制限制在设置的城市内搜索
map: mapInstance, // 展现结果的地图实例
panel: "panel", // 结果列表将在此容器中进行展示。
autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
});
AMap.event.addListener(placeSearch,"selectChanged",(e) => {
console.log('e', e);
this.setState({
current: e.selected.data
})
mapInstance.setZoomAndCenter(17, [e.selected.data.location.lng, e.selected.data.location.lat]) // 设置中心点
})
// 经纬度查询
if (Array.isArray(this.props.point)) {
placeSearch.searchNearBy('', this.state.point, 500, (status, result) =>{
console.log('result1', this.state.point, status, result)
if (status === 'complete') {
this.setState({
searchResult: result.poiList.pois,
current: result.poiList.pois[0]
})
} else {
this.setState({
searchResult: [],
current: null
})
}
})
} else {
// 关键字查询
console.log('this.state.address', this.state.address)
this.doSearch(city + '政府')
}
function doSearch (value) {
if (this.state.searchResult.length) {
this.setState({
searchResult: [],
});
}
if (value) {
placeSearch.search(city + value, (status, result) => {
console.log('result3', this.state.address, status, result)
if (status === 'complete') {
this.setState({
searchResult: result.poiList.pois,
current: result.poiList.pois[0]
})
} else {
this.setState({
searchResult: [],
current: null
})
}
});
}
}
});
},
click: (e) => {
console.log('ee', e)
}
}
return (
<Modal
className={styles.modal}
width="1000px"
title={city}
visible={visible}
onOk={this.onOk}
onCancel={this.onCancel}
>
<div className={styles.address}>
搜索:
<Input value={address} allowClear onChange={this.onInputChange} />
</div>
{visible &&
<div className={styles.main}>
<Map loading={<Spin />} events={amapEvents} amapkey='高德地图key' />
<div id='panel' style={{overflowY: 'auto', width: '300px'}} />
</div>}
</Modal>
);
}
}