refactor: point view
This commit is contained in:
@@ -2,10 +2,8 @@ import maplibregl from "maplibre-gl";
|
|||||||
import { BACKGROUND_LAYER_OPTIONS, BackgroundLayerVisibility } from "@/uhm/lib/map/styles/backgroundLayers";
|
import { BACKGROUND_LAYER_OPTIONS, BackgroundLayerVisibility } from "@/uhm/lib/map/styles/backgroundLayers";
|
||||||
import { Feature, FeatureCollection, Geometry } from "@/uhm/lib/editor/state/useEditorState";
|
import { Feature, FeatureCollection, Geometry } from "@/uhm/lib/editor/state/useEditorState";
|
||||||
import {
|
import {
|
||||||
DEFAULT_POINT_ICON_ID,
|
|
||||||
FEATURE_STATE_SOURCE_IDS,
|
FEATURE_STATE_SOURCE_IDS,
|
||||||
PATH_ARROW_ICON_ID,
|
PATH_ARROW_ICON_ID,
|
||||||
POINT_ICON_URL,
|
|
||||||
RASTER_BASE_INSERT_BEFORE_LAYER_ID,
|
RASTER_BASE_INSERT_BEFORE_LAYER_ID,
|
||||||
RASTER_BASE_LAYER_ID,
|
RASTER_BASE_LAYER_ID,
|
||||||
RASTER_BASE_SOURCE_ID,
|
RASTER_BASE_SOURCE_ID,
|
||||||
@@ -188,6 +186,19 @@ export function splitDraftFeatures(fc: FeatureCollection) {
|
|||||||
return { polygons, points };
|
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(
|
export function setSelectedFeatureState(
|
||||||
map: maplibregl.Map,
|
map: maplibregl.Map,
|
||||||
id: string | number | null,
|
id: string | number | null,
|
||||||
@@ -520,47 +531,6 @@ export function createPathArrowImageData(): ImageData | null {
|
|||||||
return ctx.getImageData(0, 0, size, size);
|
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<boolean> {
|
|
||||||
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(
|
export function buildTypeMatchExpression(
|
||||||
valueByType: Record<string, string | number | boolean>,
|
valueByType: Record<string, string | number | boolean>,
|
||||||
fallback: string | number | boolean
|
fallback: string | number | boolean
|
||||||
@@ -588,6 +558,29 @@ export function roundZoom(value: number): number {
|
|||||||
return Math.round(value * 10) / 10;
|
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 {
|
export function buildClientFeatureId(): string {
|
||||||
return newId();
|
return newId();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ import {
|
|||||||
} from "@/uhm/lib/map/styles/style";
|
} from "@/uhm/lib/map/styles/style";
|
||||||
import { EMPTY_FEATURE_COLLECTION } from "@/uhm/lib/map/geo/constants";
|
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 { 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 {
|
import {
|
||||||
addPointSymbolLayer,
|
|
||||||
applyBackgroundLayerVisibility,
|
applyBackgroundLayerVisibility,
|
||||||
buildTypeMatchExpression,
|
buildTypeMatchExpression,
|
||||||
ensurePathArrowIcon,
|
ensurePathArrowIcon,
|
||||||
@@ -326,6 +325,7 @@ export function setupMapLayers(
|
|||||||
promoteId: "id",
|
promoteId: "id",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ensurePointGeotypeIcons(map);
|
||||||
|
|
||||||
const geotypeLayers = getAllGeotypeLayers("countries", PATH_ARROW_SOURCE_ID, "places");
|
const geotypeLayers = getAllGeotypeLayers("countries", PATH_ARROW_SOURCE_ID, "places");
|
||||||
for (const layer of geotypeLayers) {
|
for (const layer of geotypeLayers) {
|
||||||
@@ -411,7 +411,5 @@ export function setupMapLayers(
|
|||||||
"circle-opacity": 1,
|
"circle-opacity": 1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
addPointSymbolLayer(map);
|
|
||||||
applyHighlightToMap(highlightFeatures || EMPTY_FEATURE_COLLECTION);
|
applyHighlightToMap(highlightFeatures || EMPTY_FEATURE_COLLECTION);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { FEATURE_STATE_SOURCE_IDS, PATH_ARROW_SOURCE_ID } from "@/uhm/lib/map/co
|
|||||||
import {
|
import {
|
||||||
applyBackgroundLayerVisibility,
|
applyBackgroundLayerVisibility,
|
||||||
buildPathArrowFeatureCollection,
|
buildPathArrowFeatureCollection,
|
||||||
|
decoratePointFeaturesWithLabels,
|
||||||
filterDraftByBinding,
|
filterDraftByBinding,
|
||||||
filterDraftByGeometryVisibility,
|
filterDraftByGeometryVisibility,
|
||||||
fitMapToFeatureCollection,
|
fitMapToFeatureCollection,
|
||||||
@@ -28,7 +29,7 @@ type UseMapSyncProps = {
|
|||||||
focusRequestKey?: string | number | null;
|
focusRequestKey?: string | number | null;
|
||||||
focusPadding?: number | maplibregl.PaddingOptions;
|
focusPadding?: number | maplibregl.PaddingOptions;
|
||||||
allowGeometryEditing: boolean;
|
allowGeometryEditing: boolean;
|
||||||
editingEngineRef: React.MutableRefObject<any>;
|
editingEngineRef: React.MutableRefObject<unknown>;
|
||||||
geolocationCenteredRef: React.MutableRefObject<boolean>;
|
geolocationCenteredRef: React.MutableRefObject<boolean>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -97,10 +98,11 @@ export function useMapSync({
|
|||||||
: fc;
|
: fc;
|
||||||
const visibleDraft = filterDraftByGeometryVisibility(visibleDraftRaw, geometryVisibilityRef.current);
|
const visibleDraft = filterDraftByGeometryVisibility(visibleDraftRaw, geometryVisibilityRef.current);
|
||||||
const { polygons, points } = splitDraftFeatures(visibleDraft);
|
const { polygons, points } = splitDraftFeatures(visibleDraft);
|
||||||
|
const labeledPoints = decoratePointFeaturesWithLabels(points);
|
||||||
const pathArrowShapes = buildPathArrowFeatureCollection(visibleDraft);
|
const pathArrowShapes = buildPathArrowFeatureCollection(visibleDraft);
|
||||||
|
|
||||||
countriesSource.setData(polygons);
|
countriesSource.setData(polygons);
|
||||||
placesSource.setData(points);
|
placesSource.setData(labeledPoints);
|
||||||
(map.getSource(PATH_ARROW_SOURCE_ID) as maplibregl.GeoJSONSource | undefined)?.setData(pathArrowShapes);
|
(map.getSource(PATH_ARROW_SOURCE_ID) as maplibregl.GeoJSONSource | undefined)?.setData(pathArrowShapes);
|
||||||
|
|
||||||
const currentSelectedIds = selectedFeatureIdsRef.current;
|
const currentSelectedIds = selectedFeatureIdsRef.current;
|
||||||
|
|||||||
@@ -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 PATH_ARROW_ICON_ID = "path-arrow-icon";
|
||||||
|
|
||||||
export const MAP_MIN_ZOOM = 2;
|
export const MAP_MIN_ZOOM = 2;
|
||||||
|
|||||||
@@ -1,53 +1,8 @@
|
|||||||
import { LayerSpecification } from "maplibre-gl";
|
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[] {
|
export function getBridgeLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||||
return [
|
void sourceId;
|
||||||
{
|
void pathArrowSourceId;
|
||||||
id: "bridge-circle",
|
return buildPointGeotypeLayers("bridge", pointSourceId!);
|
||||||
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
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,8 @@
|
|||||||
import { LayerSpecification } from "maplibre-gl";
|
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[] {
|
export function getCapitalLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||||
return [
|
void sourceId;
|
||||||
{
|
void pathArrowSourceId;
|
||||||
id: "capital-circle",
|
return buildPointGeotypeLayers("capital", pointSourceId!);
|
||||||
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
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,8 @@
|
|||||||
import { LayerSpecification } from "maplibre-gl";
|
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[] {
|
export function getCastleLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||||
return [
|
void sourceId;
|
||||||
{
|
void pathArrowSourceId;
|
||||||
id: "castle-circle",
|
return buildPointGeotypeLayers("castle", pointSourceId!);
|
||||||
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
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,8 @@
|
|||||||
import { LayerSpecification } from "maplibre-gl";
|
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[] {
|
export function getCityLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||||
return [
|
void sourceId;
|
||||||
{
|
void pathArrowSourceId;
|
||||||
id: "city-circle",
|
return buildPointGeotypeLayers("city", pointSourceId!);
|
||||||
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
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,8 @@
|
|||||||
import { LayerSpecification } from "maplibre-gl";
|
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[] {
|
export function getFortressLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||||
return [
|
void sourceId;
|
||||||
{
|
void pathArrowSourceId;
|
||||||
id: "fortress-circle",
|
return buildPointGeotypeLayers("fortress", pointSourceId!);
|
||||||
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
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import maplibregl from "maplibre-gl";
|
import maplibregl from "maplibre-gl";
|
||||||
export const TYPE_MATCH_EXPR: maplibregl.ExpressionSpecification = ["coalesce", ["get", "type"], ["get", "entity_type_id"], ""];
|
export const TYPE_MATCH_EXPR: maplibregl.ExpressionSpecification = ["coalesce", ["get", "type"], ["get", "entity_type_id"], ""];
|
||||||
|
export { ensurePointGeotypeIcons } from "./pointStyle";
|
||||||
|
|
||||||
import { getDefenseLineLayers } from "./defense_line";
|
import { getDefenseLineLayers } from "./defense_line";
|
||||||
import { getAttackRouteLayers } from "./attack_route";
|
import { getAttackRouteLayers } from "./attack_route";
|
||||||
|
|||||||
@@ -1,53 +1,8 @@
|
|||||||
import { LayerSpecification } from "maplibre-gl";
|
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[] {
|
export function getPersonActivityLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||||
return [
|
void sourceId;
|
||||||
{
|
void pathArrowSourceId;
|
||||||
id: "person_activity-circle",
|
return buildPointGeotypeLayers("person_activity", pointSourceId!);
|
||||||
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
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,8 @@
|
|||||||
import { LayerSpecification } from "maplibre-gl";
|
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[] {
|
export function getPersonBirthplaceLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||||
return [
|
void sourceId;
|
||||||
{
|
void pathArrowSourceId;
|
||||||
id: "person_birthplace-circle",
|
return buildPointGeotypeLayers("person_birthplace", pointSourceId!);
|
||||||
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
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,8 @@
|
|||||||
import { LayerSpecification } from "maplibre-gl";
|
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[] {
|
export function getPersonDeathplaceLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||||
return [
|
void sourceId;
|
||||||
{
|
void pathArrowSourceId;
|
||||||
id: "person_deathplace-circle",
|
return buildPointGeotypeLayers("person_deathplace", pointSourceId!);
|
||||||
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
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,8 @@
|
|||||||
import { LayerSpecification } from "maplibre-gl";
|
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[] {
|
export function getPortLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||||
return [
|
void sourceId;
|
||||||
{
|
void pathArrowSourceId;
|
||||||
id: "port-circle",
|
return buildPointGeotypeLayers("port", pointSourceId!);
|
||||||
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
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,8 @@
|
|||||||
import { LayerSpecification } from "maplibre-gl";
|
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[] {
|
export function getRuinLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||||
return [
|
void sourceId;
|
||||||
{
|
void pathArrowSourceId;
|
||||||
id: "ruin-circle",
|
return buildPointGeotypeLayers("ruin", pointSourceId!);
|
||||||
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
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,8 @@
|
|||||||
import { LayerSpecification } from "maplibre-gl";
|
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[] {
|
export function getTempleLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] {
|
||||||
return [
|
void sourceId;
|
||||||
{
|
void pathArrowSourceId;
|
||||||
id: "temple-circle",
|
return buildPointGeotypeLayers("temple", pointSourceId!);
|
||||||
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
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export type FeatureProperties = {
|
|||||||
entity_name?: string | null;
|
entity_name?: string | null;
|
||||||
entity_names?: string[];
|
entity_names?: string[];
|
||||||
entity_type_id?: string | null;
|
entity_type_id?: string | null;
|
||||||
|
point_label?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Feature = {
|
export type Feature = {
|
||||||
|
|||||||
Reference in New Issue
Block a user