From 7b1f7538ab4721253df4d93f51f48fa8a868d6c4 Mon Sep 17 00:00:00 2001 From: taDuc Date: Tue, 12 May 2026 17:42:59 +0700 Subject: [PATCH] refactor: point view --- src/uhm/components/map/mapUtils.ts | 79 +++++++++---------- src/uhm/components/map/useMapLayers.ts | 8 +- src/uhm/components/map/useMapSync.ts | 6 +- src/uhm/lib/map/constants.ts | 2 - src/uhm/lib/map/styles/geotypes/bridge.ts | 53 +------------ src/uhm/lib/map/styles/geotypes/capital.ts | 53 +------------ src/uhm/lib/map/styles/geotypes/castle.ts | 53 +------------ src/uhm/lib/map/styles/geotypes/city.ts | 53 +------------ src/uhm/lib/map/styles/geotypes/fortress.ts | 53 +------------ src/uhm/lib/map/styles/geotypes/index.ts | 1 + .../map/styles/geotypes/person_activity.ts | 53 +------------ .../map/styles/geotypes/person_birthplace.ts | 53 +------------ .../map/styles/geotypes/person_deathplace.ts | 53 +------------ src/uhm/lib/map/styles/geotypes/port.ts | 53 +------------ src/uhm/lib/map/styles/geotypes/ruin.ts | 53 +------------ src/uhm/lib/map/styles/geotypes/temple.ts | 53 +------------ src/uhm/types/geo.ts | 1 + 17 files changed, 89 insertions(+), 591 deletions(-) diff --git a/src/uhm/components/map/mapUtils.ts b/src/uhm/components/map/mapUtils.ts index 275c248..af4f959 100644 --- a/src/uhm/components/map/mapUtils.ts +++ b/src/uhm/components/map/mapUtils.ts @@ -2,10 +2,8 @@ import maplibregl from "maplibre-gl"; import { BACKGROUND_LAYER_OPTIONS, BackgroundLayerVisibility } from "@/uhm/lib/map/styles/backgroundLayers"; import { Feature, FeatureCollection, Geometry } from "@/uhm/lib/editor/state/useEditorState"; import { - DEFAULT_POINT_ICON_ID, FEATURE_STATE_SOURCE_IDS, PATH_ARROW_ICON_ID, - POINT_ICON_URL, RASTER_BASE_INSERT_BEFORE_LAYER_ID, RASTER_BASE_LAYER_ID, RASTER_BASE_SOURCE_ID, @@ -188,6 +186,19 @@ export function splitDraftFeatures(fc: FeatureCollection) { return { polygons, points }; } +export function decoratePointFeaturesWithLabels(fc: FeatureCollection): FeatureCollection { + return { + ...fc, + features: fc.features.map((feature) => ({ + ...feature, + properties: { + ...feature.properties, + point_label: getSingleEntityPointLabel(feature), + }, + })), + }; +} + export function setSelectedFeatureState( map: maplibregl.Map, id: string | number | null, @@ -520,47 +531,6 @@ export function createPathArrowImageData(): ImageData | null { return ctx.getImageData(0, 0, size, size); } -export function addPointSymbolLayer(map: maplibregl.Map) { - void ensurePointAssetIcon(map).then((hasPointIcon) => { - try { - if (!hasPointIcon || !map.getSource("places") || map.getLayer("places-symbol")) return; - - map.addLayer({ - id: "places-symbol", - type: "symbol", - source: "places", - layout: { - "icon-image": DEFAULT_POINT_ICON_ID, - "icon-size": 0.06, - "icon-anchor": "center", - "icon-allow-overlap": true, - }, - }); - - if (map.getLayer("places-circle")) { - map.setLayoutProperty("places-circle", "visibility", "none"); - } - } catch (err) { - console.warn("Add point symbol layer skipped", err); - } - }); -} - -export async function ensurePointAssetIcon(map: maplibregl.Map): Promise { - if (map.hasImage(DEFAULT_POINT_ICON_ID)) return true; - - try { - const image = await map.loadImage(POINT_ICON_URL); - if (!map.hasImage(DEFAULT_POINT_ICON_ID)) { - map.addImage(DEFAULT_POINT_ICON_ID, image.data); - } - return true; - } catch (error) { - console.error(`Failed to load point icon asset: ${POINT_ICON_URL}`, error); - return false; - } -} - export function buildTypeMatchExpression( valueByType: Record, fallback: string | number | boolean @@ -588,6 +558,29 @@ export function roundZoom(value: number): number { return Math.round(value * 10) / 10; } +function getSingleEntityPointLabel(feature: Feature): string | null { + const rawEntityIds = Array.isArray(feature.properties.entity_ids) + ? feature.properties.entity_ids + : (typeof feature.properties.entity_id === "string" && feature.properties.entity_id.trim().length > 0 + ? [feature.properties.entity_id] + : []); + + const entityIds = Array.from(new Set( + rawEntityIds + .filter((id): id is string => typeof id === "string") + .map((id) => id.trim()) + .filter((id) => id.length > 0) + )); + + if (entityIds.length !== 1) return null; + + const name = typeof feature.properties.entity_name === "string" + ? feature.properties.entity_name.trim() + : ""; + + return name.length ? name : null; +} + export function buildClientFeatureId(): string { return newId(); } diff --git a/src/uhm/components/map/useMapLayers.ts b/src/uhm/components/map/useMapLayers.ts index 310ffa7..d6a965f 100644 --- a/src/uhm/components/map/useMapLayers.ts +++ b/src/uhm/components/map/useMapLayers.ts @@ -11,9 +11,8 @@ import { } from "@/uhm/lib/map/styles/style"; import { EMPTY_FEATURE_COLLECTION } from "@/uhm/lib/map/geo/constants"; import { PATH_ARROW_ICON_ID, PATH_ARROW_SOURCE_ID } from "@/uhm/lib/map/constants"; -import { getAllGeotypeLayers } from "@/uhm/lib/map/styles/geotypes"; +import { ensurePointGeotypeIcons, getAllGeotypeLayers } from "@/uhm/lib/map/styles/geotypes"; import { - addPointSymbolLayer, applyBackgroundLayerVisibility, buildTypeMatchExpression, ensurePathArrowIcon, @@ -326,7 +325,8 @@ export function setupMapLayers( promoteId: "id", }); - + ensurePointGeotypeIcons(map); + const geotypeLayers = getAllGeotypeLayers("countries", PATH_ARROW_SOURCE_ID, "places"); for (const layer of geotypeLayers) { map.addLayer(layer); @@ -411,7 +411,5 @@ export function setupMapLayers( "circle-opacity": 1, }, }); - - addPointSymbolLayer(map); applyHighlightToMap(highlightFeatures || EMPTY_FEATURE_COLLECTION); } diff --git a/src/uhm/components/map/useMapSync.ts b/src/uhm/components/map/useMapSync.ts index 2eebc6a..5932a9d 100644 --- a/src/uhm/components/map/useMapSync.ts +++ b/src/uhm/components/map/useMapSync.ts @@ -7,6 +7,7 @@ import { FEATURE_STATE_SOURCE_IDS, PATH_ARROW_SOURCE_ID } from "@/uhm/lib/map/co import { applyBackgroundLayerVisibility, buildPathArrowFeatureCollection, + decoratePointFeaturesWithLabels, filterDraftByBinding, filterDraftByGeometryVisibility, fitMapToFeatureCollection, @@ -28,7 +29,7 @@ type UseMapSyncProps = { focusRequestKey?: string | number | null; focusPadding?: number | maplibregl.PaddingOptions; allowGeometryEditing: boolean; - editingEngineRef: React.MutableRefObject; + editingEngineRef: React.MutableRefObject; geolocationCenteredRef: React.MutableRefObject; }; @@ -97,10 +98,11 @@ export function useMapSync({ : fc; const visibleDraft = filterDraftByGeometryVisibility(visibleDraftRaw, geometryVisibilityRef.current); const { polygons, points } = splitDraftFeatures(visibleDraft); + const labeledPoints = decoratePointFeaturesWithLabels(points); const pathArrowShapes = buildPathArrowFeatureCollection(visibleDraft); countriesSource.setData(polygons); - placesSource.setData(points); + placesSource.setData(labeledPoints); (map.getSource(PATH_ARROW_SOURCE_ID) as maplibregl.GeoJSONSource | undefined)?.setData(pathArrowShapes); const currentSelectedIds = selectedFeatureIdsRef.current; diff --git a/src/uhm/lib/map/constants.ts b/src/uhm/lib/map/constants.ts index 9dc5f42..510508c 100644 --- a/src/uhm/lib/map/constants.ts +++ b/src/uhm/lib/map/constants.ts @@ -1,5 +1,3 @@ -export const DEFAULT_POINT_ICON_ID = "point-icon-default"; -export const POINT_ICON_URL = "/point.png"; export const PATH_ARROW_ICON_ID = "path-arrow-icon"; export const MAP_MIN_ZOOM = 2; diff --git a/src/uhm/lib/map/styles/geotypes/bridge.ts b/src/uhm/lib/map/styles/geotypes/bridge.ts index 8199f7b..8212208 100644 --- a/src/uhm/lib/map/styles/geotypes/bridge.ts +++ b/src/uhm/lib/map/styles/geotypes/bridge.ts @@ -1,53 +1,8 @@ import { LayerSpecification } from "maplibre-gl"; -import { TYPE_MATCH_EXPR } from "./index"; +import { buildPointGeotypeLayers } from "./pointStyle"; export function getBridgeLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - return [ - { - id: "bridge-circle", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "bridge"]], - paint: { - "circle-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#22c55e", - "#ef4444" - ], - "circle-radius": [ - "case", - ["boolean", ["feature-state", "selected"], false], 8, 4 - ], - "circle-stroke-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#14532d", - "#ffffff" - ], - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 3, 1 - ], - "circle-opacity": 0.9 - } - }, - { - id: "bridge-selected-halo", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "bridge"]], - paint: { - "circle-color": "#22c55e", - "circle-radius": 13, - "circle-opacity": [ - "case", - ["boolean", ["feature-state", "selected"], false], 0.28, 0 - ], - "circle-stroke-color": "#14532d", - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 2, 0 - ] - } - } - ]; + void sourceId; + void pathArrowSourceId; + return buildPointGeotypeLayers("bridge", pointSourceId!); } diff --git a/src/uhm/lib/map/styles/geotypes/capital.ts b/src/uhm/lib/map/styles/geotypes/capital.ts index 04cb171..8a66402 100644 --- a/src/uhm/lib/map/styles/geotypes/capital.ts +++ b/src/uhm/lib/map/styles/geotypes/capital.ts @@ -1,53 +1,8 @@ import { LayerSpecification } from "maplibre-gl"; -import { TYPE_MATCH_EXPR } from "./index"; +import { buildPointGeotypeLayers } from "./pointStyle"; export function getCapitalLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - return [ - { - id: "capital-circle", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "capital"]], - paint: { - "circle-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#22c55e", - "#ef4444" - ], - "circle-radius": [ - "case", - ["boolean", ["feature-state", "selected"], false], 8, 4 - ], - "circle-stroke-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#14532d", - "#ffffff" - ], - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 3, 1 - ], - "circle-opacity": 0.9 - } - }, - { - id: "capital-selected-halo", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "capital"]], - paint: { - "circle-color": "#22c55e", - "circle-radius": 13, - "circle-opacity": [ - "case", - ["boolean", ["feature-state", "selected"], false], 0.28, 0 - ], - "circle-stroke-color": "#14532d", - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 2, 0 - ] - } - } - ]; + void sourceId; + void pathArrowSourceId; + return buildPointGeotypeLayers("capital", pointSourceId!); } diff --git a/src/uhm/lib/map/styles/geotypes/castle.ts b/src/uhm/lib/map/styles/geotypes/castle.ts index 81e8241..3a27db0 100644 --- a/src/uhm/lib/map/styles/geotypes/castle.ts +++ b/src/uhm/lib/map/styles/geotypes/castle.ts @@ -1,53 +1,8 @@ import { LayerSpecification } from "maplibre-gl"; -import { TYPE_MATCH_EXPR } from "./index"; +import { buildPointGeotypeLayers } from "./pointStyle"; export function getCastleLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - return [ - { - id: "castle-circle", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "castle"]], - paint: { - "circle-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#22c55e", - "#ef4444" - ], - "circle-radius": [ - "case", - ["boolean", ["feature-state", "selected"], false], 8, 4 - ], - "circle-stroke-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#14532d", - "#ffffff" - ], - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 3, 1 - ], - "circle-opacity": 0.9 - } - }, - { - id: "castle-selected-halo", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "castle"]], - paint: { - "circle-color": "#22c55e", - "circle-radius": 13, - "circle-opacity": [ - "case", - ["boolean", ["feature-state", "selected"], false], 0.28, 0 - ], - "circle-stroke-color": "#14532d", - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 2, 0 - ] - } - } - ]; + void sourceId; + void pathArrowSourceId; + return buildPointGeotypeLayers("castle", pointSourceId!); } diff --git a/src/uhm/lib/map/styles/geotypes/city.ts b/src/uhm/lib/map/styles/geotypes/city.ts index bb3e25b..30a4900 100644 --- a/src/uhm/lib/map/styles/geotypes/city.ts +++ b/src/uhm/lib/map/styles/geotypes/city.ts @@ -1,53 +1,8 @@ import { LayerSpecification } from "maplibre-gl"; -import { TYPE_MATCH_EXPR } from "./index"; +import { buildPointGeotypeLayers } from "./pointStyle"; export function getCityLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - return [ - { - id: "city-circle", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "city"]], - paint: { - "circle-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#22c55e", - "#ef4444" - ], - "circle-radius": [ - "case", - ["boolean", ["feature-state", "selected"], false], 8, 4 - ], - "circle-stroke-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#14532d", - "#ffffff" - ], - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 3, 1 - ], - "circle-opacity": 0.9 - } - }, - { - id: "city-selected-halo", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "city"]], - paint: { - "circle-color": "#22c55e", - "circle-radius": 13, - "circle-opacity": [ - "case", - ["boolean", ["feature-state", "selected"], false], 0.28, 0 - ], - "circle-stroke-color": "#14532d", - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 2, 0 - ] - } - } - ]; + void sourceId; + void pathArrowSourceId; + return buildPointGeotypeLayers("city", pointSourceId!); } diff --git a/src/uhm/lib/map/styles/geotypes/fortress.ts b/src/uhm/lib/map/styles/geotypes/fortress.ts index d01d369..16fba88 100644 --- a/src/uhm/lib/map/styles/geotypes/fortress.ts +++ b/src/uhm/lib/map/styles/geotypes/fortress.ts @@ -1,53 +1,8 @@ import { LayerSpecification } from "maplibre-gl"; -import { TYPE_MATCH_EXPR } from "./index"; +import { buildPointGeotypeLayers } from "./pointStyle"; export function getFortressLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - return [ - { - id: "fortress-circle", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "fortress"]], - paint: { - "circle-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#22c55e", - "#ef4444" - ], - "circle-radius": [ - "case", - ["boolean", ["feature-state", "selected"], false], 8, 4 - ], - "circle-stroke-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#14532d", - "#ffffff" - ], - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 3, 1 - ], - "circle-opacity": 0.9 - } - }, - { - id: "fortress-selected-halo", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "fortress"]], - paint: { - "circle-color": "#22c55e", - "circle-radius": 13, - "circle-opacity": [ - "case", - ["boolean", ["feature-state", "selected"], false], 0.28, 0 - ], - "circle-stroke-color": "#14532d", - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 2, 0 - ] - } - } - ]; + void sourceId; + void pathArrowSourceId; + return buildPointGeotypeLayers("fortress", pointSourceId!); } diff --git a/src/uhm/lib/map/styles/geotypes/index.ts b/src/uhm/lib/map/styles/geotypes/index.ts index 8e485f7..9e1969b 100644 --- a/src/uhm/lib/map/styles/geotypes/index.ts +++ b/src/uhm/lib/map/styles/geotypes/index.ts @@ -1,5 +1,6 @@ import maplibregl from "maplibre-gl"; export const TYPE_MATCH_EXPR: maplibregl.ExpressionSpecification = ["coalesce", ["get", "type"], ["get", "entity_type_id"], ""]; +export { ensurePointGeotypeIcons } from "./pointStyle"; import { getDefenseLineLayers } from "./defense_line"; import { getAttackRouteLayers } from "./attack_route"; diff --git a/src/uhm/lib/map/styles/geotypes/person_activity.ts b/src/uhm/lib/map/styles/geotypes/person_activity.ts index d386e6e..7d4a88a 100644 --- a/src/uhm/lib/map/styles/geotypes/person_activity.ts +++ b/src/uhm/lib/map/styles/geotypes/person_activity.ts @@ -1,53 +1,8 @@ import { LayerSpecification } from "maplibre-gl"; -import { TYPE_MATCH_EXPR } from "./index"; +import { buildPointGeotypeLayers } from "./pointStyle"; export function getPersonActivityLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - return [ - { - id: "person_activity-circle", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "person_activity"]], - paint: { - "circle-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#22c55e", - "#ef4444" - ], - "circle-radius": [ - "case", - ["boolean", ["feature-state", "selected"], false], 8, 4 - ], - "circle-stroke-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#14532d", - "#ffffff" - ], - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 3, 1 - ], - "circle-opacity": 0.9 - } - }, - { - id: "person_activity-selected-halo", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "person_activity"]], - paint: { - "circle-color": "#22c55e", - "circle-radius": 13, - "circle-opacity": [ - "case", - ["boolean", ["feature-state", "selected"], false], 0.28, 0 - ], - "circle-stroke-color": "#14532d", - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 2, 0 - ] - } - } - ]; + void sourceId; + void pathArrowSourceId; + return buildPointGeotypeLayers("person_activity", pointSourceId!); } diff --git a/src/uhm/lib/map/styles/geotypes/person_birthplace.ts b/src/uhm/lib/map/styles/geotypes/person_birthplace.ts index bd59224..b6c91b3 100644 --- a/src/uhm/lib/map/styles/geotypes/person_birthplace.ts +++ b/src/uhm/lib/map/styles/geotypes/person_birthplace.ts @@ -1,53 +1,8 @@ import { LayerSpecification } from "maplibre-gl"; -import { TYPE_MATCH_EXPR } from "./index"; +import { buildPointGeotypeLayers } from "./pointStyle"; export function getPersonBirthplaceLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - return [ - { - id: "person_birthplace-circle", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "person_birthplace"]], - paint: { - "circle-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#22c55e", - "#ef4444" - ], - "circle-radius": [ - "case", - ["boolean", ["feature-state", "selected"], false], 8, 4 - ], - "circle-stroke-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#14532d", - "#ffffff" - ], - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 3, 1 - ], - "circle-opacity": 0.9 - } - }, - { - id: "person_birthplace-selected-halo", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "person_birthplace"]], - paint: { - "circle-color": "#22c55e", - "circle-radius": 13, - "circle-opacity": [ - "case", - ["boolean", ["feature-state", "selected"], false], 0.28, 0 - ], - "circle-stroke-color": "#14532d", - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 2, 0 - ] - } - } - ]; + void sourceId; + void pathArrowSourceId; + return buildPointGeotypeLayers("person_birthplace", pointSourceId!); } diff --git a/src/uhm/lib/map/styles/geotypes/person_deathplace.ts b/src/uhm/lib/map/styles/geotypes/person_deathplace.ts index 8a963d0..7f8fb6d 100644 --- a/src/uhm/lib/map/styles/geotypes/person_deathplace.ts +++ b/src/uhm/lib/map/styles/geotypes/person_deathplace.ts @@ -1,53 +1,8 @@ import { LayerSpecification } from "maplibre-gl"; -import { TYPE_MATCH_EXPR } from "./index"; +import { buildPointGeotypeLayers } from "./pointStyle"; export function getPersonDeathplaceLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - return [ - { - id: "person_deathplace-circle", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "person_deathplace"]], - paint: { - "circle-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#22c55e", - "#ef4444" - ], - "circle-radius": [ - "case", - ["boolean", ["feature-state", "selected"], false], 8, 4 - ], - "circle-stroke-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#14532d", - "#ffffff" - ], - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 3, 1 - ], - "circle-opacity": 0.9 - } - }, - { - id: "person_deathplace-selected-halo", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "person_deathplace"]], - paint: { - "circle-color": "#22c55e", - "circle-radius": 13, - "circle-opacity": [ - "case", - ["boolean", ["feature-state", "selected"], false], 0.28, 0 - ], - "circle-stroke-color": "#14532d", - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 2, 0 - ] - } - } - ]; + void sourceId; + void pathArrowSourceId; + return buildPointGeotypeLayers("person_deathplace", pointSourceId!); } diff --git a/src/uhm/lib/map/styles/geotypes/port.ts b/src/uhm/lib/map/styles/geotypes/port.ts index 1b2ff65..daeb9a0 100644 --- a/src/uhm/lib/map/styles/geotypes/port.ts +++ b/src/uhm/lib/map/styles/geotypes/port.ts @@ -1,53 +1,8 @@ import { LayerSpecification } from "maplibre-gl"; -import { TYPE_MATCH_EXPR } from "./index"; +import { buildPointGeotypeLayers } from "./pointStyle"; export function getPortLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - return [ - { - id: "port-circle", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "port"]], - paint: { - "circle-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#22c55e", - "#ef4444" - ], - "circle-radius": [ - "case", - ["boolean", ["feature-state", "selected"], false], 8, 4 - ], - "circle-stroke-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#14532d", - "#ffffff" - ], - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 3, 1 - ], - "circle-opacity": 0.9 - } - }, - { - id: "port-selected-halo", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "port"]], - paint: { - "circle-color": "#22c55e", - "circle-radius": 13, - "circle-opacity": [ - "case", - ["boolean", ["feature-state", "selected"], false], 0.28, 0 - ], - "circle-stroke-color": "#14532d", - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 2, 0 - ] - } - } - ]; + void sourceId; + void pathArrowSourceId; + return buildPointGeotypeLayers("port", pointSourceId!); } diff --git a/src/uhm/lib/map/styles/geotypes/ruin.ts b/src/uhm/lib/map/styles/geotypes/ruin.ts index f6ac4fd..fc470de 100644 --- a/src/uhm/lib/map/styles/geotypes/ruin.ts +++ b/src/uhm/lib/map/styles/geotypes/ruin.ts @@ -1,53 +1,8 @@ import { LayerSpecification } from "maplibre-gl"; -import { TYPE_MATCH_EXPR } from "./index"; +import { buildPointGeotypeLayers } from "./pointStyle"; export function getRuinLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - return [ - { - id: "ruin-circle", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "ruin"]], - paint: { - "circle-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#22c55e", - "#ef4444" - ], - "circle-radius": [ - "case", - ["boolean", ["feature-state", "selected"], false], 8, 4 - ], - "circle-stroke-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#14532d", - "#ffffff" - ], - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 3, 1 - ], - "circle-opacity": 0.9 - } - }, - { - id: "ruin-selected-halo", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "ruin"]], - paint: { - "circle-color": "#22c55e", - "circle-radius": 13, - "circle-opacity": [ - "case", - ["boolean", ["feature-state", "selected"], false], 0.28, 0 - ], - "circle-stroke-color": "#14532d", - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 2, 0 - ] - } - } - ]; + void sourceId; + void pathArrowSourceId; + return buildPointGeotypeLayers("ruin", pointSourceId!); } diff --git a/src/uhm/lib/map/styles/geotypes/temple.ts b/src/uhm/lib/map/styles/geotypes/temple.ts index 9258cf1..e917561 100644 --- a/src/uhm/lib/map/styles/geotypes/temple.ts +++ b/src/uhm/lib/map/styles/geotypes/temple.ts @@ -1,53 +1,8 @@ import { LayerSpecification } from "maplibre-gl"; -import { TYPE_MATCH_EXPR } from "./index"; +import { buildPointGeotypeLayers } from "./pointStyle"; export function getTempleLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - return [ - { - id: "temple-circle", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "temple"]], - paint: { - "circle-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#22c55e", - "#ef4444" - ], - "circle-radius": [ - "case", - ["boolean", ["feature-state", "selected"], false], 8, 4 - ], - "circle-stroke-color": [ - "case", - ["boolean", ["feature-state", "selected"], false], "#14532d", - "#ffffff" - ], - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 3, 1 - ], - "circle-opacity": 0.9 - } - }, - { - id: "temple-selected-halo", - type: "circle", - source: pointSourceId!, - filter: ["all", ["==", ["geometry-type"], "Point"], ["==", TYPE_MATCH_EXPR, "temple"]], - paint: { - "circle-color": "#22c55e", - "circle-radius": 13, - "circle-opacity": [ - "case", - ["boolean", ["feature-state", "selected"], false], 0.28, 0 - ], - "circle-stroke-color": "#14532d", - "circle-stroke-width": [ - "case", - ["boolean", ["feature-state", "selected"], false], 2, 0 - ] - } - } - ]; + void sourceId; + void pathArrowSourceId; + return buildPointGeotypeLayers("temple", pointSourceId!); } diff --git a/src/uhm/types/geo.ts b/src/uhm/types/geo.ts index ad1aa50..f459610 100644 --- a/src/uhm/types/geo.ts +++ b/src/uhm/types/geo.ts @@ -22,6 +22,7 @@ export type FeatureProperties = { entity_name?: string | null; entity_names?: string[]; entity_type_id?: string | null; + point_label?: string | null; }; export type Feature = {