Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export enum GeometryFormat {
export const NULL_STRING = '<NULL>';

export const SELECTION_LAYER_NAME = 'thematic-selection-layer';
export const PRESENTATION_LAYER_NAME = 'thematic-presentation-layer';
export const MASK_LAYER_NAME = 'thematic-mask-layer';
export const LAYER_NAME_PROP = 'layerName';
export const SELECTION_BACKGROUND_OPACITY = 0.5;
export const FULL_OPACITY = 1;
export const DEFAULT_MASK_COLOR = { r: 128, g: 128, b: 128, a: 1 };
export const DEFAULT_MERGED_STROKE_COLOR = { r: 0, g: 0, b: 0, a: 1 };
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,16 @@ import VectorSource from 'ol/source/Vector';
import GeoJSON from 'ol/format/GeoJSON';
import {
dataRecordsToOlFeatures,
fitMapToFeatures,
fitMapToData,
fitMapToDataRecords,
} from '../../util/mapUtil';
import {
createMaskLayer,
createLayer,
createPresentationLayer,
createSelectionLayer,
getSelectedFeatures,
removeManagedLayer,
removeSelectionLayer,
setSelectionBackgroundOpacity,
} from '../../util/layerUtil';
Expand All @@ -48,10 +51,17 @@ import { StyledFeatureTooltip } from './FeatureTooltip';
import {
FULL_OPACITY,
GeometryFormat,
MASK_LAYER_NAME,
PRESENTATION_LAYER_NAME,
SELECTION_BACKGROUND_OPACITY,
} from '../../constants';
import { Legend } from './Legend';
import { getMapExtentPadding } from '../../util/geometryUtil';
import {
areFeaturesPolygonal,
createMaskFeature,
getMapExtentPadding,
mergePolygonFeatures,
} from '../../util/geometryUtil';

export const OlChartMap = (props: OlChartMapProps) => {
const {
Expand Down Expand Up @@ -79,6 +89,12 @@ export const OlChartMap = (props: OlChartMapProps) => {
tooltipTemplate,
showLegend,
showTooltip,
showAreaMask,
areaMaskOpacity,
areaMaskColor,
mergePolygonEntities,
mergedPolygonStrokeWidth,
mergedPolygonStrokeColor,
} = props;

const [currentMapView, setCurrentMapView] = useState<MapViewConfigs>(mapView);
Expand Down Expand Up @@ -108,6 +124,25 @@ export const OlChartMap = (props: OlChartMapProps) => {
return data;
}, [data, geomColumn, geomFormat]);

/**
* Use OL features for WKB/WKT-specific flows that need native OpenLayers
* features repeatedly, such as extent fitting and vector source updates.
* Keep using processedData for filtering and GeoJSON-backed logic.
*/
const dataFeatures = useMemo(() => {
if (
geomFormat === GeometryFormat.WKB ||
geomFormat === GeometryFormat.WKT
) {
return dataRecordsToOlFeatures(
processedData as DataRecord[],
geomColumn,
geomFormat,
) as OlFeature[];
}
return undefined;
}, [processedData, geomColumn, geomFormat]);

/**
* Add map to correct DOM element.
*/
Expand Down Expand Up @@ -203,11 +238,9 @@ export const OlChartMap = (props: OlChartMapProps) => {
geomFormat === GeometryFormat.WKB ||
geomFormat === GeometryFormat.WKT
) {
fitMapToDataRecords(
fitMapToFeatures(
olMap,
processedData as DataRecord[],
geomColumn,
geomFormat,
dataFeatures || [],
getMapExtentPadding(mapExtentPadding),
);
} else {
Expand Down Expand Up @@ -311,11 +344,9 @@ export const OlChartMap = (props: OlChartMapProps) => {
geomFormat === GeometryFormat.WKB ||
geomFormat === GeometryFormat.WKT
) {
fitMapToDataRecords(
fitMapToFeatures(
olMap,
data,
geomColumn,
geomFormat,
dataFeatures || [],
getMapExtentPadding(mapExtentPadding),
);
} else {
Expand All @@ -333,6 +364,7 @@ export const OlChartMap = (props: OlChartMapProps) => {
geomFormat,
geomColumn,
processedData,
dataFeatures,
mapExtentPadding,
]);

Expand Down Expand Up @@ -369,6 +401,47 @@ export const OlChartMap = (props: OlChartMapProps) => {
return filteredRecords;
}, [processedData, timeColumn, timeFilter, geomFormat]);

const filteredFeatures = useMemo(() => {
if (
geomFormat === GeometryFormat.WKB ||
geomFormat === GeometryFormat.WKT
) {
if (filteredData === processedData) {
return dataFeatures;
}
return dataRecordsToOlFeatures(
filteredData as DataRecord[],
geomColumn,
geomFormat,
) as OlFeature[];
}
return undefined;
}, [filteredData, processedData, dataFeatures, geomColumn, geomFormat]);

const visibleFeatures = useMemo(() => {
if (
geomFormat === GeometryFormat.WKB ||
geomFormat === GeometryFormat.WKT
) {
return (filteredFeatures || []) as OlFeature[];
}
return new GeoJSON().readFeatures(filteredData, {
featureProjection: 'EPSG:3857',
}) as OlFeature[];
}, [filteredData, filteredFeatures, geomFormat]);

const mergedVisibleFeatures = useMemo(() => {
if (!mergePolygonEntities || !areFeaturesPolygonal(visibleFeatures)) {
return undefined;
}
return mergePolygonFeatures(visibleFeatures) as OlFeature[];
}, [mergePolygonEntities, visibleFeatures]);

const usesMergedPresentation =
mergePolygonEntities &&
areFeaturesPolygonal(visibleFeatures) &&
Boolean(mergedVisibleFeatures?.length);

/**
* Update layers
*/
Expand Down Expand Up @@ -406,25 +479,82 @@ export const OlChartMap = (props: OlChartMapProps) => {
useEffect(() => {
currentDataLayers?.forEach(dataLayer => {
const source = dataLayer.getSource();
let features: OlFeature[];
if (
geomFormat === GeometryFormat.WKB ||
geomFormat === GeometryFormat.WKT
) {
features = dataRecordsToOlFeatures(
filteredData as DataRecord[],
geomColumn,
geomFormat,
) as OlFeature[];
} else {
features = new GeoJSON().readFeatures(filteredData, {
featureProjection: 'EPSG:3857',
});
}
source?.clear();
source?.addFeatures(features);
source?.addFeatures(visibleFeatures);
});
}, [currentDataLayers, filteredData, geomColumn, geomFormat]);
}, [currentDataLayers, visibleFeatures]);

useEffect(() => {
removeManagedLayer(olMap, PRESENTATION_LAYER_NAME);

if (
!currentDataLayers ||
currentDataLayers.length === 0 ||
!usesMergedPresentation ||
!mergedVisibleFeatures
) {
return undefined;
}

const presentationLayer = createPresentationLayer(
mergedVisibleFeatures,
mergedPolygonStrokeColor,
mergedPolygonStrokeWidth,
);
olMap.addLayer(presentationLayer);

return () => {
removeManagedLayer(olMap, PRESENTATION_LAYER_NAME);
};
}, [
currentDataLayers,
mergedPolygonStrokeColor,
mergedPolygonStrokeWidth,
mergedVisibleFeatures,
olMap,
usesMergedPresentation,
]);

useEffect(() => {
removeManagedLayer(olMap, MASK_LAYER_NAME);

if (!showAreaMask || !areFeaturesPolygonal(visibleFeatures)) {
return undefined;
}

const focusFeatures =
usesMergedPresentation && mergedVisibleFeatures
? mergedVisibleFeatures
: visibleFeatures;
const projectionExtent = olMap.getView().getProjection().getExtent();
if (!projectionExtent) {
return undefined;
}

const maskFeature = createMaskFeature(focusFeatures, projectionExtent);
if (!maskFeature) {
return undefined;
}

const maskLayer = createMaskLayer(
maskFeature,
areaMaskColor,
areaMaskOpacity / 100,
);
olMap.addLayer(maskLayer);

return () => {
removeManagedLayer(olMap, MASK_LAYER_NAME);
};
}, [
mergedVisibleFeatures,
areaMaskOpacity,
areaMaskColor,
olMap,
showAreaMask,
usesMergedPresentation,
visibleFeatures,
]);

useEffect(() => {
removeSelectionLayer(olMap);
Expand All @@ -438,21 +568,30 @@ export const OlChartMap = (props: OlChartMapProps) => {
filterState,
crossFilterColumn,
);
const baseOpacity = usesMergedPresentation ? 0.01 : FULL_OPACITY;

if (filterState.value !== null && filterState.value !== undefined) {
const selectionLayer = createSelectionLayer(
currentDataLayers,
selectedFeatures,
);
olMap.addLayer(selectionLayer);
if (!usesMergedPresentation) {
const selectionLayer = createSelectionLayer(
currentDataLayers,
selectedFeatures,
);
olMap.addLayer(selectionLayer);
}
setSelectionBackgroundOpacity(
currentDataLayers,
SELECTION_BACKGROUND_OPACITY,
usesMergedPresentation ? 0.01 : SELECTION_BACKGROUND_OPACITY,
);
} else {
setSelectionBackgroundOpacity(currentDataLayers, FULL_OPACITY);
setSelectionBackgroundOpacity(currentDataLayers, baseOpacity);
}
}, [filterState, currentDataLayers, olMap, filteredData, crossFilterColumn]);
}, [
crossFilterColumn,
currentDataLayers,
filterState,
olMap,
usesMergedPresentation,
]);

useEffect(() => {
const { extentMode, fixedMaxX, fixedMaxY, fixedMinX, fixedMinY } =
Expand Down
Loading