diff --git a/src/app/editor/[id]/page.tsx b/src/app/editor/[id]/page.tsx index 37e4497..9e0ce6e 100644 --- a/src/app/editor/[id]/page.tsx +++ b/src/app/editor/[id]/page.tsx @@ -495,7 +495,7 @@ function EditorPageContent() { initialMapViewState: previewSession?.mapViewState ?? null, selectedStageId: previewSession?.selectedStageId ?? replaySelection.stageId, selectedStepIndex: previewSession?.selectedStepIndex ?? replaySelection.stepIndex, - onSelectStep: () => {}, + onSelectStep: () => { }, }); const { hiddenGeometryIds: replayPreviewHiddenGeometryIds, @@ -788,7 +788,7 @@ function EditorPageContent() { // QUY TẮC: Geo chọn đầu tiên là geo main. const finalSelectedIds = Array.from(new Set([...selectedFeatureIds, featureId])); const triggerId = selectedFeatureIds.length > 0 ? selectedFeatureIds[0] : featureId; - + setReplayFeatureId(triggerId); setReplaySelection({ stageId: null, stepIndex: null }); editor.switchReplayContext(triggerId, finalSelectedIds); @@ -997,7 +997,7 @@ function EditorPageContent() { if (isReplayEditMode && hideOutside) { // Trong mode replay, ta chỉ hiển thị những gì có trong draft của replay đó const currentReplayFeatureIds = new Set(editor.draft.features.map(f => String(f.properties.id))); - + // Ẩn tất cả các geo KHÔNG nằm trong draft replay hiện tại Object.keys(visibility).forEach(fid => { if (fid === String(replayFeatureId)) { @@ -1062,7 +1062,7 @@ function EditorPageContent() { // Xóa pending submission để backend cho phép mở editor lại. const unlockByDeletingPendingSubmission = useCallback(async () => { if (!blockedPendingSubmissionId) return; - const confirmed = window.confirm("Xoa submission PENDING de unlock editor? Hanh dong nay khong the hoan tac."); + const confirmed = window.confirm("Bạn chắc chắn muốn xóa Submition? - việc này không làm hỏng project của bạn"); if (!confirmed) return; try { setIsOpeningSection(true); @@ -1599,7 +1599,7 @@ function EditorPageContent() { } const prevBindingIds = normalizeFeatureBindingIds(targetFeature); - + // Merge prevBindingIds with sourceIds (which are strings of selected features) // filter out targetId itself (we can't bind a geometry to itself) const newSources = sourceIds.map(String).filter((x) => x !== idStr); @@ -1966,6 +1966,127 @@ function EditorPageContent() { [entities, labelContextBaseDraft] ); + if (blockedPendingSubmissionId) { + return ( +
+
+
+ + + +

Editor đang bị khóa

+
+
+ Project này đang có submission ở trạng thái PENDING (id: {blockedPendingSubmissionId}). Theo quy trình làm việc, khi submission đang pending thì không được tạo submission/commit mới và không được vào editor. +
+
+ + +
+
+
+ ); + } + + if (isOpeningSection || !activeSection) { + return ( +
+ {!activeSection && !isOpeningSection ? ( +
+

Lỗi tải Project

+
+ {entityStatus || "Không thể tải thông tin dự án. Vui lòng thử lại hoặc quay lại danh sách."} +
+
+ + +
+
+ ) : ( + <> +
+ +
+ Đang tải dữ liệu bản đồ... +
+ + )} +
+ ); + } + return (
{!isReplayEditMode && !isReplayPreviewMode ? ( @@ -1980,7 +2101,7 @@ function EditorPageContent() { onRestoreCommit={restoreCommit} isSaving={isSaving} isSubmitting={isSubmitting} - sectionTitle={activeSection?.title || "Đang tải project"} + sectionTitle={activeSection.title || "Đang tải project"} projectStatus={projectState?.status || "editing"} commitTitle={commitTitle} onCommitTitleChange={setCommitTitle} @@ -2019,8 +2140,8 @@ function EditorPageContent() { previewPlaybackSpeed={1} onPlayPreviewFromStart={() => openReplayPreview("start")} onPlayPreviewFromSelection={() => openReplayPreview("selection")} - onStopPreview={() => {}} - onResetPreview={() => {}} + onStopPreview={() => { }} + onResetPreview={() => { }} /> ) : null} - {blockedPendingSubmissionId ? ( -
-
-

Editor dang bi khoa

-
- Project nay dang co submission o trang thai PENDING (id:{" "} - {blockedPendingSubmissionId}). Theo BE moi, khi - submission dang pending thi khong duoc tao submission/commit moi va khong duoc vao editor. -
-
- - -
-
-
- ) : null} - - {!blockedPendingSubmissionId ? ( -
- {isBackgroundVisibilityReady ? ( - { - if (Array.isArray(id)) { - editor.deleteFeatures(id); - } else { - editor.deleteFeature(id); - } - }} - onHideFeature={handleHideGeometryLocal} - onUpdateFeature={editor.updateFeature} - backgroundVisibility={backgroundVisibility} - geometryVisibility={effectiveGeometryVisibility} - applyGeometryBindingFilter={isReplayEditMode || isReplayPreviewMode ? false : geometryBindingFilterEnabled} - highlightFeatures={null} - focusFeatureCollection={geometryFocusRequest?.collection || null} - focusRequestKey={geometryFocusRequest?.key ?? null} - focusPadding={96} - imageOverlay={imageOverlay} - onImageOverlayChange={setImageOverlay} - onBindGeometries={handleBindGeometries} - /> - ) : ( -
- )} - {isReplayPreviewMode ? ( - - ) : null} - {isReplayPreviewMode && replayPreview.sidebarOpen ? ( - - ) : null} - {!isReplayPreviewMode || replayPreview.timelineVisible ? ( - + {isBackgroundVisibilityReady ? ( + { + if (Array.isArray(id)) { + editor.deleteFeatures(id); + } else { + editor.deleteFeature(id); } + }} + onHideFeature={handleHideGeometryLocal} + onUpdateFeature={editor.updateFeature} + backgroundVisibility={backgroundVisibility} + geometryVisibility={effectiveGeometryVisibility} + applyGeometryBindingFilter={isReplayEditMode || isReplayPreviewMode ? false : geometryBindingFilterEnabled} + highlightFeatures={null} + focusFeatureCollection={geometryFocusRequest?.collection || null} + focusRequestKey={geometryFocusRequest?.key ?? null} + focusPadding={96} + imageOverlay={imageOverlay} + onImageOverlayChange={setImageOverlay} + onBindGeometries={handleBindGeometries} + /> + ) : ( +
+ )} + {isReplayPreviewMode ? ( + + ) : null} + {isReplayPreviewMode && replayPreview.sidebarOpen ? ( +
- ) : null} + + ) : null} + {!isReplayPreviewMode || replayPreview.timelineVisible ? ( + + ) : null} +
{!isReplayEditMode && !isReplayPreviewMode ? ( <> { - // dragging handle (between map and right panel): moving right increases right panel width setRightPanelWidth((prev) => clampNumber(prev - deltaX, 260, 720)); }} /> diff --git a/src/uhm/doc/map_styling.md b/src/uhm/doc/map_styling.md index aa32829..d868fb3 100644 --- a/src/uhm/doc/map_styling.md +++ b/src/uhm/doc/map_styling.md @@ -48,33 +48,22 @@ Geotype render hiện được tập trung ở `getAllGeotypeLayers(...)` trong Các type đang được register: - `defense_line` -- `attack_route` +- `military_route` - `retreat_route` -- `invasion_route` - `migration_route` -- `refugee_route` - `trade_route` -- `shipping_route` - `country` - `state` -- `empire` -- `kingdom` - `faction` -- `war` - `battle` -- `civilization` - `rebellion_zone` -- `person_deathplace` -- `person_birthplace` -- `person_activity` +- `person_event` - `temple` - `capital` - `city` -- `fortress` -- `castle` +- `fortification` - `ruin` - `port` -- `bridge` `GEOMETRY_TYPE_OPTIONS` trong `src/uhm/lib/map/geo/geometryTypeOptions.ts` phải khớp với tập geotype này nếu muốn user chọn được từ UI. diff --git a/src/uhm/lib/editor/project/useProjectCommands.ts b/src/uhm/lib/editor/project/useProjectCommands.ts index ece490e..cde3376 100644 --- a/src/uhm/lib/editor/project/useProjectCommands.ts +++ b/src/uhm/lib/editor/project/useProjectCommands.ts @@ -74,14 +74,7 @@ export function useProjectCommands(options: Options) { return; } - const orphanGeometries = findOrphanGeometries(options.editor.mainDraft); - if (orphanGeometries.length > 0) { - const firstOrphan = orphanGeometries[0]; - state.setSelectedFeatureIds([firstOrphan.id]); - state.setEntityFormStatus("Geometry này chưa bind entity."); - state.setEntityStatus(formatOrphanGeometryMessage("Commit", orphanGeometries)); - return; - } + const geometryChanges = options.editor.buildPayload(); state.setIsSaving(true); @@ -221,14 +214,7 @@ export function useProjectCommands(options: Options) { return; } - const orphanGeometries = findOrphanGeometries(options.editor.mainDraft); - if (orphanGeometries.length > 0) { - const firstOrphan = orphanGeometries[0]; - state.setSelectedFeatureIds([firstOrphan.id]); - state.setEntityFormStatus("Geometry này chưa bind entity."); - state.setEntityStatus(formatOrphanGeometryMessage("Submit", orphanGeometries)); - return; - } + state.setIsSubmitting(true); state.setEntityStatus(null); @@ -305,33 +291,7 @@ export function useProjectCommands(options: Options) { }; } -type OrphanGeometry = { - id: Feature["properties"]["id"]; - label: string; -}; -function findOrphanGeometries(draft: FeatureCollection): OrphanGeometry[] { - const rows: OrphanGeometry[] = []; - - for (const feature of draft.features || []) { - const entityIds = normalizeFeatureEntityIds(feature); - if (entityIds.length > 0) continue; - - const id = feature.properties.id; - rows.push({ - id, - label: String(id), - }); - } - - return rows; -} - -function formatOrphanGeometryMessage(action: "Commit" | "Submit", rows: OrphanGeometry[]): string { - const sample = rows.slice(0, 8).map((row) => row.label).join(", "); - const more = rows.length > 8 ? `, ... (+${rows.length - 8})` : ""; - return `Không thể ${action}: còn ${rows.length} geometry chưa bind entity. Hãy bind entity cho: ${sample}${more}.`; -} function toEditorSessionSnapshot(snapshot: EditorSnapshot): EditorSnapshot { return { diff --git a/src/uhm/lib/map/engines/circleEngine.ts b/src/uhm/lib/map/engines/circleEngine.ts index 944ce65..58d9299 100644 --- a/src/uhm/lib/map/engines/circleEngine.ts +++ b/src/uhm/lib/map/engines/circleEngine.ts @@ -23,6 +23,7 @@ export function initCircle( // Xóa dữ liệu preview circle trên map. const clearPreview = () => { + if (!map.isStyleLoaded()) return; (map.getSource("draw-circle-preview") as maplibregl.GeoJSONSource | undefined)?.setData( EMPTY_PREVIEW ); @@ -32,7 +33,7 @@ export function initCircle( const releaseDragPan = () => { if (!dragPanDisabledByCircle) return; dragPanDisabledByCircle = false; - if (!map.dragPan.isEnabled()) { + if (map.isStyleLoaded() && !map.dragPan.isEnabled()) { map.dragPan.enable(); } }; @@ -53,6 +54,7 @@ export function initCircle( return; } + if (!map.isStyleLoaded()) return; const ring = buildCircleRing(center, radiusMeters, CIRCLE_SEGMENTS); (map.getSource("draw-circle-preview") as maplibregl.GeoJSONSource | undefined)?.setData({ type: "FeatureCollection", @@ -91,7 +93,7 @@ export function initCircle( const onMouseMove = (e: maplibregl.MapMouseEvent) => { const canvas = map.getCanvas(); if (getMode() !== "add-circle") { - if (canvas.style.cursor === "crosshair") { + if (canvas && canvas.style.cursor === "crosshair") { canvas.style.cursor = ""; } if (isDragging) { @@ -100,7 +102,9 @@ export function initCircle( return; } - canvas.style.cursor = "crosshair"; + if (canvas) { + canvas.style.cursor = "crosshair"; + } if (!isDragging || !center) return; radiusMeters = distanceMeters(center, [e.lngLat.lng, e.lngLat.lat]); @@ -150,13 +154,20 @@ export function initCircle( document.addEventListener("keydown", onKeyDown); const cleanup = () => { - map.off("mousedown", onMouseDown); - map.off("mousemove", onMouseMove); - map.off("mouseup", onMouseUp); - document.removeEventListener("keydown", onKeyDown); - resetDrawingState(); - if (map.getCanvas().style.cursor === "crosshair") { - map.getCanvas().style.cursor = ""; + try { + map.off("mousedown", onMouseDown); + map.off("mousemove", onMouseMove); + map.off("mouseup", onMouseUp); + document.removeEventListener("keydown", onKeyDown); + resetDrawingState(); + if (map.isStyleLoaded()) { + const canvas = map.getCanvas(); + if (canvas && canvas.style.cursor === "crosshair") { + canvas.style.cursor = ""; + } + } + } catch { + // ignore } }; diff --git a/src/uhm/lib/map/engines/drawingEngine.ts b/src/uhm/lib/map/engines/drawingEngine.ts index ed5c6ef..d0ea3c7 100644 --- a/src/uhm/lib/map/engines/drawingEngine.ts +++ b/src/uhm/lib/map/engines/drawingEngine.ts @@ -12,6 +12,7 @@ export function initDrawing( let coords: [number, number][] = []; const clearPreview = () => { + if (!map.isStyleLoaded()) return; (map.getSource("draw-preview") as maplibregl.GeoJSONSource | undefined)?.setData({ type: "FeatureCollection", features: [], @@ -39,6 +40,7 @@ export function initDrawing( function update(c: [number, number][]) { const closed = closePolygon(c); + if (!map.isStyleLoaded()) return; (map.getSource("draw-preview") as maplibregl.GeoJSONSource)?.setData({ type: "FeatureCollection", features: [ @@ -130,12 +132,18 @@ export function initDrawing( document.addEventListener("keydown", onKeyDown); const cleanup = () => { - map.boxZoom.enable(); - map.doubleClickZoom.enable(); - map.off("click", onClick); - map.off("mousemove", onMove); - document.removeEventListener("keydown", onKeyDown); - cancelDrawing(); + try { + if (map.isStyleLoaded()) { + map.boxZoom.enable(); + map.doubleClickZoom.enable(); + } + map.off("click", onClick); + map.off("mousemove", onMove); + document.removeEventListener("keydown", onKeyDown); + cancelDrawing(); + } catch { + // ignore + } }; return { diff --git a/src/uhm/lib/map/engines/editingEngine.ts b/src/uhm/lib/map/engines/editingEngine.ts index 95f29d2..753b36a 100644 --- a/src/uhm/lib/map/engines/editingEngine.ts +++ b/src/uhm/lib/map/engines/editingEngine.ts @@ -37,7 +37,7 @@ export function createEditingEngine(options: { setDeleteVertexMode(false); hideContextMenu(); const map = mapRef.current; - if (!map) return; + if (!map || !map.isStyleLoaded()) return; const empty: GeoJSON.FeatureCollection = { type: "FeatureCollection", features: [] }; (map.getSource("edit-shape") as maplibregl.GeoJSONSource | undefined)?.setData(empty); (map.getSource("edit-handles") as maplibregl.GeoJSONSource | undefined)?.setData(empty); @@ -47,7 +47,7 @@ export function createEditingEngine(options: { const updateEditSources = () => { const editing = editingRef.current; const map = mapRef.current; - if (!editing || !map) return; + if (!editing || !map || !map.isStyleLoaded()) return; let shape: GeoJSON.FeatureCollection; let handles: GeoJSON.FeatureCollection; @@ -143,7 +143,7 @@ export function createEditingEngine(options: { const setDeleteVertexMode = (enabled: boolean) => { deleteVertexModeRef.current = enabled; const map = mapRef.current; - if (!map?.getLayer("edit-handles-circle")) return; + if (!map || !map.isStyleLoaded() || !map.getLayer("edit-handles-circle")) return; map.setPaintProperty("edit-handles-circle", "circle-color", enabled ? "#ef4444" : "#f97316"); map.setPaintProperty("edit-handles-circle", "circle-stroke-color", enabled ? "#7f1d1d" : "#0f172a"); }; diff --git a/src/uhm/lib/map/engines/lineEngine.ts b/src/uhm/lib/map/engines/lineEngine.ts index 99150cd..201e759 100644 --- a/src/uhm/lib/map/engines/lineEngine.ts +++ b/src/uhm/lib/map/engines/lineEngine.ts @@ -18,6 +18,7 @@ export function initLine( // Xóa dữ liệu preview line. const clearPreview = () => { + if (!map.isStyleLoaded()) return; (map.getSource("draw-line-preview") as maplibregl.GeoJSONSource | undefined)?.setData( EMPTY_PREVIEW ); @@ -36,6 +37,7 @@ export function initLine( return; } + if (!map.isStyleLoaded()) return; (map.getSource("draw-line-preview") as maplibregl.GeoJSONSource | undefined)?.setData({ type: "FeatureCollection", features: [ @@ -91,13 +93,15 @@ export function initLine( if (coords.length) { cancelLine(); } - if (canvas.style.cursor === "crosshair") { + if (canvas && canvas.style.cursor === "crosshair") { canvas.style.cursor = ""; } return; } - canvas.style.cursor = "crosshair"; + if (canvas) { + canvas.style.cursor = "crosshair"; + } if (coords.length === 0) return; const lngLat = e.originalEvent.shiftKey || e.originalEvent.altKey @@ -133,12 +137,19 @@ export function initLine( document.addEventListener("keydown", onKeyDown); const cleanup = () => { - map.off("click", onClick); - map.off("mousemove", onMove); - document.removeEventListener("keydown", onKeyDown); - cancelLine(); - if (map.getCanvas().style.cursor === "crosshair") { - map.getCanvas().style.cursor = ""; + try { + map.off("click", onClick); + map.off("mousemove", onMove); + document.removeEventListener("keydown", onKeyDown); + cancelLine(); + if (map.isStyleLoaded()) { + const canvas = map.getCanvas(); + if (canvas && canvas.style.cursor === "crosshair") { + canvas.style.cursor = ""; + } + } + } catch { + // ignore } }; diff --git a/src/uhm/lib/map/engines/pathEngine.ts b/src/uhm/lib/map/engines/pathEngine.ts index dbc4a68..601c27d 100644 --- a/src/uhm/lib/map/engines/pathEngine.ts +++ b/src/uhm/lib/map/engines/pathEngine.ts @@ -18,6 +18,7 @@ export function initPath( // Xóa dữ liệu preview path. const clearPreview = () => { + if (!map.isStyleLoaded()) return; (map.getSource("draw-path-preview") as maplibregl.GeoJSONSource | undefined)?.setData( EMPTY_PREVIEW ); @@ -30,6 +31,7 @@ export function initPath( return; } + if (!map.isStyleLoaded()) return; (map.getSource("draw-path-preview") as maplibregl.GeoJSONSource | undefined)?.setData({ type: "FeatureCollection", features: [ @@ -92,13 +94,15 @@ export function initPath( if (coords.length) { cancelPath(); } - if (canvas.style.cursor === "crosshair") { + if (canvas && canvas.style.cursor === "crosshair") { canvas.style.cursor = ""; } return; } - canvas.style.cursor = "crosshair"; + if (canvas) { + canvas.style.cursor = "crosshair"; + } if (coords.length === 0) return; const lngLat = e.originalEvent.shiftKey || e.originalEvent.altKey @@ -134,12 +138,19 @@ export function initPath( document.addEventListener("keydown", onKeyDown); const cleanup = () => { - map.off("click", onClick); - map.off("mousemove", onMove); - document.removeEventListener("keydown", onKeyDown); - cancelPath(); - if (map.getCanvas().style.cursor === "crosshair") { - map.getCanvas().style.cursor = ""; + try { + map.off("click", onClick); + map.off("mousemove", onMove); + document.removeEventListener("keydown", onKeyDown); + cancelPath(); + if (map.isStyleLoaded()) { + const canvas = map.getCanvas(); + if (canvas && canvas.style.cursor === "crosshair") { + canvas.style.cursor = ""; + } + } + } catch { + // ignore } }; diff --git a/src/uhm/lib/map/engines/pointEngine.ts b/src/uhm/lib/map/engines/pointEngine.ts index f8ef9f8..ed0799b 100644 --- a/src/uhm/lib/map/engines/pointEngine.ts +++ b/src/uhm/lib/map/engines/pointEngine.ts @@ -41,10 +41,17 @@ export function initPoint( map.on("mousemove", onMove); return () => { - map.off("click", onClick); - map.off("mousemove", onMove); - if (map.getCanvas().style.cursor === "crosshair") { - map.getCanvas().style.cursor = ""; + try { + map.off("click", onClick); + map.off("mousemove", onMove); + if (map.isStyleLoaded()) { + const canvas = map.getCanvas(); + if (canvas && canvas.style.cursor === "crosshair") { + canvas.style.cursor = ""; + } + } + } catch { + // ignore } }; } diff --git a/src/uhm/lib/map/engines/selectingEngine.ts b/src/uhm/lib/map/engines/selectingEngine.ts index 4fdbfb2..597bc8b 100644 --- a/src/uhm/lib/map/engines/selectingEngine.ts +++ b/src/uhm/lib/map/engines/selectingEngine.ts @@ -150,6 +150,7 @@ export function initSelect( } function setSelectionStateForId(id: string | number, selected: boolean) { + if (!map.isStyleLoaded()) return; for (const source of FEATURE_STATE_SOURCES) { if (!map.getSource(source)) continue; map.setFeatureState({ source, id }, { selected }); @@ -194,13 +195,19 @@ export function initSelect( } const cleanup = () => { - map.off("click", onClick); - map.off("mousemove", onMove); - if (hasContextActions) { - map.off("contextmenu", onRightClick); + try { + map.off("click", onClick); + map.off("mousemove", onMove); + if (hasContextActions) { + map.off("contextmenu", onRightClick); + } + if (map.isStyleLoaded()) { + clearSelection(false); + } + hideContextMenu(); + } catch { + // ignore } - clearSelection(false); - hideContextMenu(); }; return { diff --git a/src/uhm/lib/map/geo/geoTypeMap.json b/src/uhm/lib/map/geo/geoTypeMap.json index 0bd5164..0c27ce3 100644 --- a/src/uhm/lib/map/geo/geoTypeMap.json +++ b/src/uhm/lib/map/geo/geoTypeMap.json @@ -1,33 +1,28 @@ [ { "type_key": "defense_line", "geo_type_code": 1 }, - { "type_key": "attack_route", "geo_type_code": 2 }, + { "type_key": "military_route", "geo_type_code": 2 }, { "type_key": "retreat_route", "geo_type_code": 3 }, - { "type_key": "invasion_route", "geo_type_code": 4 }, { "type_key": "migration_route", "geo_type_code": 5 }, - { "type_key": "refugee_route", "geo_type_code": 6 }, { "type_key": "trade_route", "geo_type_code": 7 }, - { "type_key": "shipping_route", "geo_type_code": 8 }, { "type_key": "country", "geo_type_code": 9, "fixed": true }, { "type_key": "state", "geo_type_code": 10 }, - { "type_key": "empire", "geo_type_code": 11 }, - { "type_key": "kingdom", "geo_type_code": 12 }, { "type_key": "faction", "geo_type_code": 28 }, - { "type_key": "war", "geo_type_code": 13 }, { "type_key": "battle", "geo_type_code": 14 }, - { "type_key": "civilization", "geo_type_code": 15 }, { "type_key": "rebellion_zone", "geo_type_code": 16 }, - { "type_key": "person_deathplace", "geo_type_code": 17 }, - { "type_key": "person_birthplace", "geo_type_code": 18 }, - { "type_key": "person_activity", "geo_type_code": 19 }, + { "type_key": "person_event", "geo_type_code": 17 }, + { "type_key": "person_event", "geo_type_code": 18 }, + { "type_key": "person_event", "geo_type_code": 19 }, + { "type_key": "temple", "geo_type_code": 20 }, { "type_key": "capital", "geo_type_code": 21 }, { "type_key": "city", "geo_type_code": 22 }, - { "type_key": "fortress", "geo_type_code": 23 }, - { "type_key": "castle", "geo_type_code": 24 }, + + { "type_key": "fortification", "geo_type_code": 23 }, + { "type_key": "fortification", "geo_type_code": 24 }, + { "type_key": "ruin", "geo_type_code": 25 }, - { "type_key": "port", "geo_type_code": 26 }, - { "type_key": "bridge", "geo_type_code": 27 } + { "type_key": "port", "geo_type_code": 26 } ] diff --git a/src/uhm/lib/map/geo/geoTypeMap.ts b/src/uhm/lib/map/geo/geoTypeMap.ts index da849e7..5c22b1f 100644 --- a/src/uhm/lib/map/geo/geoTypeMap.ts +++ b/src/uhm/lib/map/geo/geoTypeMap.ts @@ -40,6 +40,15 @@ export function geoTypeCodeToTypeKey(code: number | null | undefined): string | return KEY_BY_CODE.get(Math.trunc(code)) ?? null; } +const DEPRECATED_MAPPING: Record = { + attack_route: "military_route", + person_birthplace: "person_event", + person_deathplace: "person_event", + person_activity: "person_event", + fortress: "fortification", + castle: "fortification", +}; + export function normalizeGeoTypeKey(value: unknown): string | null { if (typeof value === "number") { return geoTypeCodeToTypeKey(value); @@ -54,5 +63,14 @@ export function normalizeGeoTypeKey(value: unknown): string | null { return geoTypeCodeToTypeKey(Number(normalized)); } + if (normalized in DEPRECATED_MAPPING) { + return DEPRECATED_MAPPING[normalized]; + } + + const code = CODE_BY_KEY.get(normalized); + if (code !== undefined) { + return KEY_BY_CODE.get(code) ?? normalized; + } + return normalized; } diff --git a/src/uhm/lib/map/geo/geometryTypeOptions.ts b/src/uhm/lib/map/geo/geometryTypeOptions.ts index 0e555c4..d0a56c1 100644 --- a/src/uhm/lib/map/geo/geometryTypeOptions.ts +++ b/src/uhm/lib/map/geo/geometryTypeOptions.ts @@ -62,37 +62,25 @@ const RAW_GEOMETRY_TYPE_OPTIONS: Array<{ geometryPreset: GeometryPreset; }> = [ { value: "defense_line", label: "Defense Line", groupId: "line", geometryPreset: "line" }, - - { value: "attack_route", label: "Attack Route", groupId: "line", geometryPreset: "line" }, + { value: "military_route", label: "Military Route", groupId: "line", geometryPreset: "line" }, { value: "retreat_route", label: "Retreat Route", groupId: "line", geometryPreset: "line" }, - { value: "invasion_route", label: "Invasion Route", groupId: "line", geometryPreset: "line" }, { value: "migration_route", label: "Migration Route", groupId: "line", geometryPreset: "line" }, - { value: "refugee_route", label: "Refugee Route", groupId: "line", geometryPreset: "line" }, { value: "trade_route", label: "Trade Route", groupId: "line", geometryPreset: "line" }, - { value: "shipping_route", label: "Shipping Route", groupId: "line", geometryPreset: "line" }, { value: "country", label: "Country", groupId: "polygon", geometryPreset: "polygon" }, { value: "state", label: "State", groupId: "polygon", geometryPreset: "polygon" }, - { value: "empire", label: "Empire", groupId: "polygon", geometryPreset: "polygon" }, - { value: "kingdom", label: "Kingdom", groupId: "polygon", geometryPreset: "polygon" }, { value: "faction", label: "Faction", groupId: "polygon", geometryPreset: "polygon" }, - { value: "war", label: "War", groupId: "circle", geometryPreset: "circle-area" }, { value: "battle", label: "Battle", groupId: "circle", geometryPreset: "circle-area" }, - { value: "civilization", label: "Civilization", groupId: "circle", geometryPreset: "circle-area" }, { value: "rebellion_zone", label: "Rebellion Zone", groupId: "circle", geometryPreset: "circle-area" }, - { value: "person_deathplace", label: "Person Deathplace", groupId: "point", geometryPreset: "point" }, - { value: "person_birthplace", label: "Person Birthplace", groupId: "point", geometryPreset: "point" }, - { value: "person_activity", label: "Person Activity", groupId: "point", geometryPreset: "point" }, + { value: "person_event", label: "Person Event", groupId: "point", geometryPreset: "point" }, { value: "temple", label: "Temple", groupId: "point", geometryPreset: "point" }, { value: "capital", label: "Capital", groupId: "point", geometryPreset: "point" }, { value: "city", label: "City", groupId: "point", geometryPreset: "point" }, - { value: "fortress", label: "Fortress", groupId: "point", geometryPreset: "point" }, - { value: "castle", label: "Castle", groupId: "point", geometryPreset: "point" }, + { value: "fortification", label: "Fortification", groupId: "point", geometryPreset: "point" }, { value: "ruin", label: "Ruin", groupId: "point", geometryPreset: "point" }, { value: "port", label: "Port", groupId: "point", geometryPreset: "point" }, - { value: "bridge", label: "Bridge", groupId: "point", geometryPreset: "point" }, ]; export const GEOMETRY_TYPE_OPTIONS: GeometryTypeOption[] = RAW_GEOMETRY_TYPE_OPTIONS.map((item) => ({ diff --git a/src/uhm/lib/map/styles/geotypeLayers.ts b/src/uhm/lib/map/styles/geotypeLayers.ts index f854b91..0dba6a5 100644 --- a/src/uhm/lib/map/styles/geotypeLayers.ts +++ b/src/uhm/lib/map/styles/geotypeLayers.ts @@ -3,33 +3,22 @@ export const TYPE_MATCH_EXPR: maplibregl.ExpressionSpecification = ["coalesce", export { ensurePointGeotypeIcons } from "./shared/pointStyle"; import { getDefenseLineLayers } from "./geotypes/defense_line"; -import { getAttackRouteLayers } from "./geotypes/attack_route"; +import { getMilitaryRouteLayers } from "./geotypes/military_route"; import { getRetreatRouteLayers } from "./geotypes/retreat_route"; -import { getInvasionRouteLayers } from "./geotypes/invasion_route"; import { getMigrationRouteLayers } from "./geotypes/migration_route"; -import { getRefugeeRouteLayers } from "./geotypes/refugee_route"; import { getTradeRouteLayers } from "./geotypes/trade_route"; -import { getShippingRouteLayers } from "./geotypes/shipping_route"; import { getCountryLayers } from "./geotypes/country"; import { getStateLayers } from "./geotypes/state"; -import { getEmpireLayers } from "./geotypes/empire"; -import { getKingdomLayers } from "./geotypes/kingdom"; import { getFactionLayers } from "./geotypes/faction"; -import { getWarLayers } from "./geotypes/war"; import { getBattleLayers } from "./geotypes/battle"; -import { getCivilizationLayers } from "./geotypes/civilization"; import { getRebellionZoneLayers } from "./geotypes/rebellion_zone"; -import { getPersonDeathplaceLayers } from "./geotypes/person_deathplace"; -import { getPersonBirthplaceLayers } from "./geotypes/person_birthplace"; -import { getPersonActivityLayers } from "./geotypes/person_activity"; +import { getPersonEventLayers } from "./geotypes/person_event"; import { getTempleLayers } from "./geotypes/temple"; import { getCapitalLayers } from "./geotypes/capital"; import { getCityLayers } from "./geotypes/city"; -import { getFortressLayers } from "./geotypes/fortress"; -import { getCastleLayers } from "./geotypes/castle"; +import { getFortificationLayers } from "./geotypes/fortification"; import { getRuinLayers } from "./geotypes/ruin"; import { getPortLayers } from "./geotypes/port"; -import { getBridgeLayers } from "./geotypes/bridge"; import { getLineLabelLayers } from "./shared/lineLabels"; import { getPolygonLabelLayers } from "./shared/polygonLabels"; @@ -39,32 +28,21 @@ export function getAllGeotypeLayers(sourceId: string, pathArrowSourceId?: string return [ ...getCountryLayers(sourceId, pathArrowSourceId, pointSourceId), ...getStateLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getEmpireLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getKingdomLayers(sourceId, pathArrowSourceId, pointSourceId), ...getFactionLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getWarLayers(sourceId, pathArrowSourceId, pointSourceId), ...getBattleLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getCivilizationLayers(sourceId, pathArrowSourceId, pointSourceId), ...getRebellionZoneLayers(sourceId, pathArrowSourceId, pointSourceId), ...getDefenseLineLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getAttackRouteLayers(sourceId, pathArrowSourceId, pointSourceId), + ...getMilitaryRouteLayers(sourceId, pathArrowSourceId, pointSourceId), ...getRetreatRouteLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getInvasionRouteLayers(sourceId, pathArrowSourceId, pointSourceId), ...getMigrationRouteLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getRefugeeRouteLayers(sourceId, pathArrowSourceId, pointSourceId), ...getTradeRouteLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getShippingRouteLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getPersonDeathplaceLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getPersonBirthplaceLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getPersonActivityLayers(sourceId, pathArrowSourceId, pointSourceId), + ...getPersonEventLayers(sourceId, pathArrowSourceId, pointSourceId), ...getTempleLayers(sourceId, pathArrowSourceId, pointSourceId), ...getCapitalLayers(sourceId, pathArrowSourceId, pointSourceId), ...getCityLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getFortressLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getCastleLayers(sourceId, pathArrowSourceId, pointSourceId), + ...getFortificationLayers(sourceId, pathArrowSourceId, pointSourceId), ...getRuinLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getPortLayers(sourceId, pathArrowSourceId, pointSourceId), - ...getBridgeLayers(sourceId, pathArrowSourceId, pointSourceId) + ...getPortLayers(sourceId, pathArrowSourceId, pointSourceId) ]; } diff --git a/src/uhm/lib/map/styles/geotypes/bridge.ts b/src/uhm/lib/map/styles/geotypes/bridge.ts deleted file mode 100644 index fac2bae..0000000 --- a/src/uhm/lib/map/styles/geotypes/bridge.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { LayerSpecification } from "maplibre-gl"; -import { buildPointGeotypeLayers } from "../shared/pointStyle"; - -export function getBridgeLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - void sourceId; - void pathArrowSourceId; - return buildPointGeotypeLayers("bridge", pointSourceId!); -} diff --git a/src/uhm/lib/map/styles/geotypes/castle.ts b/src/uhm/lib/map/styles/geotypes/castle.ts deleted file mode 100644 index eb8fb89..0000000 --- a/src/uhm/lib/map/styles/geotypes/castle.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { LayerSpecification } from "maplibre-gl"; -import { buildPointGeotypeLayers } from "../shared/pointStyle"; - -export function getCastleLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - void sourceId; - void pathArrowSourceId; - return buildPointGeotypeLayers("castle", pointSourceId!); -} diff --git a/src/uhm/lib/map/styles/geotypes/civilization.ts b/src/uhm/lib/map/styles/geotypes/civilization.ts deleted file mode 100644 index b88267e..0000000 --- a/src/uhm/lib/map/styles/geotypes/civilization.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { LayerSpecification } from "maplibre-gl"; -import { buildPolygonGeotypeLayers } from "../shared/styleBuilders"; - -export function getCivilizationLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - void pathArrowSourceId; - void pointSourceId; - return buildPolygonGeotypeLayers(sourceId, { - typeId: "civilization", - fillColor: "#14b8a6", - strokeColor: "#134e4a", - fillOpacity: 0.34, - }); -} diff --git a/src/uhm/lib/map/styles/geotypes/empire.ts b/src/uhm/lib/map/styles/geotypes/empire.ts deleted file mode 100644 index 755558b..0000000 --- a/src/uhm/lib/map/styles/geotypes/empire.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { LayerSpecification } from "maplibre-gl"; -import { buildPolygonGeotypeLayers } from "../shared/styleBuilders"; - -export function getEmpireLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - void pathArrowSourceId; - void pointSourceId; - return buildPolygonGeotypeLayers(sourceId, { - typeId: "empire", - fillColor: "#f59e0b", - strokeColor: "#92400e", - fillOpacity: 0.36, - strokeWidth: { z1: 1.8, z4: 2.6, z6: 3.4 }, - }); -} diff --git a/src/uhm/lib/map/styles/geotypes/fortification.ts b/src/uhm/lib/map/styles/geotypes/fortification.ts new file mode 100644 index 0000000..c15b223 --- /dev/null +++ b/src/uhm/lib/map/styles/geotypes/fortification.ts @@ -0,0 +1,8 @@ +import { LayerSpecification } from "maplibre-gl"; +import { buildPointGeotypeLayers } from "../shared/pointStyle"; + +export function getFortificationLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { + void sourceId; + void pathArrowSourceId; + return buildPointGeotypeLayers("fortification", pointSourceId!); +} diff --git a/src/uhm/lib/map/styles/geotypes/fortress.ts b/src/uhm/lib/map/styles/geotypes/fortress.ts deleted file mode 100644 index 1811456..0000000 --- a/src/uhm/lib/map/styles/geotypes/fortress.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { LayerSpecification } from "maplibre-gl"; -import { buildPointGeotypeLayers } from "../shared/pointStyle"; - -export function getFortressLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - void sourceId; - void pathArrowSourceId; - return buildPointGeotypeLayers("fortress", pointSourceId!); -} diff --git a/src/uhm/lib/map/styles/geotypes/invasion_route.ts b/src/uhm/lib/map/styles/geotypes/invasion_route.ts deleted file mode 100644 index c846f75..0000000 --- a/src/uhm/lib/map/styles/geotypes/invasion_route.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { LayerSpecification } from "maplibre-gl"; -import { buildLineGeotypeLayers } from "../shared/styleBuilders"; - -export function getInvasionRouteLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - void pointSourceId; - return buildLineGeotypeLayers(sourceId, pathArrowSourceId, { - typeId: "invasion_route", - color: "#be123c", - strokeColor: "#4c0519", - width: { z1: 2.8, z4: 4.1, z6: 5.4 }, - arrowOpacity: 0.9, - }); -} diff --git a/src/uhm/lib/map/styles/geotypes/kingdom.ts b/src/uhm/lib/map/styles/geotypes/kingdom.ts deleted file mode 100644 index 5c56e05..0000000 --- a/src/uhm/lib/map/styles/geotypes/kingdom.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { LayerSpecification } from "maplibre-gl"; -import { buildPolygonGeotypeLayers } from "../shared/styleBuilders"; - -export function getKingdomLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - void pathArrowSourceId; - void pointSourceId; - return buildPolygonGeotypeLayers(sourceId, { - typeId: "kingdom", - fillColor: "#8b5cf6", - strokeColor: "#6d28d9", - fillOpacity: 0.34, - }); -} diff --git a/src/uhm/lib/map/styles/geotypes/attack_route.ts b/src/uhm/lib/map/styles/geotypes/military_route.ts similarity index 67% rename from src/uhm/lib/map/styles/geotypes/attack_route.ts rename to src/uhm/lib/map/styles/geotypes/military_route.ts index 0ae1cff..5eb8431 100644 --- a/src/uhm/lib/map/styles/geotypes/attack_route.ts +++ b/src/uhm/lib/map/styles/geotypes/military_route.ts @@ -1,10 +1,10 @@ import { LayerSpecification } from "maplibre-gl"; import { buildLineGeotypeLayers } from "../shared/styleBuilders"; -export function getAttackRouteLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { +export function getMilitaryRouteLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { void pointSourceId; return buildLineGeotypeLayers(sourceId, pathArrowSourceId, { - typeId: "attack_route", + typeId: "military_route", color: "#ef4444", strokeColor: "#7f1d1d", width: { z1: 2.6, z4: 3.8, z6: 5 }, diff --git a/src/uhm/lib/map/styles/geotypes/person_activity.ts b/src/uhm/lib/map/styles/geotypes/person_activity.ts deleted file mode 100644 index 1a0c150..0000000 --- a/src/uhm/lib/map/styles/geotypes/person_activity.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { LayerSpecification } from "maplibre-gl"; -import { buildPointGeotypeLayers } from "../shared/pointStyle"; - -export function getPersonActivityLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - 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 deleted file mode 100644 index 75f09be..0000000 --- a/src/uhm/lib/map/styles/geotypes/person_birthplace.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { LayerSpecification } from "maplibre-gl"; -import { buildPointGeotypeLayers } from "../shared/pointStyle"; - -export function getPersonBirthplaceLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - 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 deleted file mode 100644 index 3fd5e15..0000000 --- a/src/uhm/lib/map/styles/geotypes/person_deathplace.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { LayerSpecification } from "maplibre-gl"; -import { buildPointGeotypeLayers } from "../shared/pointStyle"; - -export function getPersonDeathplaceLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - void sourceId; - void pathArrowSourceId; - return buildPointGeotypeLayers("person_deathplace", pointSourceId!); -} diff --git a/src/uhm/lib/map/styles/geotypes/person_event.ts b/src/uhm/lib/map/styles/geotypes/person_event.ts new file mode 100644 index 0000000..ea7ab06 --- /dev/null +++ b/src/uhm/lib/map/styles/geotypes/person_event.ts @@ -0,0 +1,8 @@ +import { LayerSpecification } from "maplibre-gl"; +import { buildPointGeotypeLayers } from "../shared/pointStyle"; + +export function getPersonEventLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { + void sourceId; + void pathArrowSourceId; + return buildPointGeotypeLayers("person_event", pointSourceId!); +} diff --git a/src/uhm/lib/map/styles/geotypes/refugee_route.ts b/src/uhm/lib/map/styles/geotypes/refugee_route.ts deleted file mode 100644 index a72e8e8..0000000 --- a/src/uhm/lib/map/styles/geotypes/refugee_route.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { LayerSpecification } from "maplibre-gl"; -import { buildLineGeotypeLayers } from "../shared/styleBuilders"; - -export function getRefugeeRouteLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - void pointSourceId; - return buildLineGeotypeLayers(sourceId, pathArrowSourceId, { - typeId: "refugee_route", - color: "#f97316", - strokeColor: "#9a3412", - dasharray: [1, 2], - opacity: 0.84, - arrowOpacity: 0.72, - }); -} diff --git a/src/uhm/lib/map/styles/geotypes/shipping_route.ts b/src/uhm/lib/map/styles/geotypes/shipping_route.ts deleted file mode 100644 index 49a283d..0000000 --- a/src/uhm/lib/map/styles/geotypes/shipping_route.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { LayerSpecification } from "maplibre-gl"; -import { buildLineGeotypeLayers } from "../shared/styleBuilders"; - -export function getShippingRouteLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - void pointSourceId; - return buildLineGeotypeLayers(sourceId, pathArrowSourceId, { - typeId: "shipping_route", - color: "#0ea5e9", - strokeColor: "#075985", - width: { z1: 2.4, z4: 3.5, z6: 4.7 }, - dasharray: [7, 4], - arrowOpacity: 0.8, - }); -} diff --git a/src/uhm/lib/map/styles/geotypes/war.ts b/src/uhm/lib/map/styles/geotypes/war.ts deleted file mode 100644 index 36ef630..0000000 --- a/src/uhm/lib/map/styles/geotypes/war.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { LayerSpecification } from "maplibre-gl"; -import { buildPolygonGeotypeLayers } from "../shared/styleBuilders"; - -export function getWarLayers(sourceId: string, pathArrowSourceId?: string, pointSourceId?: string): LayerSpecification[] { - void pathArrowSourceId; - void pointSourceId; - return buildPolygonGeotypeLayers(sourceId, { - typeId: "war", - fillColor: "#dc2626", - strokeColor: "#7f1d1d", - fillOpacity: 0.26, - dasharray: [5, 2], - }); -} diff --git a/src/uhm/lib/map/styles/shared/pointStyle.ts b/src/uhm/lib/map/styles/shared/pointStyle.ts index 3748d80..99d304a 100644 --- a/src/uhm/lib/map/styles/shared/pointStyle.ts +++ b/src/uhm/lib/map/styles/shared/pointStyle.ts @@ -2,30 +2,23 @@ import maplibregl, { LayerSpecification } from "maplibre-gl"; import { MAP_EMPHASIS_TEXT_FONT_STACK } from "./textFonts"; export const POINT_GEOTYPE_IDS = [ - "person_birthplace", - "person_deathplace", - "person_activity", + "person_event", "temple", "capital", "city", - "fortress", - "castle", + "fortification", "ruin", "port", - "bridge", ] as const; export type PointGeotypeId = (typeof POINT_GEOTYPE_IDS)[number]; export const POINT_GEOTYPE_ICON_PATHS: Partial> = { - person_birthplace: "/images/mapIcon/point/house.png", - person_deathplace: "/images/mapIcon/point/tombstone.png", - person_activity: "/images/mapIcon/point/flag.png", + person_event: "/images/mapIcon/point/flag.png", temple: "/images/mapIcon/point/temple.png", capital: "/images/mapIcon/point/capital.png", city: "/images/mapIcon/point/city.png", - fortress: "/images/mapIcon/point/fortress.png", - castle: "/images/mapIcon/point/castle.png", + fortification: "/images/mapIcon/point/castle.png", ruin: "/images/mapIcon/point/ruin.png", }; @@ -57,21 +50,7 @@ const POINT_GEOMETRY_FILTER: maplibregl.ExpressionSpecification = [ ]; const POINT_STYLE_CONFIG: Record = { - person_birthplace: { - fill: "#22c55e", - rim: "#166534", - iconScale: 1, - haloRadius: 15, - drawGlyph: drawHouseGlyph, - }, - person_deathplace: { - fill: "#b91c1c", - rim: "#450a0a", - iconScale: 1, - haloRadius: 15, - drawGlyph: drawMemorialGlyph, - }, - person_activity: { + person_event: { fill: "#f97316", rim: "#9a3412", iconScale: 0.98, @@ -99,14 +78,7 @@ const POINT_STYLE_CONFIG: Record = { haloRadius: 15, drawGlyph: drawCityGlyph, }, - fortress: { - fill: "#64748b", - rim: "#334155", - iconScale: 1.04, - haloRadius: 16, - drawGlyph: drawShieldGlyph, - }, - castle: { + fortification: { fill: "#7c3aed", rim: "#4c1d95", iconScale: 1.04, @@ -127,13 +99,6 @@ const POINT_STYLE_CONFIG: Record = { haloRadius: 15, drawGlyph: drawAnchorGlyph, }, - bridge: { - fill: "#b45309", - rim: "#7c2d12", - iconScale: 1, - haloRadius: 14, - drawGlyph: drawBridgeGlyph, - }, }; export function buildPointGeotypeLayers( @@ -320,53 +285,9 @@ function drawGlyphWithOutline( ctx.restore(); } -function drawHouseGlyph(ctx: CanvasRenderingContext2D) { - const img = preloadedImages["person_birthplace"]; - if (img && loadedImageKeys.has("person_birthplace")) { - ctx.drawImage(img, 0, 0, ICON_CANVAS_SIZE, ICON_CANVAS_SIZE); - } else { - ctx.lineWidth = 3.5; - ctx.beginPath(); - ctx.moveTo(22, 34); - ctx.lineTo(32, 24); - ctx.lineTo(42, 34); - ctx.stroke(); - - ctx.beginPath(); - ctx.rect(25.5, 34, 13, 9); - ctx.stroke(); - - ctx.beginPath(); - ctx.moveTo(32, 43); - ctx.lineTo(32, 36.5); - ctx.stroke(); - } -} - -function drawMemorialGlyph(ctx: CanvasRenderingContext2D) { - const img = preloadedImages["person_deathplace"]; - if (img && loadedImageKeys.has("person_deathplace")) { - ctx.drawImage(img, 0, 0, ICON_CANVAS_SIZE, ICON_CANVAS_SIZE); - } else { - ctx.lineWidth = 3.6; - ctx.beginPath(); - ctx.moveTo(32, 22); - ctx.lineTo(32, 43); - ctx.moveTo(25, 28.5); - ctx.lineTo(39, 28.5); - ctx.stroke(); - - ctx.lineWidth = 2.4; - ctx.beginPath(); - ctx.moveTo(24, 45); - ctx.lineTo(40, 45); - ctx.stroke(); - } -} - function drawFlagGlyph(ctx: CanvasRenderingContext2D) { - const img = preloadedImages["person_activity"]; - if (img && loadedImageKeys.has("person_activity")) { + const img = preloadedImages["person_event"]; + if (img && loadedImageKeys.has("person_event")) { ctx.drawImage(img, 0, 0, ICON_CANVAS_SIZE, ICON_CANVAS_SIZE); } else { ctx.lineWidth = 3.2; @@ -462,32 +383,9 @@ function drawCityGlyph(ctx: CanvasRenderingContext2D) { } } -function drawShieldGlyph(ctx: CanvasRenderingContext2D) { - const img = preloadedImages["fortress"]; - if (img && loadedImageKeys.has("fortress")) { - ctx.drawImage(img, 0, 0, ICON_CANVAS_SIZE, ICON_CANVAS_SIZE); - } else { - ctx.lineWidth = 3.2; - ctx.beginPath(); - ctx.moveTo(32, 22.5); - ctx.lineTo(41, 26.5); - ctx.lineTo(39, 37.5); - ctx.lineTo(32, 43); - ctx.lineTo(25, 37.5); - ctx.lineTo(23, 26.5); - ctx.closePath(); - ctx.stroke(); - - ctx.beginPath(); - ctx.moveTo(32, 25); - ctx.lineTo(32, 39); - ctx.stroke(); - } -} - function drawCastleGlyph(ctx: CanvasRenderingContext2D) { - const img = preloadedImages["castle"]; - if (img && loadedImageKeys.has("castle")) { + const img = preloadedImages["fortification"]; + if (img && loadedImageKeys.has("fortification")) { ctx.drawImage(img, 0, 0, ICON_CANVAS_SIZE, ICON_CANVAS_SIZE); } else { ctx.lineWidth = 3; diff --git a/src/uhm/lib/map/styles/style.ts b/src/uhm/lib/map/styles/style.ts index 31b420c..f27ccb4 100644 --- a/src/uhm/lib/map/styles/style.ts +++ b/src/uhm/lib/map/styles/style.ts @@ -27,50 +27,34 @@ export const COUNTRY_FILL_COLOR_EXPRESSION: maplibregl.ExpressionSpecification = export const POLYGON_FILL_BY_TYPE: Record = { country: "#2563eb", state: "#0ea5e9", - empire: "#f59e0b", - kingdom: "#d97706", - war: "#dc2626", battle: "#f43f5e", - civilization: "#14b8a6", rebellion_zone: "#7c3aed", }; export const POLYGON_STROKE_BY_TYPE: Record = { country: "#1e3a8a", state: "#0c4a6e", - empire: "#7c2d12", - kingdom: "#9a3412", - war: "#7f1d1d", battle: "#9f1239", - civilization: "#134e4a", rebellion_zone: "#4c1d95", }; export const POLYGON_OPACITY_BY_TYPE: Record = { - war: 0.3, battle: 0.34, - civilization: 0.38, rebellion_zone: 0.32, }; export const LINE_COLOR_BY_TYPE: Record = { defense_line: "#f97316", - attack_route: "#ef4444", + military_route: "#ef4444", retreat_route: "#94a3b8", - invasion_route: "#b91c1c", migration_route: "#0ea5e9", - refugee_route: "#06b6d4", trade_route: "#eab308", - shipping_route: "#2563eb", }; export const PATH_RENDER_BY_TYPE: Record = { - attack_route: true, + military_route: true, retreat_route: true, - invasion_route: true, migration_route: true, - refugee_route: true, trade_route: true, - shipping_route: true, };