@chaosity/location-client 0.4.0 → 0.4.2
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/dist/adapters/GeoPlaces.js +53 -4
- package/dist/maps/mapStyle.js +14 -1
- package/package.json +1 -1
|
@@ -2,6 +2,47 @@ import { GeocodeCommand, GetPlaceAdditionalFeature, GetPlaceCommand, ReverseGeoc
|
|
|
2
2
|
import { geocodeResponseToFeatureCollection, getPlaceResponseToFeatureCollection, reverseGeocodeResponseToFeatureCollection, } from '@aws/amazon-location-utilities-datatypes';
|
|
3
3
|
import debug from 'debug';
|
|
4
4
|
const log = debug('location-client:geocoder');
|
|
5
|
+
/**
|
|
6
|
+
* Give the control the fields it renders, not just the ones GeoJSON needs.
|
|
7
|
+
*
|
|
8
|
+
* `@maplibre/maplibre-gl-geocoder` is a Carmen-shaped consumer: its result list
|
|
9
|
+
* calls `item.place_name.split(',')`, the input takes `result.place_name` on
|
|
10
|
+
* select, and fly-to reads `center` / `bbox`. The AWS converters produce plain
|
|
11
|
+
* GeoJSON — `properties` and `geometry` only — so a forward geocode used to
|
|
12
|
+
* hand the control features with no `place_name`. The list renderer threw, the
|
|
13
|
+
* control caught it and emitted `error`, and with no listener that surfaced as
|
|
14
|
+
* `Unhandled error. (undefined)` in the console: the Enter key silently did
|
|
15
|
+
* nothing. Suggestions were unaffected because that path renders `text`.
|
|
16
|
+
*
|
|
17
|
+
* The `as MaplibreGeocoderFeatureResults` cast this replaces is what hid it —
|
|
18
|
+
* `place_name` and `text` are required on the type.
|
|
19
|
+
*/
|
|
20
|
+
function toCarmenFeatures(features) {
|
|
21
|
+
return features.map((feature) => {
|
|
22
|
+
const p = (feature.properties ?? {});
|
|
23
|
+
const title = typeof p.Title === 'string' ? p.Title : '';
|
|
24
|
+
const label = typeof p['Address.Label'] === 'string' ? p['Address.Label'] : '';
|
|
25
|
+
// `flattenProperties` flattens nested OBJECTS (Address.Label) but leaves an
|
|
26
|
+
// array of numbers intact, so MapView is still [minx, miny, maxx, maxy].
|
|
27
|
+
const view = p.MapView;
|
|
28
|
+
const bbox = Array.isArray(view) &&
|
|
29
|
+
view.length === 4 &&
|
|
30
|
+
view.every((v) => typeof v === 'number')
|
|
31
|
+
? view
|
|
32
|
+
: undefined;
|
|
33
|
+
const center = feature.geometry?.type === 'Point'
|
|
34
|
+
? feature.geometry.coordinates
|
|
35
|
+
: undefined;
|
|
36
|
+
return {
|
|
37
|
+
...feature,
|
|
38
|
+
text: title || label,
|
|
39
|
+
place_name: label || title,
|
|
40
|
+
place_type: typeof p.PlaceType === 'string' ? [p.PlaceType] : [],
|
|
41
|
+
...(bbox ? { bbox } : {}),
|
|
42
|
+
...(center ? { center } : {}),
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
}
|
|
5
46
|
export class GeoPlaces {
|
|
6
47
|
constructor(client, map, options = {}) {
|
|
7
48
|
this.client = client;
|
|
@@ -53,10 +94,14 @@ export class GeoPlaces {
|
|
|
53
94
|
};
|
|
54
95
|
}
|
|
55
96
|
const response = (await this.client.send(new GeocodeCommand(commandInput)));
|
|
56
|
-
const
|
|
97
|
+
const converted = geocodeResponseToFeatureCollection(response, {
|
|
57
98
|
flattenProperties: true,
|
|
58
99
|
});
|
|
59
|
-
|
|
100
|
+
const result = {
|
|
101
|
+
type: 'FeatureCollection',
|
|
102
|
+
features: toCarmenFeatures(converted.features),
|
|
103
|
+
};
|
|
104
|
+
log('forwardGeocode returned %d results', result.features.length);
|
|
60
105
|
return result;
|
|
61
106
|
}
|
|
62
107
|
async reverseGeocode(config) {
|
|
@@ -70,10 +115,14 @@ export class GeoPlaces {
|
|
|
70
115
|
Language: this.normalizeLanguage(config.language),
|
|
71
116
|
};
|
|
72
117
|
const response = (await this.client.send(new ReverseGeocodeCommand(commandInput)));
|
|
73
|
-
const
|
|
118
|
+
const converted = reverseGeocodeResponseToFeatureCollection(response, {
|
|
74
119
|
flattenProperties: true,
|
|
75
120
|
});
|
|
76
|
-
|
|
121
|
+
const result = {
|
|
122
|
+
type: 'FeatureCollection',
|
|
123
|
+
features: toCarmenFeatures(converted.features),
|
|
124
|
+
};
|
|
125
|
+
log('reverseGeocode returned %d results', result.features.length);
|
|
77
126
|
return result;
|
|
78
127
|
}
|
|
79
128
|
async getSuggestions(config) {
|
package/dist/maps/mapStyle.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { parseErrorResponse } from '../transport/errors';
|
|
1
2
|
/**
|
|
2
3
|
* Build a map style descriptor URL for the Location Service API.
|
|
3
4
|
*
|
|
@@ -61,7 +62,19 @@ export async function fetchMapStyle(apiUrl, mapStyle, getToken, options = {}) {
|
|
|
61
62
|
},
|
|
62
63
|
});
|
|
63
64
|
if (!response.ok) {
|
|
64
|
-
|
|
65
|
+
// Read the body. The API sends `{message, code, requestId}` and the message
|
|
66
|
+
// is the whole point of it — for a style request it is Amazon's own
|
|
67
|
+
// sentence, forwarded verbatim by location-service-api#89:
|
|
68
|
+
//
|
|
69
|
+
// 400 "Traffic is not supported for style."
|
|
70
|
+
// 400 "light is not a supported color scheme for style Standard."
|
|
71
|
+
//
|
|
72
|
+
// This used to throw `Failed to fetch map style: 400`, discarding all of it
|
|
73
|
+
// two lines before anyone could read it — the same defect #89 fixed in the
|
|
74
|
+
// API, one layer up. Reuses parseErrorResponse so a style failure arrives as
|
|
75
|
+
// the same LocationServiceException as every other call in this package,
|
|
76
|
+
// with `code`, `statusCode` and `requestId` intact.
|
|
77
|
+
throw parseErrorResponse(response.status, response.statusText, await response.text(), response.headers);
|
|
65
78
|
}
|
|
66
79
|
const style = (await response.json());
|
|
67
80
|
if (language) {
|