精华内容
下载资源
问答
  • react-amap
    千次阅读
    2018-08-07 21:31:23

    当前高德地图的react版本

    当前react版本amap的开源库react-amap介绍

    • 使用方法
    import React from 'react';
    import ReactDOM from 'react-dom';
    import { Map, Polygon } from 'react-amap';
    
    ReactDOM.render(
     <Map amapkey={YOUR_AMAPKEY} version={VERSION} useAMapUI={USE_AMAP_UI} events={EVENTS_MAP}>
       <Polygon path={...} bubble={...}/>
     </Map>,
     document.querySelector('#app')
    )

      使用过程中需要注意,amapkey和version需要作为Map属性传入,组件内部实现了高德地图相关js文件的加载:(https://webapi.amap.com/maps?v=1.4.8&key=您申请的key值).
      组件的使用主要在events属性中,events属性是一个事件处理函数集合,组件相关的事件均可在events中处理,但Map中有一个特殊事件,Map组件创建完后会触发created事件,在这个事件处理函数中可以做一些初始化,另外,其他的地图上触发事件如click等均可放到events中传入.如下例子:

        events = {
          created: map => {
            this.setState({ mapInstance: map });
            window.AMap.plugin('AMap.Geocoder', () => {
              let geocoder = new window.AMap.Geocoder({
                //city: "010"//城市,默认:“全国”
              });
              this.setState({ geocoder });
            });
          },
          click: mapevt => {
            //console.log('mapevt:', mapevt);
            let gps = mapevt.lnglat;
            this.getAddressByGps(gps)
              .then(retAddr => this.setState({ ...retAddr }))
              .catch(error => {
                console.log('error!', error);
              });
            this.setState({ gps });
          },
        };

      created事件比较特殊,可以在此事件中初始化一些非可视化插件,比如AMap.Geocoder,AMap.Geolocation等,如上例,初始化了AMap.Geocoder ,并且塞到state中,以后可以被调用.注意调用时最好判断this.state.geocoder是否为空.
      其他详细使用方法参照官网.

    react-amap使用中的注意事项及使用体验

    1. created是加载高德js完毕触发的事件,参数为map实例,可以之后调用map的方法,在createdwindow.AMap已经加载完成,可以调用AMap相关子类及方法等,注意map是Map类的实例.
    2. 每次调用高德地图都在<Map events={created:func}>中的created中获取window.AMap,多个页面都调用了Map,会导致每个Map都要处理created函数,初始化逻辑非常冗余.如果使用redux,这部分初始化代码最好能独立,使用一个action直接获取后放入到store中,后续不用再处理created事件.
    3. 还是created造成的问题,一般非显示组件在这里面初始化,同时会保存下来供后续使用.但每个Map一般都会用到一些组件,都得重新初始化,重新创建,增加了很多没必要的开销.
    4. 对于一些非显示组件的使用,会用到window.AMap.event.addListener ,用常规回调函数方式,感觉不是很react,例子如下.这部分可以使用高德AMap的webservice替代,地址:(概述-Web服务 API | 高德地图API).
              window.AMap.event.addListener(geolocation, 'complete', data => {
                console.log('data:', data);
                //let center = {}
                ///this.setState({center:data.position, gps:data.position});
                this.setState({ center: data.position });
              }); //返回定位信息

      其他优缺点,大家可以补充.

    新的解决方案react-amap-next,重复造这个轮子的出发点

    项目地址(windsome/react-amap-next)
    1. created方法在每个Map加载中都写,重复工作大.逻辑判断复杂,非常不适合react以数据为导向的思想,初始化只不过加载高德地图的js文件,加载完成后获得window.AMap类,后续开发均基于此类.基于此,可以将初始化部分独立出来,作为一个函数loadMap调用.
    2. 对于组件的属性的设置, react-amap只是支持有限的属性.我期望实现一种方便支持所有属性的方式, 同时希望属性能方便被更新, 这导致我给组件加一个options的想法,所有属性都写在里面.
    3. 对于组件属性的更新,我希望直接修改options即完成对属性的更新,而不用手动去调用setXXX方法.
    4. 我希望得到组件的高德实例,有个某些特殊情况下需要特殊控制(一般比较少).我采用refer参数方式,类似react中的ref机制,我只实现了简单的函数方式.
    5.events的处理,我希望使用原有方式,但我希望能方便更新.
    6. 总之,我希望使用起来非常简单,并且不出错.

    react-amap-next方案介绍

    1. 地图加载部分,api.js中包装 APILoader.js, 最后通过loadMap函数给外界调用初始化过程.
    2. 地图组件部分, Map.js Marker.js MassMarks.js Polygon.js Polyline.js InfoWindow.js
    3. events部分, 使用on,off方式注册及取消某个事件.
    4. 组件的开发:主要实现constructor, componentDidMount componentDidUpdate componentWillUnmount render 函数,详细可以查看源码.主要把握创建高德实例和销毁高德实例过程.

    react-amap-next使用方法

    // 首先安装react-amap-next
    yarn add react-amap-next
    // 加载所需组件
    import { loadMap } from 'react-amap-next/lib/api'; //加载高德地图方法,如果与redux配合,可以写在action/reducer中
    import Map from 'react-amap-next/lib/Map';
    import Marker from 'react-amap-next/lib/Marker';
    
    // 在componentDidMount中加载js
    componentDidMount() {
      loadMap('<amap-key>').then(AMap=>{
        // 可在此做一些初始化
        this.setState({AMap});
      })
    }
    // 在render中使用Map,注意其中参数refer类似react中ref,只支持函数,可以获得amap实例;options是参数,更新的参数也通过此处传下去,events是地图事件的回调,设置后将会被调用,可以触发属性的改变.
    // 一般地图组件都包含AMap, refer, options, events4个属性.
    // 注意, options和events中的函数和变量最好都为外面声明的,而不使用匿名的函数.否则容易触发事件的频繁移除及更新,耗费性能.
    render() {
      return (
      <Map refer={} AMap={this.state.AMap} style={{width:1200, height:800}} options={{}} events={{}} >
      </Map>
      )
    }

    具体用例参考src/App.js.

    react-amap-next的不足之处

    1. events属性,是一些事件处理函数的集合,最好不要是写在render中的函数或匿名函数,否则每次render函数都会重新实例化,会导致频繁调用on和off进行绑定和解绑事件.
    2. options属性是高德组件的属性集合,参考高德官方文档即可.某些调用set进行设置的内容,可以作为属性添加,还有一些属性是AMap类中的一些子类,看起来比较复杂.并且属性是进行深比对,不一样的就会更新.
    3. 目前组件还比较少,只满足了我个人的使用需求,有待增加
    更多相关内容
  • react使用高德地图react-amap:Map、Markers、Circle、ContextMenu、自定义ContextMenu
  • React AMap 基于 React 封装的高德地图组件,助你轻松的接入到 React 项目中。 本库主要参考 饿了么,API基本一致。 与饿了么[react-amap]区别如下: 采用context共享map实例,其他组件没有必要一定是Map组件的子...
  • react-native-amap3d react-native高德地图组件,使用最新的3D SDK,支持Android + iOS,受启发,提供功能丰富且易用的接口。 相关项目推荐: 关联文档: : 功能 地图模式切换(常规,卫星,导航,夜间) 3D建筑...
  • react-amap是一个基于React封装的高德地图组件;帮助您轻松的接收地图到React项目中。此外必须引用的Map组件外,我们目前提供了最常用的10个地图组件,能满足大部分简单的业务场景;如果你有更复杂的需求,或者找到...
  • react-amap react中调用高德地图 amap gaode 适用方法非常简单 1.你只需要创建一个文件,复制AmapInit到这个文件 2.然后在对应的react组件中的componentDidMount中引用对应的AmapInit方法就可以了。 3.如果你需要更...
  • React AMap — 基于 React 的高德地图组件 目录 搜索区域代码 地图区域代码 自定义菜单样式 复杂而且不好口述,直接上代码,后面出视频 搜索区域代码 // ------------------外部资源 import React, { ...

     

    React AMap — 基于 React 的高德地图组件

    目录

    搜索区域代码

    地图区域代码

    自定义菜单样式


    复杂而且不好口述,直接上代码,后面出视频

    搜索区域代码

    // ------------------外部资源
    import React, { useEffect } from 'react'
    import { observer } from 'mobx-react-lite'
    import { Form, Button, Input, Select } from 'antd'
    const { Option } = Select
    // ------------------内部公共
    import SearchSelect from "react-antd-search-select";
    
    // ------------------内部私有
    import store from '../../store'
    
    export default observer(() => {
      const [form] = Form.useForm()
    
      const onEmployeeChange = () => {
        form.setFieldsValue({ customerId: undefined })
        store.setStore({ customerId: '' })
        onSearchParamsChange()
      }
    
      // 搜索客户
      const onSearchParamsChange = () => {
        const data = form.getFieldsValue(true)
        data.area = undefined
        data.range = undefined
        if (data.employeeId) {
          store.setStore({ employeeId: data.employeeId })
          store.getCustomerLocationList(data)
        } else {
    
          store.setStore({
            employeeId: '',
            customerId: '',
            visitInfo: {},
            customerLocationList: []
          })
        }
      }
    
      // 客户
      const onCustomerChange = (value) => {
        store.setStore({ customerId: value })
      }
    
      // 重置
      const handleClear = () => {
        const employeeId = form.getFieldsValue(true).employeeId
        form.resetFields()
        form.setFieldsValue({ employeeId })
        store.setStore({ customerId: null, range: undefined, area: '' })
        employeeId && store.getCustomerLocationList({ employeeId })
      }
    
      useEffect(() => {
        if (store.useInfo?.isSale) {
          form.setFieldsValue({
            employeeId: store.useInfo?.employeeId
          })
          store.getCustomerLocationList({ employeeId: store.useInfo?.employeeId })
        }
      }, [store.useInfo])
    
      useEffect(() => {
        form.setFieldsValue({ range: store.range, area: store.area })
      }, [store.range, store.area])
    
      return (
        <>
          <div className="search-block">
            <Form
              layout="inline"
              form={form}
            >
              <Form.Item label="销售" name="employeeId">
                <SearchSelect
                  url="/api/selectEmployee"
                  width={200}
                  onChange={onEmployeeChange}
                />
              </Form.Item>
              <Form.Item label="合作状态" name="customerSignType">
                <Select placeholder="请选择" allowClear onChange={onSearchParamsChange} style={{ width: 100 }}>
                  <Option value={0}>未合作</Option>
                  <Option value={1}>合作中</Option>
                  <Option value={2}>合作结束</Option>
                </Select>
              </Form.Item>
              <Form.Item label="客户" name="customerId">
                <SearchSelect
                  value={store.customerId}
                  width={200}
                  url="/customermap/search-customer.json"
                  ajaxData={{
                    initCondition: 'Init_LptCustomer',
                    queryField: 'name',
                    queryType: 'select_customer',
                    isNeedPerssion: true,
                    extendCondition: JSON.stringify([{"queryField":"creatorId","queryOption":"=","queryValue": store.employeeId}])
                  }}
                  onChange={onCustomerChange}
                />
              </Form.Item>
              <Form.Item name="area">
                <Input placeholder="区域/地点" allowClear
                       onChange={(e) => store.setStore({ area: e.target.value })} />
              </Form.Item>
              <Form.Item name="range">
                <Select placeholder="周边" allowClear style={{ width: 100 }}
                        onChange={(value) => store.setStore({ range: value })}
                >
                  <Option value={1}>1公里以内</Option>
                  <Option value={2}>2公里以内</Option>
                  <Option value={3}>3公里以内</Option>
                  <Option value={4}>4公里以内</Option>
                  <Option value={5}>5公里以内</Option>
                </Select>
              </Form.Item>
              <Form.Item>
                <Button onClick={handleClear}>清除</Button>
              </Form.Item>
            </Form>
          </div>
    
          <style jsx>{`
            .search-block {
              padding: 10px 20px;
            }
          `}</style>
        </>
      )
    })
    

    地图区域代码

    // ------------------外部资源
    import React, { useState, useEffect, useRef } from 'react';
    import { observer } from 'mobx-react-lite'
    import { toJS } from "mobx";
    import {Modal, Spin } from 'antd';
    import { Map, Markers, Circle } from 'react-amap';
    import { useDebounceFn } from "ahooks";
    // ------------------内部公共
    import EditVisitPlan from "@components/EditVisitPlan";
    import mark_gray from '@static/images/mark_gray.png'
    import mark_green from '@static/images/mark_green.png'
    // ------------------内部私有
    import store from '../../store'
    import './index.less'
    let currentMarkerData = {}
    let markerMap = []
    let MapsOption = {}
    
    // 自定义菜单
    const CustomContextMenu = ({ coverLocations, mapsOption, showRange, addVisit, setCurrentMarkerData }) => {
      return (
        <ul className="custom-amap-menu"
            style={{
              left: mapsOption.pixel.x + 5,
              top: mapsOption.pixel.y
            }}>
          {
            coverLocations.map(item => {
              const row = JSON.parse(item)
              return <li key={row.customerId}>
                <span>{row.customerName}</span>
                <ul className="customer-menus">
                  <li onClick={() => {
                    setCurrentMarkerData?.(row)
                    showRange?.()
                    }}>显示周边范围</li>
                  <li onClick={() => {
                    setCurrentMarkerData?.(row)
                    addVisit?.()
                  }}>增加拜访计划</li>
                  <li><a href={`/customer/todetail/?customerId=${row.customerId}&isinfoEdit=1`} target="_blank">重新维护地址</a></li>
                  <li><a href={`/customervisitplan/listall/?customer_id=${row.customerId}`} target="_blank">查看拜访记录</a></li>
                  <li><a href={`/customer/todetail/?customerId=${row.customerId}`} target="_blank">查看客户详情</a></li>
                </ul>
              </li>
            })
          }
        </ul>
      )
    }
    
    export default observer(() => {
      const mapInstance = useRef(null); // created map 记录map实例instance
      const contextMenu = useRef(null); // 菜单
      const [zoom, setZoom] = useState(11) // 缩放
      const [coordinates, setCoordinates] = useState([]) // 当前坐标点
      const [radius, setRadius] = useState(0) // 半径范围range
      const [markers, setMarkers] = useState([]) // Markers 数据
      const [visible, setVisible] = useState(false) // Circle 显示
      const [editVisitPlanVisible, setEditVisitPlanVisible] = useState(false) // 增加拜访计划显示
      const [customContextMenuVisible, setCustomContextMenuVisible] = useState(false) // 自定义菜单显示
    
      // 监听客户位置列表变化,控制地图显示
      useEffect(() => {
        getMarkers()
        store?.visitInfo?.city && debounceSetAddrLocation.run(store?.visitInfo?.city)
      }, [store.customerLocationList])
    
      // 监听客户变化
      useEffect(() => {
        if (markers.length && (store.customerId || store.customerId === 0)) {
          const customer = markers.find(item => {
            return item?.extData?.customerId === Number(store.customerId)
          })
          console.log('customer', customer);
    
          if (customer) {
            setZoom(16)
            setCoordinates(customer.position)
            store.setStore({ range: 3, customer })
            setVisible(true)
    
            setIconRed(customer, 500)
    
          } else {
            store.setStore({ customer: {} })
            Modal.warning({
              content: (<div>当前所选客户还没有坐标,<a href={`/customer/todetail/?customerId=${store.customerId}&isinfoEdit=1`} target="_blank">现在去维护</a></div>),
              okText: '取消'
            });
          }
        } else {
          setZoom(11)
          setCoordinates([116.397428, 39.90923])
          store.setStore({ range: undefined, customer: {} })
          setVisible(false)
        }
      }, [store.customerId])
    
      // 标红点
      const setIconRed = (customer, timeout) => {
        if (!Object.keys(store.customer).length) return
        setTimeout(() => {
          // 标红
          for(const item of markerMap) {
            if (customer?.extData?.isCover) {
              if (item?.w?.extData?.position.join() === customer?.position?.join()) {
                item.render(() => {
                  return <img src='//webapi.amap.com/theme/v1.3/markers/n/mark_r.png' />
                })
              }
            } else {
              if (item?.w?.extData?.extData.customerId === customer?.extData?.customerId) {
                item.render(() => {
                  return <img src='//webapi.amap.com/theme/v1.3/markers/n/mark_r.png' />
                })
              }
            }
          }
        }, timeout)
      }
    
      // 监听区域、地点变化,获取对应经纬点
      useEffect(() => {
        store?.area && debounceSetAddrLocation.run(store?.area);
      }, [store.area])
    
      // 监听周边变化,设置Circle⭕️半径
      useEffect(() => {
        setRadius(store.range * 1000)
      }, [store.range])
    
      // 监听经纬坐标、区域变化,控制Circle⭕️显示
      useEffect(() => {
        if (coordinates && store.area) {
          setZoom(16);
          setVisible(true)
        } else {
          setVisible(false)
        }
      }, [store.area])
    
      // 获取地图 Markers
      const getMarkers = () => {
        const list = []
        for(const item of toJS(store.customerLocationList)) {
          const position = item.location?.split(',')
          if (position.length === 2) {
            list.push({
              position,
              extData: item
            })
          }
        }
        setMarkers(list)
        store.setStore({ area: '' })
        store.setStore({ range: undefined })
      }
    
      // render动态修改标记的外观icon
      const renderMarkerFn = (extData) => {
        let icon = '//webapi.amap.com/theme/v1.3/markers/n/mark_bs.png'
        if (extData?.extData?.visitPlanStatus === 1) {
          icon = mark_gray
        } else if (extData?.extData?.visitPlanStatus === 2) {
          icon = mark_green
        }
        return <img src={icon} />
      };
    
      // 根据城市名做地理/逆地理编码 获取经纬坐标
      const setAddrLocation = (area) => {
        window.AMap.plugin('AMap.Geocoder', () => {
          let geocoder = new window.AMap.Geocoder({
            // city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
            city: store?.visitInfo?.city
          });
          // 使用geocoder做地理/逆地理编码
          geocoder.getLocation(area, (status, result) => {
            if (status === 'complete' && result.info === 'OK') {
              const location = result.geocodes[0].location;
              setCoordinates([location.lng, location.lat])
              if (store.area && result.info === 'OK') store.setStore({ range: 3 })
            }
          });
        });
      };
    
      const debounceSetAddrLocation = useDebounceFn(setAddrLocation);
    
      // 显示周边范围
      const showRange = () => {
        setZoom(16);
        setCoordinates(currentMarkerData.location.split(','));
        store.setStore({ range: 3, customerId: currentMarkerData.customerId })
        setVisible(true)
      }
    
      // 增加拜访计划
      const addVisit = () => {
        setEditVisitPlanVisible(true)
      }
    
      // Markers 事件
      const events = {
        created: (markers) => {
          for (const item of markers) {
            markerMap.push(item)
          }
        },
        click: (mapsOption, marker) => {
          currentMarkerData = marker.getExtData().extData
          setCustomContextMenuVisible(false)
          if (currentMarkerData.isCover === 1) {
            const customAmapMenu = document.getElementsByClassName('custom-amap-menu')
            if (customAmapMenu.length === 0) {
              MapsOption = mapsOption
              setCustomContextMenuVisible(true)
            }
          } else {
            contextMenu.current.open(mapInstance.current, mapsOption.lnglat);
          }
        },
        mouseover: (mapsOption, marker) => {
          marker.setLabel({
            offset: new window.AMap.Pixel(20, 20), // 修改label相对于maker的位置
            content: marker.w.extData.extData.showName
          })
          marker.setTop(true);
        },
        mouseout: (mapsOption, marker) => {
          marker.setLabel({
            content: null
          });
          marker.setTop(false);
        }
      }
    
      // 地图事件
      const mapEvents = {
        created: (instance) => {
          mapInstance.current = instance;
          contextMenu.current = new window.AMap.ContextMenu();
          contextMenu.current.addItem("显示周边范围", showRange, 0);
          contextMenu.current.addItem("增加拜访计划", addVisit, 1);
          contextMenu.current.addItem("重新维护地址", function() {
            window.open(`/customer/todetail/?customerId=${currentMarkerData.customerId}&isinfoEdit=1`);
          }, 2);
          contextMenu.current.addItem("查看拜访记录", function() {
            window.open(`/customervisitplan/listall/?customer_id=${currentMarkerData.customerId}`);
          }, 3);
          contextMenu.current.addItem("查看客户详情", function() {
            window.open(`/customer/todetail/?customerId=${currentMarkerData.customerId}`);
          }, 4);
        },
        click: () => setCustomContextMenuVisible(false),
        mapmove: () => setCustomContextMenuVisible(false),
        zoomchange: () => {
          const list = [...markers]
          console.log('mapInstance.current.getZoom()', mapInstance.current.getZoom());
          setZoom(mapInstance.current.getZoom());
          if (mapInstance.current.getZoom() > 12) {
            for(const item of list) {
              item.label = {
                content: item.extData.showName,
                offset: new window.AMap.Pixel(20, 20)
              }
            }
          } else {
            for(const item of list) {
              item.label = undefined
            }
          }
          setMarkers(list)
          console.log('keys', );
          setIconRed(store.customer)
          setCustomContextMenuVisible(false)
        },
      };
    
      return (
        <Spin spinning={store.loading} >
          <div id="customer-maps" style={{width: '100%', height: 'calc(100vh - 184px)'}}>
            <div style={{ display: store.customerLocationList.length ? 'block' : 'none', height: '100%', width: '100%' }}>
              <Map
                amapkey="0fe0e92d23dc183b6384d51515676b81"
                version="1.4.0"
                plugins={['Scale', 'ToolBar']}
                center={coordinates}
                isHotspot={true}
                zoom={zoom}
                events={mapEvents}
              >
                <Markers
                  markers={markers}
                  events={events}
                  render={renderMarkerFn}
                />
                <Circle
                  center={ coordinates }
                  radius={ radius }
                  visible={ visible }
                  style={{
                    strokeColor: "#F33", // 线颜色
                    strokeOpacity: 1, // 线透明度
                    strokeWeight: 3, // 线粗细度
                    fillColor: "#ee2200", // 填充颜色
                    fillOpacity: 0.15 // 填充透明度
                  }}
                  draggable={ false }
                  bubble
                />
              </Map>
            </div>
    
            {/* 增加拜访计划 */}
            {
              editVisitPlanVisible &&
              <EditVisitPlan
                visible={editVisitPlanVisible}
                params={{
                  customerId: currentMarkerData.customerId,
                  customerName: currentMarkerData.customerName,
                  title: '增加拜访计划',
                  isEdit: false,
                  isPhone: true,
                  onSave: () => setEditVisitPlanVisible(false),
                  onCancel: () => setEditVisitPlanVisible(false)
                }}
              />
            }
    
            {/* 重复坐标点的自定义菜单 */}
            {
              customContextMenuVisible &&
              <CustomContextMenu
                mapsOption={MapsOption}
                coverLocations={ currentMarkerData.coverLocations }
                showRange={showRange}
                addVisit={addVisit}
                setCurrentMarkerData={(data) => currentMarkerData = data}
              />
            }
          </div>
        </Spin>
      )
    })
    

    自定义菜单样式

    #customer-maps {
      position: relative;
      .custom-amap-menu {
        position: absolute;
        top: 100px;
        left: 300px;
        border: 1px solid #ccc;
        background: #fff;
        z-index: 111;
        padding: 0;
    
        ul, li {
          padding: 0;
          margin: 0;
          list-style:none
        }
    
        li {
          height: 30px;
          line-height: 30px;
          padding: 0 10px;
          position: relative;
        }
    
        li:hover {
          background: #eee;
        }
    
        li:hover ul {
          display: block;
        }
    
        ul {
          width: 100px;
          position: absolute;
          top: 0;
          right: -100px;
          display: none;
          background: #fff;
          border: 1px solid #ccc;
          z-index: 111;
        }
    
        ul li {
          height: 30px;
          line-height: 30px;
          padding: 0 10px;
          text-align: center;
          cursor: pointer;
        }
    
        ul li:hover {
          background: #eee;
        }
        a {
          color: #5f6d80;
        }
        a:hover {
          text-decoration: none;
        }
        ul li a {
          display: block;
        }
      }
    }
    
    展开全文
  • React Native地图。
  • 2.react-amap在事件绑定events中有created事件,用于兼容高德原生接口 实现功能代码如下 import React, { useEffect, useState } from "react"; import { Map, Marker } from "react-amap"; import { ...

    1.antd的select组件:onSearch函数,监测输入框中的内容,并调用高德地图API实现搜索;onChange函数:标记选中搜索中的某一条数据

    2.react-amap在事件绑定events中有created事件,用于兼容高德原生接口

    实现功能代码如下

    import React, { useEffect, useState } from "react";

    import { Map, Marker } from "react-amap";

    import { innerHeight, innerWidth } from "../styles/hzsize";

    import { Row, Col, Select } from "antd";

    import './locationcss.css'

    const MapLocation = (props) => {

        //地图搜索相关参数

        const [pois, setPois] = useState([])

        const [signAddrList, setSignAddrList] = useState({

            address: "",

            distance: NaN,

            id: "B0FFLAFX5T",

            location: { P: 25.082074, Q: 102.73076000000003, lng: '', lat: '' },

            name: "",

            shopinfo: "0",

            tel: "",

            type: ""

        })

        const polygonStyle = {

            isOutpoint: true,

            borderWeight: 3,

            strokeColor: "#FF33FF",

            strokeWeight: 6,

            strokeOpacity: 0.2,

            fillOpacity: 0.4,

            fillColor: "#1791fc",

            zIndex: 50

        }

        useEffect(() => {

        }, [props])

        // 进行select框动态输入焦点事件监听,并实现搜索

        const onSearch = (val, isFocus = false) => {

            if (isFocus && pois && pois.length) {

                return

            }

            const place = new window.AMap.PlaceSearch({

                pageSize: 10,

                pageIndex: 1,

                citylimit: true,    // 仅搜索本城市的地名

                // city:限制为只能搜索当前地区的位置  不填则为全国

            })

            // 进行搜索

            place.search(val, (status, result) => {

                const { info, poiList } = result

                if (result.length) { return }

                if (info !== 'OK') {

                    return

                }

                if (poiList.pois && Array.isArray(poiList.pois)) {

                    setPois(poiList.pois)

                }

            })

        }

        // 选中某条数据,并返回给子组件

        const onChange = (id) => {

            // 匹配出当前选中得一行数据

            const signAddrList = pois.find(item => item.id === id) || null

            console.log('signAddrList', signAddrList);

            if (signAddrList) {

                setSignAddrList(signAddrList)

                console.log('signAddrList', signAddrList);

                // 传到选择地址模态框

            }

        }

        return (

            <div className='visualization' style={{ width: innerWidth, height: innerHeight, position: "relative" }}>

                <div style={{ zIndex: 100, position: "absolute", top: "5px", width: "95%", left: "2.5%", right: "2.5%" }}>

                    <Row align='top' justify='center' style={{ width: "100%" }}>

                        <Col style={{ width: "100%" }}>

                            <Select

                                showSearch

                                style={{ width: '100%', borderRadius: "10px" }}

                                placeholder="请输入地址"

                                optionFilterProp="children"

                                allowClear

                                onSearch={onSearch}

                                onChange={onChange}

                            >

                                {

                                    pois && pois.length > 0 ? pois.map(item =>

                                        <Select.Option key={item.id} value={item.id}>{item.name}</Select.Option>

                                    ) : null

                                }

                            </Select>

                        </Col>

                    </Row>

                </div>

                <div className='map'>

                    <Map amapkey="你申请的key"

                        zoom={5}

                        pitch={45}

                        rotation={0}

                        rotateEnable={true}

                        viewMode='3D'

                        features={["bg", "road", "point"]}

                        zooms={[3, 18]}

                        center={{ longitude: 116.397439, latitude: 39.909222 }}

                    >

                        <Marker

                            events={

                                {

                                    click: (e) => {

                                    },

                                    // 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

                                                // type: '汽车服务|汽车销售|汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务|住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|交通设施服务|金融保险服务|公司企业|道路附属设施|地名地址信息|公共设施'

                                            });

                                        })

                                        // 创建搜索实例

                                        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)

                                        })

                                    }

                                }

                            }

                        />

                    </Map>

                </div>

            </div>

        )

    }

    export default MapLocation

    结果展现

    展开全文
  • React本机amap地理位置 React Native高德地图定位...import { init , Geolocation } from "react-native-amap-geolocation" ; await PermissionsAndroid . requestMultiple ( [ PermissionsAndroid . PERMISSIONS .
  • React使用高德地图 (react-amap)(一)

    万次阅读 热门讨论 2019-06-18 16:53:15
    搜了资料,发现有一个针对React进行封装的地图插件react-amap。官方网址:https://elemefe.github.io/react-amap/components/map,有兴趣的可以看下里面的API。 react-amap 安装 1、使用npm进行安装,目前是1.2.8...

    pc版React重构,使用到了高德地图。搜了资料,发现有一个针对React进行封装的地图插件react-amap。官方网址:https://elemefe.github.io/react-amap/components/map,有兴趣的可以看下里面的API。

    react-amap 安装

    1、使用npm进行安装,目前是1.2.8版本:

    cnpm i react-amap
    

    2、直接使用sdn方式引入

    <script src="https://unpkg.com/react-amap@0.2.5/dist/react-amap.min.js"></script>
    

    react-amap 使用

    import React,{Component} from 'react'
    import {Map,Marker} from 'react-amap'
    const mapKey = '1234567809843asadasd' //需要自己去高德官网上去申请
    class Address extends Component {
    	constructor (props) {
            super (props)
            this.state = {  
            }
        }
    	render(){
    		return (
    			<div style={{width: '100%', height: '400px'}}>
    				<Map amapkey={mapKey} 
    				     zoom={15}></Map>
    			</div>
    		)
    	}
    }
    
    export default Address
    

    这样的话,就会初始化一个简单的地图。
    在这里插入图片描述
    实际开发过程中,你会有比较复杂的使用场景。比如需要标记点、对地图进行缩放、能够定位到当前位置、位置搜索等等功能。需求大致如下图所示:
    在这里插入图片描述
    这样的话,那就需要引入插件以及组件的概念了。
    ToolBar、Scale插件

    <Map  plugins={["ToolBar", 'Scale']}></Map>
    

    Marker 地图标记

    <Map>
    	<Marker position={['lng','lat']}></Marker>
    </Map>
    

    InfoWindow 窗体组件

    <Map>
    	<InfoWindow
                position={this.state.position}
                visible={this.state.visible}
                isCustom={false}
                content={html}
                size={this.state.size}
                offset={this.state.offset}
                events={this.windowEvents}
              />
    </Map>
    

    通过 created 事件实现更高级的使用需求,在高德原生实例创建成功后调用,参数就是创建的实例;获取到实例之后,就可以根据高德原生的方法对实例进行操作:

    const events = {
        created: (instance) => { console.log(instance.getZoom())},
        click: () => { console.log('You clicked map') }
    }
    <Map events={events}  />
    

    实现一个较为复杂地址搜索,地址标记、逆地理解析代码:

    import React , { Component } from 'react'
    import { Modal , Input } from 'antd'
    import styles from './index.scss'
    import classname from 'classnames'
    import { Map ,Marker,InfoWindow} from 'react-amap'
    import marker from 'SRC/statics/images/signin/marker2.png'
    
    const mapKey = '42c177c66c03437400aa9560dad5451e'
    
    class Address extends Component {
        constructor (props) {
            super(props)
            this.state = {
                signAddrList:{
                    name:'',
                    addr:'',
                    longitude: 0,
                    latitude: 0
                },
                geocoder:'',
                searchContent:'',
                isChose:false
            }
        }
    
        //改变数据通用方法(单层)
    
        changeData = (value, key) => {
            let { signAddrList } = this.state
            signAddrList[key] = value
            this.setState({
                signAddrList:signAddrList
            })
        }
    
        placeSearch = (e) => {
            this.setState({searchContent:e})
        }
    
        searchPlace = (e) => {
            console.log(1234,e)
        }
    
    
    
    
    
        componentDidMount() {
        
        }
    
        render() {
            let { changeModal , saveAddressDetail } = this.props
            let { signAddrList } = this.state
            const selectAddress = {
                created:(e) => {
                    let auto
                    let geocoder
                    window.AMap.plugin('AMap.Autocomplete',() => {
                        auto = new window.AMap.Autocomplete({input:'tipinput'});
                    })
    
                    window.AMap.plugin(["AMap.Geocoder"],function(){
                        geocoder= new AMap.Geocoder({
                            radius:1000, //以已知坐标为中心点,radius为半径,返回范围内兴趣点和道路信息
                            extensions: "all"//返回地址描述以及附近兴趣点和道路信息,默认"base"
                        });
                    });
    
                    window.AMap.plugin('AMap.PlaceSearch',() => {
                        let place = new window.AMap.PlaceSearch({})
                        let _this = this
                        window.AMap.event.addListener(auto,"select",(e) => {
                            place.search(e.poi.name)
                            geocoder.getAddress(e.poi.location,function (status,result) {
                                if (status === 'complete'&&result.regeocode) {
                                    let address = result.regeocode.formattedAddress;
                                    let data = result.regeocode.addressComponent
                                    let name = data.township +data.street + data.streetNumber
                                    _this.changeData(address,'addr')
                                    _this.changeData(name,'name')
                                    _this.changeData(e.poi.location.lng,'longitude')
                                    _this.changeData(e.poi.location.lat,'latitude')
                                    _this.setState({isChose:true})
                                }
                            })
                        })
                    })
                },
                click:(e) => {
                    const _this = this
                    var geocoder
                    var infoWindow
                    var lnglatXY=new AMap.LngLat(e.lnglat.lng,e.lnglat.lat);
                    let content = '<div>定位中....</div>'
    
                    window.AMap.plugin(["AMap.Geocoder"],function(){
                        geocoder= new AMap.Geocoder({
                            radius:1000, //以已知坐标为中心点,radius为半径,返回范围内兴趣点和道路信息
                            extensions: "all"//返回地址描述以及附近兴趣点和道路信息,默认"base"
                        });
                        geocoder.getAddress(e.lnglat,function (status,result) {
                            if (status === 'complete'&&result.regeocode) {
                                let address = result.regeocode.formattedAddress;
                                let data = result.regeocode.addressComponent
                                let name = data.township +data.street + data.streetNumber
                              
                                _this.changeData(address,'addr')
                                _this.changeData(name,'name')
                                _this.changeData(e.lnglat.lng,'longitude')
                                _this.changeData(e.lnglat.lat,'latitude')
                                _this.setState({isChose:true})
                            }
                        })
                    });
                    
                }
            }
            return (
                <div>
                    <Modal visible={true}
                           title="办公地点"
                           centered={true}
                           onCancel={() => changeModal('addressStatus',0)}
                           onOk={() => saveAddressDetail(signAddrList)}
                           width={700}>
                        <div className={styles.serach}>
                            <input id="tipinput"
                                   className={styles.searchContent}
                                   onChange={(e) => this.placeSearch(e.target.value)}
                                   onKeyDown={(e) => this.searchPlace(e)} />
                            <i className={classname(styles.serachIcon,"iconfont icon-weibiaoti106")}></i>
                        </div>
                        <div className={styles.mapContainer} id="content" >
                            {
                                this.state.isChose ? <Map amapkey={mapKey}
                                                          plugins={["ToolBar", 'Scale']}
                                                          events={selectAddress}
                                                          center={ [ signAddrList.longitude,signAddrList.latitude] }
                                                          zoom={15}>
                                    <Marker position={[ signAddrList.longitude,signAddrList.latitude]}/>
                                </Map> : <Map amapkey={mapKey}
                                              plugins={["ToolBar", 'Scale']}
                                              events={selectAddress}
                                              zoom={15}>
                                    <Marker position={[ signAddrList.longitude,signAddrList.latitude]}/>
                                </Map>
                            }
                        </div>
                        <div className="mar-t-20">详细地址:
                            <span className="cor-dark mar-l-10">{signAddrList.addr}</span>
                        </div>
                    </Modal>
                </div>
            )
        }
    }
    
    export default Address
    
    展开全文
  • react+react-amap使用高德地图组件

    千次阅读 2020-07-28 15:11:46
    首先安装 npm install --save react-amap
  • react-amap 是基于 React 的高德地图组件。1. 获取地图示例react-amap 作为高德地图在 React 中的实现,实际使用中不可避免的需要通过地图对象调用各种方法,react-amap 中获取地图示例方法如下:events={{created: ...
  • 在使用react-amap高德地图时遇到一个问题,就是如何设置默认卫星地图且不显示地图类型切换插件 我的初始设置方式 <Map plugins={[{ name: 'MapType', options: { defaultType: 1, visiable:false...
  • React中使用高德地图组件React-amap

    千次阅读 2019-05-16 17:22:02
    对应的package为React-amap。 记录一下在项目中遇到的几个问题以及解决方案: 自定义Markers外观, // 标记杆塔的图片样式 style = { position: 'relative', backgroundColor: 'white', color: '...
  • react-amap 是一个基于 React 封装的高德地图组件。 https://elemefe.github.io/react-amap/articles/start 在高德开放平台申请你自己的 Key。 https://lbs.amap.com/ 安装 npm install --save react-amap GaoDeMa....
  • 本篇文章主要介绍的是 在React工程中 使用react-amap组件来写一个地图,地图上加一个点标记; 注意 :目前的本人发现在使用react-amap会对 umi 搭建的工程有所影响,建议使用原生高德api(document.ejs【可以看我的...
  • ant design 使用 react-amap 引入高德地图

    千次阅读 2020-04-14 16:50:05
    在项目目录中 使用命令 npm install --save react-amap 安装完成之后,在模块头部引入组件 然后在render,return中写入<Map >标签 amapkey:在高德官网申请的key值, zoom:地图级别(国家、省...
  • 干货,无话 ...2、npm install react-amap,引入高德地图的封装; 3、编写组件index.js: import React from "react"; import ReactDOM from "react-dom"; import Map from "./Map3"; let mapDat...
  • 使用react和高德地图实现自定义点标记,筛选高德地图、react使用高德地图展示自定义点标记,筛选项目截图
  • react-amap填坑指南

    千次阅读 2018-06-02 16:56:57
    报错:XX is not a ... react-amap版本卸载package.json里面"react-amap": "^1.2.7"2. amap版本根据react-amap文档,写在Map组件里即可&lt;Map  version={'1.4.4'}//amap版本  a...
  • -react-baidu-map基于 React 封装的百度地图组件,帮助你轻松的接入地图到 React 项目中。
  • 需要定位的地方的经纬度获取:  https://lbs.amap.com/console/show/picker import React from 'react'; import { connect } from 'dva'; import Map from 'react-amap/...import Marker from 'react-amap/lib/...
  • react-native-amap, 针对 iOS + Android响应本机AMap组件 react-native-amap针对 iOS + Android响应本机AMap组件react-native-amap-view是由react-native-maps激发的amap库的包装器,它可以在安卓和iOS中使用##Demo
  • 高德地图定位(react-native-amap-geolocation) 定位地址: react-native-amap-geolocation 安装 npm install --save react-native-amap-geolocation android react-native link react-native-amap-geolocation ios...
  • react-native-amap-location, Android amap位置sdk用于响应本机 本地AMap位置高德安卓定位SDK的ReactNative版本。 AMap Android位置 SDK 。已经处于弃坑状态。新版本RN似乎已不支持,欢迎各位大佬前来维护示例import...
  • @react-native-community/geolocation Geolocation API扩展了。 当前,在Android上,它使用 。 Google不推荐使用此API,因为它不如推荐的准确和慢。 这是我们希望在不久的将来更改的内容 。 为了将新的与React ...
  • react native开发的时候用到的这个高德的定位模块【react-native-amap-geolocation】 支持android和ios,在这里简单的捋一下流程。 一、申请apiKey 由于【react-native-amap-geolocation】使用的高德地图,因此...
  • react-native-amap-geolocation的使用 今天上午忙成的效果图,如下图 1,react-native-amap-geolocation如何获取当前信息位置?我创建了一个专门获取到当前定位信息的Position.tsx文件 如图: 我暂时先写了基础定位...
  • react-native地图组件--react-native-amap3d

    千次阅读 2020-03-12 16:39:44
    react-native-amap3d 是 react-native 高德地图组件,使用最新 3D SDK,支持 Android + iOS 参考github:https://github.com/qiuxiang/react-native-amap3d 功能 该组件提供的功能可以满足一般的react-native开发...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 31,690
精华内容 12,676
关键字:

react-amap

友情链接: Untitled.rar