antd pro中使用react-amap,拖拽icon获取经纬度

1,422 阅读1分钟

记录在antd pro中使用react-amap,调用高德地图,代码如下
这个是封装的组件,请自行删减

预览如下:
输入框与地图联动,双向数据绑定
拖拽选点,可以与Form表单使用
数据回填直接设置state中经纬度即可

import React, { Component } from 'react'
import { Map, Marker } from 'react-amap';
import { Input, Form, message } from 'antd';
import PropTypes from 'prop-types'
import styles from './index.less'
// import point from '@/assets/aliMap/point_s.png'

export default class AliMap extends Component {
	formRef = React.createRef();

	static propTypes = {
		name: PropTypes.string,
		label: PropTypes.string
	}

	static defaultProps = {
		name: 'detailAddress',
		label: '详细地址'
	}


	constructor() {
		super();
		this.state = {
			inputValue: '',
			// 展示中心经纬度和默认Marker经纬度(没啥用)
			center: '',
			position: {
				longitude: '116',
				latitude: '39'
			},
			// 拖拽小点的经纬度
			markerPosition: [],
			lnglatObj: { longitude: null, latitude: null },
			// Map配置
			mapPlugin: {
				zoom: 10,
				customLayer: true,
				amapkey: '高德地图的key',
				draggable: true
			},
		};

		// Map事件
		this.mapEvents = {
			created: (map) => {
				this.mapInstance = map;
				this.showCenter();
				this.getGeocoder(AMap)
				this.inputTip(AMap)
				this.citySearch(AMap)
				this.setAMap(AMap)
			},
			moveend: () => { this.showCenter() }
		};


		// Marker事件
		this.markerEvents = {
			dragend: (e) => {
				this.dragendMarker(e)
				this.getGeocoder(AMap)

			}
		}
	}

	setAMap = AMap => {
		this.AMap = AMap
	}

	// 拖拽Marker后获取经纬度
	dragendMarker = e => {
		const { Q, R } = e.lnglat
		this.setState({
			markerPosition: [R, Q],
			lnglatObj: { longitude: R, latitude: Q }
		})
	}

	getGeocoder = AMap => {
		AMap.plugin('AMap.Geocoder', () => {
			const geocoder = new AMap.Geocoder({
				city: '全国'
			})
			this.geoCode(geocoder)
		})
	}


	citySearch = AMap => {
		// 展示使用者当前所在城市
		AMap.plugin('AMap.CitySearch', () => {
			const citySearch = new AMap.CitySearch()
			citySearch.getLocalCity((status, result) => {
				if (status === 'complete' && result.info === 'OK') {
					const { rectangle } = result
					// 根据模糊经纬度计算中心点
					const longitude = (Number(rectangle.split(';')[0].split(',')[0]) + Number(rectangle.split(';')[1].split(',')[0])) / 2
					const latitude = (Number(rectangle.split(';')[0].split(',')[1]) + Number(rectangle.split(';')[1].split(',')[1])) / 2
					this.setState({
						position: {
							longitude,
							latitude
						}
					})
				}
			})
		})
	}



	inputTip = AMap => {
		// 输入联想提示
		AMap.plugin(['AMap.Autocomplete', 'AMap.PlaceSearch'], () => {
			const autoOptions = {
				city: "", // 城市,默认全国
				input: "keyword"// 使用联想输入的input的id
			};
			const autocomplete = new AMap.Autocomplete(autoOptions);
			AMap.event.addListener(autocomplete, "select", e => {
				this.setInputValue(e.poi.name)
				const { location, location: { lat, lng } } = e.poi
				if (e.poi.id) {
					this.setState({
						// center: `${location}`,
						position: {
							longitude: lng,
							latitude: lat
						}
					})
				} else {
					message.error('您选择的地址有误,请重新输入!')
				}
			});
		});
	}

	setInputValue = e => {
		// this.refs.detailAddress.state.value=e
		const { lnglatObj } = this.state
		this.setState({
			inputValue: e
		})
		this.props.form.setFieldsValue({
			detailAddress: { address: e, lnglatObj },
		})
		console.log(this.props.form.getFieldValue('detailAddress'))
	}

	geoCode = geocoder => {
		// 正向地理编码
		geocoder.getLocation('', (status, result) => {
			if (status === 'complete' && result.info === 'OK') {
				const { location, location: { lat, lng } } = result.geocodes[0]
				this.setState({
					center: `${location}`,
					position: {
						longitude: lng,
						latitude: lat
					},
				});
			}
		})
		// 逆向地理编码
		geocoder.getAddress(this.state.markerPosition, (status, result) => {
			if (status === 'complete' && result.info === 'OK') {
				// result为对应的地理位置详细信息
				this.setInputValue(result.regeocode.formattedAddress)
			}
		})
	}

	handleChangeDetailAddress = e => {
		this.setState({
			inputValue: e.target.value
		})
	}

	showCenter() {
		this.setState({
			center: `${this.mapInstance.getCenter()}`,
		});
	}

	render() {
		const { name, label } = this.props
		const { mapPlugin } = this.state
		return <Form.Item name={name} label={label}>
			<div style={{ width: '100%', height: '400px' }} className={styles.AliMapBigBox}>
				<Input
					placeholder='请输入'
					id='keyword'
					style={{ marginBottom: 16, width: '100%' }}
					className='ant-input' value={this.state.inputValue}
					ref='detailAddress'
					onChange={this.handleChangeDetailAddress}
				/>
				<Map events={this.mapEvents} {...mapPlugin} center={this.state.position} >
					<Marker position={this.state.position} style={{ width: 19, height: 33 }} events={this.markerEvents} dragstart={this.dragstart} draggable={true} />
				</Map>
			</div >
		</Form.Item >
	}
}