diff --git a/docs/docs/administration/services-administration.md b/docs/docs/administration/services-administration.md index 5aa8713d..89363f51 100644 --- a/docs/docs/administration/services-administration.md +++ b/docs/docs/administration/services-administration.md @@ -210,13 +210,23 @@ data workflow is documented in [Preparing data](../install/preparing-data.md). ### OSM code and alias search index The data workflow also operates the local OSM code/alias/acronym index used by -consumer autocomplete. It shows the source region and fingerprint, current +consumer autocomplete. It shows the source region, current build stage, place and term counts, publication epoch and time, whether a newer PBF has made the index stale, and the last error. Building is explicit: select the downloaded region and confirm the operation, or run `openmapx data search-index build [region]`. A new PBF never triggers a country- or planet-scale rebuild during API boot. +A ready index covers the documented aliases/codes/acronyms; it does not establish +ordinary business-name/address coverage. For an investigation, record the +authenticated `/api/data-manager/search-index/status` response's +`sourceFingerprint` and `epoch` as well as the Overture status response's release +and region. The search card's summary does not display the source fingerprint. +Keep unavailable generations unknown and do not rebuild or flush shared caches +to diagnose a query. See the +[business retrieval investigation](../developer/business-name-address-retrieval.md) +for the distinction between source presence and searchable candidates. + The job requires PostGIS and Osmium Tool. It streams records in bounded batches into `osm_search__staging`, builds exact/prefix and geographic indexes, validates counts and referential integrity, then swaps schemas in one database diff --git a/docs/docs/developer/business-name-address-retrieval.md b/docs/docs/developer/business-name-address-retrieval.md new file mode 100644 index 00000000..98f4bf4e --- /dev/null +++ b/docs/docs/developer/business-name-address-retrieval.md @@ -0,0 +1,167 @@ +--- +title: Berlin business name/address retrieval investigation +description: Source identities, reusable regressions and a bounded local lexical evaluation for issue 430. +--- + +# Business name/address retrieval: decision and next steps + +**2026-10-08: GO for staged local lexical development over existing Overture +data; NO-GO for production adoption yet.** The disposable PostgreSQL probe +retrieves Moch without another ingestion source. Combined with saved geocoder +results, verified Hit@3 rises **4/9→8/9**. A mall association gap, three weak +address-query Enter decisions, unknown deployed generations and unmeasured +regional/cold performance remain gates. No application provider/schema, +production data/cache/configuration, ingestion or deployment changed. + +## Reusable inputs and external evidence + +The [regression corpus](https://github.com/OpenMapX/openmapx/tree/main/scripts/discovery-eval/business-name-address) +keeps 13 versioned queries, 52 distinct raw/adapter candidate projections, reviewed +source identities, real-adapter checks and a current-checkout replay. Its README +provides commands, recapture conditions and rights. Inputs were captured on +2026-10-07; these are not today's live provider results. + +Dated dropdowns/status snapshots, timings, repeated per-query lists, historical +rank/Enter outputs and the original report are in the [October 7 capture archive](https://gist.github.com/Medformatik/c36d8b8f44c88971277659512a533a51/8b33cd9238ba743f54f3235f2831470cf3bb5972). +The throwaway code, 3,255-row source projection, SQL plans/costs, current-main +replay/composition and reproduction instructions are in the [October 8 lexical +probe archive](https://gist.github.com/Medformatik/3fdd91df857e72bf3a492836324f3c69/4f458cce9bdcce34cb335881e91c56a5bbf781e1). Both commit permalinks have checksum manifests and +attribution. Full raw operator files/screenshots/test logs were temporary; no +public durable archive is claimed for them. Prior Git history is preserved. + +| Input/condition | Pin or limitation | +| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Initial source/replay | Main `3c80939d26a09f131b16d849895255436b5e5798` | +| Current-main replay/composition | Freshly fetched `fe6b7969979ae024655e38d3b4f605295e757f93`, clean source export; #432 included; #429/#438 evaluated separately below | +| Captured query context | EN, Berlin `[13.416,52.5194]`, zoom 15; upstream rounded `[13.42,52.52]`, MapTiler limit 6/autocomplete/types including POI, aggregate limit 8 | +| Public deployment/provider/cache | Unknown deployment SHA, provider generation/chain, OSM extract, active Overture generation and cache history; authenticated status 401. Enabled registry does not prove health/data/capability bindings | +| OSM | API bbox/direct versioned elements, not deployed data or a regional PBF; Overpass failed before API fallback | +| Overture | Dated release `2026-09-23.1`, bbox `[13.408,52.513,13.426,52.527]`, 3,255 rows; export SHA256 `a9ec6402ecd390d6200151ace4d5a5a7106d1ca8641652e19dd336211684ba93`; STAC 403, explicit release readable | +| Live UI | Separate dated anonymous capture, 1280×800/DPR1/dark/fixed Berlin camera; 13 lists/two Enter observations. No prototype UI or application-only comparison | + +## Identity and source presence + +[Official Moch](https://www.edeka.de/maerkte/408935/) verifies Grunerstr. 20, +10179 Berlin, phone +493024045625; rechecked 2026-10-08. Its point is a listing +location, not a surveyed entrance. Shared mall address/proximity/brand cannot +establish exact tenant identity. + +| Entity | Evidence and judgment | +| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Moch/Overture | **Present, verified listing:** GERS `035b544e-40f5-4ce0-a06f-1c9032ded028` v13, matching name/address/phone; Meta 194804870560113 updated2026-08-24. Operating status null=unknown | +| OSM EDEKA room | **Present, operator unresolved:** way 1204762785 v3, supermarket/indoor/level −1/name EDEKA; no operator/contact/street/number. Exact Moch attributes absent in inspected mall records, not globally absent OSM | +| Alexanderstraße 25 result | MapTiler `poi.39267497` references that same way, which does not assert this address; Nominatim gives Alexanderstraße without house number. **Address inference/identity ambiguity**, neither a verified other branch nor confirmed Moch | +| MediaMarkt | OSM node 322490364 v24 at Grunerstraße 20, branch-specific website. GERS `bfbe5e1d-7db5-482e-8772-f53959dde008` v9 and `81270f18-8f0b-48a9-ae69-31d4ef96cdd5` v8 describe the mall branch: duplicate judgment must retain IDs/credits. Espressobar `337b556d-d0d0-4c38-a81b-c92bc326eba1` is a separately named tenant | +| Schaaf alternative | Dated official profile 407497, Schillingstr. 2/phone +493023458611, OSM node 9154787137 v13 and GERS `a56cd442-edcf-4d26-98c1-9c70de50f1d7` v11 agree. Raw MapTiler references the node but formats Singerstraße 121. Official profile recheck 404 on October 8 leaves current operation unknown, not proven closed | +| REWE | Dated official profile 1350030/OSM node 348000444 v29 verify Invalidenstraße 158. Overture **unknown**, outside inspected bbox | +| Deployed copies | **Unknown** for every source-presence judgment; no production DB access | + +Provenance/licenses remain separate from code licensing: MapTiler terms, OSM +ODbL, Overture/Meta CDLA-Permissive 2.0, Foursquare Apache 2.0 and contributor CC0 +where recorded. No ATP coverage claim/new-source requirement. If an intended +generation lacks Moch, inspect release/import filters before proposing enrichment. + +## Separate retrieval, adaptation, ranking and selection + +Raw MapTiler and independently captured adapted rows have the same 78 candidates +and ID order across 13 queries: the adapter does not cause Moch's omission. All +aggregate replies were empty/partial: unavailable retrieval, not source absence. +Initial combined 78→ranked 65 losses happen after retrieval. The OSM index covers +aliases/codes/acronyms, skipping ordinary business names; Overture exposes category +search rather than named-business candidates; Overpass matches whole query against +name without address decomposition. Code: `integrations/geocoding-maptiler/provider.ts`, +`services/data-manager/src/jobs/search-index/{terms,extract}.ts`, +`integrations/poi-overture/index.ts`, `packages/core/src/utils/overpass.service.ts`, +`integrations/search-suggestions/orchestrator.ts`, shared `suggestionRanking.ts`. + +| Offline layer/run | Verified Hit@3 | Interpretation | +| ----------------------------------------- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Saved raw/adapted/combined | 4/9 | Five Moch variants have no confirmed exact tenant; three have unresolved possible matches | +| Same pool, initial/current-main ranker | 4/9→4/9 | #432 puts Berlin MediaMarkt above Rijswijk; Enter becomes weak/search instead of opening Rijswijk. EDEKA Alexa also becomes weak/search. Total 65 rows unchanged | +| Local lexical candidates | 7/8 inspected-source positives | Four Moch variants, two MediaMarkt variants and Schaaf; REWE outside bbox excluded from this denominator, not called absent | +| Lexical+saved adapter/current-main ranked | 8/9 | Combined 90→ranked 75; EDEKA Alexa stays missing. Both lexical negatives return 0; geocoder address/area fallback remains | + +Moch ranks first for four retrieved variants. Enter opens it for `EDEKA Moch`, +but remains weak/search for `EDEKA Moch Grunerstraße 20`, `EDEKA Grunerstraße 20 +Berlin` and `EDEKA Grunerstraße`: selection-policy gaps despite retrieval success. +Explicit Alexanderstraße still opens the unresolved provider row and stays +unjudged. Offline outputs are not observed new live navigation. + +## Separately pinned #429/#438 comparison + +[PR #438](https://github.com/OpenMapX/openmapx/pull/438) head +`dadd03d5339ad65b64de7a8240054d3befacd10c` was evaluated against its verified +ancestor `5f07b70967319b4b2c86769b542b551b93f98e02`, using clean task-owned source +exports and identical input pools. Fresh main +`9b212363ba891e97ac4a19c080a10bbc0e343cbd` produces the same traces as that base. +No other task's branch/worktree was changed; #438 is unmerged in this comparison. + +Geocoder candidates stay78 but ranked rows rise65→78; lexical+geocoder candidates +stay90 but ranked rows rise75→90. All candidates survive shared ranking in these +small pools. Verified Hit@3 stays4/9 and8/9 respectively; every Enter action is +unchanged. This is deduplication preservation, not new upstream/local retrieval. +The two MediaMarkt GERS rows and MapTiler branch now remain separate until +corroborated cross-source identity. Duplicate handling remains an integration +gate; the missing Alexa association and three weak Moch address selections remain. +The archive contains separate base/head/current-main traces and recomputed counts. + +## Local probe and bounded integration rules + +Throwaway SQL normalizes case/diacritics/German street spellings; decomposes name +and same-address street requirements, a separate house-number field and separate +locality tokens; permits only ≥3-character final +name prefixes; excludes permanent closure while retaining unknown status. Wrong +operator/house/city cannot fall through to that business. Whole/leading business +names precede tenants merely mentioning them. An initial Espressobar-first result +was reproduced by a failing DB check and corrected. GERS candidates remain distinct +before ranking: no invented mall alias or cross-source link. A review reproduced +postcode-as-house substitution; separate address roles now reject it and region-as-city +substitution. Trailing single house numbers/suffixes are supported; ranges and +general address parsing, +brand+city without street, multilingual matching and mall associations remain incomplete. + +| Measured local cost | Result/conditions | +| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Database | PostgreSQL 18.6/PostGIS 3.6.4/aarch64; image `ghcr.io/baosystems/postgis@sha256:f5d625d4263fd9e9a90033951619c2707734a04abbce41ade91522f3428e42d9`; network disabled, own tmpfs 256 MiB, 2 CPU/512 MiB | +| Import/index build | 1.60s/0.16s including Docker/psql overhead; 3,255 places+3,255 addresses | +| Table/index bytes | 2,392,064/1,056,768 across both tables | +| Memory | Whole-container cgroup peak 300,068,864 bytes over probe session, not process peak RSS | +| Warm SQL p95 | 0.205–3.396ms per-query range; 20 EXPLAIN ANALYZE/BUFFERS repeats/query, nearest-rank p95; warmed by import/earlier calls | +| Warm command p95 | 67.8–94.0ms including Docker exec/psql startup; not application/provider latency | +| Plans/cold/scale | Selective bitmap indexes; broad EDEKA includes sequential scans. LIMIT caps candidates, not scanned rows. OS-cold/regional/production costs unknown; shared host load uncontrolled | + +Follow-up: an isolated regional lexical index over existing imports, retaining the +specialized alias index; acquire≤30/output≤8 (combined API 8/hard 20/UI 10), one SQL +operation/300ms DB deadline within existing 1,200 ms provider deadline, no remote +candidate enrichment. Proposed provider p95 cold≤500ms/warm≤150ms and interaction +cold≤5000ms/warm≤2000ms remain **unproven**. Cache by release/index epoch/query/ +language/region/proximity; test both orders/cold/warm. Unready/timeout reports +partial/unavailable with geocoder fallback; do not cache failures as authoritative misses. + +Use existing `SearchSuggestion`: `id=overture:`, `ids.overture`, actual +source name/address/coordinates, provider, matched name, neutral importance. Keep +structured provenance/release/address in audit rows, credits in attributions; +selection requires `poi-overture` resolver/PostGIS ready on the same generation. +Brand IDs/proximity/shared addresses/switchboards cannot alone merge branches. +Conflicts stay separate; verified links retain IDs/credits. Missing selection +must not silently substitute another branch. + +## Validation, admin inspection and remaining work + +Compact corpus: 14 real-adapter/term-extractor checks. Probe: 10 normalization/SQL +checks plus 15 transactional DB checks for identities, negatives, abbreviations, +boundaries, branches/tenants, permanent/unknown closure, remote address, same-address +consistency, postcode/region role confusion, caps, injection and timeout. Focused/types/lint/docs/CI recorded in PR. + +Existing admin workflows expose Overture release/region/counts and search-index +epoch/publication/staleness. Fingerprint is available in authenticated status, +not the card summary. Ready alias-index/healthy Overture does not establish business +lexical coverage. Documentation corrected; no admin behavior/shared caches changed. + +Next: review separately owned #438/#429; +address verified name+address Enter intent while retaining unknown-identity guards; +resolve or retain the EDEKA Alexa gap; inspect intended generation/resolver and +measure regional/cold/warm resource costs. Promotion requires 9/9 verified positives +in top 3, zero wrong-branch/false exact negatives, branch preservation and controlled +fallback/latency. No production feature, embeddings, ATP pipeline, global rollout, +merge or deployment is authorized by this evaluation. diff --git a/docs/docs/developer/discovery-evaluation.md b/docs/docs/developer/discovery-evaluation.md index 46d2cc81..2711eb80 100644 --- a/docs/docs/developer/discovery-evaluation.md +++ b/docs/docs/developer/discovery-evaluation.md @@ -10,6 +10,12 @@ connects existing semantic search fixtures, conflation guards, Overture gates, place-card and selected-sheet contracts and navigation replays. It does not turn synthetic tests into evidence of current regional coverage or installed-device readiness. +For business-name/address retrieval, see the +[Berlin EDEKA investigation](business-name-address-retrieval.md). It compares +independent raw, adapted, combined, ranked and live UI evidence and uses stable +source identities. The pilot's label/radius score alone cannot verify a nearby +same-brand tenant or resolve a conflicting returned address. + ## Run and compare From the repository root: diff --git a/knip.jsonc b/knip.jsonc index fcaded21..4029eb0a 100644 --- a/knip.jsonc +++ b/knip.jsonc @@ -9,6 +9,7 @@ "workspaces": { ".": { "entry": [ + "scripts/discovery-eval/business-name-address/replay.ts", "scripts/check-dockerfile-workspace-sync.ts", "scripts/check-credential-keys.ts", "scripts/check-feed-ids.ts", diff --git a/scripts/discovery-eval/business-name-address/README.md b/scripts/discovery-eval/business-name-address/README.md new file mode 100644 index 00000000..561618f3 --- /dev/null +++ b/scripts/discovery-eval/business-name-address/README.md @@ -0,0 +1,57 @@ +# Business name/address regression corpus + +Reusable inputs from [#430](https://github.com/OpenMapX/openmapx/issues/430). +See the [findings and follow-up](../../../docs/docs/developer/business-name-address-retrieval.md). +This directory implements no search provider or ingestion process. + +- `queries-v1.json`: 13 frozen queries, expected identities/negatives and budgets. + Alexanderstraße remains unresolved, outside exact-business recall. +- `responses-v1.json`: 52 distinct selected raw MapTiler features and adapted rows, + reused by ID across queries. Fixed inputs captured 2026-10-07; neither projection + is a full payload or a claim about today's provider/deployment. +- `sources-v1.json`: compact reviewed OSM/Overture identity/provenance records. + A shared mall address or brand is not a verified business cross-link. +- `evidence.test.ts`: real-adapter identity/order parity and specialized OSM + term-extractor behavior. Tests do not freeze historical ranking or UI state. +- `replay.ts`: current-checkout place-only combination/ranking/Enter comparison + over fixed inputs. It reports its own revision/dirty state. The historical + aggregate was empty/partial; absence from it proves no source gap. Shortcuts, + recents and actual UI observations are separate evidence. + +```sh +pnpm exec vitest run scripts/discovery-eval/business-name-address/evidence.test.ts +pnpm exec tsc -p scripts/discovery-eval/business-name-address/tsconfig.json +pnpm -C packages/cli exec tsx ../../scripts/discovery-eval/business-name-address/replay.ts \ + --out /tmp/business-retrieval-replay.json +``` + +## External captures and recapture + +The [dated capture archive](https://gist.github.com/Medformatik/c36d8b8f44c88971277659512a533a51/8b33cd9238ba743f54f3235f2831470cf3bb5972) preserves historical request parameters, +response hashes/timings, full selected per-query lists, source acquisition details, +UI observations, status limitations and the original report. `checksums.json` +binds its exact bytes. These remain audit records rather than CI expectations. +The report links the reviewed 2026-10-08 lexical probe, its disposable container +command, measured costs and remaining adoption gates. Full raw operator +files and execution logs were temporary and are not a durable public artifact. + +For recapture, use query file order. Fetch raw MapTiler and public adapter/aggregate +layers independently. Match the adapter's rounded `[13.42,52.52]` upstream anchor; +EN, zoom 15, MapTiler limit 6/autocomplete true/types including POI, aggregate +limit 8. Use an operator-owned key; never print or store it. Capture timestamps, +parameters, status and byte hashes before projection. Record remote deployment, +provider/generation and cache conditions separately, unknown when unavailable. +Use isolated caches for cold/warm claims. Freeze a new version for changed +judgments; do not replace historical fixtures with live responses. + +## Source credits and rights + +© MapTiler, © OpenStreetMap contributors. MapTiler search results remain subject +to [MapTiler Cloud terms](https://www.maptiler.com/terms/cloud/), including export +permission in section 6.4 and database attribution in section 6.3. OSM: © +OpenStreetMap contributors, [ODbL-1.0](https://www.openstreetmap.org/copyright). +Overture/Meta: [CDLA-Permissive-2.0](https://cdla.dev/permissive-2-0/). Foursquare: +[Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0), copyright Foursquare Labs. +Selected source records retain applicable dataset/license IDs. External samples +are not relicensed as application code; official retailer pages establish +identity facts, not permission to redistribute their pages or photos. diff --git a/scripts/discovery-eval/business-name-address/evidence.test.ts b/scripts/discovery-eval/business-name-address/evidence.test.ts new file mode 100644 index 00000000..e77d85bc --- /dev/null +++ b/scripts/discovery-eval/business-name-address/evidence.test.ts @@ -0,0 +1,63 @@ +import { readFileSync } from "node:fs"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import { + maptilerGeocodingService, + setMaptilerApiKey, +} from "../../../integrations/geocoding-maptiler/provider.js"; +import { extractTerms } from "../../../services/data-manager/src/jobs/search-index/terms.js"; + +function read(name: string) { + return JSON.parse(readFileSync(new URL(name, import.meta.url), "utf8")); +} +const queries = read("queries-v1.json"); +const responses = read("responses-v1.json"); +const sources = read("sources-v1.json"); + +afterEach(() => { + setMaptilerApiKey(undefined); + vi.unstubAllGlobals(); +}); + +describe("business name/address adapter regression corpus", () => { + for (const entry of responses.cases) { + it(`${entry.caseId}: preserves every captured candidate and its displayed identity`, async () => { + const query = queries.cases.find((c: { id: string }) => c.id === entry.caseId); + const features = entry.rawIds.map((id: string) => { + const feature = responses.features.find((f: { raw: { id: string } }) => f.raw.id === id); + if (!feature) throw new Error("Missing regression candidate"); + return feature; + }); + const fetch = vi + .fn() + .mockResolvedValue( + Response.json({ features: features.map((f: { raw: unknown }) => f.raw) }), + ); + vi.stubGlobal("fetch", fetch); + setMaptilerApiKey("fixture-only"); + const adapted = await maptilerGeocodingService.autocomplete(query.query, queries.language, { + proximity: queries.upstreamProximity, + zoom: queries.zoom, + }); + const fields = (r: { + id: string; + label: string; + sublabel?: string; + coordinates?: readonly number[]; + type: string; + rawCategory?: string; + ids?: unknown; + }) => [r.id, r.label, r.sublabel, r.coordinates, r.type, r.rawCategory, r.ids]; + expect(adapted.map(fields)).toEqual( + features.map((f: { adapted: Parameters[0] }) => fields(f.adapted)), + ); + expect(fetch).toHaveBeenCalledTimes(1); + }); + } + + it("keeps ordinary business names outside the specialized code/alias index", () => { + for (const id of ["way/1204762785", "node/322490364", "node/348000444", "node/9154787137"]) { + const record = sources.osm.records.find((r: { id: string }) => r.id === id); + expect(extractTerms(record.tags)).toEqual([]); + } + }); +}); diff --git a/scripts/discovery-eval/business-name-address/queries-v1.json b/scripts/discovery-eval/business-name-address/queries-v1.json new file mode 100644 index 00000000..6d2d9877 --- /dev/null +++ b/scripts/discovery-eval/business-name-address/queries-v1.json @@ -0,0 +1,83 @@ +{ + "version": 1, + "baseline": "3c80939d26a09f131b16d849895255436b5e5798", + "region": "Berlin ALEXA and nearby branch controls", + "language": "en", + "center": [13.416, 52.5194], + "upstreamProximity": [13.42, 52.52], + "zoom": 15, + "budgets": { + "maxRank": 3, + "maxWrongBranchClaims": 0, + "coldMs": 5000, + "warmMs": 2000 + }, + "cases": [ + { + "id": "moch-name", + "query": "EDEKA Moch", + "target": "moch" + }, + { + "id": "moch-address", + "query": "EDEKA Moch Grunerstraße 20", + "target": "moch" + }, + { + "id": "edeka-address", + "query": "EDEKA Grunerstraße 20 Berlin", + "target": "moch" + }, + { + "id": "edeka-alexa", + "query": "EDEKA Alexa", + "target": "moch" + }, + { + "id": "edeka-gruner", + "query": "EDEKA Grunerstraße", + "target": "moch" + }, + { + "id": "edeka-alexander", + "query": "EDEKA Alexanderstraße 25 Berlin", + "target": null, + "judgment": "Returned-address control; real-world branch identity unresolved, excluded from exact-entity denominator" + }, + { + "id": "edeka-brand", + "query": "EDEKA", + "target": null + }, + { + "id": "media-alexa", + "query": "MediaMarkt Alexa", + "target": "media" + }, + { + "id": "media-address", + "query": "MediaMarkt Grunerstraße 20 Berlin", + "target": "media" + }, + { + "id": "rewe-address", + "query": "REWE Invalidenstraße 158 Berlin", + "target": "rewe" + }, + { + "id": "wrong-address", + "query": "EDEKA Moch Grunerstraße 999 Berlin", + "target": "negative" + }, + { + "id": "invented-name", + "query": "Zzqxv430 Testladen Grunerstraße 20 Berlin", + "target": "negative" + }, + { + "id": "schaaf-address", + "query": "EDEKA Schaaf Schillingstraße 2 Berlin", + "target": "schaaf" + } + ] +} diff --git a/scripts/discovery-eval/business-name-address/replay.ts b/scripts/discovery-eval/business-name-address/replay.ts new file mode 100644 index 00000000..68a83e9d --- /dev/null +++ b/scripts/discovery-eval/business-name-address/replay.ts @@ -0,0 +1,65 @@ +/** Offline diagnostic replay. It never calls providers or changes production data. */ +import { execFileSync } from "node:child_process"; +import { readFileSync, writeFileSync } from "node:fs"; +import { getQueryVariants } from "../../../integrations/geocoding/query-expansion.js"; +import type { AutocompleteResult } from "../../../packages/core/src/types/geocoding.js"; +import { + enterAction, + rankAutocompleteRows, +} from "../../../packages/core/src/utils/suggestionRanking.js"; + +interface QuerySet { + baseline: string; + center: [number, number]; + zoom: number; + cases: Array<{ id: string; query: string }>; +} +interface Responses { + features: Array<{ raw: { id: string }; adapted: AutocompleteResult }>; + cases: Array<{ + caseId: string; + rawIds: string[]; + }>; +} +function read(name: string): T { + return JSON.parse(readFileSync(new URL(name, import.meta.url), "utf8")) as T; +} +const queries = read("queries-v1.json"); +const responses = read("responses-v1.json"); +const revision = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim(); +const report = { + captureBaseline: queries.baseline, + replayRevision: revision, + dirty: execFileSync("git", ["status", "--porcelain"], { encoding: "utf8" }).trim() !== "", + sameRevision: revision === queries.baseline, + mode: "place-only source replay; shortcuts and live UI are separate evidence", + cases: responses.cases.map((fixture) => { + const entry = queries.cases.find((query) => query.id === fixture.caseId); + if (!entry) throw new Error("Missing business retrieval query"); + const context = { query: entry.query, proximity: queries.center, zoom: queries.zoom }; + // The historical aggregate was empty/partial. Replay the captured geocoder + // pool; do not treat the unavailable aggregate as source absence. + const combined = fixture.rawIds.map((id) => { + const feature = responses.features.find((candidate) => candidate.raw.id === id); + if (!feature) throw new Error("Missing captured candidate"); + return feature.adapted; + }); + const ranked = rankAutocompleteRows({ places: combined }, context); + const action = enterAction(ranked, context); + return { + caseId: fixture.caseId, + variants: getQueryVariants(entry.query), + partial: true, + combinedIds: combined.map((row) => row.id), + rankedIds: ranked.map((row) => row.id), + enter: action.kind === "open" ? { kind: "open", id: action.row.id } : action, + }; + }), +}; +const output = `${JSON.stringify(report, null, 2)}\n`; +const outIndex = process.argv.indexOf("--out"); +if (outIndex >= 0) { + const out = process.argv[outIndex + 1]; + if (!out) throw new Error("Missing --out path"); + writeFileSync(out, output); +} else process.stdout.write(output); diff --git a/scripts/discovery-eval/business-name-address/responses-v1.json b/scripts/discovery-eval/business-name-address/responses-v1.json new file mode 100644 index 00000000..c5173db9 --- /dev/null +++ b/scripts/discovery-eval/business-name-address/responses-v1.json @@ -0,0 +1,1445 @@ +{ + "version": 1, + "provenance": "Selected raw MapTiler features and public adapted rows captured 2026-10-07; fixed historical inputs, not current production results", + "archive": "https://gist.github.com/Medformatik/c36d8b8f44c88971277659512a533a51/8b33cd9238ba743f54f3235f2831470cf3bb5972", + "queriesSha256": "bdc16e4a468dcda386be3f5cca86398b1e204056399b4fd1a4559d03eec27572", + "features": [ + { + "raw": { + "id": "poi.30456941", + "text": "EDEKA Koch-Sportpark", + "place_name": "EDEKA Koch-Sportpark, Karl-Brandt-Weg 11, 44629 Herne, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [7.208717748485128, 51.55210278682949] }, + "properties": { "ref": "osm:w25670529", "categories": ["stadium"], "wikidata": "Q1671027" } + }, + "adapted": { + "id": "maptiler:poi.30456941", + "ids": { "wikidata": "Q1671027" }, + "label": "EDEKA Koch-Sportpark", + "sublabel": "EDEKA Koch-Sportpark, Karl-Brandt-Weg 11, 44629 Herne, Germany", + "coordinates": [7.208717748485128, 51.55210278682949], + "type": "poi", + "rawCategory": "stadium", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.27997147", + "text": "Edeka Möck", + "place_name": "Edeka Möck, August-Lämmle-Straße 17, 72766 Reutlingen, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [9.22899305820465, 48.48657027701767] }, + "properties": { + "ref": "osm:n3593639849", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "72766", + "addr:city": "Reutlingen", + "addr:housenumber": "17", + "addr:street": "August-Lämmle-Straße" + } + } + }, + "adapted": { + "id": "maptiler:poi.27997147", + "label": "Edeka Möck", + "sublabel": "Edeka Möck, August-Lämmle-Straße 17, 72766 Reutlingen, Germany", + "coordinates": [9.22899305820465, 48.48657027701767], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.32434263", + "text": "Edeka Möck", + "place_name": "Edeka Möck, Friedrich-Naumann-Straße 36, 72762 Reutlingen, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [9.191001408020384, 48.48736248347219] }, + "properties": { + "ref": "osm:w62488816", + "categories": ["supermarket", "retail building"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "72762", + "addr:city": "Reutlingen", + "addr:housenumber": "36", + "addr:street": "Friedrich-Naumann-Straße" + } + } + }, + "adapted": { + "id": "maptiler:poi.32434263", + "label": "Edeka Möck", + "sublabel": "Edeka Möck, Friedrich-Naumann-Straße 36, 72762 Reutlingen, Germany", + "coordinates": [9.191001408020384, 48.48736248347219], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.31643808", + "text": "Edeka Möck", + "place_name": "Edeka Möck, 72810 Gomaringen, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [9.102380722761154, 48.459401998661164] }, + "properties": { + "ref": "osm:n13314629571", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "72810", + "addr:city": "Gomaringen", + "addr:housenumber": "15", + "addr:street": "Ohmenhäuser Straße" + } + } + }, + "adapted": { + "id": "maptiler:poi.31643808", + "label": "Edeka Möck", + "sublabel": "Edeka Möck, 72810 Gomaringen, Germany", + "coordinates": [9.102380722761154, 48.459401998661164], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.14639240", + "text": "Edeka Möck", + "place_name": "Edeka Möck, Robert-Bosch-Straße 19, 72810 Gomaringen, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [9.080636147370342, 48.455747733004614] }, + "properties": { + "ref": "osm:w27644197", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "72810", + "addr:city": "Gomaringen", + "addr:housenumber": "19", + "addr:street": "Robert-Bosch-Straße" + } + } + }, + "adapted": { + "id": "maptiler:poi.14639240", + "label": "Edeka Möck", + "sublabel": "Edeka Möck, Robert-Bosch-Straße 19, 72810 Gomaringen, Germany", + "coordinates": [9.080636147370342, 48.455747733004614], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.14883072", + "text": "Edeka Koch", + "place_name": "Edeka Koch, Im Grund 1, 72469 Meßstetten, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [8.954309790404409, 48.1768506016719] }, + "properties": { + "ref": "osm:w922994590", + "categories": ["supermarket", "building"], + "feature_tags": { + "addr:housenumber": "1", + "shop": "supermarket", + "addr:street": "Im Grund", + "addr:postcode": "72469", + "addr:city": "Meßstetten" + } + } + }, + "adapted": { + "id": "maptiler:poi.14883072", + "label": "Edeka Koch", + "sublabel": "Edeka Koch, Im Grund 1, 72469 Meßstetten, Germany", + "coordinates": [8.954309790404409, 48.1768506016719], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "address.12686057", + "text": "Grunerstraße", + "place_name": "Grunerstraße 20, 10179 Berlin, Germany", + "place_type": ["address"], + "geometry": { "type": "Point", "coordinates": [13.41582100000005, 52.518307] }, + "properties": { "ref": "osm:w1025851956", "wikidata": "Q1550809" } + }, + "adapted": { + "id": "maptiler:address.12686057", + "ids": { "wikidata": "Q1550809" }, + "label": "Grunerstraße", + "sublabel": "Grunerstraße 20, 10179 Berlin, Germany", + "coordinates": [13.41582100000005, 52.518307], + "type": "address", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "address.10027702", + "text": "Groenerstraße", + "place_name": "Groenerstraße 20, 13585 Berlin, Germany", + "place_type": ["address"], + "geometry": { "type": "Point", "coordinates": [13.20358299999998, 52.543163] }, + "properties": { "ref": "osm:w1306242932" } + }, + "adapted": { + "id": "maptiler:address.10027702", + "label": "Groenerstraße", + "sublabel": "Groenerstraße 20, 13585 Berlin, Germany", + "coordinates": [13.20358299999998, 52.543163], + "type": "address", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "address.10343043", + "text": "Gründerstraße", + "place_name": "Gründerstraße 20, 12526 Berlin, Germany", + "place_type": ["address"], + "geometry": { "type": "Point", "coordinates": [13.574141999999938, 52.409928] }, + "properties": { "ref": "osm:w130868556" } + }, + "adapted": { + "id": "maptiler:address.10343043", + "label": "Gründerstraße", + "sublabel": "Gründerstraße 20, 12526 Berlin, Germany", + "coordinates": [13.574141999999938, 52.409928], + "type": "address", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "address.9410688", + "text": "Grünerstraße", + "place_name": "Grünerstraße 20, 95615 Marktredwitz, Germany", + "place_type": ["address"], + "geometry": { "type": "Point", "coordinates": [12.09223099999997, 50.005279] }, + "properties": { "ref": "osm:w147440163" } + }, + "adapted": { + "id": "maptiler:address.9410688", + "label": "Grünerstraße", + "sublabel": "Grünerstraße 20, 95615 Marktredwitz, Germany", + "coordinates": [12.09223099999997, 50.005279], + "type": "address", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "address.5097698", + "text": "Grunerstraße", + "place_name": "Grunerstraße 20, 65510 Idstein, Germany", + "place_type": ["address"], + "geometry": { "type": "Point", "coordinates": [8.267456000000038, 50.216309] }, + "properties": { "ref": "osm:w11487422" } + }, + "adapted": { + "id": "maptiler:address.5097698", + "label": "Grunerstraße", + "sublabel": "Grunerstraße 20, 65510 Idstein, Germany", + "coordinates": [8.267456000000038, 50.216309], + "type": "address", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "place.4929509", + "text": "Colonia 20 de Noviembre", + "place_name": "Colonia 20 de Noviembre, Huaniqueo, Mexico", + "place_type": ["place"], + "geometry": { "type": "Point", "coordinates": [-101.58130947500467, 19.893160393441814] }, + "properties": { "ref": "osm:n4554041879", "place_designation": "hamlet" } + }, + "adapted": { + "id": "maptiler:place.4929509", + "label": "Colonia 20 de Noviembre", + "sublabel": "Colonia 20 de Noviembre, Huaniqueo, Mexico", + "coordinates": [-101.58130947500467, 19.893160393441814], + "type": "region", + "rawCategory": "place/hamlet", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.39267497", + "text": "EDEKA", + "place_name": "EDEKA, Alexanderstraße 25, 10178 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.416776409228078, 52.51855355456135] }, + "properties": { + "ref": "osm:w1204762785", + "categories": ["supermarket"], + "feature_tags": { "shop": "supermarket", "level": "-1", "addr:city": "Berlin" } + } + }, + "adapted": { + "id": "maptiler:poi.39267497", + "label": "EDEKA", + "sublabel": "EDEKA, Alexanderstraße 25, 10178 Berlin, Germany", + "coordinates": [13.416776409228078, 52.51855355456135], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15407240", + "text": "EDEKA", + "place_name": "EDEKA, Markt 11, 13597 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.204706087708473, 52.53740364108829] }, + "properties": { + "ref": "osm:n271738194", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "13597", + "addr:city": "Berlin", + "addr:housenumber": "11", + "addr:street": "Markt" + } + } + }, + "adapted": { + "id": "maptiler:poi.15407240", + "label": "EDEKA", + "sublabel": "EDEKA, Markt 11, 13597 Berlin, Germany", + "coordinates": [13.204706087708473, 52.53740364108829], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15448214", + "text": "EDEKA", + "place_name": "EDEKA, Buntzelstraße 14, 12526 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.57199840247631, 52.408887070774476] }, + "properties": { + "ref": "osm:n471301175", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "12526", + "addr:city": "Berlin", + "addr:housenumber": "14", + "addr:street": "Buntzelstraße" + } + } + }, + "adapted": { + "id": "maptiler:poi.15448214", + "label": "EDEKA", + "sublabel": "EDEKA, Buntzelstraße 14, 12526 Berlin, Germany", + "coordinates": [13.57199840247631, 52.408887070774476], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.30149398", + "text": "EDEKA", + "place_name": "EDEKA, Falkenseer Chaussee 266a, 13583 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.186250478029251, 52.54698238754912] }, + "properties": { + "ref": "osm:n1008550282", + "categories": ["supermarket"], + "feature_tags": { "shop": "supermarket" } + } + }, + "adapted": { + "id": "maptiler:poi.30149398", + "label": "EDEKA", + "sublabel": "EDEKA, Falkenseer Chaussee 266a, 13583 Berlin, Germany", + "coordinates": [13.186250478029251, 52.54698238754912], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15445342", + "text": "EDEKA", + "place_name": "EDEKA, Barnimstraße 18, 10249 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.42295877635479, 52.52607532450191] }, + "properties": { + "ref": "osm:n448814806", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "10249", + "addr:city": "Berlin", + "addr:housenumber": "18", + "addr:street": "Barnimstraße" + } + } + }, + "adapted": { + "id": "maptiler:poi.15445342", + "label": "EDEKA", + "sublabel": "EDEKA, Barnimstraße 18, 10249 Berlin, Germany", + "coordinates": [13.42295877635479, 52.52607532450191], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15632141", + "text": "EDEKA", + "place_name": "EDEKA, Straßburger Straße 9A-C, 10405 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.41357808560133, 52.52919226436692] }, + "properties": { + "ref": "osm:n3889187276", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "10405", + "addr:city": "Berlin", + "addr:housenumber": "9A-C", + "addr:street": "Straßburger Straße" + } + } + }, + "adapted": { + "id": "maptiler:poi.15632141", + "label": "EDEKA", + "sublabel": "EDEKA, Straßburger Straße 9A-C, 10405 Berlin, Germany", + "coordinates": [13.41357808560133, 52.52919226436692], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15895501", + "text": "EDEKA", + "place_name": "EDEKA, Annenstraße 4a, 10179 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.415483734242002, 52.50777084974184] }, + "properties": { + "ref": "osm:w52092588", + "categories": ["supermarket", "commercial building"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "10179", + "addr:city": "Berlin", + "addr:housenumber": "4a", + "addr:street": "Annenstraße" + } + } + }, + "adapted": { + "id": "maptiler:poi.15895501", + "label": "EDEKA", + "sublabel": "EDEKA, Annenstraße 4a, 10179 Berlin, Germany", + "coordinates": [13.415483734242002, 52.50777084974184], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.32007491", + "text": "EDEKA", + "place_name": "EDEKA, Templiner Straße 13a, 10119 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.40784888714552, 52.53201304601752] }, + "properties": { + "ref": "osm:n6595730361", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "level": "0", + "addr:postcode": "10119", + "addr:city": "Berlin", + "addr:housenumber": "12", + "addr:street": "Templiner Straße" + } + } + }, + "adapted": { + "id": "maptiler:poi.32007491", + "label": "EDEKA", + "sublabel": "EDEKA, Templiner Straße 13a, 10119 Berlin, Germany", + "coordinates": [13.40784888714552, 52.53201304601752], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15469482", + "text": "EDEKA", + "place_name": "EDEKA, Ritterstraße 38-40, 10969 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.403648883104324, 52.5035654379113] }, + "properties": { + "ref": "osm:n652570198", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "10969", + "addr:city": "Berlin", + "addr:housenumber": "38-40", + "addr:street": "Ritterstraße" + } + } + }, + "adapted": { + "id": "maptiler:poi.15469482", + "label": "EDEKA", + "sublabel": "EDEKA, Ritterstraße 38-40, 10969 Berlin, Germany", + "coordinates": [13.403648883104324, 52.5035654379113], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15864452", + "text": "EDEKA", + "place_name": "EDEKA, Platz der Vereinten Nationen 14, 10249 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.428411649527902, 52.52262534175838] }, + "properties": { + "ref": "osm:w24035130", + "categories": ["supermarket", "retail building"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "10249", + "addr:city": "Berlin", + "addr:housenumber": "14", + "addr:street": "Platz der Vereinten Nationen" + } + } + }, + "adapted": { + "id": "maptiler:poi.15864452", + "label": "EDEKA", + "sublabel": "EDEKA, Platz der Vereinten Nationen 14, 10249 Berlin, Germany", + "coordinates": [13.428411649527902, 52.52262534175838], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "address.6574798", + "text": "Alexanderstraße", + "place_name": "Alexanderstraße 25, 10179 Berlin, Germany", + "place_type": ["address"], + "geometry": { "type": "Point", "coordinates": [13.41794200000004, 52.519004] }, + "properties": { "ref": "osm:w100405009", "wikidata": "Q17486182" } + }, + "adapted": { + "id": "maptiler:address.6574798", + "ids": { "wikidata": "Q17486182" }, + "label": "Alexanderstraße", + "sublabel": "Alexanderstraße 25, 10179 Berlin, Germany", + "coordinates": [13.41794200000004, 52.519004], + "type": "address", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15258278", + "text": "Edeka", + "place_name": "Edeka, Berliner Straße 96, 13507 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.284847810864449, 52.589088279152] }, + "properties": { + "ref": "osm:n316772479", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "13507", + "addr:city": "Berlin", + "addr:housenumber": "96", + "addr:street": "Berliner Straße" + } + } + }, + "adapted": { + "id": "maptiler:poi.15258278", + "label": "Edeka", + "sublabel": "Edeka, Berliner Straße 96, 13507 Berlin, Germany", + "coordinates": [13.284847810864449, 52.589088279152], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15539884", + "text": "MediaMarkt", + "place_name": "MediaMarkt, Pr Willem Alexander Prom 69-83, 2284 DJ Rijswijk, Netherlands", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [4.316869229078293, 52.03636822992996] }, + "properties": { + "ref": "osm:n1845949909", + "categories": ["electronics"], + "feature_tags": { + "shop": "electronics", + "level": "1", + "addr:postcode": "2284DJ", + "addr:city": "Rijswijk", + "addr:housenumber": "69-83", + "addr:street": "Pr Willem Alexander Prom" + } + } + }, + "adapted": { + "id": "maptiler:poi.15539884", + "label": "MediaMarkt", + "sublabel": "MediaMarkt, Pr Willem Alexander Prom 69-83, 2284 DJ Rijswijk, Netherlands", + "coordinates": [4.316869229078293, 52.03636822992996], + "type": "poi", + "rawCategory": "electronics", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15422100", + "text": "MediaMarkt", + "place_name": "MediaMarkt, Grunerstraße 20, 10179 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.414790779352188, 52.51986159027454] }, + "properties": { + "ref": "osm:n322490364", + "categories": ["electronics"], + "feature_tags": { + "shop": "electronics", + "level": "0", + "addr:postcode": "10179", + "addr:city": "Berlin", + "addr:housenumber": "20", + "addr:street": "Grunerstraße" + } + } + }, + "adapted": { + "id": "maptiler:poi.15422100", + "label": "MediaMarkt", + "sublabel": "MediaMarkt, Grunerstraße 20, 10179 Berlin, Germany", + "coordinates": [13.414790779352188, 52.51986159027454], + "type": "poi", + "rawCategory": "electronics", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15388462", + "text": "MediaMarkt", + "place_name": "MediaMarkt, Äußere Schneeberger Straße 95, 08056 Zwickau, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [12.499412186443806, 50.70416170071806] }, + "properties": { + "ref": "osm:n267485594", + "categories": ["electronics"], + "feature_tags": { + "shop": "electronics", + "addr:postcode": "08056", + "addr:city": "Zwickau", + "addr:housenumber": "95", + "addr:street": "Äußere Schneeberger Straße" + } + } + }, + "adapted": { + "id": "maptiler:poi.15388462", + "label": "MediaMarkt", + "sublabel": "MediaMarkt, Äußere Schneeberger Straße 95, 08056 Zwickau, Germany", + "coordinates": [12.499412186443806, 50.70416170071806], + "type": "poi", + "rawCategory": "electronics", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15513302", + "text": "MediaMarkt", + "place_name": "MediaMarkt, Waldershofer Straße 10, 95615 Marktredwitz, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [12.077845813448675, 49.99956173454102] }, + "properties": { + "ref": "osm:w145348876", + "categories": ["electronics", "building"], + "feature_tags": { + "addr:housenumber": "10", + "shop": "electronics", + "addr:street": "Waldershofer Straße", + "addr:postcode": "95615", + "addr:city": "Marktredwitz" + } + } + }, + "adapted": { + "id": "maptiler:poi.15513302", + "label": "MediaMarkt", + "sublabel": "MediaMarkt, Waldershofer Straße 10, 95615 Marktredwitz, Germany", + "coordinates": [12.077845813448675, 49.99956173454102], + "type": "poi", + "rawCategory": "electronics", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.27301831", + "text": "MediaMarkt", + "place_name": "MediaMarkt, Schloßplatz 8, 26122 Oldenburg, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [8.216576837003231, 53.13856416583732] }, + "properties": { + "ref": "osm:n3555055573", + "categories": ["electronics"], + "feature_tags": { + "shop": "electronics", + "level": "-1", + "addr:postcode": "26122", + "addr:city": "Oldenburg", + "addr:housenumber": "3", + "addr:street": "Schloßplatz" + } + } + }, + "adapted": { + "id": "maptiler:poi.27301831", + "label": "MediaMarkt", + "sublabel": "MediaMarkt, Schloßplatz 8, 26122 Oldenburg, Germany", + "coordinates": [8.216576837003231, 53.13856416583732], + "type": "poi", + "rawCategory": "electronics", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.31290179", + "text": "MediaMarkt", + "place_name": "MediaMarkt, Posthalterweg 15, 26129 Oldenburg, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [8.172727230560895, 53.16099834226386] }, + "properties": { + "ref": "osm:w1134980105", + "categories": ["electronics", "retail building"], + "feature_tags": { + "shop": "electronics", + "addr:postcode": "26129", + "addr:city": "Oldenburg", + "addr:housenumber": "15", + "addr:street": "Posthalterweg" + } + } + }, + "adapted": { + "id": "maptiler:poi.31290179", + "label": "MediaMarkt", + "sublabel": "MediaMarkt, Posthalterweg 15, 26129 Oldenburg, Germany", + "coordinates": [8.172727230560895, 53.16099834226386], + "type": "poi", + "rawCategory": "electronics", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.34392614", + "text": "MediaMarkt", + "place_name": "MediaMarkt, Berliner Straße 15, 89250 Senden, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [10.039082317799625, 48.33283310114879] }, + "properties": { + "ref": "osm:w100513761", + "categories": ["electronics", "retail building"], + "wikidata": "Q659320", + "feature_tags": { + "shop": "electronics", + "addr:postcode": "89250", + "addr:city": "Senden", + "addr:housenumber": "13", + "addr:street": "Berliner Straße" + } + } + }, + "adapted": { + "id": "maptiler:poi.34392614", + "ids": { "wikidata": "Q659320" }, + "label": "MediaMarkt", + "sublabel": "MediaMarkt, Berliner Straße 15, 89250 Senden, Germany", + "coordinates": [10.039082317799625, 48.33283310114879], + "type": "poi", + "rawCategory": "electronics", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.30823762", + "text": "MediaMarkt", + "place_name": "MediaMarkt, Berliner Allee 34a, 22850 Norderstedt, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [9.985382588983953, 53.6835389749034] }, + "properties": { + "ref": "osm:w907293928", + "categories": ["electronics"], + "feature_tags": { + "shop": "electronics", + "level": "1", + "addr:postcode": "22850", + "addr:city": "Norderstedt", + "addr:housenumber": "8", + "addr:street": "De-Gasperi-Passage" + } + } + }, + "adapted": { + "id": "maptiler:poi.30823762", + "label": "MediaMarkt", + "sublabel": "MediaMarkt, Berliner Allee 34a, 22850 Norderstedt, Germany", + "coordinates": [9.985382588983953, 53.6835389749034], + "type": "poi", + "rawCategory": "electronics", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15426609", + "text": "REWE", + "place_name": "REWE, Invalidenstraße 158, 10115 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.397083505988121, 52.531980821191] }, + "properties": { + "ref": "osm:n348000444", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "level": "0", + "addr:postcode": "10115", + "addr:city": "Berlin", + "addr:housenumber": "158", + "addr:street": "Invalidenstraße" + } + } + }, + "adapted": { + "id": "maptiler:poi.15426609", + "label": "REWE", + "sublabel": "REWE, Invalidenstraße 158, 10115 Berlin, Germany", + "coordinates": [13.397083505988121, 52.531980821191], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15741076", + "text": "REWE", + "place_name": "REWE, Heidestraße 41, 10557 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.3660389482975, 52.53228104144362] }, + "properties": { + "ref": "osm:n8367158861", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "10557", + "level": "0", + "addr:city": "Berlin", + "addr:housenumber": "41", + "addr:street": "Heidestraße" + } + } + }, + "adapted": { + "id": "maptiler:poi.15741076", + "label": "REWE", + "sublabel": "REWE, Heidestraße 41, 10557 Berlin, Germany", + "coordinates": [13.3660389482975, 52.53228104144362], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.34014416", + "text": "REWE", + "place_name": "REWE, Aaron-Bernstein-Platz 7, 10117 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.389315493404865, 52.52533119149872] }, + "properties": { + "ref": "osm:n11027556740", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "level": "-1", + "addr:postcode": "10117", + "addr:city": "Berlin", + "addr:housenumber": "111", + "addr:street": "Friedrichstraße" + } + } + }, + "adapted": { + "id": "maptiler:poi.34014416", + "label": "REWE", + "sublabel": "REWE, Aaron-Bernstein-Platz 7, 10117 Berlin, Germany", + "coordinates": [13.389315493404865, 52.52533119149872], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.15509199", + "text": "REWE", + "place_name": "REWE, Chausseestraße 118-120, 10115 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.383975215256214, 52.529563891805815] }, + "properties": { + "ref": "osm:n1110843201", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "addr:postcode": "10115", + "level": "0", + "addr:city": "Berlin", + "addr:housenumber": "118-120", + "addr:street": "Chausseestraße" + } + } + }, + "adapted": { + "id": "maptiler:poi.15509199", + "label": "REWE", + "sublabel": "REWE, Chausseestraße 118-120, 10115 Berlin, Germany", + "coordinates": [13.383975215256214, 52.529563891805815], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.36656201", + "text": "Rewe To Go", + "place_name": "Rewe To Go, Europaplatz 2, 10557 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.369845424343566, 52.52523409426698] }, + "properties": { + "ref": "osm:w407684446", + "categories": ["supermarket"], + "feature_tags": { "shop": "supermarket", "level": "-1" } + } + }, + "adapted": { + "id": "maptiler:poi.36656201", + "label": "Rewe To Go", + "sublabel": "Rewe To Go, Europaplatz 2, 10557 Berlin, Germany", + "coordinates": [13.369845424343566, 52.52523409426698], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "address.8692633", + "text": "Invalidenstraße", + "place_name": "Invalidenstraße 158, 10115 Berlin, Germany", + "place_type": ["address"], + "geometry": { "type": "Point", "coordinates": [13.39708399999995, 52.531981] }, + "properties": { "ref": "osm:w1021196045", "wikidata": "Q463414" } + }, + "adapted": { + "id": "maptiler:address.8692633", + "ids": { "wikidata": "Q463414" }, + "label": "Invalidenstraße", + "sublabel": "Invalidenstraße 158, 10115 Berlin, Germany", + "coordinates": [13.39708399999995, 52.531981], + "type": "address", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "place.4795446", + "text": "Berlin Center", + "place_name": "Berlin Center, Berlin Township, United States", + "place_type": ["place"], + "geometry": { "type": "Point", "coordinates": [-85.13417344540358, 42.90058887898288] }, + "properties": { "ref": "osm:n153413103", "place_designation": "hamlet" } + }, + "adapted": { + "id": "maptiler:place.4795446", + "label": "Berlin Center", + "sublabel": "Berlin Center, Berlin Township, United States", + "coordinates": [-85.13417344540358, 42.90058887898288], + "type": "region", + "rawCategory": "place/hamlet", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "region.505", + "text": "Berlin", + "place_name": "Berlin, Germany", + "place_type": ["region"], + "geometry": { "type": "Point", "coordinates": [13.39513085782528, 52.51738870388956] }, + "properties": { "ref": "osm:r62422", "wikidata": "Q64", "place_designation": "city" } + }, + "adapted": { + "id": "maptiler:region.505", + "ids": { "wikidata": "Q64" }, + "label": "Berlin", + "sublabel": "Berlin, Germany", + "coordinates": [13.39513085782528, 52.51738870388956], + "type": "region", + "rawCategory": "place/city", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "locality.2701", + "text": "Neukölln", + "place_name": "Neukölln, Berlin, Germany", + "place_type": ["locality"], + "geometry": { "type": "Point", "coordinates": [13.43534991145134, 52.48114978975832] }, + "properties": { "ref": "osm:r409213", "wikidata": "Q169492", "place_designation": "suburb" } + }, + "adapted": { + "id": "maptiler:locality.2701", + "ids": { "wikidata": "Q169492" }, + "label": "Neukölln", + "sublabel": "Neukölln, Berlin, Germany", + "coordinates": [13.43534991145134, 52.48114978975832], + "type": "region", + "rawCategory": "place/suburb", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "place.4534518", + "text": "Stone Pieces", + "place_name": "Stone Pieces, Berlin, Germany", + "place_type": ["place"], + "geometry": { "type": "Point", "coordinates": [13.129702471196651, 52.38950275667193] }, + "properties": { + "ref": "osm:r14687142", + "wikidata": "Q515015", + "place_designation": "neighbourhood" + } + }, + "adapted": { + "id": "maptiler:place.4534518", + "ids": { "wikidata": "Q515015" }, + "label": "Stone Pieces", + "sublabel": "Stone Pieces, Berlin, Germany", + "coordinates": [13.129702471196651, 52.38950275667193], + "type": "region", + "rawCategory": "place/neighbourhood", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "neighbourhood.20256", + "text": "Berliner Vorstadt", + "place_name": "Berliner Vorstadt, Potsdam, Germany", + "place_type": ["neighbourhood"], + "geometry": { "type": "Point", "coordinates": [13.079091534018517, 52.412128278186444] }, + "properties": { + "ref": "osm:r6577655", + "wikidata": "Q48173386", + "place_designation": "suburb" + } + }, + "adapted": { + "id": "maptiler:neighbourhood.20256", + "ids": { "wikidata": "Q48173386" }, + "label": "Berliner Vorstadt", + "sublabel": "Berliner Vorstadt, Potsdam, Germany", + "coordinates": [13.079091534018517, 52.412128278186444], + "type": "street", + "rawCategory": "place/suburb", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "place.2470107", + "text": "Berliner Siedlung", + "place_name": "Berliner Siedlung, Treuenbrietzen, Germany", + "place_type": ["place"], + "geometry": { "type": "Point", "coordinates": [12.889782898128033, 52.10644753168435] }, + "properties": { + "ref": "osm:n7678030785", + "wikidata": "Q113687898", + "place_designation": "neighbourhood" + } + }, + "adapted": { + "id": "maptiler:place.2470107", + "ids": { "wikidata": "Q113687898" }, + "label": "Berliner Siedlung", + "sublabel": "Berliner Siedlung, Treuenbrietzen, Germany", + "coordinates": [12.889782898128033, 52.10644753168435], + "type": "region", + "rawCategory": "place/neighbourhood", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.2947497", + "text": "20", + "place_name": "20, Siemenssiedlung am Hohenzollernkanal III, Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.251579366624355, 52.55727716817165] }, + "properties": { "ref": "osm:n11165225437", "categories": ["water well"] } + }, + "adapted": { + "id": "maptiler:poi.2947497", + "label": "20", + "sublabel": "20, Siemenssiedlung am Hohenzollernkanal III, Berlin, Germany", + "coordinates": [13.251579366624355, 52.55727716817165], + "type": "poi", + "rawCategory": "water well", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.2947574", + "text": "20", + "place_name": "20, Saatwinkel, Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.242084681987762, 52.55983688062971] }, + "properties": { "ref": "osm:n11165225465", "categories": ["water well"] } + }, + "adapted": { + "id": "maptiler:poi.2947574", + "label": "20", + "sublabel": "20, Saatwinkel, Berlin, Germany", + "coordinates": [13.242084681987762, 52.55983688062971], + "type": "poi", + "rawCategory": "water well", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.6230752", + "text": "20", + "place_name": "20, Elisabeth-Schwarzhaupt-Platz, Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.383162542017772, 52.53501260472217] }, + "properties": { "ref": "osm:w372459506", "categories": ["pitch", "beachvolleyball"] } + }, + "adapted": { + "id": "maptiler:poi.6230752", + "label": "20", + "sublabel": "20, Elisabeth-Schwarzhaupt-Platz, Berlin, Germany", + "coordinates": [13.383162542017772, 52.53501260472217], + "type": "poi", + "rawCategory": "pitch", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "poi.32879876", + "text": "Edeka Schaaf", + "place_name": "Edeka Schaaf, Singerstraße 121, 10179 Berlin, Germany", + "place_type": ["poi"], + "geometry": { "type": "Point", "coordinates": [13.420668505132198, 52.51747194496568] }, + "properties": { + "ref": "osm:n9154787137", + "categories": ["supermarket"], + "feature_tags": { + "shop": "supermarket", + "level": "0", + "addr:postcode": "10179", + "addr:city": "Berlin", + "addr:housenumber": "2", + "addr:street": "Schillingstraße" + } + } + }, + "adapted": { + "id": "maptiler:poi.32879876", + "label": "Edeka Schaaf", + "sublabel": "Edeka Schaaf, Singerstraße 121, 10179 Berlin, Germany", + "coordinates": [13.420668505132198, 52.51747194496568], + "type": "poi", + "rawCategory": "supermarket", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "address.4011014", + "text": "Schillingstraße", + "place_name": "Schillingstraße 2, 10179 Berlin, Germany", + "place_type": ["address"], + "geometry": { "type": "Point", "coordinates": [13.42051600000002, 52.517376] }, + "properties": { "ref": "osm:w1076055688" } + }, + "adapted": { + "id": "maptiler:address.4011014", + "label": "Schillingstraße", + "sublabel": "Schillingstraße 2, 10179 Berlin, Germany", + "coordinates": [13.42051600000002, 52.517376], + "type": "address", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "address.9975161", + "text": "Schillingstraße", + "place_name": "Schillingstraße 2, 13403 Berlin, Germany", + "place_type": ["address"], + "geometry": { "type": "Point", "coordinates": [13.320637000000033, 52.566285] }, + "properties": { "ref": "osm:w1156572743" } + }, + "adapted": { + "id": "maptiler:address.9975161", + "label": "Schillingstraße", + "sublabel": "Schillingstraße 2, 13403 Berlin, Germany", + "coordinates": [13.320637000000033, 52.566285], + "type": "address", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "address.18028993", + "text": "Schillingstrasse", + "place_name": "Schillingstrasse, 10179 Berlin, Germany", + "place_type": ["address"], + "geometry": { "type": "Point", "coordinates": [13.420090489089489, 52.51717590797079] }, + "properties": { "ref": "osm:n10188970798" } + }, + "adapted": { + "id": "maptiler:address.18028993", + "label": "Schillingstrasse", + "sublabel": "Schillingstrasse, 10179 Berlin, Germany", + "coordinates": [13.420090489089489, 52.51717590797079], + "type": "address", + "provider": "geocoding-maptiler" + } + }, + { + "raw": { + "id": "address.6705156", + "text": "Schellingstraße", + "place_name": "Schellingstraße, 10785 Berlin, Germany", + "place_type": ["address"], + "geometry": { "type": "Point", "coordinates": [13.37306197732687, 52.505255650814135] }, + "properties": { "ref": "osm:w1472672676" } + }, + "adapted": { + "id": "maptiler:address.6705156", + "label": "Schellingstraße", + "sublabel": "Schellingstraße, 10785 Berlin, Germany", + "coordinates": [13.37306197732687, 52.505255650814135], + "type": "address", + "provider": "geocoding-maptiler" + } + } + ], + "cases": [ + { + "caseId": "moch-name", + "rawIds": [ + "poi.30456941", + "poi.27997147", + "poi.32434263", + "poi.31643808", + "poi.14639240", + "poi.14883072" + ] + }, + { + "caseId": "moch-address", + "rawIds": [ + "address.12686057", + "address.10027702", + "address.10343043", + "address.9410688", + "address.5097698", + "place.4929509" + ] + }, + { + "caseId": "edeka-address", + "rawIds": [ + "poi.39267497", + "poi.15407240", + "poi.15448214", + "poi.30149398", + "address.12686057", + "address.10027702" + ] + }, + { + "caseId": "edeka-alexa", + "rawIds": [ + "poi.39267497", + "poi.15445342", + "poi.15632141", + "poi.15895501", + "poi.32007491", + "poi.15469482" + ] + }, + { + "caseId": "edeka-gruner", + "rawIds": [ + "poi.39267497", + "poi.15448214", + "poi.15864452", + "poi.15445342", + "poi.15632141", + "poi.15895501" + ] + }, + { + "caseId": "edeka-alexander", + "rawIds": [ + "poi.39267497", + "poi.15445342", + "poi.15632141", + "poi.32007491", + "address.6574798", + "poi.15258278" + ] + }, + { + "caseId": "edeka-brand", + "rawIds": [ + "poi.39267497", + "poi.15864452", + "poi.15445342", + "poi.15632141", + "poi.15895501", + "poi.32007491" + ] + }, + { + "caseId": "media-alexa", + "rawIds": [ + "poi.15539884", + "poi.15422100", + "poi.15388462", + "poi.15513302", + "poi.27301831", + "poi.31290179" + ] + }, + { + "caseId": "media-address", + "rawIds": [ + "poi.15422100", + "address.12686057", + "poi.34392614", + "poi.30823762", + "address.10027702", + "address.10343043" + ] + }, + { + "caseId": "rewe-address", + "rawIds": [ + "poi.15426609", + "poi.15741076", + "poi.34014416", + "poi.15509199", + "poi.36656201", + "address.8692633" + ] + }, + { + "caseId": "wrong-address", + "rawIds": [ + "place.4795446", + "region.505", + "locality.2701", + "place.4534518", + "neighbourhood.20256", + "place.2470107" + ] + }, + { + "caseId": "invented-name", + "rawIds": [ + "address.12686057", + "address.10027702", + "address.10343043", + "poi.2947497", + "poi.2947574", + "poi.6230752" + ] + }, + { + "caseId": "schaaf-address", + "rawIds": [ + "poi.32879876", + "address.4011014", + "address.9975161", + "address.18028993", + "address.6705156", + "region.505" + ] + } + ] +} diff --git a/scripts/discovery-eval/business-name-address/sources-v1.json b/scripts/discovery-eval/business-name-address/sources-v1.json new file mode 100644 index 00000000..c94acbfb --- /dev/null +++ b/scripts/discovery-eval/business-name-address/sources-v1.json @@ -0,0 +1,322 @@ +{ + "version": 1, + "assessedAt": "2026-10-07T20:40:55.784378+00:00", + "osm": { + "access": "OSM API map bbox and direct versioned elements; no deployed extract", + "bbox": [13.414, 52.5185, 13.418, 52.521], + "mapSha256": "b0e10e00f82586f4746e2ea77101a110250e8fa34d64742fea960a0e28f21ce1", + "records": [ + { + "id": "node/322490364", + "version": 24, + "timestamp": "2024-09-05T10:13:11Z", + "tags": { + "addr:city": "Berlin", + "addr:country": "DE", + "addr:housename": "MediaMarkt", + "addr:housenumber": "20", + "addr:postcode": "10179", + "addr:street": "Grunerstraße", + "addr:suburb": "Mitte", + "brand": "MediaMarkt", + "brand:wikidata": "Q2381223", + "contact:phone": "+49 30 2408840", + "level": "0", + "name": "MediaMarkt", + "shop": "electronics", + "website": "https://www.mediamarkt.de/de/store/berlin-mitte-190" + } + }, + { + "id": "way/258898047", + "version": 38, + "timestamp": "2026-09-04T20:52:25Z", + "tags": { + "addr:city": "Berlin", + "addr:country": "DE", + "addr:housename": "Alexa", + "addr:housenumber": "20", + "addr:postcode": "10179", + "addr:street": "Grunerstraße", + "addr:suburb": "Mitte", + "alt_name": "Alexa Berlin", + "contact:website": "https://www.alexacentre.com/", + "name": "Alexa", + "phone": "+49 30 269340121", + "shop": "mall" + } + }, + { + "id": "way/1204762785", + "version": 3, + "timestamp": "2026-01-23T16:12:26Z", + "tags": { + "addr:city": "Berlin", + "brand": "Edeka", + "brand:wikidata": "Q701755", + "indoor": "room", + "level": "-1", + "name": "EDEKA", + "shop": "supermarket" + } + }, + { + "id": "node/348000444", + "version": 29, + "timestamp": "2025-04-10T11:24:48Z", + "tags": { + "addr:city": "Berlin", + "addr:housenumber": "158", + "addr:postcode": "10115", + "addr:street": "Invalidenstraße", + "brand": "Rewe", + "brand:wikidata": "Q16968817", + "level": "0", + "name": "REWE", + "phone": "+49 30 28390336", + "shop": "supermarket", + "website": "https://www.rewe.de/marktseite/rewe-markt-berlin-invalidenstra%C3%9Fe-158/" + } + }, + { + "id": "node/9154787137", + "version": 13, + "timestamp": "2026-08-18T07:17:13Z", + "tags": { + "addr:city": "Berlin", + "addr:country": "DE", + "addr:housenumber": "2", + "addr:postcode": "10179", + "addr:street": "Schillingstraße", + "addr:suburb": "Mitte", + "brand": "Edeka", + "brand:wikidata": "Q701755", + "contact:website": "https://www.edeka.de/eh/minden-hannover/edeka-schaaf-schillingstr.-2/index.jsp", + "level": "0", + "name": "Edeka Schaaf", + "shop": "supermarket" + } + } + ] + }, + "overture": { + "access": "read-only DuckDB 1.5.6 S3 bbox scan; no import", + "release": "2026-09-23.1", + "url": "s3://overturemaps-us-west-2/release/2026-09-23.1/theme=places/type=place/*", + "bbox": [13.408, 52.513, 13.426, 52.527], + "unfilteredRowCount": 3255, + "subsetSha256": "a9ec6402ecd390d6200151ace4d5a5a7106d1ca8641652e19dd336211684ba93", + "records": [ + { + "id": "466267a9-58bc-48bd-9457-93e7eb90e2b8", + "version": 10, + "names": { + "primary": "EDEKA Barnimstraße" + }, + "addresses": [ + { + "freeform": "Barnimstraße 18", + "locality": "Berlin", + "postcode": "10249", + "region": null, + "country": "DE" + } + ], + "phones": ["+493024729176"], + "websites": ["https://www.edeka.de/"], + "confidence": 0.999917788362503, + "operating_status": null, + "sources": [ + { + "property": "", + "dataset": "meta", + "license": "CDLA-Permissive-2.0", + "record_id": "366295967427907", + "update_time": "2026-09-14T00:00:00.000Z" + }, + { + "property": "/properties/confidence", + "dataset": "Overture", + "license": "CDLA-Permissive-2.0", + "update_time": "2026-09-17T22:52:12Z" + } + ], + "bbox": { + "xmin": 13.422950744628906, + "xmax": 13.422952651977539, + "ymin": 52.52610778808594, + "ymax": 52.52611541748047 + } + }, + { + "id": "bfbe5e1d-7db5-482e-8772-f53959dde008", + "version": 9, + "names": { + "primary": "MediaMarkt Berlin-Mitte (im Alexa)" + }, + "addresses": [ + { + "freeform": "Grunerstraße 20", + "locality": "Berlin", + "postcode": "10179", + "region": null, + "country": "DE" + } + ], + "phones": ["+4922122243333"], + "websites": [ + "https://www.mediamarkt.de/de/store/berlin-mitte-190?utm_source=places+link&utm_medium=seo-places+link&utm_term=Media+Markt+Berlin-Mitte+StoreId+190" + ], + "confidence": 0.9999635516405105, + "operating_status": null, + "sources": [ + { + "property": "", + "dataset": "meta", + "license": "CDLA-Permissive-2.0", + "record_id": "295733827232255", + "update_time": "2026-09-14T00:00:00.000Z" + }, + { + "property": "/properties/confidence", + "dataset": "Overture", + "license": "CDLA-Permissive-2.0", + "update_time": "2026-09-17T22:52:12Z" + } + ], + "bbox": { + "xmin": 13.414756774902344, + "xmax": 13.414758682250977, + "ymin": 52.519893646240234, + "ymax": 52.519901275634766 + } + }, + { + "id": "035b544e-40f5-4ce0-a06f-1c9032ded028", + "version": 13, + "names": { + "primary": "EDEKA Moch Supermarket" + }, + "addresses": [ + { + "freeform": "Grunerstraße 20", + "locality": "Berlin", + "postcode": "10179", + "region": null, + "country": "DE" + } + ], + "phones": ["+493024045625"], + "websites": ["http://Edeka.de/"], + "confidence": 0.9999057413816452, + "operating_status": null, + "sources": [ + { + "property": "", + "dataset": "meta", + "license": "CDLA-Permissive-2.0", + "record_id": "194804870560113", + "update_time": "2026-08-24T00:00:00.000Z" + }, + { + "property": "/properties/confidence", + "dataset": "Overture", + "license": "CDLA-Permissive-2.0", + "update_time": "2026-09-17T22:52:12Z" + } + ], + "bbox": { + "xmin": 13.414728164672852, + "xmax": 13.414730072021484, + "ymin": 52.51996994018555, + "ymax": 52.51997756958008 + } + }, + { + "id": "81270f18-8f0b-48a9-ae69-31d4ef96cdd5", + "version": 8, + "names": { + "primary": "MediaMarkt" + }, + "addresses": [ + { + "freeform": "Grunerstr. 20", + "locality": "Berlin", + "postcode": "10179", + "region": "Berlin", + "country": "DE" + } + ], + "phones": ["030 2408840"], + "websites": ["https://www.mediamarkt.de/markt/berlin-mitte"], + "confidence": 0.77, + "operating_status": null, + "sources": [ + { + "property": "", + "dataset": "Foursquare", + "license": "Apache-2.0", + "record_id": "4b1530cef964a5201da923e3", + "update_time": "2026-04-11T00:00:00.000" + }, + { + "property": "/properties/confidence", + "dataset": "Overture", + "license": "CDLA-Permissive-2.0", + "update_time": "2026-09-17T22:52:12Z" + } + ], + "bbox": { + "xmin": 13.414745330810547, + "xmax": 13.41474723815918, + "ymin": 52.519866943359375, + "ymax": 52.519874572753906 + } + }, + { + "id": "a56cd442-edcf-4d26-98c1-9c70de50f1d7", + "version": 11, + "names": { + "primary": "EDEKA Schaaf" + }, + "addresses": [ + { + "freeform": "Schillingstraße 2", + "locality": "Berlin", + "postcode": "10179", + "region": null, + "country": "DE" + } + ], + "phones": ["+493023458611"], + "websites": [ + "https://www.edeka.de/eh/minden-hannover/edeka-schaaf-schillingstr.-2/index.jsp" + ], + "confidence": 0.9999163304030895, + "operating_status": null, + "sources": [ + { + "property": "", + "dataset": "meta", + "license": "CDLA-Permissive-2.0", + "record_id": "101877065539523", + "update_time": "2026-09-14T00:00:00.000Z" + }, + { + "property": "/properties/confidence", + "dataset": "Overture", + "license": "CDLA-Permissive-2.0", + "update_time": "2026-09-17T22:52:12Z" + } + ], + "bbox": { + "xmin": 13.420568466186523, + "xmax": 13.420570373535156, + "ymin": 52.51737594604492, + "ymax": 52.51738357543945 + } + } + ] + }, + "archive": "https://gist.github.com/Medformatik/c36d8b8f44c88971277659512a533a51/8b33cd9238ba743f54f3235f2831470cf3bb5972" +} diff --git a/scripts/discovery-eval/business-name-address/tsconfig.json b/scripts/discovery-eval/business-name-address/tsconfig.json new file mode 100644 index 00000000..e6f83d5e --- /dev/null +++ b/scripts/discovery-eval/business-name-address/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../tsconfig.json", + "include": ["*.ts"] +} diff --git a/scripts/discovery-eval/tsconfig.json b/scripts/discovery-eval/tsconfig.json index a3bb5722..7b871988 100644 --- a/scripts/discovery-eval/tsconfig.json +++ b/scripts/discovery-eval/tsconfig.json @@ -7,5 +7,5 @@ "noEmit": true, "typeRoots": ["../../packages/cli/node_modules/@types"] }, - "include": ["*.ts", "../record-search-eval.mts"] + "include": ["*.ts", "business-name-address/*.ts", "../record-search-eval.mts"] }