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
兼职前端开发