goblin-swiss 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/getAddress.js +67 -34
- package/package.json +1 -1
package/lib/getAddress.js
CHANGED
|
@@ -1,69 +1,102 @@
|
|
|
1
|
-
const BASE_URL = 'https://api3.geo.admin.ch/rest/services/ech/MapServer/
|
|
1
|
+
const BASE_URL = 'https://api3.geo.admin.ch/rest/services/ech/MapServer/';
|
|
2
2
|
|
|
3
3
|
const LAYER = 'ch.swisstopo.amtliches-gebaeudeadressverzeichnis';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* street: string|null,
|
|
12
|
-
* houseNumber: string|null,
|
|
13
|
-
* zip: string|null,
|
|
14
|
-
* city: string|null,
|
|
15
|
-
* municipality: string|null,
|
|
16
|
-
* municipalityId: number|null,
|
|
17
|
-
* egid: number|null,
|
|
18
|
-
* edid: number|null,
|
|
19
|
-
* egaid: number|null
|
|
20
|
-
* }|null>}
|
|
21
|
-
*/
|
|
22
|
-
async function getAddress(featureId, signal) {
|
|
23
|
-
const [egid, edid = '0'] = String(featureId).split('_');
|
|
5
|
+
function parseZipLabel(zipLabel) {
|
|
6
|
+
const match = String(zipLabel ?? '')
|
|
7
|
+
.trim()
|
|
8
|
+
.match(/^(\d{4})\s+(.+)$/);
|
|
9
|
+
return match ? {zip: match[1], city: match[2]} : {zip: null, city: null};
|
|
10
|
+
}
|
|
24
11
|
|
|
12
|
+
async function findAddress(featureId, locale, signal) {
|
|
13
|
+
const [egid, edid = '0'] = String(featureId).split('_');
|
|
25
14
|
const params = new URLSearchParams({
|
|
26
15
|
layer: LAYER,
|
|
27
16
|
searchText: egid,
|
|
28
17
|
searchField: 'bdg_egid',
|
|
29
18
|
contains: 'false',
|
|
30
19
|
returnGeometry: 'false',
|
|
31
|
-
lang:
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const response = await fetch(`${BASE_URL}?${params}`, {
|
|
35
|
-
signal,
|
|
20
|
+
lang: locale,
|
|
36
21
|
});
|
|
37
22
|
|
|
23
|
+
const response = await fetch(`${BASE_URL}find?${params}`, {signal});
|
|
38
24
|
if (!response.ok) {
|
|
39
25
|
throw new Error(
|
|
40
26
|
`GeoAdmin lookup failed: ${response.status} ${response.statusText}`
|
|
41
27
|
);
|
|
42
28
|
}
|
|
43
29
|
|
|
44
|
-
const
|
|
30
|
+
const {results = []} = await response.json();
|
|
31
|
+
return (
|
|
32
|
+
results.find(({attributes}) => String(attributes?.adr_edid ?? '0') === edid)
|
|
33
|
+
?.attributes ??
|
|
34
|
+
results[0]?.attributes ??
|
|
35
|
+
null
|
|
36
|
+
);
|
|
37
|
+
}
|
|
45
38
|
|
|
46
|
-
|
|
39
|
+
async function getFeatureAddress(featureId, locale, signal) {
|
|
40
|
+
if (String(featureId).includes('_')) {
|
|
41
|
+
return findAddress(featureId, locale, signal);
|
|
42
|
+
}
|
|
47
43
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
const params = new URLSearchParams({
|
|
45
|
+
returnGeometry: 'false',
|
|
46
|
+
lang: locale,
|
|
47
|
+
});
|
|
48
|
+
const response = await fetch(
|
|
49
|
+
`${BASE_URL}${LAYER}/${encodeURIComponent(featureId)}?${params}`,
|
|
50
|
+
{signal}
|
|
51
|
+
);
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`GeoAdmin lookup failed: ${response.status} ${response.statusText}`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
52
57
|
|
|
53
|
-
|
|
58
|
+
const {feature} = await response.json();
|
|
59
|
+
return feature?.attributes ?? null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Resolve a structured address from a GeoAdmin SearchServer featureId.
|
|
64
|
+
*
|
|
65
|
+
* @param {string|number} featureId - SearchServer featureId.
|
|
66
|
+
* @param {string} [locale='fr'] - Result language.
|
|
67
|
+
* @param {AbortSignal} [signal] - Optional abort signal.
|
|
68
|
+
* @returns {Promise<{
|
|
69
|
+
* street: string|null,
|
|
70
|
+
* houseNumber: string|null,
|
|
71
|
+
* zip: string|null,
|
|
72
|
+
* city: string|null,
|
|
73
|
+
* municipality: string|null,
|
|
74
|
+
* municipalityId: number|null,
|
|
75
|
+
* egid: number|null,
|
|
76
|
+
* edid: number|null,
|
|
77
|
+
* egaid: number|null,
|
|
78
|
+
* canton: string|null
|
|
79
|
+
* }|null>}
|
|
80
|
+
*/
|
|
81
|
+
async function getAddress(featureId, locale = 'fr', signal) {
|
|
82
|
+
const attrs = await getFeatureAddress(featureId, locale, signal);
|
|
83
|
+
if (!attrs) {
|
|
54
84
|
return null;
|
|
55
85
|
}
|
|
56
86
|
|
|
57
|
-
const
|
|
87
|
+
const {zip, city} = parseZipLabel(attrs.zip_label);
|
|
58
88
|
|
|
59
89
|
return {
|
|
60
|
-
street: attrs.stn_label ??
|
|
90
|
+
street: attrs.stn_label ?? null,
|
|
61
91
|
houseNumber: attrs.adr_number ?? null,
|
|
92
|
+
zip,
|
|
93
|
+
city,
|
|
62
94
|
municipality: attrs.com_name ?? null,
|
|
63
95
|
municipalityId: attrs.com_fosnr ?? null,
|
|
64
96
|
egid: attrs.bdg_egid ?? null,
|
|
65
97
|
edid: attrs.adr_edid ?? null,
|
|
66
98
|
egaid: attrs.adr_egaid ?? null,
|
|
99
|
+
canton: attrs.com_canton ?? null,
|
|
67
100
|
};
|
|
68
101
|
}
|
|
69
102
|
|