Skip to content

Commit

Permalink
[wip] topicmap selections feature complete, cesium still has rerender…
Browse files Browse the repository at this point in the history
… issue, have newSelection/flyto flag
  • Loading branch information
mxfh committed Nov 25, 2024
1 parent 279cee6 commit 9a76949
Show file tree
Hide file tree
Showing 15 changed files with 186 additions and 136 deletions.
74 changes: 46 additions & 28 deletions apps/geoportal/src/app/components/GeoportalMap/GeoportalMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import TopicMapComponent from "react-cismap/topicmaps/TopicMapComponent";
import GazetteerHitDisplay from "react-cismap/GazetteerHitDisplay";
import { ProjSingleGeoJson } from "react-cismap/ProjSingleGeoJson";
import GenericModalApplicationMenu from "react-cismap/topicmaps/menu/ModalApplicationMenu";
import { TopicMapContext } from "react-cismap/contexts/TopicMapContextProvider";
import { UIDispatchContext } from "react-cismap/contexts/UIContextProvider";

import {
Expand Down Expand Up @@ -66,7 +67,7 @@ import {
useZoomControls as useZoomControlsCesium,
setCurrentSceneStyle,
} from "@carma-mapping/cesium-engine";
import { LibFuzzySearch } from "@carma-mapping/fuzzy-search";
import { LibFuzzySearch, SearchResultItem } from "@carma-mapping/fuzzy-search";

import versionData from "../../../version.json";

Expand Down Expand Up @@ -218,15 +219,14 @@ export const GeoportalMap = () => {
)
);

const { topicMapCtx, setShowTourOverlay } = useCarmaMapContext();

const { setShowTourOverlay } = useCarmaMapContext();
const {
routedMapRef: routedMap,
//realRoutedMapRef: routedMapRef,
realRoutedMapRef: routeMapRef,
referenceSystem,
referenceSystemDefinition,
maskingPolygon,
} = topicMapCtx;
} = useContext<typeof TopicMapContext>(TopicMapContext);

