Improve UI

This commit is contained in:
Andras Schmelczer 2026-02-05 21:19:19 +00:00
parent 5fe192d25a
commit ae29662c92
14 changed files with 221 additions and 313 deletions

View file

@ -3,7 +3,7 @@ import { Map as MapGL, useControl } from 'react-map-gl/maplibre';
import type { MapRef } from 'react-map-gl/maplibre';
import { MapboxOverlay } from '@deck.gl/mapbox';
import { H3HexagonLayer } from '@deck.gl/geo-layers';
import { IconLayer, PolygonLayer } from '@deck.gl/layers';
import { IconLayer, PolygonLayer, TextLayer } from '@deck.gl/layers';
import type { PickingInfo } from '@deck.gl/core';
import 'maplibre-gl/dist/maplibre-gl.css';
import type {
@ -11,7 +11,6 @@ import type {
PostcodeData,
ViewState,
ViewChangeParams,
Bounds,
POI,
FeatureMeta,
} from '../types';
@ -23,7 +22,6 @@ import {
getBoundsFromViewState,
emojiToTwemojiUrl,
getMapStyle,
POSTCODE_ZOOM_THRESHOLD,
} from '../lib/map-utils';
import { INITIAL_VIEW_STATE, MAP_MIN_ZOOM, MAP_BOUNDS } from '../lib/consts';
import PostcodeSearch, { type SearchedPostcode } from './PostcodeSearch';
@ -39,6 +37,18 @@ function osmIdToUrl(id: string): string | null {
return `https://www.openstreetmap.org/${typeMap[match[1]]}/${match[2]}`;
}
/** Calculate the centroid of a polygon from its vertices */
function polygonCentroid(vertices: [number, number][]): [number, number] {
if (vertices.length === 0) return [0, 0];
let sumLng = 0;
let sumLat = 0;
for (const [lng, lat] of vertices) {
sumLng += lng;
sumLat += lat;
}
return [sumLng / vertices.length, sumLat / vertices.length];
}
interface MapProps {
data: HexagonData[];
postcodeData: PostcodeData[];
@ -437,6 +447,30 @@ export default memo(function Map({
[postcodeData, postcodeColorTrigger, handlePostcodeClick, handlePostcodeHoverCallback]
);
const postcodeLabelsLayer = useMemo(
() =>
new TextLayer<PostcodeData>({
id: 'postcode-labels',
data: postcodeData,
getPosition: (d) => polygonCentroid(d.vertices),
getText: (d) => d.postcode,
getSize: 12,
getColor: theme === 'dark' ? [220, 220, 220, 220] : [40, 40, 40, 220],
getTextAnchor: 'middle',
getAlignmentBaseline: 'center',
fontFamily: 'Inter, system-ui, sans-serif',
fontWeight: 600,
outlineWidth: 2,
outlineColor: theme === 'dark' ? [30, 30, 30, 200] : [255, 255, 255, 200],
sizeUnits: 'pixels',
sizeMinPixels: 10,
sizeMaxPixels: 14,
billboard: false,
pickable: false,
}),
[postcodeData, theme]
);
const poiLayer = useMemo(
() =>
new IconLayer<POI>({
@ -488,12 +522,14 @@ export default memo(function Map({
}, [searchedPostcode, searchedPostcodeHasData]);
const layers = useMemo(() => {
const baseLayers = usePostcodeView ? [postcodeLayer, poiLayer] : [hexLayer, poiLayer];
const baseLayers = usePostcodeView
? [postcodeLayer, postcodeLabelsLayer, poiLayer]
: [hexLayer, poiLayer];
if (searchedPostcodeHighlightLayer) {
return [...baseLayers, searchedPostcodeHighlightLayer];
}
return baseLayers;
}, [usePostcodeView, hexLayer, postcodeLayer, poiLayer, searchedPostcodeHighlightLayer]);
}, [usePostcodeView, hexLayer, postcodeLayer, postcodeLabelsLayer, poiLayer, searchedPostcodeHighlightLayer]);
return (
<div className="flex-1 h-full relative" ref={containerRef}>