import React, { useEffect, useImperativeHandle, useState } from 'react'; import Loading from '../Loading'; import { GetGDMap } from '../../utils/MapUtil'; import { AMapType } from './typing.d' const AMapComponent = React.forwardRef((props, ref) => { const markerDefaultIcon = require('react-base-client/src/assets/amap/marker-default.png'); const mapId = props.mapId || Math.round(Math.random() * 100000) + 'mapId'; const [getMap, setMap] = useState(); const [getAMap, setAMap] = useState(); const [getPositionPicker, setPositionPicker] = useState(); const [getLayerAll, setLayerAll] = useState>([]) /** * 让地图中心位置视图转移 显示在某个经纬度 *_grade:等级1~15 缩放等级 全国~街道 */ function setZommAndCenterView( _map: any, _grade: string | number, _lng: string | number, _lat: string | number, ) { _map?.setZoomAndCenter?.(_grade, [_lng, _lat]); _map?.getCenter?.(); } /** * 让地图中心位置视图转移 显示在某个经纬度 * _grade:等级1~15 缩放等级 全国~街道 */ function setZommAndCenterViewNoMap( _grade: string | number, _lng: string | number, _lat: string | number, ) { getMap?.setZoomAndCenter?.(_grade, [_lng, _lat]); getMap?.getCenter?.(); } /** * 初始化窗口 */ function initSimpleInfoWdw( AMap: any, rowItem: AMapType.RowData, marker: any, _map: any ) { const _window = window as any; _window.AMapUI.loadUI( ['overlay/SimpleInfoWindow'], (SimpleInfoWindow: any) => { const infoWindow = new SimpleInfoWindow({ infoTitle: `${rowItem.f_title ? rowItem.f_title : ''}`, infoBody: rowItem.f_context ? rowItem.f_context : '', //基点指向marker的头部位置 offset: new AMap.Pixel(-5, -5), zindex: "1001" }); //marker 点击时打开 AMap.event.addListener(marker, 'click', (e: any) => { const rowdata: AMapType.RowData = e.target.getExtData(); rowItem.windowEventClassAndCallback && rowItem.windowEventClassAndCallback.length > 0 && addClickCallback(infoWindow, rowItem, rowdata) if (!rowItem.f_isclose_window) { infoWindow.open(_map, [rowdata.f_longitude, rowdata.f_latitude]); } // eslint-disable-next-line @typescript-eslint/no-unused-expressions rowItem.callBack && rowItem.callBack(e, rowdata); }); /* if (isEndData && !rowItem.f_isclose_window) { infoWindow.open(_map, [rowItem.f_longitude, rowItem.f_latitude]); } */ }, ); } /** * 添加回调事件 * @param infoWindow * @param rowItem * @param rowdata */ function addClickCallback(infoWindow: any, rowItem: AMapType.RowData, rowdata: any) { if (rowItem.windowEventClassAndCallback) { for (const itemRow of rowItem.windowEventClassAndCallback) { infoWindow .get$InfoBody() .on( 'click', `.${itemRow.class || 'windClickAmap'}`, function (event: any) { //阻止冒泡 event.stopPropagation(); // 触发窗口回调事件 itemRow.callback(event, rowdata); }, ); } } } /** * 赋值地图参数 */ const upMapOnData = () => { for (const layerItem of getLayerAll) { getMap?.remove(layerItem) } const labelsLayer = new AMap.LabelsLayer({ zooms: [3, 20], zIndex: 1000, }) for (let i = 0; i < props.rowData.length; i++) { const rowItem = props.rowData[i]; // 单点聚焦 if ( props.rowData && props.rowData.length === 1 && rowItem.f_longitude && rowItem.f_latitude ) { setZommAndCenterView( getMap, 15, rowItem.f_longitude, rowItem.f_latitude, ); } // 多点聚焦 if ( props.rowData && props.rowData.length > 1 && i === props.rowData.length - 1 && rowItem.f_longitude && rowItem.f_latitude ) { setZommAndCenterView( getMap, 15, rowItem.f_longitude, rowItem.f_latitude, ); } if (rowItem.f_longitude && rowItem.f_latitude) { const icon: AMap.LabelMarker.IconOptions = { // 图标类型,现阶段只支持 image 类型 type: 'image', // 图片 url image: rowItem.f_icon || markerDefaultIcon, // 图片尺寸 size: [25, 35], // 图片相对 position 的锚点,默认为 bottom-center anchor: 'center' } const text: AMap.LabelMarker.TextOptions = { // 要展示的文字内容 content: rowItem.f_label, // 文本标注方位 可选值:'top'|'right'|'bottom'|'left'|'center',默认值: 'right'。 direction: 'bottom', // 在 direction 基础上的偏移量 offset: [0, 0], // 文字样式 style: { // 字体大小 fontSize: 16, // 字体格式 fontWeight: 'bold', // 字体颜色 fillColor: '#00B9FF', // 背景颜色 backgroundColor: '#ffffff', // 文字内边距 padding: '5px', // 自定义样式 ...rowItem.labelStyle } }; const labelsMarker = new AMap.LabelMarker({ position: [rowItem.f_longitude, rowItem.f_latitude], zIndex: 16, // 将第一步创建的 icon 对象传给 icon 属性 icon: icon, // 将第二步创建的 text 对象传给 text 属性 text: text, }); labelsMarker.setExtData(rowItem) // 添加一个 labelMarker labelsLayer.add(labelsMarker); /* const marker = new getAMap.Marker({ offset: new getAMap.Pixel(-18, -10), position: [rowItem.f_longitude, rowItem.f_latitude], icon: new getAMap.Icon({ image: rowItem.f_icon || markerDefaultIcon, //人员图标URL imageOffset: new getAMap.Pixel(0, 5), // 图标偏移位置 imageSize: new getAMap.Size(23, 31), //图标大小 }), extData: rowItem, }); marker.setMap(getMap); initSimpleInfoWdw(getAMap, rowItem, marker, getMap, i === props.rowData.length - 1);*/ initSimpleInfoWdw(getAMap, rowItem, labelsMarker, getMap); } } setLayerAll([labelsLayer, ...getLayerAll]) getMap.add(labelsLayer); }; /** * 初始化地图 */ const initMap = () => { GetGDMap().then((AMap: any) => { const _map = new AMap.Map(mapId, { zoom: 12, viewMode: '2D', //设置地图模式 lang: 'zh_cn', //设置地图语言类型 zindex: 98, }); // 异步加载地图插件 AMap.plugin(['AMap.ToolBar', 'AMap.Geolocation'], () => { //异步加载插件 _map.addControl(new AMap.ToolBar()); //初始化工具插件 // 异步加载获取当前定位信息插件 if (props.dragMapSetting?.isGetLocation) { const loading = Loading() // 初始化时自动获取当前位置信息 const geoLocation = new AMap.Geolocation({ // 是否使用高精度定位,默认:true enableHighAccuracy: true, // 设置定位超时时间,默认:无穷大 timeout: 10000, // 定位按钮的停靠位置的偏移量 offset: [10, 20], // 定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false zoomToAccuracy: true, // 定位按钮的排放位置, RB表示右下 position: 'LB' }) _map.addControl(geoLocation) geoLocation.getCurrentPosition(); AMap.event.addListener(geoLocation, "complete", (rowdata: any) => { loading.close(); props.dragMapSetting?.getLoactionSuccessCallBack?.(rowdata) }); AMap.event.addListener(geoLocation, "error", (rowdata: any) => { loading.close(); props.dragMapSetting?.getLoactionFailCallBack?.(rowdata) }); } }); props.dragMapSetting && poiPickerDropReady(_map) setAMap(AMap); setMap(_map); }) }; /** * poi选址 */ const poiPickerDropReady = (_map: any) => { const _window = window as any; _window.AMapUI.loadUI(['misc/PositionPicker'], (PositionPicker: any) => { const positionPicker = new PositionPicker({ mode: props.dragMapSetting?.mapModel, map: _map }); positionPicker.on('success', (positionResult: any) => { props.dragMapSetting?.dragMapSuccessCallBack?.(positionResult) }); positionPicker.on('fail', (positionResult: any) => { props.dragMapSetting?.dragMapFailCallBack?.(positionResult) }); positionPickerStartAndStop(positionPicker) setPositionPicker(positionPicker) }) } /** * 拖拽选点开关 * @param positionPicker */ const positionPickerStartAndStop = (positionPicker: any) => { if (props.dragMapSetting?.mapModel === 'dragMap') { positionPicker?.start() //开启拖拽选点 } else { positionPicker?.stop() // 关闭拖拽选点 } } useEffect(() => { initMap(); }, [props.mapId]); useEffect(() => { getMap && upMapOnData(); }, [props.rowData, getMap]); useEffect(() => { positionPickerStartAndStop(getPositionPicker) }, [props.dragMapSetting?.mapModel]); useImperativeHandle( ref, () => { return { setZommAndCenterViewNoMap } } ) return ( <>
); }); export default AMapComponent;