From fe6e59f42766973f071fcebbabfcd261aaaf1539 Mon Sep 17 00:00:00 2001 From: Jan-Henrik Bruhn Date: Fri, 6 Mar 2026 12:55:31 +0100 Subject: [PATCH] fix: adjust category assignments, fix retries --- apps/web/app/admin/cities/new/page.tsx | 10 +++++++--- infra/osm2pgsql.lua | 10 ++++++---- shared/src/osm-tags.ts | 11 +++++++---- shared/src/profiles.ts | 5 ----- shared/src/queue.ts | 3 ++- worker/src/valhalla-main.ts | 1 + 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/apps/web/app/admin/cities/new/page.tsx b/apps/web/app/admin/cities/new/page.tsx index f2c6898..2de3fbc 100644 --- a/apps/web/app/admin/cities/new/page.tsx +++ b/apps/web/app/admin/cities/new/page.tsx @@ -195,6 +195,7 @@ interface NominatimResult { lon: string; type: string; class: string; + place_rank: number; geojson?: { type: string; coordinates: unknown }; } @@ -232,13 +233,16 @@ function LocationSelector({ setSearching(true); try { const res = await fetch( - `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(query)}&polygon_geojson=1&featuretype=settlement&format=json&limit=8`, + `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(query)}&polygon_geojson=1&format=json&limit=8`, { headers: { "User-Agent": "Transportationer/1.0 (15-minute city analyzer)" } }, ); const data: NominatimResult[] = await res.json(); - // Keep only results that have a real polygon boundary + // Keep only results with a real polygon and place_rank >= 13. + // Landkreise/counties are rank 12; cities/towns/municipalities are 13+. const polygons = data.filter( - (r) => r.geojson?.type === "Polygon" || r.geojson?.type === "MultiPolygon", + (r) => + r.place_rank >= 12 && + (r.geojson?.type === "Polygon" || r.geojson?.type === "MultiPolygon"), ); setResults(polygons); setShowDropdown(true); diff --git a/infra/osm2pgsql.lua b/infra/osm2pgsql.lua index eac061c..cccf26c 100644 --- a/infra/osm2pgsql.lua +++ b/infra/osm2pgsql.lua @@ -36,8 +36,10 @@ local tag_map = { bicycle_rental = { 'transport', 'bike_share' }, car_sharing = { 'transport', 'car_share' }, ferry_terminal = { 'transport', 'ferry' }, + bus_station = { 'transport', 'bus_stop' }, -- work_school kindergarten = { 'work_school', 'kindergarten' }, + childcare = { 'work_school', 'kindergarten' }, school = { 'work_school', 'school' }, university = { 'work_school', 'university' }, college = { 'work_school', 'university' }, @@ -59,6 +61,7 @@ local tag_map = { }, shop = { supermarket = { 'service_trade', 'supermarket' }, + wholesale = { 'service_trade', 'supermarket' }, convenience = { 'service_trade', 'convenience' }, bakery = { 'service_trade', 'cafe' }, pharmacy = { 'service_trade', 'pharmacy' }, @@ -66,6 +69,8 @@ local tag_map = { dry_cleaning = { 'service_trade', 'laundry' }, greengrocer = { 'service_trade', 'market' }, butcher = { 'service_trade', 'market' }, + department_store= { 'service_trade', 'market' }, + mall = { 'service_trade', 'market' }, }, highway = { bus_stop = { 'transport', 'bus_stop' }, @@ -75,14 +80,13 @@ local tag_map = { halt = { 'transport', 'train_station' }, tram_stop = { 'transport', 'tram_stop' }, subway_entrance = { 'transport', 'metro' }, + subway_station = { 'transport', 'metro' }, }, -- public_transport stop_position/platform intentionally excluded: -- they duplicate highway=bus_stop / railway=tram_stop nodes at the same -- physical location and would double-count those stops in scoring. office = { coworking = { 'work_school', 'coworking' }, - company = { 'work_school', 'office' }, - government = { 'work_school', 'office' }, }, tourism = { museum = { 'culture_community', 'museum' }, @@ -99,8 +103,6 @@ local tag_map = { arts_centre = { 'culture_community', 'community_center' }, }, landuse = { - commercial = { 'work_school', 'office' }, - office = { 'work_school', 'office' }, recreation_ground = { 'recreation', 'green_space' }, grass = { 'recreation', 'green_space' }, meadow = { 'recreation', 'green_space' }, diff --git a/shared/src/osm-tags.ts b/shared/src/osm-tags.ts index 96ef238..c259dad 100644 --- a/shared/src/osm-tags.ts +++ b/shared/src/osm-tags.ts @@ -39,6 +39,7 @@ export const CATEGORIES: CategoryDefinition[] = [ key: "shop", values: [ "supermarket", + "wholesale", "convenience", "bakery", "pharmacy", @@ -46,6 +47,8 @@ export const CATEGORIES: CategoryDefinition[] = [ "dry_cleaning", "greengrocer", "butcher", + "department_store", + "mall", ], }, { @@ -73,11 +76,11 @@ export const CATEGORIES: CategoryDefinition[] = [ { key: "highway", values: ["bus_stop"] }, { key: "railway", - values: ["station", "halt", "tram_stop", "subway_entrance"], + values: ["station", "halt", "tram_stop", "subway_entrance", "subway_station"], }, { key: "amenity", - values: ["bicycle_rental", "car_sharing", "ferry_terminal"], + values: ["bicycle_rental", "car_sharing", "ferry_terminal", "bus_station"], }, { key: "public_transport", @@ -92,18 +95,18 @@ export const CATEGORIES: CategoryDefinition[] = [ defaultThresholdMinutes: 20, color: "#2a9d8f", tags: [ - { key: "office", values: ["coworking", "company", "government"] }, + { key: "office", values: ["coworking"] }, { key: "amenity", values: [ "kindergarten", + "childcare", "school", "university", "college", "driving_school", ], }, - { key: "landuse", values: ["commercial", "office"] }, ], }, { diff --git a/shared/src/profiles.ts b/shared/src/profiles.ts index 7555c7f..8dae43c 100644 --- a/shared/src/profiles.ts +++ b/shared/src/profiles.ts @@ -59,7 +59,6 @@ export const UNIVERSAL_SUBCATEGORY_WEIGHTS: Record = { kindergarten: 0.75, // essential for young families university: 0.55, // higher education — relevant to students/young adults coworking: 0.55, // remote / flexible work - office: 0.1, // landuse centroid — not a meaningful walkable destination // ── culture_community ───────────────────────────────────────────────────── hospital: 1.0, // critical healthcare @@ -132,7 +131,6 @@ export const PROFILES: Record = { gym: 0.5, university: 0.2, coworking: 0.25, - office: 0.05, theatre: 0.3, museum: 0.35, bar: 0.0, @@ -179,7 +177,6 @@ export const PROFILES: Record = { kindergarten: 0.05, university: 0.15, coworking: 0.05, - office: 0.0, playground: 0.3, gym: 0.5, swimming_pool: 0.5, @@ -222,7 +219,6 @@ export const PROFILES: Record = { kindergarten: 0.05, playground: 0.15, university: 0.35, - office: 0.05, social_services: 0.4, }, }, @@ -269,7 +265,6 @@ export const PROFILES: Record = { // not relevant school: 0.05, kindergarten: 0.05, - office: 0.05, playground: 0.2, }, }, diff --git a/shared/src/queue.ts b/shared/src/queue.ts index 45de497..9741903 100644 --- a/shared/src/queue.ts +++ b/shared/src/queue.ts @@ -147,7 +147,8 @@ export const JOB_OPTIONS: Record = { removeOnFail: { age: 86400 * 30 }, }, "build-valhalla": { - attempts: 1, + attempts: 3, + backoff: { type: "fixed", delay: 60_000 }, removeOnComplete: { age: 86400 * 7 }, removeOnFail: { age: 86400 * 30 }, }, diff --git a/worker/src/valhalla-main.ts b/worker/src/valhalla-main.ts index 02ff36c..b395285 100644 --- a/worker/src/valhalla-main.ts +++ b/worker/src/valhalla-main.ts @@ -75,6 +75,7 @@ const worker = new Worker( concurrency: 1, lockDuration: 1_800_000, // 30 min — large-region tile builds can be very slow lockRenewTime: 60_000, + maxStalledCount: 3, }, );