react+ts引入高德地图实现搜索选址

1.引入高德js的mapUtils.ts文件

// 搞得地图js APi
const gdApi =
  "https://webapi.amap.com/maps?v=2.0&key=自己配置的高德key&plugin=AMap.Geocoder";

export function initMap() {
  return new Promise((resolve, reject) => {
    loadScripts(gdApi, () => {
      resolve(false);
    });
  });
}

export function loadScripts(srcArr: any, callback: any) {
  let array: any[] = [];
  if (typeof srcArr === "string") {
    array = [srcArr];
  } else if (Array.isArray(srcArr) && srcArr.length > 0) {
    array = srcArr;
  } else {
    return;
  }
  //获取页面上已经加载的js
  const scriptList = document.getElementsByTagName("script");
  let scriptArr: any[] = [];
  for (let i = 0; i < scriptList.length; i++) {
    scriptArr.push(scriptList[i].getAttribute("src"));
  }
  var loaderJs = (src, handler) => {
    //如果之前已经加载过了,就跳过
    const hasNode = scriptArr.find((item) => item == src);
    if (hasNode) {
      handler && handler();
      return;
    }
    var script = document.createElement("script");
    script.src = src;
    script.onload = () => {
      script.onload = null;
      handler();
    };
    script.onerror = () => {
      // 加载失败后,可继续加载下一个js。
      console.log("加载js失败:" + src);
      script.onload = null;
      handler();
    };
    var head = document.getElementsByTagName("head")[0];
    (head || document.body).appendChild(script);
  };
  (function run() {
    if (array.length != 0) {
      loaderJs(array.shift(), run);
    } else {
      callback && callback();
    }
  })();
}

2.开发一个地图组件

import React, { memo, useEffect, useState } from "react";
// 公共组件
import { Input, message } from "antd";
// 其他文件
import { initMap } from "utils/mapUtils";
import cityData from "./city";   //所有的城市js,因为高德没有返回城市的正确citycode,所以自己匹配回显
import "./style.scss";   //样式文件

let map: any = null;
let marker: any = null;
let placeSearch: any = null;
let districtSearch: any = null;

