react-amap 高德地图 react组件

1,194 阅读2分钟

react-amap 高德地图 react组件

直接上代码(注意高德定位api需要在https下使用)

官网定位文档: lbs.amap.com/api/javascr…

import React, { Component } from 'react';
import { Select, Modal, Button, Input } from 'antd';
import { Map, Marker } from 'react-amap';

class Index extends Component {
    constructor(props) {
        super(props);
        this.state = { 
            mapSearchValue:null,
            detailedAddress:'',
            qrcodeModalVisible: false,
            pois:[],
            signAddrList:[],
            latNum:39.90932,
            lngNum:116.396961,
            _zoom:10,
            twoPage:false,
        }
    }
      //地图搜索
   getMapSearch=(val)=>{
	const place = new window.AMap.PlaceSearch({
		pageSize: 10,
		pageIndex: 1,
		// citylimit: true,    // 仅搜索本城市的地名
		// city, // 限制为只能搜索当前地区的位置
        extensions:'all'
	})
	  // 进行搜索
	place.search(val,(status, result)=>{
		const {info,poiList} = result
		if(result.length || info  !== 'OK') return
		if(poiList.pois){
			this.setState({
				pois:poiList.pois,
			})
		}
	})
  }
  getMapChange=(id)=>{
	const signAddrList= this.state.pois.find(item => item.id === id) || null
	const {
		location: { lat, lng },
	} = signAddrList
	if(signAddrList){
        let cityName = ''
        if(signAddrList.pname === signAddrList.cityname){
            cityName = signAddrList.cityname
        }else{
            cityName = signAddrList.pname + signAddrList.cityname
        }
		this.setState({ 
			signAddrList:signAddrList,
			mapSearchValue: cityName + signAddrList.adname + signAddrList.name,
            detailedAddress: cityName + signAddrList.adname + signAddrList.address,
            latNum:lat,
            lngNum:lng,
            _zoom:14
		})
	}
  }

    getEvents = () => {
        return {
            click: (e) => {
                const {
                    lnglat: { lat, lng },
                } = e

                window.AMap.plugin('AMap.Geocoder', () => {
                    const geocoder = new window.AMap.Geocoder({
                        city: '北京',
                        citylimit: true,
                        extensions:'all'
                    })
                    // 根据给定坐标进行解析
                    geocoder.getAddress([lng, lat], (status, result) => {
                        // 当编码执行成功时触发此事件
                        if (status === 'complete' && result.info === 'OK') {
                            const {  regeocode:{ addressComponent={} }  } = result
                            this.setState({
                                latNum: lat,
                                lngNum: lng,
                                _zoom: 14,
                                mapSearchValue: result?.regeocode?.formattedAddress,
                                detailedAddress:addressComponent.province+addressComponent.city+addressComponent.district+addressComponent.township+addressComponent.street+(addressComponent.streetNumber+''),
                            })
                            this.getMapSearch(result?.regeocode?.formattedAddress)
                        }
                    })
                })
            },
            // created必须要拥有,用来初始化创建相应对象
            created: () => {
                let auto
                let placeSearch
                window.AMap.plugin('AMap.Autocomplete', () => {
                    auto = new window.AMap.Autocomplete({
                        input: 'tipinput',
                        pageSize: 10,
                        pageIndex: 1,
                        // citylimit: true,    // 仅搜索本城市的地名
                        // city: '昆明', // 限制为只能搜索当前地区的位置
                        outPutDirAuto: true
                    });
                })
                // 创建搜索实例
                window.AMap.plugin('AMap.PlaceSearch', () => {
                    placeSearch = new window.AMap.PlaceSearch({
                        input: 'tipinput',
                        pageSize: 10,
                        pageIndex: 1,
                        // citylimit: true,    // 仅搜索本城市的地名
                    });
                })
                window.AMap.event.addListener(auto, "select", (e) => {
                    placeSearch.search(e.poi.name)
                })
                 this.getCurrentCity()
            },
        }
    }
    
