Skip to content

Commit

Permalink
Connect UI to the map
Browse files Browse the repository at this point in the history
  • Loading branch information
clementprdhomme committed Oct 24, 2024
1 parent 310bcd5 commit 0254e22
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 12 deletions.
8 changes: 4 additions & 4 deletions client/src/components/map/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@ export const BASEMAPS: Record<BasemapStyle, { name: string; image: string }> = {
};

export const LABELS: Record<LabelsStyle, { name: string }> = {
dark: {
name: "Dark",
},
light: {
name: "Light",
},
dark: {
name: "Dark",
},
"": {
name: "No labels",
},
};

export const DEFAULT_MAP_SETTINGS = {
basemap: BasemapStyle.Light,
labels: LabelsStyle.Dark,
labels: LabelsStyle.Light,
};
21 changes: 13 additions & 8 deletions client/src/components/map/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"use client";

import { useCallback, useEffect, useMemo, useRef } from "react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import ReactMapGL from "react-map-gl";

import { SIDEBAR_WIDTH } from "@/components/ui/sidebar";
import { env } from "@/env";
import useApplyMapSettings from "@/hooks/use-apply-map-settings";
import useBreakpoint from "@/hooks/use-breakpoint";
import useIsSidebarExpanded from "@/hooks/use-is-sidebar-expanded";
import useMapBounds from "@/hooks/use-map-bounds";
Expand All @@ -18,8 +19,10 @@ import type { MapRef, LngLatLike } from "react-map-gl";
import "mapbox-gl/dist/mapbox-gl.css";

const Map = () => {
const isDesktop = useBreakpoint("xl", false, true);
const mapRef = useRef<MapRef>(null);
const [map, setMap] = useState<MapRef | null>(null);

const isDesktop = useBreakpoint("xl", false, true);

const isSidebarExpanded = useIsSidebarExpanded();
const previousIsSidebarExpanded = usePrevious(isSidebarExpanded);
Expand All @@ -44,17 +47,18 @@ const Map = () => {
}, [bounds, isDesktop, isSidebarExpanded]);

const onMove = useCallback(() => {
if (mapRef.current) {
setBounds(mapRef.current.getBounds()?.toArray() as [LngLatLike, LngLatLike]);
}
}, [mapRef, setBounds]);
setBounds(map?.getBounds()?.toArray() as [LngLatLike, LngLatLike]);
}, [map, setBounds]);

// Update the position of the map based on the sidebar's state
useEffect(() => {
if (isSidebarExpanded !== previousIsSidebarExpanded) {
mapRef.current?.fitBounds(bounds, initialViewState.fitBoundsOptions);
map?.fitBounds(bounds, initialViewState.fitBoundsOptions);
}
}, [isSidebarExpanded, previousIsSidebarExpanded, initialViewState, bounds]);
}, [map, isSidebarExpanded, previousIsSidebarExpanded, initialViewState, bounds]);

// Apply the basemap and labels
useApplyMapSettings(map);

return (
<ReactMapGL
Expand All @@ -66,6 +70,7 @@ const Map = () => {
mapStyle={env.NEXT_PUBLIC_MAPBOX_STYLE}
onMove={onMove}
logoPosition="bottom-right"
onLoad={() => setMap(mapRef.current)}
>
<Controls />
</ReactMapGL>
Expand Down
19 changes: 19 additions & 0 deletions client/src/hooks/use-apply-map-settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useEffect } from "react";
import { MapRef } from "react-map-gl";

import { toggleGroupLayers } from "@/utils/map";

import useMapBasemap from "./use-map-basemap";
import useMapLabels from "./use-map-labels";

export default function useApplyMapSettings(map: MapRef | null) {
const [basemap] = useMapBasemap();
const [labels] = useMapLabels();

useEffect(() => {
if (map) {
toggleGroupLayers(map, "basemap-", (group) => group === `basemap-${basemap}`);
toggleGroupLayers(map, "labels-", (group) => group === `labels-${labels}`);
}
}, [map, basemap, labels]);
}
35 changes: 35 additions & 0 deletions client/src/utils/map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { MapRef } from "react-map-gl";

/**
* Toggle on/off the layers of the groups matching the prefix based on the return value of the
* callback
*/
export const toggleGroupLayers = (
map: MapRef,
groupPrefix: string,
callback: (groupName: string) => boolean,
) => {
const mapboxMap = map?.getMap();
const mapboxStyle = map?.getStyle();

const { "mapbox:groups": mapboxGroups } =
(mapboxStyle?.metadata as { "mapbox:groups": Record<string, { name: string }> }) ?? {};

const mapboxLayers = mapboxStyle?.layers ?? [];

const groupsIdsMatchingPrefix = Object.entries(mapboxGroups ?? {})
.filter(([, { name }]) => name.startsWith(groupPrefix))
.map(([key]) => key);

mapboxLayers.forEach((layer) => {
const { "mapbox:group": group } = (layer.metadata as { "mapbox:group": string }) ?? {};

if (groupsIdsMatchingPrefix.includes(group)) {
mapboxMap?.setLayoutProperty(
layer.id,
"visibility",
callback(mapboxGroups[group].name) ? "visible" : "none",
);
}
});
};

0 comments on commit 0254e22

Please sign in to comment.