// 表单传入参数类型定义
interface IProps {
  LngLat: any[];    //经纬度集合
  housingName: string;   //回显的
  isChoose: boolean;
  cityKeywords: string; // 行政区名、citycode、adcode、商圈名
  onConfirm: (item: any) => void;
}
// 弹框选择项目组件
const MapLocation: React.FC<IProps> = ({
  LngLat,
  housingName,
  isChoose,
  onConfirm,
  cityKeywords,
}) => {
  const [lnglatString, setLnglatString] = useState<string>("");
  const [address, setAddress] = useState<string>("");
  const [housingEstateName, seHousingEstateName] = useState<string>("");
  // const [addressInfo, setAddressInfo] = useState<any>({});
  const [provinceCity, setProvinceCity] = useState<any>([]);
  // 进入加载地图
  useEffect(() => {
    initMap().then(() => {
      createMap();
    });
  }, []); // eslint-disable-line
  // 监听城市名称传入,定位地图中心点
  useEffect(() => {
    if ((!LngLat || LngLat.length <= 0) && cityKeywords) {
      console.log(LngLat, "99999999999999");
      setMapCurPos();
    }
  }, [cityKeywords]); // eslint-disable-line
  // 监听选点后,传到外面组件
  useEffect(() => {
    let outParams = {
      housingEstateName: housingEstateName,
      lnglatString: lnglatString,
      address: address,
      // addressInfo: addressInfo,
      provinceCity: provinceCity,
    };
    onConfirm(outParams);
  }, [lnglatString, address]); // eslint-disable-line

  const createMap = () => {
    if (!AMap) {
      message.error("地图加载失败!");
      return;
    }
    let mapParams: any = { zoom: 12 };
    if (LngLat && LngLat.length > 0) {
      mapParams.center = LngLat;
      mapParams.zoom = 14;
    }
    map = new AMap.Map("chooseAddressMapBox", mapParams);
    if (isChoose) {
      // map.on("click", (e) => {
      //   console.log("e", e);
      //   setMarkerShowAddress([e.lnglat.lng, e.lnglat.lat]);
      // });
    }
    initSearchLnglat();
  };
  const initSearchLnglat = () => {
    AMap.plugin(["AMap.PlaceSearch", "AMap.DistrictSearch"], () => {
      //初始化地点查询
      placeSearch = new AMap.PlaceSearch({
        map: map,
        panel: "result",
        pageSize: 5,
        extensions: "all",
      });
      // //点击后选中
      // placeSearch.listElementClick((data) => {
      //   console.log(data, "66666666666");
      // });
      placeSearch.on("listElementClick", function (e) {
        console.log(e.data, "88888888"); //则是包含所有的marker数据
        let {
          cityname,
          location,
          pcode,
          adcode,
          pname,
          adname,
          address,
          name,
        } = e.data;
        let _index = cityData.findIndex((r) => r.areaName == cityname);
        if (_index != -1) {
          setProvinceCity([pcode, cityData[_index].areaCode, adcode]);
        }
        //setMarkerShowAddress([location.lng, location.lat]);
        setAddress(pname + cityname + adname + address);
        seHousingEstateName(name);
        setLnglatString(location.lng + "," + location.lat);
      });

      //初始化地址提示
      // var auto = new AMap.AutoComplete({
      //   input: "tipinput",
      // });
      // auto.search("天安门", function (status, result) {
      //   // 搜索成功时,result即是对应的匹配数据
      //   console.log(result);
      // });
      // //点击后选中
      // auto.on("select", (e) => {
      //   //注册监听,当选中某条记录时会触发
      //   placeSearch.setCity(e.poi.adcode);
      //   placeSearch.search(e.poi.name); //关键字查询查询
      //   setMarkerShowAddress([e.poi.location.lng, e.poi.location.lat]);
      // });
      // 初始化城市查询
      districtSearch = new AMap.DistrictSearch({
        level: "city",
      });
    });
  };
  const onchange = (e) => {
    seHousingEstateName(e.target.value);
    if (!e.target.value) return;
    placeSearch.search(e.target.value, function (status, result) {
      // 查询成功时,result即对应匹配的POI信息
      console.log(result, "高德地图返回结果");
    });
  };

  const setMarkerShowAddress = (position: any[]) => {
    if (!position || position.length <= 0) return;
    if (!marker) {
      marker = new AMap.Marker();
    }
    map.add(marker);
    marker.setPosition(position);
    map.setCenter(position);
    setLnglatString(position.join(","));
    var geocoder = new AMap.Geocoder();
    geocoder.getAddress(position, (status, result) => {
      console.log("result", result);
      if (status === "complete" && result.regeocode) {
        setAddress(result.regeocode.formattedAddress);
        // setAddressInfo(result.regeocode);
      } else {
        console.log("根据经纬度查询地址失败");
      }
    });
  };
  // 查询高德城市信息
  const setMapCurPos = () => {
    if (!districtSearch) return;
    districtSearch.search(cityKeywords, (status, result) => {
      const data = (result.districtList && result.districtList[0]) || null;
      if (!data) return;
      const centerPos = [data.center.lng, data.center.lat];
      const citycode = data.adcode;
      map.setCenter(centerPos);
      placeSearch.setCity(citycode);
    });
  };
  // 监听传入的经纬度变化,地图标记更新
  useEffect(() => {
    if (map) {
      if (LngLat && LngLat.length > 0) {
        placeSearch.clear();
        seHousingEstateName(housingName);
        setMarkerShowAddress(LngLat);
      } else if (marker) {
        map.remove(marker);
        setLnglatString("");
        setAddress("");
      }
    }
  }, [LngLat]); // eslint-disable-line
  return (
    <>
      <div className="edit_location_box">
        <div id="chooseAddressMapBox" style={{ height: 500 }}></div>
        <div className="address_info">
          <div className="foldtxt">经纬度:{lnglatString}</div>
          <div className="foldtxt">地址:{address}</div>
          <div>
            <Input
              id="tipinput"
              value={housingEstateName}
              onChange={onchange}
              placeholder="输入关键字查询"
            />
          </div>
          <div id="result"></div>
        </div>
      </div>
    </>
  );
};
export default memo(MapLocation);

style.scss

.edit_location_box {
  position: relative;
  .address_info {
    position: absolute;
    top: 0;
    left: 0;
    width: 300px;
    z-index: 100;
    padding: 10px;
    background-color: rgba($color: #fff, $alpha: 0.8);
    .foldtxt {
      font-weight: bold;
      font-size: 15px;
      color: #00004c;
    }
  }
}
.amap-sug-result {
  z-index: 3000 !important;
}

页面上引用

import { MapLocation } from "components";
  <Modal
        title="地图选点"
        open={mapVisible}
        onCancel={modalMapCancel}
        width={"60%"}
        forceRender={true}
        footer={
          <>
            <Button type="primary" onClick={modalMapConfirm} loading={loading}>
              确定
            </Button>
            <Button type="default" onClick={modalMapCancel} loading={loading}>
              关闭
            </Button>
          </>
        }
      >
        <MapLocation
          LngLat={LngLat}
          housingName={housingName.current}
          isChoose={true}
          cityKeywords={cityKeywords}
          onConfirm={mapConfirm}
        />
      </Modal>

以上就是全部
效果图
在这里插入图片描述
在这里插入图片描述
需要指导的可以找我QQ 2981739544
兼职前端开发

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tyler1121

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值