From d719d0e1bef32e1b9f066aad3f92e0412828a867 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Tue, 30 Apr 2024 15:59:07 +0200 Subject: [PATCH] Some work on NSI --- src/Logic/Web/NameSuggestionIndex.ts | 80 ++++++++++++++ .../ThemeConfig/Conversion/Validation.ts | 3 + .../Helpers/NameSuggestionIndexInput.svelte | 102 +++++------------- src/test.ts | 4 + 4 files changed, 112 insertions(+), 77 deletions(-) create mode 100644 src/Logic/Web/NameSuggestionIndex.ts diff --git a/src/Logic/Web/NameSuggestionIndex.ts b/src/Logic/Web/NameSuggestionIndex.ts new file mode 100644 index 0000000000..8484631ea2 --- /dev/null +++ b/src/Logic/Web/NameSuggestionIndex.ts @@ -0,0 +1,80 @@ +import * as nsi from "../../../node_modules/name-suggestion-index/dist/nsi.json" +import * as nsiFeatures from "../../../node_modules/name-suggestion-index/dist/featureCollection.json" +import { LocationConflation } from "@rapideditor/location-conflation" +import type { Feature, MultiPolygon } from "geojson" +import * as turf from "@turf/turf" + +/** + * Main name suggestion index file + */ +interface NSIFile { + _meta: { + version: string + generated: string + url: string + hash: string + } + nsi: { + [path: string]: NSIEntry + } +} + +/** + * A collection of brands/operators/flagpoles/... with common properties + * See https://github.com/osmlab/name-suggestion-index/wiki/Category-Files for an introduction and + * https://github.com/osmlab/name-suggestion-index/blob/main/schema/categories.json for a full breakdown + */ +interface NSIEntry { + properties: { + path: string + skipCollection?: boolean + preserveTags?: string[] + exclude: unknown + } + items: NSIItem[] +} + +/** + * Represents a single brand/operator/flagpole/... + */ +export interface NSIItem { + displayName: string + id: string + locationSet: { + include: string[], + exclude: string[] + } + tags: { + [key: string]: string + } + fromTemplate?: boolean +} + +export default class NameSuggestionIndex { + + private static readonly nsiFile: Readonly = nsi + private static loco = new LocationConflation(nsiFeatures) // Some additional boundaries + private static singleton: NameSuggestionIndex + + public static getSuggestionsFor(path: string, country: Set): NSIItem[] { + const entry = NameSuggestionIndex.nsiFile.nsi[path] + return entry.items.filter(i => { + if(i.locationSet.include.indexOf("001") >= 0){ + return true + } + if(i.locationSet.include.some(c => country.indexOf(c) >= 0)){ + return true + } + + const resolvedSet = NameSuggestionIndex.loco.resolveLocationSet(item.locationSet) + if (resolvedSet) { + // We actually have a location set, so we can check if the feature is in it, by determining if our point is inside the MultiPolygon using @turf/boolean-point-in-polygon + // This might occur for some extra boundaries, such as counties, ... + const setFeature: Feature = resolvedSet.feature + return turf.booleanPointInPolygon([lon, lat], setFeature.geometry) + } + + return false + }) + } +} diff --git a/src/Models/ThemeConfig/Conversion/Validation.ts b/src/Models/ThemeConfig/Conversion/Validation.ts index 68ea1ba376..e88311aa87 100644 --- a/src/Models/ThemeConfig/Conversion/Validation.ts +++ b/src/Models/ThemeConfig/Conversion/Validation.ts @@ -1091,6 +1091,9 @@ class MiscTagRenderingChecks extends DesugaringStep { ) } } + if(json.freeform.type === "nsi"){ + throw "Should validate NSI: path should exist" + } } if (json.render && json["question"] && json.freeform === undefined) { context.err( diff --git a/src/UI/InputElement/Helpers/NameSuggestionIndexInput.svelte b/src/UI/InputElement/Helpers/NameSuggestionIndexInput.svelte index 85cc5e81bf..9d7e8e568e 100644 --- a/src/UI/InputElement/Helpers/NameSuggestionIndexInput.svelte +++ b/src/UI/InputElement/Helpers/NameSuggestionIndexInput.svelte @@ -1,24 +1,23 @@