react开发高德地图,展示特定的行政区,并实现海量标注

一、JS API结合React使用

1、官网:https://lbs.amap.com/api/javascript-api-v2/guide/abc/amap-react
2、NPM 安装 Loader

npm i @amap/amap-jsapi-loader --save

3、功能需要申请加载地图相关的key和密钥,使用前读者需提前申请好。
在这里插入图片描述

二、实战开发

1、密钥的使用方式有多种,具体可以参考:https://lbs.amap.com/api/javascript-api-v2/guide/abc/jscode

2、本人这里是通过明文的方式设置的,并不是很安全。请在引入@amap/amap-jsapi-loader前就配置好密钥。
在这里插入图片描述
3、AMapLoader预加载所需地图插件,并实例化地图。只要实例化地图,就可以简单得展示一个地图了。
在这里插入图片描述
4、AMap.DistrictSearch插件行政区查询,该插件可以查询特定行政区的地域边界点。组装完边界值后,使用mask掩膜处理,就可以只展示该区域了。
在这里插入图片描述
5、AMap.DistrictLayer.Province可以对选定的行政区做背景颜色的更改。
在这里插入图片描述
6、海量标注
1)AMap.LabelsLayer实例化,添加标注图层。
在这里插入图片描述
2)AMap.LabelMarker实例化,添加海量标注点。
在这里插入图片描述

三、效果图

在这里插入图片描述

四、完整代码

const initMap = () => {
    AMapLoader.load({
      key: dicParams.mapKey, // 申请好的Web端开发者Key,首次调用 load 时必填
      version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
      plugins: ["AMap.DistrictSearch", "AMap.DistrictLayer"], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
    })
      .then((AMap) => {
        var opts = {
          subdistrict: 0, //返回下一级行政区
          extensions: "all", //返回行政区边界坐标组等具体信息
        };
        //实例化DistrictSearch 行政区查询
        const district = new AMap.DistrictSearch(opts);
        district.search("云南", function (status, result) {
          var bounds = result.districtList[0].boundaries;
          var mask = [];
          for (var i = 0; i < bounds.length; i += 1) {
            mask.push([bounds[i]]);
          }

          const m = new AMap.Map("container", {
            mask: mask,
            // 设置地图容器id
            viewMode: "3D", // 是否为3D地图模式
            zoom: 7, // 初始化地图级别
            resizeEnable: true,
            center: [101.917169, 24.766915], // 初始化地图中心点位置
            cursor: "pointer",
          });
          mapRef.current = m

          // 省市行政区域图层
          const disProvince = new AMap.DistrictLayer.Province({
            zIndex: 12,
            adcode: [530000], // 530000为云南行政区 行政区编码: https://a.amap.com/Loca/static/mock/adcodes.js
            depth: 0, // 显示程度 0 省级 1 市级 2 区/县级
            styles: {
              fill: function (properties) {
                // properties为可用于做样式映射的字段,包含
                // NAME_CHN:中文名称
                // adcode_pro
                // adcode_cit
                // adcode

                if (properties.adcode === 530000) {
                  // 云南省行政区域
                  return "#CCE4FF";
                } else {
                  return "#FFFFFF";
                }
              },
              "province-stroke": "cornflowerblue",
              "city-stroke": "white", // 中国地级市边界
              "county-stroke": "rgba(255,255,255,0.5)", // 中国区县边界
            },
          });

          disProvince.setMap(m);

          var markers = [];
          var layer = new AMap.LabelsLayer({
            zooms: [3, 20],
            zIndex: 1000,
            // collision: false,
            // 设置 allowCollision:true,可以让标注避让用户的标注
            // allowCollision: true
          });
          layer.add(markers);
          // 图层添加到地图
          m.add(layer);

          // 将 marker 添加到图层
          layer.add(markers);
        });
      })
      .catch((e) => {
        console.log(e);
      });
  };

  // 报警、预警标注
  const markWarns = (data) => {
    if (mapRef.current) {
      // 没有报警时的图标对象
      var icon1 = {
        // 图标类型,现阶段只支持 image 类型
        type: "image",
        // 图片 url
        image: require("@/assets/images/comprehensiveBoard/noWarn.png"),
        // 图片尺寸
        size: [33, 33],
        // 图片相对 position 的锚点,默认为 bottom-center
        anchor: "center",
        offset: [0, -20],
      };

      // 存在报警时的图标对象
      var icon2 = {
        // 图标类型,现阶段只支持 image 类型
        type: "image",
        // 图片 url
        image: require("@/assets/images/comprehensiveBoard/hasWarn.png"),
        // 图片尺寸
        size: [33, 33],
        // 图片相对 position 的锚点,默认为 bottom-center
        anchor: "center",
        offset: [0, -20],
      };

      // 文本标注
      var textStyle = {
        fontSize: 10,
        fontWeight: "normal",
        fillColor: "#6C6C6C",
        fold: true,
        padding: "2, 5",
        borderColor: "#3D90F2",
        borderWidth: 1,
      };

      var LabelsData: any[] = []

      for(var i = 0; i < data.length; i++) {
        const item = data[i]
        const obj = {
              name: item.name,
              position: item.position,
              zooms: [3, 20], // 标注显示级别范围, 可选值:[3,20]
              opacity: 1,
              zIndex: 10,
              fold: false, // 文字是否折行(6个字一折行)
              icon: item.warnCount || item.earlyWarnCount ? icon2 : icon1,
              text: {
                // 要展示的文字内容
                content: item.company,
                // 文字方向,有 icon 时为围绕文字的方向,没有 icon 时,则为相对 position 的位置
                direction: "right",
                // 在 direction 基础上的偏移量
                offset: [0, -20],
                // 文字样式
                style: textStyle,
              },
            }

            LabelsData.push(obj)
      }

      var markers = [];
      var layer = new AMap.LabelsLayer({
        zooms: [3, 20],
        zIndex: 1000,
        // collision: false,
        // 设置 allowCollision:true,可以让标注避让用户的标注
        // allowCollision: true
      });
      layer.add(markers);
      // 图层添加到地图
      mapRef.current.add(layer);

      // 初始化 labelMarker
      for (var i = 0; i < LabelsData.length; i++) {
        var curData = LabelsData[i];
        const current = data[i]
        curData["extData"] = {
          index: i,
        };

        var labelMarker = new AMap.LabelMarker(curData);

        markers.push(labelMarker);

        // 给marker绑定事件 回显报警数量和预警数量
        labelMarker.on("mouseover", function (e) {
          var position = e.data.data && e.data.data.position;

          if (position && (current.warnCount || current.earlyWarnCount)) {
            normalMarker.setContent(
              `<div class="amap-info-window">` +
                `<div class="warn-tip-box">` +
                `<span>当前报警</span>` +
                `<span class="warn-count">${current.warnCount}</span>` +
                `</div>` +
                `<div class="early-warn-tip-box">` +
                `<span>预警数</span>` +
                `<span class="early-warn-count">${current.earlyWarnCount}</span>` +
                `</div>` +
                `</div>`
            );
            normalMarker.setPosition(position);
            normalMarker.setOffset(new AMap.Pixel(58, 40));
            mapRef.current.add(normalMarker);
          }
        });

        labelMarker.on("mouseout", function () {
          mapRef.current.remove(normalMarker);
        });
      }
      // 将 marker 添加到图层
      layer.add(markers);
      // m.setFitView(null, false, [100, 150, 10,10]);

      // 普通点
      var normalMarker = new AMap.Marker({
        anchor: "bottom-center",
        offset: [0, -15],
      });
    }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值