const { setAppMenuVisible } =
useContext<typeof UIDispatchContext>(UIDispatchContext);
Expand Down Expand Up @@ -258,17 +258,34 @@ export const GeoportalMap = () => {

useFeatureInfoModeCursorStyle();

const { selection, setSelection, overlayFeature, setOverlayFeature } = useSelection();
useSelectionTopicMap();
useSelectionCesium(!isMode2d, useMemo(() => ({
markerAsset,
markerAnchorHeight,
isPrimaryStyle: showPrimaryTileset,
surfaceProviderRef,
terrainProviderRef,
}),
[markerAsset, markerAnchorHeight, showPrimaryTileset, surfaceProviderRef, terrainProviderRef]
));
const { selection, setSelection, setIsNewSelection, overlayFeature } =
useSelection();

useSelectionTopicMap(isMode2d);
useSelectionCesium(
!isMode2d,
useMemo(
() => ({
markerAsset,
markerAnchorHeight,
isPrimaryStyle: showPrimaryTileset,
surfaceProviderRef,
terrainProviderRef,
}),
[
markerAsset,
markerAnchorHeight,
showPrimaryTileset,
surfaceProviderRef,
terrainProviderRef,
]
)
);

const onGazetteerSelection = (selection: SearchResultItem) => {
setSelection(selection);
setIsNewSelection(true);
};

useEffect(() => {
let isSame = true;
Expand Down Expand Up @@ -313,7 +330,6 @@ export const GeoportalMap = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [allow3d]);


const renderInfoBox = () => {
if (isMode2d) {
if (isModeMeasurement) {
Expand Down Expand Up @@ -435,8 +451,9 @@ export const GeoportalMap = () => {
dataTestId="measurement-control"
>
<img
src={`${getUrlPrefix()}${isModeMeasurement ? "measure-active.png" : "measure.png"
}`}
src={`${getUrlPrefix()}${
isModeMeasurement ? "measure-active.png" : "measure.png"
}`}
alt="Measure"
className="w-6"
/>
Expand Down Expand Up @@ -496,11 +513,9 @@ export const GeoportalMap = () => {
>
<LibFuzzySearch
gazData={gazData}
referenceSystem={referenceSystem}
referenceSystemDefinition={referenceSystemDefinition}
gazetteerHit={selection}
setGazetteerHit={setSelection}
setOverlayFeature={setOverlayFeature}
//referenceSystem={referenceSystem}
//referenceSystemDefinition={referenceSystemDefinition}
onSelection={onGazetteerSelection}
placeholder="Wohin?"
/>
</div>
Expand Down Expand Up @@ -560,10 +575,13 @@ export const GeoportalMap = () => {
mapRef={routedMap}
/>
)}
<GazetteerHitDisplay
key={"gazHit" + JSON.stringify(selection)}
gazetteerHit={selection}
/>
!overlayFeature &&{" "}
{
<GazetteerHitDisplay
key={"gazHit" + JSON.stringify(selection)}
gazetteerHit={selection}
/>
}
{focusMode && <PaleOverlay />}
{createCismapLayers(layers, {
focusMode,
Expand Down
6 changes: 4 additions & 2 deletions libraries/appframeworks/portals/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export {

export { GazDataProvider, useGazData } from "./lib/components/GazDataProvider";

export { SelectionProvider, useSelection } from "./lib/components/SelectionProvider";
export {
SelectionProvider,
useSelection,
} from "./lib/components/SelectionProvider";
export { useSelectionTopicMap } from "./lib/hooks/useSelectionTopicMap";
export { useSelectionCesium } from "./lib/hooks/useSelectionCesium";

Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ type CarmaMapProviderProps = {
};

type CarmaMapContextType = {
topicMapCtx?: typeof TopicMapContext;
cesiumCtx?: CesiumContextType;
setShowTourOverlay: Dispatch<SetStateAction<boolean>>;
};

Expand All @@ -42,23 +40,7 @@ export const useCarmaMapContext = () => {
"useCarmaMapContext must be used within a CarmaMapProvider"
);
}
const { setShowTourOverlay } = context;
// forward other contexts here if needed
const topicMapContext = useContext<typeof TopicMapContext>(TopicMapContext);
const cesiumContext = useCesiumContext();

const combinedContext = useMemo(
() => ({
setShowTourOverlay,
topicMapCtx: topicMapContext,
cesiumCtx: cesiumContext,
//routedMapRef: topicMapContext.realRoutedMapRef,
//realRoutedMapRef: undefined,
}),
[setShowTourOverlay, topicMapContext, cesiumContext]
);

return combinedContext;
return context;
};

export const CarmaMapContextProvider = ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,34 @@ import { Option, SearchResultItem } from "@carma-mapping/fuzzy-search";
import { Feature } from "geojson";
import { createContext, useContext, useState } from "react";


interface SelectionContextType {
selection: SearchResultItem | null;
setSelection: (selection: SearchResultItem | null) => void;
isNewSelection: boolean;
setIsNewSelection: (isNewSelection: boolean) => void;
overlayFeature: Feature | null;
setOverlayFeature: (feature: Feature | null) => void;
}

const SelectionContext = createContext<SelectionContextType | undefined>(undefined);
const SelectionContext = createContext<SelectionContextType | undefined>(
undefined
);

interface SelectionProviderProps {
children: React.ReactNode;
}

export function SelectionProvider({
children,
}: SelectionProviderProps) {
export function SelectionProvider({ children }: SelectionProviderProps) {
//const [gazetteerHit, setGazetteerHit] = useState(null);
const [selection, setSelection] = useState<SearchResultItem|null>(null);
const [overlayFeature, setOverlayFeature] = useState<Feature|null>(null);
const [selection, setSelection] = useState<SearchResultItem | null>(null);
const [isNewSelection, setIsNewSelection] = useState<boolean>(false);
const [overlayFeature, setOverlayFeature] = useState<Feature | null>(null);

const value = {
selection,
setSelection,
isNewSelection,
setIsNewSelection,
overlayFeature,
setOverlayFeature,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import {
useCesiumContext,
} from "@carma-mapping/cesium-engine";
import { Viewer } from "cesium";
import { MutableRefObject, useEffect, useState } from "react";
import { MutableRefObject, useEffect, useMemo, useState, useRef } from "react";
import { useSelection } from "../components/SelectionProvider";
import { carmaHitTrigger } from "../utils/carmaHitTrigger";
import { SearchResultItem } from "../../../../../mapping/fuzzy-search/src/index";

export const SELECTED_POLYGON_ID = "searchgaz-highlight-polygon";
export const INVERTED_SELECTED_POLYGON_ID = "searchgaz-inverted-polygon";
Expand All @@ -34,20 +35,34 @@ export const useSelectionCesium = (
cesiumOptions: CesiumOptions
) => {
const { viewerRef } = useCesiumContext();
const { selection, setSelection } = useSelection();
const { selection, setSelection, isNewSelection, setIsNewSelection } =
useSelection();

const [selectedCesiumEntityData, setSelectedCesiumEntityData] =
useState<EntityData | null>(null);

const options = {
cesiumOptions,
selectedCesiumEntityData,
setSelectedCesiumEntityData,
selectedPolygonId: SELECTED_POLYGON_ID,
invertedSelectedPolygonId: INVERTED_SELECTED_POLYGON_ID,
};
// Ref to store the previous selection
const previousSelectionRef = useRef<SearchResultItem | null>(null);

useEffect(() => {
// Check if the current selection is the same as the previous one
if (areSelectionsEqual(previousSelectionRef.current, selection)) {
// If same, do not retrigger the effect
return;
}

// Update the previous selection ref
//previousSelectionRef.current = selection;

const options = {
cesiumOptions,
flyTo: isNewSelection,
selectedCesiumEntityData,
setSelectedCesiumEntityData,
selectedPolygonId: SELECTED_POLYGON_ID,
invertedSelectedPolygonId: INVERTED_SELECTED_POLYGON_ID,
};

console.debug("HOOK: useSelectionCesium", selection, isActive);
if (selection && isActive) {
carmaHitTrigger([selection], [viewerRef], options);
Expand All @@ -71,5 +86,19 @@ export const useSelectionCesium = (
isActive,
cesiumOptions,
setSelectedCesiumEntityData,
selectedCesiumEntityData,
]);
};

// Utility function to compare two selections
const areSelectionsEqual = (
prevSelection: SearchResultItem | null,
currentSelection: SearchResultItem | null
): boolean => {
// Implement your comparison logic here
// For example, if EntityData has an 'id' field:
if (prevSelection === currentSelection) return true;
if (!prevSelection || !currentSelection) return false;
console.debug("HOOK: areSelectionsEqual", prevSelection, currentSelection);
return prevSelection.more === currentSelection.more;
};
Original file line number Diff line number Diff line change
@@ -1,57 +1,56 @@
import { MutableRefObject, useEffect, useState } from "react";
import { useContext, useEffect } from "react";

import { builtInGazetteerHitTrigger } from "react-cismap/tools/gazetteerHelper";
import { TopicMapContext } from "react-cismap/contexts/TopicMapContextProvider";

import { useSelection } from "../components/SelectionProvider";
import { useCarmaMapContext } from "../components/CarmaMapContextProvider";

export const useSelectionTopicMap = () => {
const { selection, setSelection, overlayFeature, setOverlayFeature } =
useSelection();
export const useSelectionTopicMap = (enable: boolean) => {
const {
selection,
setSelection,
overlayFeature,
setOverlayFeature,
isNewSelection,
setIsNewSelection,
} = useSelection();

const topicMapCtx = useContext<typeof TopicMapContext>(TopicMapContext);

const { topicMapCtx } = useCarmaMapContext();
const {
routedMapRef: routedMap,
//routedMapRef: routedMap,
realRoutedMapRef: routedMapRef,
referenceSystem,
referenceSystemDefinition,
} = topicMapCtx;
console.debug("topicMapCtx", topicMapCtx);

useEffect(() => {
if (!routedMapRef.current || !selection) return;
//const routedMap = routedMapRef.current;
console.debug("HOOK: clear overlay on empty selection", selection);
if (isNewSelection && selection === null) {
setOverlayFeature(null);
}
}, [isNewSelection, selection, setOverlayFeature]);

console.debug(
"HOOK: useSelectionTopicMap selection",
selection,
routedMapRef
);
if (selection.type === "bezirke" || selection.type === "quartiere") {
console.debug("selection is area");
//setOverlayFeature(selection);
/*
routedMap && builtInGazetteerHitTrigger(
[selection],
routedMapRef,
referenceSystem,
referenceSystemDefinition,
setSelection,
setOverlayFeature
);
*/
} else {
useEffect(() => {
console.debug("HOOK: useSelectionTopicMap selection LEAFLET", selection);
if (selection && isNewSelection && enable) {
const { leafletElement } = routedMapRef.current?.leafletMap;
builtInGazetteerHitTrigger(
selection,
routedMapRef,
[selection],
leafletElement,
referenceSystem,
referenceSystemDefinition,
setSelection,
setOverlayFeature
);
setIsNewSelection(false);
}

return () => console.info("unmounting useSelectionTopicMap");
}, [
isNewSelection,
setIsNewSelection,
enable,
selection,
routedMapRef,
referenceSystem,
Expand Down
Loading

0 comments on commit 9a76949

Please sign in to comment.