Skip to content

Commit 6e64853

Browse files
committed
feat(overture): link the Overture Maps reference to the GERS explorer
The place card credited Overture by showing the GERS id under "Overture Maps" but without a link. Make it clickable: the gers id-scheme view now builds an explore.overturemaps.org deep link — ?feature=places.place.<gers>#16/<lat>/<lng>. buildUrl gains an optional context carrying the place coordinates (place-ids), and buildExternalRefs threads place.coordinates through. Degrades to the bare ?feature= link when coordinates are absent.
1 parent 9d879a2 commit 6e64853

5 files changed

Lines changed: 41 additions & 7 deletions

File tree

apps/web/src/components/panels/place/PlaceInfoTab.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ export function PlaceInfoTab({ place, isLoading }: Props) {
267267
const hasDescription = Boolean(infoDescription);
268268
const hasFacts = Boolean(place.facts?.length);
269269
const hasOsmTags = Boolean(place.osmTags && Object.keys(place.osmTags).length > 0);
270-
const externalRefs = buildExternalRefs(place.ids);
270+
const externalRefs = buildExternalRefs(place.ids, place.coordinates);
271271
const hasExternalRefs = externalRefs.length > 0;
272272
const hasAnyContent = hasDescription || hasFacts || hasOsmTags || hasExternalRefs;
273273

apps/web/src/components/panels/place/externalIdLinks.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ export interface ExternalRef {
2121
* schemes (transit providers, data-source item ids) are not cross-refs
2222
* and shouldn't be shown.
2323
*/
24-
export function buildExternalRefs(ids: PlaceIds | undefined): ExternalRef[] {
24+
export function buildExternalRefs(
25+
ids: PlaceIds | undefined,
26+
coordinates?: [number, number],
27+
): ExternalRef[] {
2528
if (!ids) return [];
2629

2730
type Entry = {
@@ -45,7 +48,7 @@ export function buildExternalRefs(ids: PlaceIds | undefined): ExternalRef[] {
4548
order: view.displayOrder ?? Number.POSITIVE_INFINITY,
4649
insertionIndex: insertionIndex++,
4750
label: view.label,
48-
url: view.buildUrl?.(value),
51+
url: view.buildUrl?.(value, { coordinates }),
4952
});
5053
}
5154

packages/place-ids/src/builtin-views.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,15 @@ export function registerBuiltinIdSchemeViews(): void {
5757
scheme: "gers",
5858
label: "Overture Maps",
5959
displayOrder: 25,
60-
// Overture's GERS ids have no canonical per-feature public page, so the id
61-
// is shown as a source credit without a deep link (like EVA/GTFS).
60+
buildUrl(value, context) {
61+
// Overture's GERS explorer: ?feature=places.place.<gers>#<zoom>/<lat>/<lng>.
62+
const base = `https://explore.overturemaps.org/?feature=places.place.${encodeURIComponent(value)}`;
63+
const c = context?.coordinates;
64+
if (c && Number.isFinite(c[0]) && Number.isFinite(c[1])) {
65+
return `${base}#16/${c[1]}/${c[0]}`;
66+
}
67+
return base;
68+
},
6269
});
6370

6471
// Transit / stations

packages/place-ids/src/external-platforms.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,18 @@ describe("external platform URL builders", () => {
8989
expect(view?.label).toBe("Overture Maps");
9090
expect(view?.internal).toBeFalsy();
9191
});
92+
93+
it("builds an Overture explorer deep link from the gers id + coordinates", () => {
94+
registerBuiltinIdSchemeViews();
95+
const view = getIdSchemeView("gers");
96+
expect(
97+
view?.buildUrl?.("aff9ee5d-3ec2-4ab0-af60-823b5244fb5f", { coordinates: [6.6867, 51.1734] }),
98+
).toBe(
99+
"https://explore.overturemaps.org/?feature=places.place.aff9ee5d-3ec2-4ab0-af60-823b5244fb5f#16/51.1734/6.6867",
100+
);
101+
// Without coordinates it still links to the feature, omitting the viewport.
102+
expect(view?.buildUrl?.("abc")).toBe(
103+
"https://explore.overturemaps.org/?feature=places.place.abc",
104+
);
105+
});
92106
});

packages/place-ids/src/presentation.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@
88
* order for anything without an explicit number.
99
*/
1010

11+
/**
12+
* Optional context passed to {@link IdSchemeView.buildUrl}, for schemes whose
13+
* URL embeds the place's location (e.g. a map-explorer deep link).
14+
*/
15+
export interface IdSchemeUrlContext {
16+
/** Place coordinates as `[lng, lat]`. */
17+
coordinates?: [number, number];
18+
}
19+
1120
export interface IdSchemeView {
1221
/** Scheme key in `Place.ids` (e.g. `"osm"`, `"yelp"`, `"ocm"`). */
1322
scheme: string;
@@ -24,9 +33,10 @@ export interface IdSchemeView {
2433
/**
2534
* Return an external URL for a given id value, or `undefined` if the
2635
* scheme isn't naturally linkable (e.g. a raw EVA number). Accepts the
27-
* raw id value (without the `scheme:` prefix).
36+
* raw id value (without the `scheme:` prefix) and optional place context
37+
* (e.g. coordinates) for schemes whose URL embeds a map viewport.
2838
*/
29-
buildUrl?(value: string): string | undefined;
39+
buildUrl?(value: string, context?: IdSchemeUrlContext): string | undefined;
3040
}
3141

3242
const registry = new Map<string, IdSchemeView>();

0 commit comments

Comments
 (0)