import React, { Fragment, useEffect, useRef, useState } from 'react'; import style from './index.less'; import AMapLoader from '@amap/amap-jsapi-loader'; import { ProFormSelect } from '@ant-design/pro-components'; import img from './point.png'; import { Modal } from 'antd'; import { debounce } from '@/utils/tools'; declare global { interface Window { _AMapSecurityConfig?: { securityJsCode: string; }; } } export type MapProps = { onSelect: (flag?: boolean, formVals?: unknown) => void; onCancel: (flag?: boolean, formVals?: unknown) => void; open: boolean; }; export const aMapConfig = { key: '9cfc9370bd8a941951da1cea0308e9e3', securityJsCode: '7b16386c7f744c3ca05595965f2b037f', }; const ProFromMap: React.FC = ({ open, onSelect, onCancel }) => { const mapRef = useRef(null); const geocoderRef = useRef(null); const autoCompleteRef = useRef(null); const addMarkerRef = useRef(null); const markerRef = useRef(null); const locationList = useRef([]); const localData = useRef(null); const [selectValue, setSelectValue] = useState(null); const [locationOptions, setLocationOptions] = useState(null); useEffect(() => { console.log('open', open); if (!open) return; window._AMapSecurityConfig = { securityJsCode: aMapConfig.securityJsCode, }; AMapLoader.load({ key: aMapConfig.key, // 申请好的Web端开发者Key,首次调用 load 时必填 version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15 plugins: ['AMap.Scale'], //需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['...','...'] }) .then((AMap) => { mapRef.current = new AMap.Map('container', { // 设置地图容器id viewMode: '3D', // 是否为3D地图模式 zoom: 11, // 初始化地图级别 center: [120.384599, 36.062687], // 初始化地图中心点位置 }); // 浏览器定位 AMap.plugin('AMap.Geolocation', function () { var geolocation = new AMap.Geolocation({ enableHighAccuracy: false, //是否使用高精度定位,默认:true timeout: 10000, //超过10秒后停止定位,默认:5s position: 'RB', //定位按钮的停靠位置 offset: [10, 20], //定位按钮与设置的停靠位置的偏移量,默认:[10, 20] zoomToAccuracy: true, //定位成功后是否自动调整地图视野到定位点 }); mapRef.current.addControl(geolocation); geolocation.getCurrentPosition(); }); // 添加插件 AMap.plugin('AMap.AutoComplete', function () { // 注意:输入提示插件2.0版本需引入AMap.AutoComplete,而1.4版本应使用AMap.Autocomplete // 实例化AutoComplete autoCompleteRef.current = new AMap.AutoComplete({ city: '370200', // 青岛市 citylimit: false, }); }); // 将经纬度坐标转化为详细地址 AMap.plugin('AMap.Geocoder', () => { geocoderRef.current = new AMap.Geocoder({ extensions: 'base', batch: false, city: '370200', // 青岛市 }); }); // 添加事件 mapRef.current.on('click', (eve) => { console.log(eve); const { lat, lng } = eve.lnglat; if (geocoderRef.current && addMarkerRef.current) { const lnglat1 = [lng, lat]; geocoderRef.current.getAddress(lnglat1, (status, result) => { if (status === 'complete' && result.info === 'OK') { const { formattedAddress } = result.regeocode; const id = Date.now(); result.id = id; result.address = formattedAddress; result.location = { lat: lat, lng: lng, }; setSelectValue(id); setLocationOptions([result]); localData.current = result; console.log(result, '详细地址'); } }); addMarkerRef.current && addMarkerRef.current(lnglat1); } }); addMarkerRef.current = (LngLat: any) => { if (markerRef.current) { mapRef.current.remove(markerRef.current); markerRef.current = null; addMarkerRef.current && addMarkerRef.current(LngLat); } else { markerRef.current = new AMap.Marker({ icon: new AMap.Icon({ size: new AMap.Size(32, 32), // 图标显示大小 image: img, // 自定义图标 URL imageSize: new AMap.Size(32, 32), // 强制缩放原始图片大小 }), anchor: 'bottom-center', // 设置锚点方位 position: LngLat, //标注点位置 title: `鼠标移入显示的提示`, //标注点标题 map: mapRef.current, //将标注点添加到地图上 }); } }; // 获取输入提示信息 }) .catch((e) => { console.log(e); }); }, [open]); useEffect(() => { return () => { mapRef.current?.destroy(); }; }, []); function autoInput(keywords: string) { return new Promise((resolve, reject) => { autoCompleteRef.current.search(keywords, function (status: string, result) { if (status === 'complete' && result.info === 'OK') { // 搜索成功时,result即是对应的匹配数据 resolve(result.tips); } else { reject(null); } }); }); } const searchLocation = async (keyWords: string) => { const keywordsToSearch = keyWords || '青岛'; const resData = await autoInput(keywordsToSearch); locationList.current = resData; setLocationOptions(resData); return resData || []; }; // 防抖版本(确保组件卸载时清除) const debounceSearch = useRef(debounce(searchLocation, 500)).current; function selectItem(id: any) { const items = locationList.current.filter((item) => item.id === id); if (items.length) { const value = items[0]; setSelectValue(value.id); addMarkerRef.current([value.location.lng, value.location.lat]); mapRef.current.setZoomAndCenter(16, [value.location.lng, value.location.lat]); localData.current = value; } } function locationSuccess() { if (localData.current) { onSelect && onSelect(localData.current); } } return (
); }; export default ProFromMap;