Skip to content

Commit 2fadf9f

Browse files
committed
Pull OSM element type (N/W/R through to conflated dataset.
1 parent 8fd31b5 commit 2fadf9f

6 files changed

Lines changed: 40 additions & 2 deletions

File tree

config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ upload:
277277
conflated_layer_name: "conflated_pois"
278278
osm_properties:
279279
- osm_id
280+
- osm_type # node|way|relation — drives popup OSM link path
280281
- source
281282
- name
282283
- conf_mean # drives confidence-based point coloring
@@ -292,6 +293,8 @@ upload:
292293
conflated_properties:
293294
- unified_id
294295
- source
296+
- osm_id
297+
- osm_type # node|way|relation — drives popup OSM link path
295298
- shared_label
296299
- conf_mean
297300
- name

site/src/components/PoiPopup.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@
195195
<a
196196
v-if="entry.osm_id"
197197
class="osm-link"
198-
:href="`https://www.openstreetmap.org/node/${cleanOsmId(entry.osm_id)}`"
198+
:href="`https://www.openstreetmap.org/${entry.osm_type || 'node'}/${cleanOsmId(entry.osm_id)}`"
199199
target="_blank"
200200
rel="noopener"
201201
>

site/src/layers/conflatedLayer.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ export function wrapConflatedFeature(rf) {
7070
_source: 'conflated',
7171
unified_id: rf.get('unified_id'),
7272
source: rf.get('source'),
73+
osm_id: rf.get('osm_id'),
74+
osm_type: rf.get('osm_type'),
7375
shared_label: rf.get('shared_label'),
7476
name: rf.get('name'),
7577
brand: rf.get('brand'),

site/src/layers/osmLayer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export function wrapOsmFeature(rf) {
7575
const props = {
7676
_source: 'osm',
7777
osm_id: rf.get('osm_id'),
78+
osm_type: rf.get('osm_type'),
7879
name: rf.get('name'),
7980
conf_mean: rf.get('conf_mean'),
8081
source_dataset: 'OpenStreetMap',

src/openpois/conflation/merge.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ def _build_matched_gdf(
116116
geoms = _pick_geometries(osm_geoms, ov_geoms)
117117

118118
osm_ids = osm_gdf["osm_id"].to_numpy()[oi]
119+
osm_types = osm_gdf["osm_type"].to_numpy()[oi]
119120
ov_ids = overture_gdf["overture_id"].to_numpy()[vi]
120121

121122
unified_ids = np.array(
@@ -131,6 +132,7 @@ def _build_matched_gdf(
131132
"unified_id": unified_ids,
132133
"source": "matched",
133134
"osm_id": osm_ids,
135+
"osm_type": osm_types,
134136
"overture_id": ov_ids,
135137
"name": names,
136138
"brand": brands,
@@ -166,6 +168,7 @@ def _build_unmatched_osm_gdf(
166168
n = len(idx)
167169

168170
osm_ids = osm_gdf["osm_id"].to_numpy()[idx]
171+
osm_types = osm_gdf["osm_type"].to_numpy()[idx]
169172
names = osm_gdf["name"].to_numpy()[idx]
170173
brand_arr = (
171174
osm_gdf["brand"].to_numpy()[idx]
@@ -186,6 +189,7 @@ def _build_unmatched_osm_gdf(
186189
"unified_id": unified_ids,
187190
"source": "osm",
188191
"osm_id": osm_ids,
192+
"osm_type": osm_types,
189193
"overture_id": np.full(n, None, dtype = object),
190194
"name": names,
191195
"brand": brand_arr,
@@ -241,6 +245,7 @@ def _build_unmatched_overture_gdf(
241245
"unified_id": unified_ids,
242246
"source": "overture",
243247
"osm_id": np.full(n, None, dtype = object),
248+
"osm_type": np.full(n, None, dtype = object),
244249
"overture_id": ov_ids,
245250
"name": names,
246251
"brand": brand_arr,

tests/test_merge.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def osm_gdf():
2121
return gpd.GeoDataFrame(
2222
{
2323
"osm_id": [100, 200, 300],
24+
"osm_type": ["node", "way", "relation"],
2425
"name": ["Coffee Shop", "Grocery Store", "Park"],
2526
"brand": ["Starbucks", None, None],
2627
"conf_mean": [0.8, 0.6, 0.9],
@@ -171,6 +172,7 @@ def test_geometry_preference_polygon_over_point(self):
171172
osm = gpd.GeoDataFrame(
172173
{
173174
"osm_id": [1],
175+
"osm_type": ["way"],
174176
"name": ["Park"],
175177
"brand": [None],
176178
"conf_mean": [0.9],
@@ -219,7 +221,8 @@ def test_expected_columns(
219221
osm_labels, ov_labels,
220222
)
221223
expected_cols = {
222-
"unified_id", "source", "osm_id", "overture_id",
224+
"unified_id", "source", "osm_id", "osm_type",
225+
"overture_id",
223226
"name", "brand", "shared_label",
224227
"conf_mean", "conf_lower", "conf_upper",
225228
"match_score", "match_distance_m",
@@ -252,6 +255,30 @@ def test_shared_label_values(
252255
].iloc[0]
253256
assert park_row["shared_label"] == "Park"
254257

258+
def test_osm_type_propagation(
259+
self, osm_gdf, overture_gdf, matches,
260+
):
261+
"""osm_type must flow through matched + unmatched-OSM rows and
262+
be null on unmatched-Overture rows so the frontend can route
263+
OpenStreetMap links to /node/, /way/, or /relation/ correctly.
264+
"""
265+
osm_labels = np.array(["Cafe", "Supermarket", "Park"])
266+
ov_labels = np.array(["Cafe", "Supermarket", "Park"])
267+
result = merge_matched_pois(
268+
osm_gdf, overture_gdf, matches,
269+
osm_labels, ov_labels,
270+
)
271+
# Matched row (osm_idx=0 → node)
272+
matched = result[result["source"] == "matched"].iloc[0]
273+
assert matched["osm_type"] == "node"
274+
# Unmatched-OSM rows (idx 1,2 → way, relation)
275+
osm_only = result[result["source"] == "osm"].set_index("osm_id")
276+
assert osm_only.loc[200, "osm_type"] == "way"
277+
assert osm_only.loc[300, "osm_type"] == "relation"
278+
# Unmatched-Overture rows carry no osm_type
279+
ov_only = result[result["source"] == "overture"]
280+
assert ov_only["osm_type"].isna().all()
281+
255282

256283
# -----------------------------------------------------------------
257284
# Disk-backed row-sliced merge

0 commit comments

Comments
 (0)