react地图组件

最近项目中有此需求,react地图组件的开发:
1 输入地址可查询出对应地图位置并标记点
2 能返回经纬度,并提交服务端保存
3 在地图上点击某一点,也能返回对应经纬度和地址信息
4 国内,国外均可使用

经过调研决定,采用谷歌地图和高德地图来封装组件,当渲染地图组件时,先试图请求谷歌map的api,
若能访问则使用谷歌地图,若不能访问,则调用国内高德地图,

框架环境:react+dva+antd+umiJs;其中需要用到prop-types,axios,scriptjs,对应npm安装即可。

具体组件如下:

[javascript]  view plain  copy
  1. import React from 'react'  
  2. import PropTypes from 'prop-types'  
  3. import { Spin } from 'antd';  
  4. import axios from 'axios';  
  5. import $script from 'scriptjs'  
  6. import styles from './AMap.less'  
  7.   
  8. const googleMapSdk='https://maps.googleapis.com/maps/api/js?key=your key';  
  9. const gaodeMapSdk='https://webapi.amap.com/maps?v=1.4.2&key=your key';  
  10.   
  11. let map = null;  
  12. let marker = null;  
  13. let geocoder = null;  
  14. let zoomLevel=15;  
  15.   
  16. class AMapModule extends React.Component {  
  17.   constructor(props){  
  18.     super(props);   
  19.     this.state = {  
  20.       status:0  
  21.     };     
  22.   }  
  23.   componentWillMount(){  
  24.     if(!window.AMap&&!(window.google&&window.google.maps)){  
  25.       axios.get(googleMapSdk,{timeout: 1000}).then(res => {  
  26.             $script( [googleMapSdk],function(a,b){})  
  27.           }).catch(function (error) {  
  28.             $script( [gaodeMapSdk],function(a,b){})  
  29.       });   
  30.     }  
  31.   }  
  32.   componentDidMount(){  
  33.     let _this=this;  
  34.     function listenerStorage(){  
  35.       if(window.AMap||(window.google && window.google.maps)){  
  36.         if(window.AMap) {  
  37.           const {lat, lng, getMapAddress} = _this.props;  
  38.           const latlngxy=[(!lng||lng=='undefined'||lng=='0')?116.397428:lng,(!lat||lat=='undefined'||lat=='0')?39.90923:lat];//默认北京天安门  
  39.           map = new window.AMap.Map('allmap', {  
  40.               resizeEnable: true,  
  41.               center: latlngxy,  
  42.               zoom: zoomLevel  
  43.             });  
  44.               
  45.           //高德设置语言    ['en', 'zh_en', 'zh_cn']  
  46.           let mapLang;  
  47.           if(window.localStorage.getItem('i18n') == 'en_US'){  
  48.             mapLang = 'en';  
  49.           }else{  
  50.             mapLang = 'zh_cn';  
  51.           }       
  52.           map.setLang(mapLang);  
  53.       
  54.           // 在新中心点添加 marker   
  55.           marker = new window.AMap.Marker({  
  56.               map: map,  
  57.               position: latlngxy  
  58.           });  
  59.       
  60.           map.on('click',function(e){  
  61.             marker.setPosition(e.lnglat);  
  62.             window.AMap.service('AMap.Geocoder',function(){//回调函数  
  63.               //实例化Geocoder  
  64.               geocoder = new window.AMap.Geocoder({});  
  65.               geocoder.getAddress(e.lnglat,function(status,result){  
  66.                 if(status === 'complete' && result.info === 'OK'){  
  67.                   const address=result.regeocode.formattedAddress  
  68.                   getMapAddress&&getMapAddress(address);  
  69.                 }  
  70.               })  
  71.             })  
  72.           })  
  73.         }  
  74.       
  75.         if(window.google && window.google.maps){  
  76.       
  77.           const {lat, lng, getMapAddress} = _this.props;  
  78.           const latlngxy=[(!lng||lng=='undefined'||lng=='0')?116.397428:lng,(!lat||lat=='undefined'||lat=='0')?39.90923:lat];//默认北京天安门  
  79.        
  80.           var uluru = {lat: parseFloat(latlngxy[1]), lng: parseFloat(latlngxy[0])};  // google need number  
  81.       
  82.           initMap()  
  83.           function initMap() {  
  84.             map = new window.google.maps.Map(document.getElementById('allmap'), {  
  85.                 resizeEnable: true,  
  86.                 center: uluru,  
  87.                 zoom: zoomLevel  
  88.             });  
  89.             // 在新中心点添加 marker   
  90.             marker = new window.google.maps.Marker({  
  91.                 map: map,  
  92.                 position: uluru  
  93.             });  
  94.           }  
  95.       
  96.           map.addListener('click',function(e){  
  97.             let latlng=e.latLng;  
  98.             marker.setPosition(latlng);  
  99.             geocoder = new window.google.maps.Geocoder()  
  100.             geocoder.geocode({'location': latlng}, function(results, status) {  
  101.               if (status === 'OK') {  
  102.                 const address=results[0].formatted_address  
  103.                 getMapAddress&&getMapAddress(address.substring(0,address.indexOf(' ')));  
  104.               } else {  
  105.                 console.log('Geocoder failed due to: ' + status);  
  106.               }  
  107.             });  
  108.           })  
  109.         }  
  110.         _this.setState({  
  111.           status:1  
  112.         })  
  113.       }else{  
  114.         setTimeout(function(){  
  115.           listenerStorage()  
  116.         },800)  
  117.       }  
  118.     }  
  119.     listenerStorage();  
  120.   }  
  121.   
  122.   componentWillReceiveProps=(nextProps)=>{  
  123.     const {getMapPoint}=this.props;  
  124.     if(window.AMap && nextProps.address&&nextProps.address!=this.props.address) {  
  125.       window.AMap.service('AMap.Geocoder',function(){//回调函数  
  126.           //实例化Geocoder  
  127.           geocoder = new window.AMap.Geocoder({});  
  128.           geocoder.getLocation(nextProps.address, function (status, result) {  
  129.             if (status === 'complete' && result.info === 'OK') {  
  130.               let latlng = result.geocodes[0].location;  
  131.               getMapPoint&&getMapPoint(latlng);  
  132.               // 设置缩放级别和中心点  
  133.               let latlngxy = [latlng['lng'],latlng['lat']];  
  134.               const currentZoom=map.getZoom();  
  135.               map.setZoomAndCenter(currentZoom!=zoomLevel?currentZoom:zoomLevel, latlngxy);  
  136.               // 在新中心点添加 marker   
  137.               marker.setPosition(latlng);  
  138.             } else {  
  139.               console.log('search "' + nextProps.address + '" no data')  
  140.             }  
  141.           });  
  142.       });  
  143.     }  
  144.   
  145.     if(window.google && window.google.maps && nextProps.address&&nextProps.address!=this.props.address){  
  146.       geocoder = new window.google.maps.Geocoder()  
  147.       geocoder.geocode({'address': nextProps.address}, function(results, status) {  
  148.         if (status === 'OK') {  
  149.           let latlng = results[0].geometry.location;  
  150.           getMapPoint&&getMapPoint({lat:latlng.lat(),lng:latlng.lng()});  
  151.           map.setCenter(latlng);  
  152.           // 在新中心点添加 marker   
  153.           marker.setPosition(latlng);  
  154.         } else {  
  155.           console.log('Geocode was not successful for the following reason: ' + status);  
  156.         }  
  157.       });  
  158.     }  
  159.   }  
  160.    
  161.   render(){  
  162.     const { height } = this.props;  
  163.     return(  
  164.       <div className={styles.container} style={{height:height?height:300}}>  
  165.         <Spin spinning={this.state.status==0?true:false} tip="Loading...">  
  166.           <div id="allmap" className={styles.mapContainer} style={{height:height?height:300}} />  
  167.         </Spin>  
  168.       </div>  
  169.     )  
  170.   }  
  171. }  
  172.   
  173. AMapModule.propTypes = {  
  174.   lng: PropTypes.string,  
  175.   lat: PropTypes.string,  
  176.   className: PropTypes.string,  
  177. }  
  178.   
  179. export default AMapModule              

