const truthy = new Set(["yes", "true", "1", "designated", "permissive"]); const lockSeamarkTypes = new Set(["lock", "lock_basin", "lock_gate"]); function stringValue(value) { return typeof value === "string" ? value.trim() : ""; } export function normalizedValue(value) { return stringValue(value).toLowerCase(); } export function isLockFeature(properties) { const seamarkType = normalizedValue(properties["seamark:type"]); const seamarkGateCategory = normalizedValue(properties["seamark:gate:category"]); const waterway = normalizedValue(properties.waterway); return ( truthy.has(normalizedValue(properties.lock)) || ["lock", "lock_gate"].includes(waterway) || normalizedValue(properties.water) === "lock" || lockSeamarkTypes.has(seamarkType) || (seamarkType === "gate" && ["lock", "lock_gate"].includes(seamarkGateCategory)) || normalizedValue(properties.obstacle) === "lock" ); } export function sourceId(feature, fallbackIndex, importSource) { const properties = feature.properties ?? {}; const osmId = properties["@id"] ?? properties.osm_id ?? properties.osmId; const osmType = normalizedValue(properties["@type"] ?? properties.osm_type ?? properties.osmType); const osmTypePrefix = { node: "n", way: "w", relation: "r" }[osmType]; const normalizedOsmId = String(osmId ?? "").match(/\d+/)?.[0]; if (osmTypePrefix && normalizedOsmId) { return `${osmTypePrefix}${normalizedOsmId}`; } const rawId = feature.id ?? properties.id ?? fallbackIndex; const rawType = properties.type ?? "osm"; const id = String(rawId); if (id.includes("/") || /^[nwr]\d+$/.test(id)) { return id; } return `${rawType}/${importSource}/${id}`; } export function featureName(properties) { return ( stringValue(properties.lock_name) || stringValue(properties.name) || stringValue(properties["seamark:name"]) || null ); }