React工程中用百度地图实现可检索和标注功能

前言:

项目需要设置学员上课签到的打卡定位经纬度,所以需要调用地图api来获取坐标点。

调研后决定使用百度地图api,项目是react技术栈,所以使用了 React-BMapGL npm包,这个包也是百度地图官方推荐的方案。

应用:

  1. 先注册百度账号,申请认证成为开发者,然后在应用管理中增加应用获取 ak
xml 复制代码
<script type="text/javascript" src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=您的密钥">
</script>
  1. 安装 react-bmapgl

npm install react-bmapgl --save

  1. 在项目中使用
jsx 复制代码
import ZoomControl from "react-bmapgl/Control/ZoomControl";
import Map from "react-bmapgl/Map";
import AutoComplete from "react-bmapgl/Services/AutoComplete";
    // 创建地理编码实例, 并配置参数获取乡镇级数据
    myGeo = new BMapGL.Geocoder({ extensions_town: true });


    const mapRef = useRef(null);


    const onMapClick = (e) => {
        const pt = e.latlng;
        // 根据坐标得到地址描述
        myGeo.getLocation(new BMapGL.Point(pt.lng, pt.lat), function (result) {
          if (result) {
            const surroundingPois = result?.surroundingPois || [];
            const surroundingAddress = `${surroundingPois?.[0]?.address || ""}${
              surroundingPois?.[0]?.title || ""
            }`;
            setAddress(surroundingAddress || result.address);
            setPlace(surroundingAddress || result.address);
          }
        });
    };


    const setPlace = (myValue) => {
        let mapInstance = mapRef.current.map;
        mapInstance.clearOverlays(); //清除地图上所有覆盖物
        var local = new BMapGL.LocalSearch(mapInstance, {
          //智能搜索
          onSearchComplete: () => {
            let pp = local.getResults().getPoi(0).point; //获取第一个智能搜索的结果
            mapInstance.centerAndZoom(pp, 15);
            mapInstance.addOverlay(new BMapGL.Marker(pp)); //添加标注
            if (scope) {
              const circle = new BMapGL.Circle(pp, scope, {
                strokeColor: "#f00",
                strokeWeight: 2,
                fillColor: "#ff0",
                fillOpacity: 0.3,
              });
              mapInstance.addOverlay(circle); //添加范围
            }
            setPoint(pp);
          },
        });
        local.search(myValue);
      };
    <Input
         style={{ marginBottom: 20 }}
         id='selectAddressInput'
         value={address}
         onChange={(e) => handleChangeInput(e)}
         placeholder='请输入地点'
         maxLength={100}
    />
    <AutoComplete
        input='selectAddressInput'
        onConfirm={(e) => {
          const { province, city, district, street, business } = e.item.value;
          setAddress(`${province}${city}${district}${street}${business}`);
          setPlace(`${province}${city}${district}${street}${business}`);
          setTimeout(() => {
            let arr = document.querySelectorAll(".tangram-suggestion-main");
            arr[arr.length - 1].style.display = "none";
            }, 300);
          }}
     />
    <Map
        ref={mapRef}
        center={new BMapGL.Point(116.404449, 39.914889)}
        zoom={12}
        onClick={onMapClick}
        enableDoubleClickZoom={false}
        enableScrollWheelZoom={true}
    >
         <ZoomControl />
    </Map>

默认展示

搜索地点

选中地点,改变中心并且加标注

代码讲解:

以上代码引入了 Map ZoomControl AutoComplete 三个组件,分别是地图,缩放控件,结果提示服务。

  1. 创建创建地理编码实例 new BMapGL.Geocoder()

  2. 当点击地图时,根据坐标点可以得到地址描述 myGeo.getLocation,设置地址描述

  3. 设置点击的地点,通过Ref获取地图实例,清除地图上的覆盖物,输入地址描述调用检索服务查询第一个智能搜索地点的坐标点,然后将中心定在这个坐标点(centerAndZoom),并添加标注(addOverlay(new BMapGL.Marker(pp)))

  4. 结果提示服务在点击确认服务后,会根据检索服务返回的数值重新设置地址描述,重置中心点和更新标注。

总结:

将这个组件封装后可以作为表单组件使用,只需求提供 value 属性和 onChange 方法即可,value作为初始值,onChange时将最新值回调传出,后续应用就不用再研究百度地图具体的api,只需要引用这个组件就可以方便的渲染可搜索和加标注的地图组件,并获取坐标点和地址描述。

相关推荐
程序员黑豆1 小时前
鸿蒙应用开发:V1与V2版本数据持久化实战教程
前端·harmonyos
小月土星5 小时前
React Router 前端路由深度解析:从传统后端路由到现代 SPA 的完整演进
前端
程序员黑豆5 小时前
鸿蒙开发 Navigation 路由教程:从入门到实战
前端·harmonyos
烬羽7 小时前
React Router v7 完全指南:一个 Demo 吃透前端路由
javascript·react.js·前端框架
烬羽7 小时前
React Router 嵌套路由:一个 `Outlet` 引发的布局思考
react.js·面试·前端框架
烬羽7 小时前
从"整个页面刷新"到"丝滑切换":手写一个 HashRouter 彻底搞懂前端路由
javascript·前端框架·全栈
用户938515635077 小时前
从零理解 React Router v6:每一个 API 都是怎么工作的
前端·javascript·全栈
用户059540174469 小时前
Redis缓存回滚踩坑实录:一个配置失误,让我在凌晨3点丢了3000条数据
前端·css
kyriewen10 小时前
别再这样写条件渲染了——你的React组件里藏着这5种定时炸弹
前端·javascript·react.js
IT_陈寒10 小时前
Redis缓存击穿把我坑惨了,原来这样设过期时间才靠谱
前端·人工智能·后端