调用如下:

[javascript]  view plain  copy
  1. <div style={{width:'500px'}}>  
  2.             <Form>  
  3.                 <FormItem  
  4.                           label={  
  5.                             <span>  
  6.                               地址  
  7.                             </span>  
  8.                           }>  
  9.                           {getFieldDecorator('position', {  
  10.                             initialValue: '北京'  
  11.                           })(  
  12.                             <Input placeholder={'请输入地址'} />  
  13.                             )}  
  14.                 </FormItem>  
  15.                 <FormItem  
  16.                 label={  
  17.                     <span>  
  18.                       经度  
  19.                     </span>  
  20.                   }>  
  21.                               {getFieldDecorator('longitude', {  
  22.                                 initialValue: ''  
  23.                               })(  
  24.                                 <Input />  
  25.                                 )}  
  26.                           </FormItem>  
  27.                           <FormItem label={  
  28.                     <span>  
  29.                       维度  
  30.                     </span>  
  31.                   }>  
  32.                               {getFieldDecorator('latitude', {  
  33.                                 initialValue: ''  
  34.                               })(  
  35.                                 <Input/>  
  36.                                 )}  
  37.                 </FormItem>  
  38.                   
  39.                     <AMap   
  40.                         lng={''}  
  41.                         lat={''}  
  42.                         address={getFieldValue('position')}  
  43.                         getMapPoint={(point)=>{  
  44.                             setFieldsValue({  
  45.                                 latitude: point.lat,  
  46.                                 longitude: point.lng  
  47.                             });  
  48.                         }}  
  49.                         getMapAddress={(address)=>{  
  50.                             setFieldsValue({  
  51.                                 position: address  
  52.                             });  
  53.                         }}  
  54.                     />  
  55.                   
  56.             </Form>  
  57.             </div>  

截图示例如下:


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值