import React, { useEffect, useRef, useState } from 'react'; import { useRecoilState } from 'recoil'; import { currentMap } from '../../store/page'; import Contourlayer from './Contourlayer'; import IconLayer from './IconLayer'; import './style.scss'; let timer = null; const CustomizeMap = (props: ICustomizeMapProps) => { const { ZLG, id, options, ind, change, time, isPreviewShow, Line, Polygon, gisChildren, isUpdateChildren, PointLayer, imgs, PopupLayer, Popup, zoomValue } = props; const { mapKey, mapStyle, zoom, token, longitude, latitude, mapTheme, maxZoom, minZoom, isSave, customizeMapStyle, restore, mapType, mapService } = options; const [first, setFirst] = useState(0); //记录第一次 const [mapDom, setMapDom] = useState(null); //当前地图元素 const [currentMapData, setCurrentMapData] = useRecoilState(currentMap); //记录当前地图 const [gisChildrenNum, setGisChildrenNum] = useState(0); //记录gis图层个数 const mapRef = useRef(); const iconRef = useRef(null); const contourRef = useRef(null); useEffect(() => { if (mapDom) { mapDom.destroy(); } let map = null; //normal 标准 macaron 马卡龙 fresh 草色青 whitesmoke 远山黛 light 月光银 grey 雅土灰 dark 幻影黑 darkblue 极夜蓝 blue 靛青蓝 graffiti 涂鸦 timer = setTimeout(() => { map = new ZLG({ dom: 'map' + id, // dom: mapRef.current, map: { style: mapService ? mapStyle : 'blank', token: token, //高德key securityKey: mapKey, //高德密 center: [longitude, latitude], zoom: zoom, minZoom, maxZoom // zoomEnable // style: 'amap://styles/normal',//高德key // token: 'a21e63692a6def00f737027b4b399610', //高德key // style: // 'http://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=d54d4141c348ac140ddecf5d75eee329', // style: 'http://172.28.41.10:1234/api/styles/normal', // style: 'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}', // style: 'http://172.28.41.10:1235/gaodechina/{z}/{x}/{y}.png', // rotation: 1.22, // pitch: 45.42056074766357 // style:'mapbox://styles/gujiawei/clhejyg44015701pn1g33h8bw', //mapbox在线 // token:'pk.eyJ1IjoiZ3VqaWF3ZWkiLCJhIjoiY2xoZWpneGduMGN2eTNpcDRjYm1sZWtxaiJ9.rpfvRA13nKFQgnddizioDg'//mapbox token } }); map?.__scene?.on('loaded', () => { imgs?.forEach((item) => { map.addImage(item?.key, item?.url); }); //地图绑定事件 mapEvent(map); gisChildren.forEach((item) => { let config = JSON.parse(item?.config); if (config?.type === 'gis_contour') { renderContour(map, config, item); } else if (config?.type === 'gis_icon') { renderIcon(map, config, item); } }); setGisChildrenNum(gisChildren?.length); setMapDom(map); setFirst(1); }); }, time); return () => { if (map) { map.destroy(); setMapDom(null); } //清空轮训气泡定时器解决多个地图时,删除一个地图没有清空定时器报错问题。 if (iconRef?.current) { iconRef?.current?.destroy(); } if (contourRef?.current) { contourRef?.current?.destroy(); } clearTimeout(timer); }; }, []); //地图绑定事件 const mapEvent = (map) => { map?.__scene?.on('movestart', () => { const mapWrap = document?.querySelector(`.${'map' + id}`); let marker = mapWrap ?.querySelector('.l7-marker-container2') ?.querySelector('.l7-popup') || mapWrap ?.querySelector('.l7-marker-container') ?.querySelector('.l7-popup'); if (marker) { marker.remove(); } const oldTip = mapWrap?.querySelector('.div-map') || mapWrap?.querySelector('.div-contour-map'); //如果存在删除原来的 if (oldTip) { oldTip.remove(); } }); map?.__scene?.on('zoomstart', () => { const mapWrap = document?.querySelector(`.${'map' + id}`); const marker = mapWrap ?.querySelector('.l7-marker-container2') ?.querySelector('.l7-popup') || mapWrap ?.querySelector('.l7-marker-container') ?.querySelector('.l7-popup'); if (marker) { marker.remove(); } const oldTip = mapWrap?.querySelector('.div-map') || mapWrap?.querySelector('.div-contour-map'); //如果存在删除原来的 if (oldTip) { oldTip.remove(); } }); }; //图标图层 const renderIcon = (map, config, item) => { iconRef.current = new IconLayer({ map, PointLayer, data: config?.customizeContourData !== '' ? config?.customizeContourData : config?.builtInContour, gisLaryerIndex: Number(item?.elementIndex * 100), isHide: item?.isHide, iconLayerParser: config?.iconLayerParser, iconLayerTextName: config?.iconLayerTextName, iconLayerTextFontsize: config?.iconLayerTextFontsize, iconLayerTextColor: config?.iconLayerTextColor, iconLayerTextPosition: config?.iconLayerTextPosition, iconLayerTextOffset: config?.iconLayerTextOffset, iconLayerIconColor: config?.iconLayerIconColor, showIcon: config?.showIcon, PopupLayer, Popup, bubbleOptins: { bubbleTitleFields: config?.bubbleTitleFields, bubbleTitleType: config?.bubbleTitleType, bubbleTitleCustom: config?.bubbleTitleCustom, bubbleTitleFontSize: config?.bubbleTitleFontSize, bubbleTitleFontColor: config?.bubbleTitleFontColor, bubbleTitleIndicatorPrincipalFields: config?.bubbleTitleIndicatorPrincipalFields, bubbleTitlePrincipalFieldsFontSize: config?.bubbleTitlePrincipalFieldsFontSize, bubbleTitlePrincipalFieldsFontColor: config?.bubbleTitlePrincipalFieldsFontColor, bubbleTitlePrincipalFieldsValueFontColor: config?.bubbleTitlePrincipalFieldsValueFontColor, bubbleTitlePrincipalFieldsValueFontSize: config?.bubbleTitlePrincipalFieldsValueFontSize, bubbleTitleIndicatorType: config?.bubbleTitleIndicatorType, bubbleTitleIndicatorViceFields: config?.bubbleTitleIndicatorViceFields, bubbleTitleViceFieldsFontSize: config?.bubbleTitleViceFieldsFontSize, bubbleTitleViceFieldsFontColor: config?.bubbleTitleViceFieldsFontColor, bubbleTitleViceFieldsValueFontSize: config?.bubbleTitleViceFieldsValueFontSize, bubbleTitleViceFieldsValueFontColor: config?.bubbleTitleViceFieldsValueFontColor, bubbleTitleTiledFields: config?.bubbleTitleTiledFields, bubbleTitleTiledFieldsFontSize: config?.bubbleTitleTiledFieldsFontSize, bubbleTitleTiledFieldsFontColor: config?.bubbleTitleTiledFieldsFontColor, bubbleTitleTiledFieldsValueFontColor: config?.bubbleTitleTiledFieldsValueFontColor, bubbleEvent: config?.bubbleEvent, bubbleWrapFlex: config?.bubbleWrapFlex, bubbleWrapBackgroundColor: config?.bubbleWrapBackgroundColor, bubbleWrapRightLeft: config?.bubbleWrapRightLeft, bubbleWrapTopBottom: config?.bubbleWrapTopBottom, bubbleWrapWidth: config?.bubbleWrapWidth, bubblePolling: config?.bubblePolling, bubblePollingTime: config?.bubblePollingTime }, scale: zoomValue, id }); }; //轮廓填充图层 const renderContour = (map, config, item) => { contourRef.current = new Contourlayer({ map, Line, data: config?.builtInContourData === 'customize' ? config?.customizeContourData : config?.builtInContour, Polygon, gisLaryerIndex: Number(item?.elementIndex * 100), isHide: item?.isHide, contourBackgroudColor: config?.contourBackgroudColor, contourLineColor: config?.contourLineColor, contourLineStyle: config?.contourLineStyle, contourLineSize: config?.contourLineSize, contourLineDashedInterval: config?.contourLineDashedInterval, contourLineDashedLength: config?.contourLineDashedLength, contourFillBackgroud: config?.contourFillBackgroud, contourFillBackgroudType: config?.contourFillBackgroudType, quantizeNumValue: config?.quantizeNumValue, contourLayerParser: config?.contourLayerParser, builtInContourData: config?.builtInContourData, contourFields: config?.contourFields, PointLayer, contourTextFields: config?.contourTextFields, contourTextFontsize: config?.contourTextFontsize, contourTextColor: config?.contourTextColor, contourTextPosition: config?.contourTextPosition, contourTextOffset: config?.contourTextOffset, contourActive: config?.contourActive, contourActiveEvent: config?.contourActiveEvent, contourActiveColor: config?.contourActiveColor, Popup: PopupLayer, Tip: Popup, bubbleOptins: { bubbleTitleFields: config?.contourBubbleTitleFields, bubbleTitleType: config?.contourBubbleTitleType, bubbleTitleCustom: config?.contourBubbleTitleCustom, bubbleTitleFontSize: config?.contourBubbleTitleFontSize, bubbleTitleFontColor: config?.contourBubbleTitleFontColor, bubbleTitleIndicatorPrincipalFields: config?.contourBubbleTitleIndicatorPrincipalFields, bubbleTitlePrincipalFieldsFontSize: config?.contourBubbleTitlePrincipalFieldsFontSize, bubbleTitlePrincipalFieldsFontColor: config?.contourBubbleTitlePrincipalFieldsFontColor, bubbleTitlePrincipalFieldsValueFontColor: config?.contourBubbleTitlePrincipalFieldsValueFontColor, bubbleTitlePrincipalFieldsValueFontSize: config?.contourBubbleTitlePrincipalFieldsValueFontSize, bubbleTitleIndicatorType: config?.contourBubbleTitleIndicatorType, bubbleTitleIndicatorViceFields: config?.contourBubbleTitleIndicatorViceFields, bubbleTitleViceFieldsFontSize: config?.contourBubbleTitleViceFieldsFontSize, bubbleTitleViceFieldsFontColor: config?.contourBubbleTitleViceFieldsFontColor, bubbleTitleViceFieldsValueFontSize: config?.contourBubbleTitleViceFieldsValueFontSize, bubbleTitleViceFieldsValueFontColor: config?.contourBubbleTitleViceFieldsValueFontColor, bubbleTitleTiledFields: config?.contourBubbleTitleTiledFields, bubbleTitleTiledFieldsFontSize: config?.contourBubbleTitleTiledFieldsFontSize, bubbleTitleTiledFieldsFontColor: config?.contourBubbleTitleTiledFieldsFontColor, bubbleTitleTiledFieldsValueFontColor: config?.contourBubbleTitleTiledFieldsValueFontColor, bubbleEvent: config?.contourBubbleEvent, bubbleWrapFlex: config?.contourBubbleWrapFlex, bubbleWrapBackgroundColor: config?.contourBubbleWrapBackgroundColor, bubbleWrapRightLeft: config?.contourBubbleWrapRightLeft, bubbleWrapTopBottom: config?.contourBubbleWrapTopBottom, bubbleWrapWidth: config?.contourBubbleWrapWidth, bubblePolling: config?.contourBubblePolling, bubblePollingTime: config?.contourBubblePollingTime }, scale: zoomValue, id }); }; useEffect(() => { if (iconRef?.current) { iconRef?.current?.destroy(); } if (contourRef?.current) { contourRef?.current?.destroy(); } if (mapDom && isPreviewShow) { mapDom.destroy(); setMapDom(null); } else { if (first === 1) { if (!document.querySelector(`#map${id}`)) { let dom = document.createElement('div'); dom.id = `map${id}`; dom.style.width = '100%'; dom.style.height = '100%'; dom.style.transform = `scale(calc(${1 / zoomValue}))`; document.querySelector(`.map${id}`).appendChild(dom); } let map = null; timer = setTimeout(() => { map = new ZLG({ dom: 'map' + id, // dom: mapRef.current, map: { style: mapService ? mapStyle : 'blank', token: token, //高德key securityKey: mapKey, //高德密 center: [longitude, latitude], zoom: zoom, minZoom, maxZoom // zoomEnable // style: 'amap://styles/normal',//高德key // token: 'a21e63692a6def00f737027b4b399610', //高德key // style: // 'http://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=d54d4141c348ac140ddecf5d75eee329', // style: 'http://172.28.41.10:1234/api/styles/normal', // style: 'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}', // style: 'http://172.28.41.10:1235/gaodechina/{z}/{x}/{y}.png', // rotation: 1.22, // pitch: 45.42056074766357 // style:'mapbox://styles/gujiawei/clhejyg44015701pn1g33h8bw', //mapbox在线 // token:'pk.eyJ1IjoiZ3VqaWF3ZWkiLCJhIjoiY2xoZWpneGduMGN2eTNpcDRjYm1sZWtxaiJ9.rpfvRA13nKFQgnddizioDg'//mapbox token } }); map?.__scene?.on('loaded', () => { imgs?.forEach((item) => { map.addImage(item?.key, item?.url); }); //地图绑定事件 mapEvent(map); gisChildren.forEach((item) => { let config = JSON.parse(item?.config); if (config?.type === 'gis_contour') { renderContour(map, config, item); } else if (config?.type === 'gis_icon') { renderIcon(map, config, item); } }); setGisChildrenNum(gisChildren?.length); setMapDom(map); }); }, time); } } }, [isPreviewShow]); useEffect(() => { if (first === 1) { if (mapDom) { mapDom.destroy(); } if (!document.querySelector(`#map${id}`)) { let dom = document.createElement('div'); dom.id = `map${id}`; dom.style.width = '100%'; dom.style.height = '100%'; dom.style.transform = `scale(calc(${1 / zoomValue}))`; document.querySelector(`.map${id}`).appendChild(dom); } let map = new ZLG({ dom: 'map' + id, map: { style: mapService ? mapStyle : 'blank', token: token, //高德key securityKey: mapKey, //高德密 center: [longitude, latitude], zoom: zoom, minZoom, maxZoom // zoomEnable } }); map?.__scene?.on('loaded', () => { imgs?.forEach((item) => { map.addImage(item?.key, item?.url); }); //地图绑定事件 mapEvent(map); gisChildren.forEach((item) => { let config = JSON.parse(item?.config); if (config?.type === 'gis_contour') { renderContour(map, config, item); } else if (config?.type === 'gis_icon') { renderIcon(map, config, item); } }); setGisChildrenNum(gisChildren?.length); setMapDom(map); }); } }, [imgs?.length]); //切换自定义主题 useEffect(() => { if (first === 1) { mapDom.setMap(mapStyle); } }, [mapTheme]); //切换底图 useEffect(() => { if (first === 1 && mapStyle !== '' && !customizeMapStyle) { if (mapDom) { mapDom.destroy(); } if (iconRef?.current) { iconRef?.current?.destroy(); } if (contourRef?.current) { contourRef?.current?.destroy(); } if (!document.querySelector(`#map${id}`)) { let dom = document.createElement('div'); dom.id = `map${id}`; dom.style.width = '100%'; dom.style.height = '100%'; dom.style.transform = `scale(calc(${1 / zoomValue}))`; document.querySelector(`.map${id}`).appendChild(dom); } let map = new ZLG({ dom: 'map' + id, map: { style: mapService ? mapStyle : 'blank', token: token, //高德key securityKey: mapKey, //高德密 center: [longitude, latitude], zoom: zoom, minZoom, maxZoom // zoomEnable } }); map?.__scene?.on('loaded', () => { imgs?.forEach((item) => { map.addImage(item?.key, item?.url); }); //地图绑定事件 mapEvent(map); gisChildren.forEach((item) => { let config = JSON.parse(item?.config); if (config?.type === 'gis_contour') { renderContour(map, config, item); } else if (config?.type === 'gis_icon') { renderIcon(map, config, item); } }); setGisChildrenNum(gisChildren?.length); setMapDom(map); }); } }, [mapStyle, minZoom, maxZoom, mapService]); //恢复默认值的时候切换底图 与maxzoom冲突 所以分开 useEffect(() => { if (first === 1 && mapStyle !== '' && token !== '') { if (iconRef?.current) { iconRef?.current?.destroy(); } if (contourRef?.current) { contourRef?.current?.destroy(); } if (stringLength(token) !== 32 && mapType === 'gaode') { mapDom.destroy(); } else { mapDom.destroy(); if (!document.querySelector(`#map${id}`)) { let dom = document.createElement('div'); dom.id = `map${id}`; dom.style.width = '100%'; dom.style.height = '100%'; dom.style.transform = `scale(calc(${1 / zoomValue}))`; document.querySelector(`.map${id}`).appendChild(dom); } let map = new ZLG({ dom: 'map' + id, map: { style: mapService ? mapStyle : 'blank', token: token, //高德key securityKey: mapKey, //高德密 center: [longitude, latitude], zoom: zoom, minZoom, maxZoom } }); map?.__scene?.on('loaded', () => { imgs?.forEach((item) => { map.addImage(item?.key, item?.url); }); //地图绑定事件 mapEvent(map); gisChildren.forEach((item) => { let config = JSON.parse(item?.config); if (config?.type === 'gis_contour') { renderContour(map, config, item); } else if (config?.type === 'gis_icon') { renderIcon(map, config, item); } }); setGisChildrenNum(gisChildren?.length); setMapDom(map); }); } } }, [isSave, restore]); //设置中心点位置 useEffect(() => { if (first === 1 && !customizeMapStyle) { mapDom.setCenter([longitude, latitude]); } }, [longitude, latitude]); //设置zoom级别 useEffect(() => { if (first === 1 && !customizeMapStyle) { mapDom.setZoom(zoom); } }, [zoom]); useEffect(() => { if (first === 1) { if (iconRef?.current) { iconRef?.current?.destroy(); } if (contourRef?.current) { contourRef?.current?.destroy(); } const mapWrap = document.querySelector(`.${'map' + id}`); let marker = mapWrap?.querySelector('.l7-marker-container2') || mapWrap?.querySelector('.l7-marker-container'); if (marker) { marker.innerHTML = ''; } if (gisChildren?.length > gisChildrenNum) { let config = JSON.parse(gisChildren?.[0]?.config); if (config?.type === 'gis_contour') { renderContour(mapDom, config, gisChildren?.[0]); } else if (config?.type === 'gis_icon') { renderIcon(mapDom, config, gisChildren?.[0]); } setGisChildrenNum(gisChildren?.length); } else { mapDom.removeAllLayer(); gisChildren.forEach((item) => { let config = JSON.parse(item?.config); if (config?.type === 'gis_contour') { renderContour(mapDom, config, item); } else if (config?.type === 'gis_icon') { renderIcon(mapDom, config, item); } }); setGisChildrenNum(gisChildren?.length); } } }, [gisChildren?.length]); useEffect(() => { if (first === 1) { if (iconRef?.current) { iconRef?.current?.destroy(); } if (contourRef?.current) { contourRef?.current?.destroy(); } const mapWrap = document.querySelector(`.${'map' + id}`); const marker = mapWrap ?.querySelector('.l7-marker-container2') ?.querySelector('.l7-popup') || mapWrap ?.querySelector('.l7-marker-container') ?.querySelector('.l7-popup'); if (marker) { marker.remove(); } const oldTip = mapWrap?.querySelector('.div-map') || mapWrap?.querySelector('.div-contour-map'); //如果存在删除原来的 if (oldTip) { oldTip.remove(); } mapDom.removeAllLayer(); gisChildren.forEach((item) => { let config = JSON.parse(item?.config); if (config?.type === 'gis_contour') { renderContour(mapDom, config, item); } else if (config?.type === 'gis_icon') { renderIcon(mapDom, config, item); } }); setGisChildrenNum(gisChildren?.length); } }, [isUpdateChildren]); //编辑视角 const editingPerspective = (index) => { if (index === currentMapData) { change({ zoom: mapDom?.getZoom(), center: mapDom?.getCenter() }); setCurrentMapData(-1); } else { setCurrentMapData(index); } }; //计算字符串的length const stringLength = (str) => { let length = str?.length; let count = 0; for (let i = 0; i < length; i++) { if ((str.charCodeAt(i) & 0xff00) != 0) { count++; } count++; } return count; }; return (