Skip to content

Commit

Permalink
feat(client): Highlight the selected location on the map
Browse files Browse the repository at this point in the history
  • Loading branch information
clementprdhomme committed Nov 28, 2024
1 parent c6aecc9 commit c9490c8
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 1 deletion.
14 changes: 13 additions & 1 deletion client/src/components/map/layer-manager/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useMemo } from "react";
import { Layer } from "react-map-gl";

import MaskLayer from "@/components/map/layer-manager/mask-layer";
import useMapLayers from "@/hooks/use-map-layers";

import LayerManagerItem from "./item";
import MaskLayer from "./mask-layer";
import SelectedLocationLayer from "./selected-location-layer";

const LayerManager = () => {
const [layers] = useMapLayers();
Expand All @@ -15,6 +16,13 @@ const LayerManager = () => {
*/
const positioningLayers = useMemo(() => {
return [
<Layer
key="layer-position-selected-location"
id="layer-position-selected-location"
type="background"
layout={{ visibility: "none" }}
beforeId="selected-location"
/>,
...layers.map((layer, index) => {
const beforeId = index === 0 ? "data-layers" : `layer-position-${layers[index - 1].id}`;
return (
Expand All @@ -39,6 +47,10 @@ const LayerManager = () => {

const layerManagerItems = useMemo(() => {
return [
<SelectedLocationLayer
key="layer-selected-location"
beforeId="layer-position-selected-location"
/>,
...layers.map((layer) => {
const beforeId = `layer-position-${layer.id}`;
const { id, ...settings } = layer;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { PathStyleExtension } from "@deck.gl/extensions";
import { GeoJsonLayer } from "@deck.gl/layers";
import { useContext, useEffect, useMemo } from "react";

import useLocation from "@/hooks/use-location";
import { useLocationGeometry } from "@/hooks/use-location-geometry";

import { DeckGLMapboxOverlayContext } from "../deckgl-mapbox-provider";

interface SelectedLocationLayerProps {
beforeId: string;
}

const SelectedLocationLayer = ({ beforeId }: SelectedLocationLayerProps) => {
const [location] = useLocation();
const { data, isLoading } = useLocationGeometry(location.code.slice(-1)[0]);
const geometry = useMemo(() => {
if (isLoading || data === undefined || data === null || location.code[0] === "SS") {
// We return an empty feature collection so that while the geometry is loading, we don't show
// anything
return {
type: "FeatureCollection",
features: [],
};
}

return data;
}, [data, isLoading, location.code]);

const { addLayer, removeLayer } = useContext(DeckGLMapboxOverlayContext);

useEffect(() => {
const layers = [
new GeoJsonLayer({
id: "selected-location-background-stroke",
beforeId,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
data: geometry,
stroked: true,
filled: false,
getLineColor: [255, 255, 255],
getLineWidth: 3,
lineWidthUnits: "pixels",
}),
new GeoJsonLayer({
id: "selected-location-top-stroke",
beforeId,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
data: geometry,
stroked: true,
filled: false,
getLineColor: [255, 204, 21], // supernova-yellow-400
getLineWidth: 2,
lineWidthUnits: "pixels",
getDashArray: [4, 2],
extensions: [new PathStyleExtension({ dash: true, highPrecisionDash: true })],
}),
];

layers.forEach((layer) => addLayer(layer));

return () => {
layers.forEach((layer) => removeLayer(layer.id));
};
}, [addLayer, beforeId, geometry, removeLayer]);

return null;
};

export default SelectedLocationLayer;

0 comments on commit c9490c8

Please sign in to comment.