diff --git a/client/src/components/map/layer-manager/index.tsx b/client/src/components/map/layer-manager/index.tsx
index bc008f3..d31f606 100644
--- a/client/src/components/map/layer-manager/index.tsx
+++ b/client/src/components/map/layer-manager/index.tsx
@@ -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();
@@ -15,6 +16,13 @@ const LayerManager = () => {
*/
const positioningLayers = useMemo(() => {
return [
+ ,
...layers.map((layer, index) => {
const beforeId = index === 0 ? "data-layers" : `layer-position-${layers[index - 1].id}`;
return (
@@ -39,6 +47,10 @@ const LayerManager = () => {
const layerManagerItems = useMemo(() => {
return [
+ ,
...layers.map((layer) => {
const beforeId = `layer-position-${layer.id}`;
const { id, ...settings } = layer;
diff --git a/client/src/components/map/layer-manager/selected-location-layer.tsx b/client/src/components/map/layer-manager/selected-location-layer.tsx
new file mode 100644
index 0000000..e9a88f4
--- /dev/null
+++ b/client/src/components/map/layer-manager/selected-location-layer.tsx
@@ -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;