    getCurrentCity = ()=>{
        //高德api定位需要在https下使用 否则定位超时定位失败
        let that = this;
        const mapObj = new window.AMap.Map('iCenter');
        mapObj.plugin('AMap.Geolocation', function() {
          const geolocation = new window.AMap.Geolocation({
            // 是否使用高精度定位,默认:true
            enableHighAccuracy: true,
            // 设置定位超时时间,默认:无穷大
            timeout: 5000,
            // 定位按钮的停靠位置的偏移量
            offset: [10, 20],
            //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
            zoomToAccuracy: true,
            //  定位按钮的排放位置,  RB表示右下
            position: 'RB'
          })
    
          geolocation.getCurrentPosition(function(status,result){
            if(status=='complete'){
              onComplete(result)
            }else{
              onError(result)
            }
          });
    
          function onComplete (data) {
            // data是具体的定位信息
            console.log("项目内自己定位适用ios",data);
            const { position:{ lat=39.90932,lng=116.396961 }} = data;
            that.getMapInFo( lng,lat,14);
          }
    
          function onError (error) {
            // 定位出错
     
          }
        });
     }

    nextPege = () =>{
        this.setState({
            twoPage:true
        })
    }

    getFooterDom = () =>{
        const { handelCancel, handelSubmit } = this.props;
        const { twoPage, mapSearchValue, lngNum, latNum, detailedAddress } = this.state;
        return (<div>
            {!twoPage ? <>
                <Button onClick={handelCancel}>关闭</Button>
                <Button type='primary' onClick={this.nextPege} disabled={!mapSearchValue}>下一步</Button>
            </> :
                <>
                    <Button onClick={() => { this.setState({ twoPage: false }) }}>上一步</Button>
                    <Button type='primary' onClick={() => {
                        // if(!mapSearchValue){
                        //     message.warning('请填写地址名称!')
                        //     return false;
                        // }
                        let arr = [{
                            mapSearchValue,
                            detailedAddress,
                            lngNum,
                            latNum,
                        }]
                        handelSubmit(arr);
                        this.setState({twoPage:false}) }}>确定</Button>
                </>
            }
        </div>)
    }

    render() { 
        const { mapSearchValue, lngNum,latNum, twoPage, detailedAddress, _zoom } = this.state;
        const { mapModalVisible, handelCancel } = this.props;
        const plugins = [
            {
            name: 'ToolBar',
            options: {
                visible: true, // 不设置该属性默认就是 true
                onCreated(ins) {
                // console.log(ins)
                },
            },
            },
        ]

        return ( 
            <Modal
                title='添加处理位置'
                width={680}
                visible={mapModalVisible}
                onCancel={handelCancel}
                footer={ this.getFooterDom() }
                className='addMapMod'
                >
               { !twoPage ? <div className='mapBox' style={{ width: '100%', height: '300px' }}>
                    <Select
                        style={{width:300, zIndex:1}}
                        showSearch
                        placeholder='搜索地点'
                        value={mapSearchValue}
                        onSearch={this.getMapSearch}
                        onChange={this.getMapChange}
                        filterOption={false}
                        className="meetingMapInput"
                        suffixIcon={<i className="iconfont">&#xe623;</i>}
                    >
                        {
                            this.state.pois.length != 0 && this.state.pois.map(item=>
                                {
                                    let cityName = ''
                                    if(item.pname === item.cityname){
                                        cityName = item.cityname
                                    }else{
                                        cityName = item.pname + item.cityname
                                    }
                                    return(
                                        <Select.Option key={item.id} value={item.id}>
                                            <span>{item.name}</span>
                                            &nbsp;&nbsp;
                                            <span style={{color:'#898d97'}}>{cityName}</span>
                                            <span style={{color:'#898d97'}}>{item.adname}</span>
                                        </Select.Option>
                                    )
                                }
                            )
                        }
                    </Select>
                    <Map 
                        amapkey={'42c177c66c03437400aa9560dad5451e'} 
                        events={this.getEvents()} plugins={plugins}  
                        center={[lngNum,latNum]}
                        zoom={_zoom}
                        >
                        {mapSearchValue&&
                        <Marker 
                            position={{longitude: lngNum, latitude: latNum}}
                            />}
                    </Map>
                </div>:
                <div className='mapInfo' style={{height:300}}>
                    <div className='oneInfo'>
                        <label>地址名称:</label> <Input placeholder='请填写地址名称' value={mapSearchValue} style={{width:360,height:36}} onChange={(e)=>{this.setState({mapSearchValue:e.target.value})}}/>
                    </div>
                    <div style={{margin:'4px 0px',color:'#111f2c66'}}>请完善发生地点名称</div>
                    <div className='twoInfo'>
                        <label>详细地址:</label> <span> {detailedAddress} </span>
                    </div>
                </div> 
                }
            </Modal>
         );
    }
}
 
export default Index;