refactor: rename entity type configuration to geometry type and relocate to dedicated map utilities.
This commit is contained in:
@@ -31,8 +31,8 @@ import {
|
||||
HIDDEN_BACKGROUND_LAYER_VISIBILITY,
|
||||
} from "@/uhm/lib/map/styles/backgroundLayers";
|
||||
import {
|
||||
ENTITY_TYPE_OPTIONS,
|
||||
} from "@/uhm/lib/utils/entityTypeOptions";
|
||||
GEOMETRY_TYPE_OPTIONS,
|
||||
} from "@/uhm/lib/map/geo/geometryTypeOptions";
|
||||
import {
|
||||
EntityFormState,
|
||||
GeometryMetaFormState,
|
||||
@@ -1560,7 +1560,7 @@ export default function Page() {
|
||||
entities={entities}
|
||||
selectedGeometryEntityIds={selectedGeometryEntityIds}
|
||||
onEntityIdsChange={handleEntityIdsChange}
|
||||
entityTypeOptions={ENTITY_TYPE_OPTIONS}
|
||||
entityTypeOptions={GEOMETRY_TYPE_OPTIONS}
|
||||
geometryMetaForm={geometryMetaForm}
|
||||
onGeometryMetaFormChange={handleGeometryMetaFormChange}
|
||||
isEntitySubmitting={isEntitySubmitting}
|
||||
|
||||
@@ -4,12 +4,12 @@ import { type CSSProperties, useMemo, useState } from "react";
|
||||
import { Entity } from "@/uhm/api/entities";
|
||||
import { Feature } from "@/uhm/lib/editor/state/useEditorState";
|
||||
import {
|
||||
EntityGeometryPreset,
|
||||
EntityTypeGroupId,
|
||||
EntityTypeOption,
|
||||
findEntityTypeOption,
|
||||
groupEntityTypeOptions,
|
||||
} from "@/uhm/lib/utils/entityTypeOptions";
|
||||
GeometryPreset,
|
||||
GeometryTypeGroupId,
|
||||
GeometryTypeOption,
|
||||
findGeometryTypeOption,
|
||||
groupGeometryTypeOptions,
|
||||
} from "@/uhm/lib/map/geo/geometryTypeOptions";
|
||||
import type { GeometryMetaFormState } from "@/uhm/lib/editor/session/sessionTypes";
|
||||
|
||||
type Props = {
|
||||
@@ -19,7 +19,7 @@ type Props = {
|
||||
entities: Entity[];
|
||||
selectedGeometryEntityIds: string[];
|
||||
onEntityIdsChange: (values: string[]) => void;
|
||||
entityTypeOptions: EntityTypeOption[];
|
||||
entityTypeOptions: GeometryTypeOption[];
|
||||
geometryMetaForm: GeometryMetaFormState;
|
||||
onGeometryMetaFormChange: (key: keyof GeometryMetaFormState, value: string) => void;
|
||||
isEntitySubmitting: boolean;
|
||||
@@ -81,13 +81,13 @@ export default function SelectedGeometryPanel({
|
||||
if (!selectedFeatures || selectedFeatures.length === 0) return null;
|
||||
const representativeFeature = selectedFeatures[0];
|
||||
|
||||
const groupedEntityTypeOptions = groupEntityTypeOptions(entityTypeOptions);
|
||||
const groupedGeometryTypeOptions = groupGeometryTypeOptions(entityTypeOptions);
|
||||
const featureGeometryPreset = resolveFeatureGeometryPreset(representativeFeature);
|
||||
const allowedGroupIds = getAllowedGroupIdsForPreset(featureGeometryPreset);
|
||||
const groupedGeoTypeOptions = groupedEntityTypeOptions.filter((group) =>
|
||||
const groupedGeoTypeOptions = groupedGeometryTypeOptions.filter((group) =>
|
||||
allowedGroupIds.includes(group.id)
|
||||
);
|
||||
const selectedTypeOption = findEntityTypeOption(geometryMetaForm.type_key);
|
||||
const selectedTypeOption = findGeometryTypeOption(geometryMetaForm.type_key);
|
||||
const hasCurrentVisibleTypeOption = groupedGeoTypeOptions.some((group) =>
|
||||
group.options.some((option) => option.value === geometryMetaForm.type_key)
|
||||
);
|
||||
@@ -342,20 +342,20 @@ function MinusIcon() {
|
||||
);
|
||||
}
|
||||
|
||||
function resolveFeatureGeometryPreset(feature: Feature): EntityGeometryPreset {
|
||||
function resolveFeatureGeometryPreset(feature: Feature): GeometryPreset {
|
||||
const explicitPreset = normalizeGeometryPreset(feature.properties.geometry_preset);
|
||||
if (explicitPreset) return explicitPreset;
|
||||
|
||||
const semanticType = normalizeTypeId(feature.properties.type) || normalizeTypeId(feature.properties.entity_type_id);
|
||||
if (semanticType) {
|
||||
const option = findEntityTypeOption(semanticType);
|
||||
const option = findGeometryTypeOption(semanticType);
|
||||
if (option) return option.geometryPreset;
|
||||
}
|
||||
|
||||
return mapGeometryTypeToPreset(feature.geometry.type);
|
||||
}
|
||||
|
||||
function normalizeGeometryPreset(value: unknown): EntityGeometryPreset | null {
|
||||
function normalizeGeometryPreset(value: unknown): GeometryPreset | null {
|
||||
if (typeof value !== "string") return null;
|
||||
const normalized = value.trim().toLowerCase();
|
||||
if (
|
||||
@@ -377,7 +377,7 @@ function normalizeTypeId(value: unknown): string | null {
|
||||
|
||||
function mapGeometryTypeToPreset(
|
||||
geometryType: Feature["geometry"]["type"]
|
||||
): EntityGeometryPreset {
|
||||
): GeometryPreset {
|
||||
if (geometryType === "Point" || geometryType === "MultiPoint") {
|
||||
return "point";
|
||||
}
|
||||
@@ -388,8 +388,8 @@ function mapGeometryTypeToPreset(
|
||||
}
|
||||
|
||||
function getAllowedGroupIdsForPreset(
|
||||
geometryPreset: EntityGeometryPreset
|
||||
): EntityTypeGroupId[] {
|
||||
geometryPreset: GeometryPreset
|
||||
): GeometryTypeGroupId[] {
|
||||
if (geometryPreset === "point") {
|
||||
return ["point"];
|
||||
}
|
||||
@@ -405,7 +405,7 @@ function getAllowedGroupIdsForPreset(
|
||||
return ["polygon"];
|
||||
}
|
||||
|
||||
function formatGeometryPresetLabel(preset: EntityGeometryPreset | null): string {
|
||||
function formatGeometryPresetLabel(preset: GeometryPreset | null): string {
|
||||
if (preset === "point") return "point - Điểm";
|
||||
if (preset === "line") return "line - Tuyến";
|
||||
if (preset === "circle-area") return "circle - Tròn";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { EntityGeometryPreset } from "@/uhm/lib/utils/entityTypeOptions";
|
||||
import type { GeometryPreset } from "@/uhm/lib/map/geo/geometryTypeOptions";
|
||||
|
||||
export type EditorMode =
|
||||
| "idle"
|
||||
@@ -38,4 +38,4 @@ export type CreatedEntitySummary = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type GeometryPreset = EntityGeometryPreset;
|
||||
export type { GeometryPreset };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DEFAULT_ENTITY_TYPE_ID } from "@/uhm/lib/utils/entityTypeOptions";
|
||||
import { DEFAULT_GEOMETRY_TYPE_ID } from "@/uhm/lib/map/geo/geometryTypeOptions";
|
||||
import { geoTypeCodeToTypeKey, typeKeyToGeoTypeCode } from "@/uhm/lib/map/geo/geoTypeMap";
|
||||
import type { Change } from "@/uhm/lib/editor/draft/editorTypes";
|
||||
import type { EntitySnapshot } from "@/uhm/types/entities";
|
||||
@@ -659,7 +659,7 @@ export function getDefaultTypeIdForFeature(feature: Feature): string {
|
||||
if (preset === "line") return "defense_line";
|
||||
if (preset === "point") return "city";
|
||||
if (preset === "circle-area") return "war";
|
||||
if (preset === "polygon") return DEFAULT_ENTITY_TYPE_ID;
|
||||
if (preset === "polygon") return DEFAULT_GEOMETRY_TYPE_ID;
|
||||
|
||||
const geometryType = feature.geometry.type;
|
||||
if (geometryType === "LineString" || geometryType === "MultiLineString") {
|
||||
@@ -668,7 +668,7 @@ export function getDefaultTypeIdForFeature(feature: Feature): string {
|
||||
if (geometryType === "Point" || geometryType === "MultiPoint") {
|
||||
return "city";
|
||||
}
|
||||
return DEFAULT_ENTITY_TYPE_ID;
|
||||
return DEFAULT_GEOMETRY_TYPE_ID;
|
||||
}
|
||||
|
||||
export function normalizeFeatureEntityIds(feature: Feature): string[] {
|
||||
|
||||
+24
-24
@@ -1,27 +1,27 @@
|
||||
export type EntityTypeGroupId =
|
||||
export type GeometryTypeGroupId =
|
||||
| "line"
|
||||
| "polygon"
|
||||
| "circle"
|
||||
| "point";
|
||||
|
||||
export type EntityGeometryPreset = "line" | "polygon" | "circle-area" | "point";
|
||||
export type GeometryPreset = "line" | "polygon" | "circle-area" | "point";
|
||||
|
||||
export type EntityTypeGroup = {
|
||||
id: EntityTypeGroupId;
|
||||
export type GeometryTypeGroup = {
|
||||
id: GeometryTypeGroupId;
|
||||
label: string;
|
||||
geometryLabel: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
export type EntityTypeOption = {
|
||||
export type GeometryTypeOption = {
|
||||
value: string;
|
||||
label: string;
|
||||
groupId: EntityTypeGroupId;
|
||||
groupId: GeometryTypeGroupId;
|
||||
groupLabel: string;
|
||||
geometryPreset: EntityGeometryPreset;
|
||||
geometryPreset: GeometryPreset;
|
||||
};
|
||||
|
||||
export const ENTITY_TYPE_GROUPS: EntityTypeGroup[] = [
|
||||
export const GEOMETRY_TYPE_GROUPS: GeometryTypeGroup[] = [
|
||||
{
|
||||
id: "line",
|
||||
label: "line - Tuyến",
|
||||
@@ -48,18 +48,18 @@ export const ENTITY_TYPE_GROUPS: EntityTypeGroup[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const GROUP_BY_ID: Record<EntityTypeGroupId, EntityTypeGroup> = {
|
||||
line: ENTITY_TYPE_GROUPS[0],
|
||||
polygon: ENTITY_TYPE_GROUPS[1],
|
||||
circle: ENTITY_TYPE_GROUPS[2],
|
||||
point: ENTITY_TYPE_GROUPS[3],
|
||||
const GROUP_BY_ID: Record<GeometryTypeGroupId, GeometryTypeGroup> = {
|
||||
line: GEOMETRY_TYPE_GROUPS[0],
|
||||
polygon: GEOMETRY_TYPE_GROUPS[1],
|
||||
circle: GEOMETRY_TYPE_GROUPS[2],
|
||||
point: GEOMETRY_TYPE_GROUPS[3],
|
||||
};
|
||||
|
||||
const RAW_ENTITY_TYPE_OPTIONS: Array<{
|
||||
const RAW_GEOMETRY_TYPE_OPTIONS: Array<{
|
||||
value: string;
|
||||
label: string;
|
||||
groupId: EntityTypeGroupId;
|
||||
geometryPreset: EntityGeometryPreset;
|
||||
groupId: GeometryTypeGroupId;
|
||||
geometryPreset: GeometryPreset;
|
||||
}> = [
|
||||
{ value: "defense_line", label: "Defense Line", groupId: "line", geometryPreset: "line" },
|
||||
|
||||
@@ -94,29 +94,29 @@ const RAW_ENTITY_TYPE_OPTIONS: Array<{
|
||||
{ value: "bridge", label: "Bridge", groupId: "point", geometryPreset: "point" },
|
||||
];
|
||||
|
||||
export const ENTITY_TYPE_OPTIONS: EntityTypeOption[] = RAW_ENTITY_TYPE_OPTIONS.map((item) => ({
|
||||
export const GEOMETRY_TYPE_OPTIONS: GeometryTypeOption[] = RAW_GEOMETRY_TYPE_OPTIONS.map((item) => ({
|
||||
...item,
|
||||
groupLabel: GROUP_BY_ID[item.groupId].label,
|
||||
}));
|
||||
|
||||
export const DEFAULT_ENTITY_TYPE_ID = "country";
|
||||
export const DEFAULT_GEOMETRY_TYPE_ID = "country";
|
||||
|
||||
// Gom option theo group để render select phân nhóm.
|
||||
export function groupEntityTypeOptions(options: EntityTypeOption[] = ENTITY_TYPE_OPTIONS): Array<{
|
||||
id: EntityTypeGroupId;
|
||||
export function groupGeometryTypeOptions(options: GeometryTypeOption[] = GEOMETRY_TYPE_OPTIONS): Array<{
|
||||
id: GeometryTypeGroupId;
|
||||
label: string;
|
||||
geometryLabel: string;
|
||||
description: string;
|
||||
options: EntityTypeOption[];
|
||||
options: GeometryTypeOption[];
|
||||
}> {
|
||||
return ENTITY_TYPE_GROUPS.map((group) => ({
|
||||
return GEOMETRY_TYPE_GROUPS.map((group) => ({
|
||||
...group,
|
||||
options: options.filter((option) => option.groupId === group.id),
|
||||
})).filter((group) => group.options.length > 0);
|
||||
}
|
||||
|
||||
// Tìm option theo type id, trả null nếu không tồn tại.
|
||||
export function findEntityTypeOption(typeId: string | null | undefined): EntityTypeOption | null {
|
||||
export function findGeometryTypeOption(typeId: string | null | undefined): GeometryTypeOption | null {
|
||||
if (!typeId) return null;
|
||||
return ENTITY_TYPE_OPTIONS.find((option) => option.value === typeId) || null;
|
||||
return GEOMETRY_TYPE_OPTIONS.find((option) => option.value === typeId) || null;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { EntityGeometryPreset } from "@/uhm/lib/utils/entityTypeOptions";
|
||||
import type { GeometryPreset } from "@/uhm/lib/map/geo/geometryTypeOptions";
|
||||
|
||||
export type Geometry =
|
||||
| { type: "Point"; coordinates: [number, number] }
|
||||
@@ -13,7 +13,7 @@ export type FeatureId = string | number;
|
||||
export type FeatureProperties = {
|
||||
id: FeatureId;
|
||||
type?: string | null;
|
||||
geometry_preset?: EntityGeometryPreset | null;
|
||||
geometry_preset?: GeometryPreset | null;
|
||||
time_start?: number | null;
|
||||
time_end?: number | null;
|
||||
binding?: string[];
|
||||
|
||||
Reference in New Issue
Block a user