@chaosity/location-client 0.5.1 → 0.7.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/README.md +73 -4
- package/dist/adapters/GeoPlaces.d.ts +1 -1
- package/dist/auth/TokenProvider.js +3 -3
- package/dist/cjs/adapters/GeoPlaces.d.ts +64 -0
- package/dist/cjs/adapters/GeoPlaces.js +213 -0
- package/dist/cjs/auth/TokenProvider.d.ts +64 -0
- package/dist/cjs/auth/TokenProvider.js +144 -0
- package/dist/cjs/auth/tokenRefresh.d.ts +37 -0
- package/dist/cjs/auth/tokenRefresh.js +58 -0
- package/dist/cjs/client/GeoPlacesClient.d.ts +42 -0
- package/dist/cjs/client/GeoPlacesClient.js +92 -0
- package/dist/cjs/errors/LocationServiceException.d.ts +44 -0
- package/dist/cjs/errors/LocationServiceException.js +60 -0
- package/dist/cjs/index.d.ts +24 -0
- package/dist/cjs/index.js +72 -0
- package/dist/cjs/maps/Utils.d.ts +2 -0
- package/dist/cjs/maps/Utils.js +8 -0
- package/dist/cjs/maps/createTransformRequest.d.ts +12 -0
- package/dist/cjs/maps/createTransformRequest.js +87 -0
- package/dist/cjs/maps/mapEnums.d.ts +102 -0
- package/dist/cjs/maps/mapEnums.js +103 -0
- package/dist/cjs/maps/mapLanguage.d.ts +43 -0
- package/dist/cjs/maps/mapLanguage.js +75 -0
- package/dist/cjs/maps/mapPoi.d.ts +44 -0
- package/dist/cjs/maps/mapPoi.js +64 -0
- package/dist/cjs/maps/mapStyle.d.ts +77 -0
- package/dist/cjs/maps/mapStyle.js +111 -0
- package/dist/cjs/maps/staticMap.d.ts +85 -0
- package/dist/cjs/maps/staticMap.js +81 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/server/LocationServiceConnector.d.ts +104 -0
- package/dist/cjs/server/LocationServiceConnector.js +270 -0
- package/dist/cjs/server/getClientConfig.d.ts +94 -0
- package/dist/cjs/server/getClientConfig.js +174 -0
- package/dist/cjs/server/index.d.ts +6 -0
- package/dist/cjs/server/index.js +9 -0
- package/dist/cjs/transport/endpoints.d.ts +2 -0
- package/dist/cjs/transport/endpoints.js +34 -0
- package/dist/cjs/transport/errors.d.ts +32 -0
- package/dist/cjs/transport/errors.js +120 -0
- package/dist/cjs/transport/http.d.ts +24 -0
- package/dist/cjs/transport/http.js +142 -0
- package/dist/cjs/types/index.d.ts +53 -0
- package/dist/cjs/types/index.js +3 -0
- package/dist/cjs/utils/roundPosition.d.ts +66 -0
- package/dist/cjs/utils/roundPosition.js +109 -0
- package/dist/cjs/utils/tokenClaims.d.ts +55 -0
- package/dist/cjs/utils/tokenClaims.js +61 -0
- package/dist/client/GeoPlacesClient.d.ts +6 -3
- package/dist/client/GeoPlacesClient.js +35 -11
- package/dist/index.d.ts +22 -22
- package/dist/index.js +12 -12
- package/dist/maps/Utils.d.ts +1 -1
- package/dist/maps/Utils.js +1 -1
- package/dist/maps/createTransformRequest.d.ts +2 -0
- package/dist/maps/createTransformRequest.js +45 -1
- package/dist/maps/mapLanguage.d.ts +1 -1
- package/dist/maps/mapStyle.d.ts +1 -1
- package/dist/maps/mapStyle.js +2 -2
- package/dist/maps/staticMap.d.ts +1 -1
- package/dist/maps/staticMap.js +1 -1
- package/dist/server/LocationServiceConnector.d.ts +58 -9
- package/dist/server/LocationServiceConnector.js +217 -38
- package/dist/server/getClientConfig.d.ts +58 -4
- package/dist/server/getClientConfig.js +108 -66
- package/dist/server/index.d.ts +6 -6
- package/dist/server/index.js +3 -3
- package/dist/transport/endpoints.d.ts +1 -1
- package/dist/transport/endpoints.js +1 -1
- package/dist/transport/errors.d.ts +14 -1
- package/dist/transport/errors.js +16 -1
- package/dist/transport/http.js +2 -2
- package/dist/types/index.d.ts +19 -0
- package/package.json +33 -11
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The values Amazon Location accepts for each map parameter.
|
|
4
|
+
*
|
|
5
|
+
* WHY THESE ARE EXPORTED AS VALUES, NOT JUST TYPES
|
|
6
|
+
*
|
|
7
|
+
* A type union gives you compile-time safety and nothing to iterate. Every
|
|
8
|
+
* consumer that renders a style picker then re-types the same list by hand into
|
|
9
|
+
* a `<select>`, and those copies drift the moment AWS adds a style. Exporting
|
|
10
|
+
* the arrays means a dropdown is `MAP_STYLES.map(...)` and cannot disagree with
|
|
11
|
+
* the type beside it.
|
|
12
|
+
*
|
|
13
|
+
* THESE ARE CASE SENSITIVE
|
|
14
|
+
*
|
|
15
|
+
* AWS documents them so, and since location-service-api#89 the API enforces it
|
|
16
|
+
* rather than forwarding a wrong-cased value for Amazon to reject with an
|
|
17
|
+
* unhelpful 404. `'light'` is not `'Light'`:
|
|
18
|
+
*
|
|
19
|
+
* GET /maps/Standard/descriptor?colorScheme=light
|
|
20
|
+
* 400 "'colorScheme' is case sensitive — use 'Light', not 'light'"
|
|
21
|
+
*
|
|
22
|
+
* So take the values from here rather than typing them, and the case is right
|
|
23
|
+
* by construction.
|
|
24
|
+
*
|
|
25
|
+
* MEMBERSHIP IS NOT THE WHOLE STORY
|
|
26
|
+
*
|
|
27
|
+
* A value being in one of these lists does not mean it is legal in every
|
|
28
|
+
* COMBINATION. `Traffic: 'All'` is valid, and `Style: 'Satellite'` is valid,
|
|
29
|
+
* but together they are not:
|
|
30
|
+
*
|
|
31
|
+
* 400 "Traffic is not supported for style."
|
|
32
|
+
*
|
|
33
|
+
* Amazon owns those rules and answers them per request; the API forwards that
|
|
34
|
+
* message verbatim. Do not try to encode combination rules here — they change
|
|
35
|
+
* without an SDK release.
|
|
36
|
+
*
|
|
37
|
+
* KEEPING THESE HONEST
|
|
38
|
+
*
|
|
39
|
+
* The API derives its copy from the AWS SDK's own `enums.d.ts` via
|
|
40
|
+
* `npm run generate:maps-enums`, so that side cannot drift. This file is the
|
|
41
|
+
* client-side mirror and every value below was additionally confirmed against
|
|
42
|
+
* the live geo-maps API on 2026-08-26. If the API starts rejecting something
|
|
43
|
+
* listed here, its generated list is the authority.
|
|
44
|
+
*/
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.MAP_FEATURE_MODES = exports.SCALE_BAR_UNITS = exports.LABEL_SIZES = exports.SPRITE_VARIANTS = exports.TRAVEL_MODES = exports.TRAFFIC_MODES = exports.CONTOUR_DENSITIES = exports.BUILDINGS = exports.TERRAINS = exports.COLOR_SCHEMES = exports.STATIC_MAP_STYLES = exports.MAP_STYLES = void 0;
|
|
47
|
+
/** Map styles for the style descriptor. */
|
|
48
|
+
exports.MAP_STYLES = [
|
|
49
|
+
'Hybrid',
|
|
50
|
+
'Monochrome',
|
|
51
|
+
'Satellite',
|
|
52
|
+
'Standard',
|
|
53
|
+
];
|
|
54
|
+
/**
|
|
55
|
+
* Styles the STATIC map accepts — deliberately narrower than `MAP_STYLES`.
|
|
56
|
+
*
|
|
57
|
+
* `/maps/static/*` takes only Satellite and Standard. Passing Hybrid or
|
|
58
|
+
* Monochrome there is a 400, so the two lists are not interchangeable.
|
|
59
|
+
*/
|
|
60
|
+
exports.STATIC_MAP_STYLES = ['Satellite', 'Standard'];
|
|
61
|
+
/** Light or dark cartography. Not applicable to the raster styles. */
|
|
62
|
+
exports.COLOR_SCHEMES = ['Dark', 'Light'];
|
|
63
|
+
/** Terrain overlay. `Hillshade` is shaded relief; `Terrain3D` is elevation. */
|
|
64
|
+
exports.TERRAINS = ['Hillshade', 'Terrain3D'];
|
|
65
|
+
/** 3D building extrusions. One value today, kept a list for when that changes. */
|
|
66
|
+
exports.BUILDINGS = ['Buildings3D'];
|
|
67
|
+
/**
|
|
68
|
+
* Elevation contour line density.
|
|
69
|
+
*
|
|
70
|
+
* All three work. An earlier version of this library documented `Medium` as
|
|
71
|
+
* "the only value currently supported by the AWS SDK", which was wrong — `High`
|
|
72
|
+
* and `Low` were both confirmed against the live API on 2026-08-26.
|
|
73
|
+
*/
|
|
74
|
+
exports.CONTOUR_DENSITIES = ['High', 'Low', 'Medium'];
|
|
75
|
+
/**
|
|
76
|
+
* Traffic overlay.
|
|
77
|
+
*
|
|
78
|
+
* `Congestion` was previously missing from this library's types, so it could
|
|
79
|
+
* not be requested from TypeScript even though the API accepts it.
|
|
80
|
+
*/
|
|
81
|
+
exports.TRAFFIC_MODES = ['All', 'Congestion'];
|
|
82
|
+
/** Routing overlays. Sent as a comma-separated list; each entry is checked. */
|
|
83
|
+
exports.TRAVEL_MODES = ['Transit', 'Truck'];
|
|
84
|
+
/** Sprite sheet variant. One value today. */
|
|
85
|
+
exports.SPRITE_VARIANTS = ['Default'];
|
|
86
|
+
/** Static map label size. */
|
|
87
|
+
exports.LABEL_SIZES = ['Large', 'Small'];
|
|
88
|
+
/** Static map scale bar units. */
|
|
89
|
+
exports.SCALE_BAR_UNITS = [
|
|
90
|
+
'Kilometers',
|
|
91
|
+
'KilometersMiles',
|
|
92
|
+
'Miles',
|
|
93
|
+
'MilesKilometers',
|
|
94
|
+
];
|
|
95
|
+
/**
|
|
96
|
+
* Static map points-of-interest rendering.
|
|
97
|
+
*
|
|
98
|
+
* A MODE, not a list of categories — an easy one to get wrong, and the reason
|
|
99
|
+
* the static map route returned a confusing error before
|
|
100
|
+
* location-service-api#35. To filter POIs on an interactive map, use
|
|
101
|
+
* `setPoiVisibility` instead.
|
|
102
|
+
*/
|
|
103
|
+
exports.MAP_FEATURE_MODES = ['Disabled', 'Enabled'];
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { MapLike } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* The `text-field` expression that prefers `language`, then English, then the
|
|
4
|
+
* feature's default name.
|
|
5
|
+
*
|
|
6
|
+
* Based on the approach documented at:
|
|
7
|
+
* https://docs.aws.amazon.com/location/latest/developerguide/how-to-set-preferred-language-map.html
|
|
8
|
+
*/
|
|
9
|
+
export declare function languageExpression(language: string): unknown[];
|
|
10
|
+
/**
|
|
11
|
+
* Whether a `text-field` reads a name property — the only kind of label a
|
|
12
|
+
* language rewrite makes sense for (#28).
|
|
13
|
+
*
|
|
14
|
+
* The AWS Standard style has 62 symbol layers with a text-field and 30 of
|
|
15
|
+
* them do NOT label by name: `building_label_number` reads
|
|
16
|
+
* `addr_housenumber`, and the 29 `shield_*` layers read `shield_text` or
|
|
17
|
+
* `ref`. Replacing those with a `name:<lang>` coalesce points them at a
|
|
18
|
+
* property their features do not carry, and the house numbers and road
|
|
19
|
+
* shields disappear — for `en` too. Measured against the live sandbox on
|
|
20
|
+
* 2026-08-29; the testbed showed it as "one map has house numbers, the
|
|
21
|
+
* others don't".
|
|
22
|
+
*
|
|
23
|
+
* Serialising the expression is the simplest exact test: `name`, `name:en`,
|
|
24
|
+
* `name_en` and a literal `{name}` template all contain it, and none of the
|
|
25
|
+
* non-name properties do.
|
|
26
|
+
*/
|
|
27
|
+
export declare function labelsByName(textField: unknown): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Apply a preferred display language to the name labels on a MapLibre map.
|
|
30
|
+
*
|
|
31
|
+
* AWS GeoMaps vector tiles carry `name:${lang}` properties (`name:en`,
|
|
32
|
+
* `name:fr`, `name:ja`, …). Every symbol layer whose `text-field` reads a
|
|
33
|
+
* name is rewritten to prefer the requested language, falling back to
|
|
34
|
+
* English then the default name. Layers that label by something else — house
|
|
35
|
+
* numbers, road shields — are left exactly as the style declared them.
|
|
36
|
+
*
|
|
37
|
+
* @param map - MapLibre Map instance (or any object matching the MapLike interface)
|
|
38
|
+
* @param language - ISO 639-1 language code (e.g. 'en', 'fr', 'de', 'ja', 'zh', 'ar')
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* map.once('style.load', () => applyMapLanguage(map, 'fr'))
|
|
42
|
+
*/
|
|
43
|
+
export declare function applyMapLanguage(map: MapLike, language: string): void;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.languageExpression = languageExpression;
|
|
4
|
+
exports.labelsByName = labelsByName;
|
|
5
|
+
exports.applyMapLanguage = applyMapLanguage;
|
|
6
|
+
/**
|
|
7
|
+
* The `text-field` expression that prefers `language`, then English, then the
|
|
8
|
+
* feature's default name.
|
|
9
|
+
*
|
|
10
|
+
* Based on the approach documented at:
|
|
11
|
+
* https://docs.aws.amazon.com/location/latest/developerguide/how-to-set-preferred-language-map.html
|
|
12
|
+
*/
|
|
13
|
+
function languageExpression(language) {
|
|
14
|
+
return language === 'en'
|
|
15
|
+
? ['coalesce', ['get', 'name:en'], ['get', 'name']]
|
|
16
|
+
: [
|
|
17
|
+
'coalesce',
|
|
18
|
+
['get', `name:${language}`],
|
|
19
|
+
['get', 'name:en'],
|
|
20
|
+
['get', 'name'],
|
|
21
|
+
];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Whether a `text-field` reads a name property — the only kind of label a
|
|
25
|
+
* language rewrite makes sense for (#28).
|
|
26
|
+
*
|
|
27
|
+
* The AWS Standard style has 62 symbol layers with a text-field and 30 of
|
|
28
|
+
* them do NOT label by name: `building_label_number` reads
|
|
29
|
+
* `addr_housenumber`, and the 29 `shield_*` layers read `shield_text` or
|
|
30
|
+
* `ref`. Replacing those with a `name:<lang>` coalesce points them at a
|
|
31
|
+
* property their features do not carry, and the house numbers and road
|
|
32
|
+
* shields disappear — for `en` too. Measured against the live sandbox on
|
|
33
|
+
* 2026-08-29; the testbed showed it as "one map has house numbers, the
|
|
34
|
+
* others don't".
|
|
35
|
+
*
|
|
36
|
+
* Serialising the expression is the simplest exact test: `name`, `name:en`,
|
|
37
|
+
* `name_en` and a literal `{name}` template all contain it, and none of the
|
|
38
|
+
* non-name properties do.
|
|
39
|
+
*/
|
|
40
|
+
function labelsByName(textField) {
|
|
41
|
+
return JSON.stringify(textField)?.includes('name') ?? false;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Apply a preferred display language to the name labels on a MapLibre map.
|
|
45
|
+
*
|
|
46
|
+
* AWS GeoMaps vector tiles carry `name:${lang}` properties (`name:en`,
|
|
47
|
+
* `name:fr`, `name:ja`, …). Every symbol layer whose `text-field` reads a
|
|
48
|
+
* name is rewritten to prefer the requested language, falling back to
|
|
49
|
+
* English then the default name. Layers that label by something else — house
|
|
50
|
+
* numbers, road shields — are left exactly as the style declared them.
|
|
51
|
+
*
|
|
52
|
+
* @param map - MapLibre Map instance (or any object matching the MapLike interface)
|
|
53
|
+
* @param language - ISO 639-1 language code (e.g. 'en', 'fr', 'de', 'ja', 'zh', 'ar')
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* map.once('style.load', () => applyMapLanguage(map, 'fr'))
|
|
57
|
+
*/
|
|
58
|
+
function applyMapLanguage(map, language) {
|
|
59
|
+
try {
|
|
60
|
+
const expression = languageExpression(language);
|
|
61
|
+
map.getStyle().layers.forEach((layer) => {
|
|
62
|
+
if (layer.type !== 'symbol')
|
|
63
|
+
return;
|
|
64
|
+
const textField = map.getLayoutProperty(layer.id, 'text-field');
|
|
65
|
+
if (textField === undefined || textField === null)
|
|
66
|
+
return;
|
|
67
|
+
if (!labelsByName(textField))
|
|
68
|
+
return;
|
|
69
|
+
map.setLayoutProperty(layer.id, 'text-field', expression);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Style may not be fully loaded — call after 'style.load' event
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Map } from 'maplibre-gl';
|
|
2
|
+
/**
|
|
3
|
+
* Mapping of POI category names to their MapLibre layer IDs in AWS GeoMaps tiles.
|
|
4
|
+
* Layer IDs are stable across Standard, Monochrome, and Hybrid map styles.
|
|
5
|
+
*/
|
|
6
|
+
export declare const POI_CATEGORIES: {
|
|
7
|
+
readonly food_drink: readonly ["poi_100_food_drink"];
|
|
8
|
+
readonly entertainment: readonly ["poi_200_going_out_entertainment"];
|
|
9
|
+
readonly sights: readonly ["poi_300_sights_museums"];
|
|
10
|
+
readonly transit: readonly ["poi_400_transit"];
|
|
11
|
+
readonly accommodations: readonly ["poi_500_accommodations"];
|
|
12
|
+
readonly leisure: readonly ["poi_550_leisure_outdoor"];
|
|
13
|
+
readonly shopping: readonly ["poi_600_shopping"];
|
|
14
|
+
readonly business: readonly ["poi_700_business_services"];
|
|
15
|
+
readonly facilities: readonly ["poi_800_facilities"];
|
|
16
|
+
readonly areas: readonly ["poi_900_areas_buildings"];
|
|
17
|
+
readonly parks: readonly ["poi_landuse_park", "poi_landuse_public_complex"];
|
|
18
|
+
};
|
|
19
|
+
export type PoiCategory = keyof typeof POI_CATEGORIES;
|
|
20
|
+
/**
|
|
21
|
+
* Set the visibility of one or more POI categories on the map.
|
|
22
|
+
*
|
|
23
|
+
* @param map - MapLibre Map instance
|
|
24
|
+
* @param category - POI category key or array of keys
|
|
25
|
+
* @param visible - Whether to show (true) or hide (false) the category
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* // Hide transit and shopping POIs
|
|
29
|
+
* setPoiVisibility(map, ['transit', 'shopping'], false)
|
|
30
|
+
*
|
|
31
|
+
* // Show all food & drink POIs
|
|
32
|
+
* setPoiVisibility(map, 'food_drink', true)
|
|
33
|
+
*/
|
|
34
|
+
export declare function setPoiVisibility(map: Map, category: PoiCategory | PoiCategory[], visible: boolean): void;
|
|
35
|
+
/**
|
|
36
|
+
* Show or hide all POI layers at once.
|
|
37
|
+
*
|
|
38
|
+
* @param map - MapLibre Map instance
|
|
39
|
+
* @param visible - Whether to show or hide all POIs
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* setAllPoiVisibility(map, false) // hide everything
|
|
43
|
+
*/
|
|
44
|
+
export declare function setAllPoiVisibility(map: Map, visible: boolean): void;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POI_CATEGORIES = void 0;
|
|
4
|
+
exports.setPoiVisibility = setPoiVisibility;
|
|
5
|
+
exports.setAllPoiVisibility = setAllPoiVisibility;
|
|
6
|
+
/**
|
|
7
|
+
* Mapping of POI category names to their MapLibre layer IDs in AWS GeoMaps tiles.
|
|
8
|
+
* Layer IDs are stable across Standard, Monochrome, and Hybrid map styles.
|
|
9
|
+
*/
|
|
10
|
+
exports.POI_CATEGORIES = {
|
|
11
|
+
food_drink: ['poi_100_food_drink'],
|
|
12
|
+
entertainment: ['poi_200_going_out_entertainment'],
|
|
13
|
+
sights: ['poi_300_sights_museums'],
|
|
14
|
+
transit: ['poi_400_transit'],
|
|
15
|
+
accommodations: ['poi_500_accommodations'],
|
|
16
|
+
leisure: ['poi_550_leisure_outdoor'],
|
|
17
|
+
shopping: ['poi_600_shopping'],
|
|
18
|
+
business: ['poi_700_business_services'],
|
|
19
|
+
facilities: ['poi_800_facilities'],
|
|
20
|
+
areas: ['poi_900_areas_buildings'],
|
|
21
|
+
parks: ['poi_landuse_park', 'poi_landuse_public_complex'],
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Set the visibility of one or more POI categories on the map.
|
|
25
|
+
*
|
|
26
|
+
* @param map - MapLibre Map instance
|
|
27
|
+
* @param category - POI category key or array of keys
|
|
28
|
+
* @param visible - Whether to show (true) or hide (false) the category
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // Hide transit and shopping POIs
|
|
32
|
+
* setPoiVisibility(map, ['transit', 'shopping'], false)
|
|
33
|
+
*
|
|
34
|
+
* // Show all food & drink POIs
|
|
35
|
+
* setPoiVisibility(map, 'food_drink', true)
|
|
36
|
+
*/
|
|
37
|
+
function setPoiVisibility(map, category, visible) {
|
|
38
|
+
const categories = Array.isArray(category) ? category : [category];
|
|
39
|
+
const visibility = visible ? 'visible' : 'none';
|
|
40
|
+
for (const cat of categories) {
|
|
41
|
+
for (const layerId of exports.POI_CATEGORIES[cat]) {
|
|
42
|
+
try {
|
|
43
|
+
if (map.getLayer(layerId)) {
|
|
44
|
+
map.setLayoutProperty(layerId, 'visibility', visibility);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Layer may not exist in the current map style
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Show or hide all POI layers at once.
|
|
55
|
+
*
|
|
56
|
+
* @param map - MapLibre Map instance
|
|
57
|
+
* @param visible - Whether to show or hide all POIs
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* setAllPoiVisibility(map, false) // hide everything
|
|
61
|
+
*/
|
|
62
|
+
function setAllPoiVisibility(map, visible) {
|
|
63
|
+
setPoiVisibility(map, Object.keys(exports.POI_CATEGORIES), visible);
|
|
64
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { StyleSpecification } from 'maplibre-gl';
|
|
2
|
+
import type { Buildings, ColorScheme, ContourDensity, MapStyle, Terrain, TrafficMode, TravelMode } from './mapEnums.js';
|
|
3
|
+
/**
|
|
4
|
+
* Options for building an AWS Location Service map style URL.
|
|
5
|
+
* All parameters map directly to query parameters supported by the style descriptor endpoint.
|
|
6
|
+
*
|
|
7
|
+
* Values are CASE SENSITIVE — the API rejects a wrong-cased one with a 400 that
|
|
8
|
+
* names the right spelling. Import the arrays from `mapEnums` to build pickers
|
|
9
|
+
* rather than typing the values, and the case is right by construction.
|
|
10
|
+
*/
|
|
11
|
+
export interface MapStyleOptions {
|
|
12
|
+
/** Color scheme for the map (default: Light). Not applicable to Satellite/Hybrid styles. */
|
|
13
|
+
colorScheme?: ColorScheme;
|
|
14
|
+
/** ISO 3166-1 alpha-3 country code for political boundary perspective (e.g. 'IND', 'TUR'). */
|
|
15
|
+
politicalView?: string;
|
|
16
|
+
/** Terrain overlay type. */
|
|
17
|
+
terrain?: Terrain;
|
|
18
|
+
/** Enable 3D building extrusions. */
|
|
19
|
+
buildings?: Buildings;
|
|
20
|
+
/**
|
|
21
|
+
* Elevation contour line density.
|
|
22
|
+
*
|
|
23
|
+
* All of High, Low and Medium work. This was previously typed as `'Medium'`
|
|
24
|
+
* alone, documented as "the only value currently supported by the AWS SDK",
|
|
25
|
+
* which was wrong — the other two were confirmed against the live API.
|
|
26
|
+
*/
|
|
27
|
+
contourDensity?: ContourDensity;
|
|
28
|
+
/**
|
|
29
|
+
* Traffic overlay.
|
|
30
|
+
*
|
|
31
|
+
* `Congestion` was previously missing here, so it could not be requested from
|
|
32
|
+
* TypeScript even though the API accepts it.
|
|
33
|
+
*
|
|
34
|
+
* Valid on its own, but NOT with every style: `Satellite` + `All` answers
|
|
35
|
+
* 400 "Traffic is not supported for style." Amazon owns that rule.
|
|
36
|
+
*/
|
|
37
|
+
traffic?: TrafficMode;
|
|
38
|
+
/** Travel mode overlays for routing-specific features. */
|
|
39
|
+
travelModes?: TravelMode[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Build a map style descriptor URL for the Location Service API.
|
|
43
|
+
*
|
|
44
|
+
* @param apiUrl - Base URL of the Location Service API
|
|
45
|
+
* @param mapStyle - Map style name (e.g. 'Standard', 'Monochrome', 'Satellite', 'Hybrid')
|
|
46
|
+
* @param options - Optional style parameters
|
|
47
|
+
* @returns Full style descriptor URL
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* const url = buildMapStyleUrl(API_URL, 'Standard', { colorScheme: 'Dark', terrain: 'Hillshade' })
|
|
51
|
+
* map.setStyle(url)
|
|
52
|
+
*/
|
|
53
|
+
export declare function buildMapStyleUrl(apiUrl: string, mapStyle: MapStyle, options?: MapStyleOptions): string;
|
|
54
|
+
/**
|
|
55
|
+
* Fetch the map style descriptor with authentication and apply descriptor-level modifications.
|
|
56
|
+
*
|
|
57
|
+
* Language is applied directly to the descriptor's layer definitions before MapLibre ever
|
|
58
|
+
* processes them, eliminating the visual flash that occurs when modifying layers post-load.
|
|
59
|
+
* All other style parameters (terrain, traffic, etc.) are passed as query parameters.
|
|
60
|
+
*
|
|
61
|
+
* The returned style object can be passed directly to `new maplibregl.Map({ style })` or
|
|
62
|
+
* `map.setStyle()`. Tile, glyph, and sprite requests still go through `transformRequest`
|
|
63
|
+
* for authentication — this only pre-processes the descriptor itself.
|
|
64
|
+
*
|
|
65
|
+
* @param apiUrl - Base URL of the Location Service API
|
|
66
|
+
* @param mapStyle - Map style name (e.g. 'Standard', 'Monochrome', 'Satellite', 'Hybrid')
|
|
67
|
+
* @param getToken - Callback returning the current auth token
|
|
68
|
+
* @param options - Style options; `language` is applied to the descriptor, all others become URL params
|
|
69
|
+
* @returns Modified MapLibre StyleSpecification object
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* const style = await fetchMapStyle(API_URL, 'Standard', getToken, { colorScheme: 'Dark', language: 'fr' })
|
|
73
|
+
* const map = new maplibregl.Map({ style, transformRequest: createTransformRequest(API_URL, getToken) })
|
|
74
|
+
*/
|
|
75
|
+
export declare function fetchMapStyle(apiUrl: string, mapStyle: MapStyle, getToken: () => string | undefined, options?: MapStyleOptions & {
|
|
76
|
+
language?: string;
|
|
77
|
+
}): Promise<StyleSpecification>;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildMapStyleUrl = buildMapStyleUrl;
|
|
4
|
+
exports.fetchMapStyle = fetchMapStyle;
|
|
5
|
+
const errors_js_1 = require("../transport/errors.js");
|
|
6
|
+
const mapLanguage_js_1 = require("./mapLanguage.js");
|
|
7
|
+
/**
|
|
8
|
+
* Build a map style descriptor URL for the Location Service API.
|
|
9
|
+
*
|
|
10
|
+
* @param apiUrl - Base URL of the Location Service API
|
|
11
|
+
* @param mapStyle - Map style name (e.g. 'Standard', 'Monochrome', 'Satellite', 'Hybrid')
|
|
12
|
+
* @param options - Optional style parameters
|
|
13
|
+
* @returns Full style descriptor URL
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const url = buildMapStyleUrl(API_URL, 'Standard', { colorScheme: 'Dark', terrain: 'Hillshade' })
|
|
17
|
+
* map.setStyle(url)
|
|
18
|
+
*/
|
|
19
|
+
function buildMapStyleUrl(apiUrl, mapStyle, options = {}) {
|
|
20
|
+
const params = new URLSearchParams();
|
|
21
|
+
if (options.colorScheme)
|
|
22
|
+
params.set('color-scheme', options.colorScheme);
|
|
23
|
+
if (options.politicalView)
|
|
24
|
+
params.set('political-view', options.politicalView);
|
|
25
|
+
if (options.terrain)
|
|
26
|
+
params.set('terrain', options.terrain);
|
|
27
|
+
if (options.buildings)
|
|
28
|
+
params.set('buildings', options.buildings);
|
|
29
|
+
if (options.contourDensity)
|
|
30
|
+
params.set('contour-density', options.contourDensity);
|
|
31
|
+
if (options.traffic)
|
|
32
|
+
params.set('traffic', options.traffic);
|
|
33
|
+
if (options.travelModes?.length)
|
|
34
|
+
params.set('travel-modes', options.travelModes.join(','));
|
|
35
|
+
const qs = params.toString();
|
|
36
|
+
return `${apiUrl}/maps/${mapStyle}/descriptor${qs ? `?${qs}` : ''}`;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Fetch the map style descriptor with authentication and apply descriptor-level modifications.
|
|
40
|
+
*
|
|
41
|
+
* Language is applied directly to the descriptor's layer definitions before MapLibre ever
|
|
42
|
+
* processes them, eliminating the visual flash that occurs when modifying layers post-load.
|
|
43
|
+
* All other style parameters (terrain, traffic, etc.) are passed as query parameters.
|
|
44
|
+
*
|
|
45
|
+
* The returned style object can be passed directly to `new maplibregl.Map({ style })` or
|
|
46
|
+
* `map.setStyle()`. Tile, glyph, and sprite requests still go through `transformRequest`
|
|
47
|
+
* for authentication — this only pre-processes the descriptor itself.
|
|
48
|
+
*
|
|
49
|
+
* @param apiUrl - Base URL of the Location Service API
|
|
50
|
+
* @param mapStyle - Map style name (e.g. 'Standard', 'Monochrome', 'Satellite', 'Hybrid')
|
|
51
|
+
* @param getToken - Callback returning the current auth token
|
|
52
|
+
* @param options - Style options; `language` is applied to the descriptor, all others become URL params
|
|
53
|
+
* @returns Modified MapLibre StyleSpecification object
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* const style = await fetchMapStyle(API_URL, 'Standard', getToken, { colorScheme: 'Dark', language: 'fr' })
|
|
57
|
+
* const map = new maplibregl.Map({ style, transformRequest: createTransformRequest(API_URL, getToken) })
|
|
58
|
+
*/
|
|
59
|
+
async function fetchMapStyle(apiUrl, mapStyle, getToken, options = {}) {
|
|
60
|
+
const { language, ...styleOptions } = options;
|
|
61
|
+
const url = buildMapStyleUrl(apiUrl, mapStyle, styleOptions);
|
|
62
|
+
const token = getToken();
|
|
63
|
+
const response = await fetch(url, {
|
|
64
|
+
headers: {
|
|
65
|
+
Authorization: `Bearer ${token}`,
|
|
66
|
+
Accept: 'application/json',
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
if (!response.ok) {
|
|
70
|
+
// Read the body. The API sends `{message, code, requestId}` and the message
|
|
71
|
+
// is the whole point of it — for a style request it is Amazon's own
|
|
72
|
+
// sentence, forwarded verbatim by location-service-api#89:
|
|
73
|
+
//
|
|
74
|
+
// 400 "Traffic is not supported for style."
|
|
75
|
+
// 400 "light is not a supported color scheme for style Standard."
|
|
76
|
+
//
|
|
77
|
+
// This used to throw `Failed to fetch map style: 400`, discarding all of it
|
|
78
|
+
// two lines before anyone could read it — the same defect #89 fixed in the
|
|
79
|
+
// API, one layer up. Reuses parseErrorResponse so a style failure arrives as
|
|
80
|
+
// the same LocationServiceException as every other call in this package,
|
|
81
|
+
// with `code`, `statusCode` and `requestId` intact.
|
|
82
|
+
throw (0, errors_js_1.parseErrorResponse)(response.status, response.statusText, await response.text(), response.headers);
|
|
83
|
+
}
|
|
84
|
+
const style = (await response.json());
|
|
85
|
+
if (language) {
|
|
86
|
+
applyLanguageToDescriptor(style, language);
|
|
87
|
+
}
|
|
88
|
+
return style;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Apply a preferred language to the name labels within a style descriptor.
|
|
92
|
+
* Mutates the style in place — call before passing to MapLibre.
|
|
93
|
+
*
|
|
94
|
+
* Only a `text-field` that reads a name property is rewritten. House numbers
|
|
95
|
+
* (`addr_housenumber`) and road shields (`shield_text`) used to be rewritten
|
|
96
|
+
* too, and vanished from every map that asked for a language (#28); the rule
|
|
97
|
+
* lives in `labelsByName` so this and `applyMapLanguage` cannot disagree.
|
|
98
|
+
*/
|
|
99
|
+
function applyLanguageToDescriptor(style, language) {
|
|
100
|
+
const expression = (0, mapLanguage_js_1.languageExpression)(language);
|
|
101
|
+
for (const layer of style.layers) {
|
|
102
|
+
if (layer.type !== 'symbol')
|
|
103
|
+
continue;
|
|
104
|
+
const layout = layer.layout;
|
|
105
|
+
if (layout?.['text-field'] === undefined)
|
|
106
|
+
continue;
|
|
107
|
+
if (!(0, mapLanguage_js_1.labelsByName)(layout['text-field']))
|
|
108
|
+
continue;
|
|
109
|
+
layout['text-field'] = expression;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { ColorScheme, LabelSize, MapFeatureMode, ScaleBarUnit, StaticMapStyle } from './mapEnums.js';
|
|
2
|
+
/**
|
|
3
|
+
* Static maps: build the URL, send the right headers, get a Blob.
|
|
4
|
+
*
|
|
5
|
+
* This exists because `/maps/static/{fileName}` is the one map route MapLibre
|
|
6
|
+
* never requests, so `createTransformRequest` never sees it and every caller was
|
|
7
|
+
* left to hand-roll the fetch. Ours did — `nextjs-address-finder-full`'s
|
|
8
|
+
* NearbySearch.tsx carried a comment explaining the rule — which is the clearest
|
|
9
|
+
* sign it belonged in the library (client#25, api#35).
|
|
10
|
+
*
|
|
11
|
+
* Two things make a plain fetch fail, and neither is discoverable:
|
|
12
|
+
*
|
|
13
|
+
* 1. `Accept` MUST name the exact type. Measured against the sandbox on
|
|
14
|
+
* 2026-08-26: `image/png` -> 200, while `image/*`, `*\/*`, and the header a
|
|
15
|
+
* browser sends for `<img>` all -> 406. Not even `image/*` is enough.
|
|
16
|
+
*
|
|
17
|
+
* 2. The type follows the STYLE, not the file name, and the default is
|
|
18
|
+
* Satellite:
|
|
19
|
+
*
|
|
20
|
+
* Standard -> image/png
|
|
21
|
+
* Satellite -> image/jpeg <- the default when `style` is omitted
|
|
22
|
+
*
|
|
23
|
+
* So the naive `Accept: image/png` is wrong for the DEFAULT request. The API
|
|
24
|
+
* hit the mirror image of this bug itself: it hard-coded image/png on the
|
|
25
|
+
* response and labelled every default render — a JPEG — as a PNG.
|
|
26
|
+
*
|
|
27
|
+
* `<img src="...">` cannot be made to work: it sends neither `Authorization` nor
|
|
28
|
+
* an acceptable `Accept`. Fetching to a Blob is the only viable shape, which is
|
|
29
|
+
* why this returns one rather than a URL.
|
|
30
|
+
*/
|
|
31
|
+
/** `map`, or `map@2x` for a retina render. There is no file extension. */
|
|
32
|
+
export type StaticMapFileName = 'map' | 'map@2x';
|
|
33
|
+
export interface StaticMapOptions {
|
|
34
|
+
/** Pixels, 64-1500. */
|
|
35
|
+
width: number;
|
|
36
|
+
/** Pixels, 64-1500. */
|
|
37
|
+
height: number;
|
|
38
|
+
/** `[longitude, latitude]`. */
|
|
39
|
+
center?: [number, number];
|
|
40
|
+
/** `[west, south, east, north]`. */
|
|
41
|
+
boundingBox?: [number, number, number, number];
|
|
42
|
+
/** Positions the render must contain, as `[lng, lat]` pairs. */
|
|
43
|
+
boundedPositions?: Array<[number, number]>;
|
|
44
|
+
zoom?: number;
|
|
45
|
+
radius?: number;
|
|
46
|
+
padding?: number;
|
|
47
|
+
cropLabels?: boolean;
|
|
48
|
+
style?: StaticMapStyle;
|
|
49
|
+
colorScheme?: ColorScheme;
|
|
50
|
+
labelSize?: LabelSize;
|
|
51
|
+
/**
|
|
52
|
+
* `Enabled` | `Disabled` -- NOT a list of categories. api#35 records this
|
|
53
|
+
* being passed as a string array against the SDK's Enabled|Disabled type,
|
|
54
|
+
* working only by stringification. Typed here so that cannot recur.
|
|
55
|
+
*/
|
|
56
|
+
pointsOfInterests?: MapFeatureMode;
|
|
57
|
+
scaleBarUnit?: ScaleBarUnit;
|
|
58
|
+
/** Defaults to `map`. */
|
|
59
|
+
fileName?: StaticMapFileName;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The Accept header this request must send.
|
|
63
|
+
*
|
|
64
|
+
* Exported because it is the one rule a caller cannot guess, and anyone doing
|
|
65
|
+
* their own fetch — a server-side render, a proxy — needs it too. Satellite is
|
|
66
|
+
* the default, so an absent style means JPEG.
|
|
67
|
+
*/
|
|
68
|
+
export declare function staticMapAccept(style?: StaticMapStyle): string;
|
|
69
|
+
/** Build the request URL without fetching it. */
|
|
70
|
+
export declare function buildStaticMapUrl(apiUrl: string, options: StaticMapOptions): string;
|
|
71
|
+
/**
|
|
72
|
+
* Fetch a static map as a Blob.
|
|
73
|
+
*
|
|
74
|
+
* @param apiUrl Base URL of the Location Service API
|
|
75
|
+
* @param options Render options; exactly one of center / boundingBox / boundedPositions
|
|
76
|
+
* @param getToken Callback returning the current auth token
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* const blob = await fetchStaticMap(API_URL, {
|
|
80
|
+
* width: 640, height: 400, center: [151.2093, -33.8688], zoom: 14,
|
|
81
|
+
* style: 'Standard',
|
|
82
|
+
* }, getToken)
|
|
83
|
+
* const url = URL.createObjectURL(blob) // remember to revokeObjectURL
|
|
84
|
+
*/
|
|
85
|
+
export declare function fetchStaticMap(apiUrl: string, options: StaticMapOptions, getToken: () => string | undefined): Promise<Blob>;
|