diff --git a/apps/geoportal/src/app/components/GeoportalMap/GeoportalMap.tsx b/apps/geoportal/src/app/components/GeoportalMap/GeoportalMap.tsx index 08eb0d7cb0..4ee32f7ac2 100644 --- a/apps/geoportal/src/app/components/GeoportalMap/GeoportalMap.tsx +++ b/apps/geoportal/src/app/components/GeoportalMap/GeoportalMap.tsx @@ -100,8 +100,13 @@ import { getLayersIdle, getShowHamburgerMenu, setLayersIdle, + setMaplibreMaps, } from "../../store/slices/mapping.ts"; -import { getUIMode, UIMode } from "../../store/slices/ui.ts"; +import { + getUIMode, + UIMode, + getTriggerFeatureInfoUpdate, +} from "../../store/slices/ui.ts"; import LoginForm from "../LoginForm.tsx"; import { useModelSelectionDispatcher } from "../../hooks/useModelSelectionDispatcher.ts"; @@ -215,6 +220,7 @@ export const GeoportalMap = ({ height, width, allow3d }: MapProps) => { const [shouldUpdateFeatureInfo, setShouldUpdateFeatureInfo] = useState(false); const layersIdle = useSelector(getLayersIdle); + const triggerFeatureInfoUpdate = useSelector(getTriggerFeatureInfoUpdate); const version = getApplicationVersion(versionData); @@ -528,10 +534,11 @@ export const GeoportalMap = ({ height, width, allow3d }: MapProps) => { ); useEffect(() => { - if (shouldUpdateFeatureInfo) updateFeatureInfoLeaflet(); + if (shouldUpdateFeatureInfo || triggerFeatureInfoUpdate > 0) + updateFeatureInfoLeaflet(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [shouldUpdateFeatureInfo]); + }, [shouldUpdateFeatureInfo, triggerFeatureInfoUpdate]); const topicMapLocationChangedHandler = useCallback( (p: { lat: number; lng: number; zoom: number }) => { @@ -588,6 +595,7 @@ export const GeoportalMap = ({ height, width, allow3d }: MapProps) => { selectedFeature, leafletMap: getLeafletMap(), maplibreMapsRef, + setMaplibreMaps: (entry) => dispatch(setMaplibreMaps(entry)), }), [ uiMode, @@ -596,6 +604,7 @@ export const GeoportalMap = ({ height, width, allow3d }: MapProps) => { selectedFeature, getLeafletMap, maplibreMapsRef, + setMaplibreMaps, ] ); diff --git a/apps/geoportal/src/app/components/GeoportalMap/hooks/useCreateCismapLayer.ts b/apps/geoportal/src/app/components/GeoportalMap/hooks/useCreateCismapLayer.ts index 00b81d32cc..d12cf749cc 100644 --- a/apps/geoportal/src/app/components/GeoportalMap/hooks/useCreateCismapLayer.ts +++ b/apps/geoportal/src/app/components/GeoportalMap/hooks/useCreateCismapLayer.ts @@ -72,6 +72,7 @@ export const useCreateCismapLayers = ( selectedFeature, leafletMap, maplibreMapsRef, + setMaplibreMaps, }: { mode: UIMode; dispatch: Dispatch; @@ -79,6 +80,7 @@ export const useCreateCismapLayers = ( selectedFeature: any; leafletMap: LeafletMap; maplibreMapsRef?: React.MutableRefObject>; + setMaplibreMaps?: (entry: { id: string; map: any }) => void; } ) => { const [globalHits, setGlobalHits] = useState({}); @@ -272,6 +274,9 @@ export const useCreateCismapLayers = ( if (maplibreMapsRef) { maplibreMapsRef.current.set(layer.id, map); } + if (setMaplibreMaps) { + setMaplibreMaps({ id: layer.id, map }); + } }, onStyleIdle: (e) => { setIdleLayers((old) => { diff --git a/apps/geoportal/src/app/components/GeoportalMap/topicmap.utils.ts b/apps/geoportal/src/app/components/GeoportalMap/topicmap.utils.ts index 8371bde88b..e1951d087b 100644 --- a/apps/geoportal/src/app/components/GeoportalMap/topicmap.utils.ts +++ b/apps/geoportal/src/app/components/GeoportalMap/topicmap.utils.ts @@ -456,6 +456,7 @@ const createVectorFeature = async ( geometry: selectedVectorFeature.geometry, id: layer.id, vectorId: selectedVectorFeature.id, + sourceFeature: selectedVectorFeature, showMarker: selectedVectorFeature.geometry.type === "Polygon" || selectedVectorFeature.geometry.type === "MultiPolygon", diff --git a/apps/geoportal/src/app/components/layers/GeoportalLayerButton.tsx b/apps/geoportal/src/app/components/layers/GeoportalLayerButton.tsx index 3c06d270ec..691ff0e0cc 100644 --- a/apps/geoportal/src/app/components/layers/GeoportalLayerButton.tsx +++ b/apps/geoportal/src/app/components/layers/GeoportalLayerButton.tsx @@ -7,7 +7,12 @@ import { useDispatch, useSelector } from "react-redux"; import { useSortable } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; -import { faEye, faEyeSlash, faX } from "@fortawesome/free-solid-svg-icons"; +import { + faEye, + faEyeSlash, + faFilter, + faX, +} from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import L from "leaflet"; @@ -15,6 +20,7 @@ import { TopicMapContext } from "react-cismap/contexts/TopicMapContextProvider"; import type { Layer } from "@carma/types"; import { cn, getHashParams } from "@carma-commons/utils"; +import type { FilterInfo } from "@carma-mapping/components"; import { updateInfoElementsAfterRemovingFeature } from "../../store/slices/features"; import { @@ -22,11 +28,13 @@ import { getClickFromInfoView, getLayers, getSelectedLayerIndex, + getActiveFilterLayerID, getShowLeftScrollButton, removeLayer, setClickFromInfoView, setSelectedLayerIndex, setSelectedLayerIndexNoSelection, + setActiveFilterLayerID, setShowLeftScrollButton, setShowRightScrollButton, toggleUseInFeatureInfo, @@ -40,7 +48,7 @@ import "./pulsing.css"; import "./tabs.css"; import { LayerButton, LayerIcon } from "@carma-mapping/components"; -import { Spin } from "antd"; +import { Badge, Spin } from "antd"; import { LoadingOutlined } from "@ant-design/icons"; import { useLayerLoading } from "@carma-mapping/utils"; @@ -51,6 +59,7 @@ interface LayerButtonProps { icon?: string; layer: Layer; background?: boolean; + filterInfo?: FilterInfo; } const GeoportalLayerButton = ({ @@ -60,6 +69,7 @@ const GeoportalLayerButton = ({ icon, layer, background, + filterInfo, }: LayerButtonProps) => { const { ref, inView } = useInView({ threshold: 0.99, @@ -84,6 +94,7 @@ const GeoportalLayerButton = ({ const showLayerHideButtons = useSelector(getUIShowLayerHideButtons); const showLeftScrollButton = useSelector(getShowLeftScrollButton); const clickFromInfoView = useSelector(getClickFromInfoView); + const activeFilterLayerID = useSelector(getActiveFilterLayerID); const mode = useSelector(getUIMode); const showSettings = index === selectedLayerIndex; const layers = useSelector(getLayers); @@ -202,6 +213,42 @@ const GeoportalLayerButton = ({ {!background && ( <> {title} + {layer.filterConfig && ( + + )} +