Skip to content

Commit 98b801c

Browse files
authored
feat(location): support Map (#30648)
### Issue # (if applicable) Closes #30647. ### Reason for this change In [aws-location-alpha](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-location-alpha-readme.html), `map` has not been supported yet. ### Description of changes Add `Map` class. ### Description of how you validated changes Add a unit test and a integ test. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent e3024fc commit 98b801c

13 files changed

+895
-0
lines changed

Diff for: packages/@aws-cdk/aws-location-alpha/README.md

+30
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,36 @@ global, trusted providers Esri and HERE. With affordable data, tracking and geof
2424
capabilities, and built-in metrics for health monitoring, you can build sophisticated
2525
location-enabled applications.
2626

27+
## Map
28+
29+
The Amazon Location Service Map resource gives you access to the underlying basemap data for a map.
30+
You use the Map resource with a map rendering library to add an interactive map to your application.
31+
You can add other functionality to your map, such as markers (or pins), routes, and polygon areas, as needed for your application.
32+
33+
For information about how to use map resources in practice, see [Using Amazon Location Maps in your application](https://docs.aws.amazon.com/location/latest/developerguide/using-maps.html).
34+
35+
To create a map, define a `Map`:
36+
37+
```ts
38+
new location.Map(this, 'Map', {
39+
mapName: 'my-map',
40+
style: location.Style.VECTOR_ESRI_NAVIGATION,
41+
customLayers: [location.CustomLayer.POI],
42+
});
43+
```
44+
45+
Use the `grant()` or `grantRendering()` method to grant the given identity permissions to perform actions
46+
on the map:
47+
48+
```ts
49+
declare const role: iam.Role;
50+
51+
const map = new location.Map(this, 'Map', {
52+
style: location.Style.VECTOR_ESRI_NAVIGATION,
53+
});
54+
map.grantRendering(role);
55+
```
56+
2757
## Place Index
2858

2959
A key function of Amazon Location Service is the ability to search the geolocation information.

Diff for: packages/@aws-cdk/aws-location-alpha/lib/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from './geofence-collection';
2+
export * from './map';
23
export * from './place-index';
34
export * from './route-calculator';
45
export * from './tracker';

Diff for: packages/@aws-cdk/aws-location-alpha/lib/map.ts

+333
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
1+
import * as iam from 'aws-cdk-lib/aws-iam';
2+
import { ArnFormat, IResource, Lazy, Resource, Stack, Token } from 'aws-cdk-lib/core';
3+
import { Construct } from 'constructs';
4+
import { CfnMap } from 'aws-cdk-lib/aws-location';
5+
import { generateUniqueId } from './util';
6+
7+
/**
8+
* Represents the Amazon Location Service Map
9+
*/
10+
export interface IMap extends IResource {
11+
/**
12+
* The name of the map
13+
*
14+
* @attribute
15+
*/
16+
readonly mapName: string;
17+
18+
/**
19+
* The Amazon Resource Name (ARN) of the Map
20+
*
21+
* @attribute Arn, MapArn
22+
*/
23+
readonly mapArn: string;
24+
}
25+
26+
/**
27+
* Properties for the Amazon Location Service Map
28+
*/
29+
export interface MapProps {
30+
/**
31+
* A name for the map
32+
*
33+
* Must be between 1 and 100 characters and contain only alphanumeric characters,
34+
* hyphens, periods and underscores.
35+
*
36+
* @default - A name is automatically generated
37+
*/
38+
readonly mapName?: string;
39+
40+
/**
41+
* A description for the map
42+
*
43+
* @default - no description
44+
*/
45+
readonly description?: string;
46+
47+
/**
48+
* Specifies the map style selected from an available data provider.
49+
*/
50+
readonly style: Style;
51+
52+
/**
53+
* Specifies the custom layers for the style.
54+
*
55+
* @default - no custom layes
56+
*/
57+
readonly customLayers?: CustomLayer[];
58+
59+
/**
60+
* Specifies the map political view selected from an available data provider.
61+
*
62+
* The political view must be used in compliance with applicable laws, including those laws about mapping of the country or region where the maps,
63+
* images, and other data and third-party content which you access through Amazon Location Service is made available.
64+
*
65+
* @see https://docs.aws.amazon.com/location/latest/developerguide/map-concepts.html#political-views
66+
*
67+
* @default - no political view
68+
*/
69+
readonly politicalView?: PoliticalView;
70+
}
71+
72+
/**
73+
* An additional layer you can enable for a map style.
74+
*/
75+
export enum CustomLayer {
76+
/**
77+
* The POI custom layer adds a richer set of places, such as shops, services, restaurants, attractions, and other points of interest to your map.
78+
* Currently only the VectorEsriNavigation map style supports the POI custom layer.
79+
*/
80+
POI = 'POI',
81+
}
82+
83+
/**
84+
* The map style selected from an available data provider.
85+
*
86+
* @see https://docs.aws.amazon.com/location/latest/developerguide/what-is-data-provider.html
87+
*/
88+
export enum Style {
89+
90+
/**
91+
* The Esri Navigation map style, which provides a detailed basemap for the world symbolized
92+
* with a custom navigation map style that's designed for use during the day in mobile devices.
93+
* It also includes a richer set of places, such as shops, services, restaurants, attractions,
94+
* and other points of interest. Enable the POI layer by setting it in CustomLayers to leverage
95+
* the additional places data.
96+
*/
97+
VECTOR_ESRI_NAVIGATION = 'VectorEsriNavigation',
98+
99+
/**
100+
* The Esri Imagery map style. A raster basemap that provides one meter or better
101+
* satellite and aerial imagery in many parts of the world and lower resolution
102+
* satellite imagery worldwide.
103+
*/
104+
RASTER_ESRI_IMAGERY = 'RasterEsriImagery',
105+
106+
/**
107+
* The Esri Light Gray Canvas map style, which provides a detailed vector basemap
108+
* with a light gray, neutral background style with minimal colors, labels, and features
109+
* that's designed to draw attention to your thematic content.
110+
*/
111+
VECTOR_ESRI_LIGHT_GRAY_CANVAS = 'VectorEsriLightGrayCanvas',
112+
113+
/**
114+
* The Esri Light map style, which provides a detailed vector basemap
115+
* with a classic Esri map style.
116+
*/
117+
VECTOR_ESRI_TOPOGRAPHIC = 'VectorEsriTopographic',
118+
119+
/**
120+
* The Esri Street Map style, which provides a detailed vector basemap for the world
121+
* symbolized with a classic Esri street map style. The vector tile layer is similar
122+
* in content and style to the World Street Map raster map.
123+
*/
124+
VECTOR_ESRI_STREETS = 'VectorEsriStreets',
125+
126+
/**
127+
* The Esri Dark Gray Canvas map style. A vector basemap with a dark gray,
128+
* neutral background with minimal colors, labels, and features that's designed
129+
* to draw attention to your thematic content.
130+
*/
131+
VECTOR_ESRI_DARK_GRAY_CANVAS = 'VectorEsriDarkGrayCanvas',
132+
133+
/**
134+
* A default HERE map style containing a neutral, global map and its features
135+
* including roads, buildings, landmarks, and water features. It also now includes
136+
* a fully designed map of Japan.
137+
*/
138+
VECTOR_HERE_EXPLORE = 'VectorHereExplore',
139+
140+
/**
141+
* A global map containing high resolution satellite imagery.
142+
*/
143+
RASTER_HERE_EXPLORE_SATELLITE = 'RasterHereExploreSatellite',
144+
145+
/**
146+
* A global map displaying the road network, street names, and city labels
147+
* over satellite imagery. This style will automatically retrieve both raster
148+
* and vector tiles, and your charges will be based on total tiles retrieved.
149+
*/
150+
HYBRID_HERE_EXPLORE_SATELLITE = 'HybridHereExploreSatellite',
151+
152+
/**
153+
* The HERE Contrast (Berlin) map style is a high contrast detailed base map
154+
* of the world that blends 3D and 2D rendering.
155+
*/
156+
VECTOR_HERE_CONTRAST = 'VectorHereContrast',
157+
158+
/**
159+
* A global map containing truck restrictions and attributes (e.g. width / height / HAZMAT)
160+
* symbolized with highlighted segments and icons on top of HERE Explore to support
161+
* use cases within transport and logistics.
162+
*/
163+
VECTOR_HERE_EXPLORE_TRUCK = 'VectorHereExploreTruck',
164+
165+
/**
166+
* The Grab Standard Light map style provides a basemap with detailed land use coloring,
167+
* area names, roads, landmarks, and points of interest covering Southeast Asia.
168+
*/
169+
VECTOR_GRAB_STANDARD_LIGHT = 'VectorGrabStandardLight',
170+
171+
/**
172+
* The Grab Standard Dark map style provides a dark variation of the standard basemap
173+
* covering Southeast Asia.
174+
*/
175+
VECTOR_GRAB_STANDARD_DARK = 'VectorGrabStandardDark',
176+
177+
/**
178+
* The Open Data Standard Light map style provides a detailed basemap for the world
179+
* suitable for website and mobile application use. The map includes highways major roads,
180+
* minor roads, railways, water features, cities, parks, landmarks, building footprints,
181+
* and administrative boundaries.
182+
*/
183+
VECTOR_OPEN_DATA_STANDARD_LIGHT = 'VectorOpenDataStandardLight',
184+
185+
/**
186+
* Open Data Standard Dark is a dark-themed map style that provides a detailed basemap
187+
* for the world suitable for website and mobile application use. The map includes highways
188+
* major roads, minor roads, railways, water features, cities, parks, landmarks,
189+
* building footprints, and administrative boundaries.
190+
*/
191+
VECTOR_OPEN_DATA_STANDARD_DARK = 'VectorOpenDataStandardDark',
192+
193+
/**
194+
* The Open Data Visualization Light map style is a light-themed style with muted colors
195+
* and fewer features that aids in understanding overlaid data.
196+
*/
197+
VECTOR_OPEN_DATA_VISUALIZATION_LIGHT = 'VectorOpenDataVisualizationLight',
198+
199+
/**
200+
* The Open Data Visualization Dark map style is a dark-themed style with muted colors
201+
* and fewer features that aids in understanding overlaid data.
202+
*/
203+
VECTOR_OPEN_DATA_VISUALIZATION_DARK = 'VectorOpenDataVisualizationDark',
204+
205+
}
206+
207+
/**
208+
* The map political view.
209+
*/
210+
export enum PoliticalView {
211+
/**
212+
* An India (IND) political view
213+
*/
214+
INDIA = 'IND',
215+
}
216+
217+
/**
218+
* The Amazon Location Service Map
219+
*
220+
* @see https://docs.aws.amazon.com/location/latest/developerguide/map-concepts.html
221+
*/
222+
export class Map extends Resource implements IMap {
223+
/**
224+
* Use an existing map by name
225+
*/
226+
public static fromMapName(scope: Construct, id: string, mapName: string): IMap {
227+
const mapArn = Stack.of(scope).formatArn({
228+
service: 'geo',
229+
resource: 'map',
230+
resourceName: mapName,
231+
});
232+
233+
return Map.fromMapArn(scope, id, mapArn);
234+
}
235+
236+
/**
237+
* Use an existing map by ARN
238+
*/
239+
public static fromMapArn(scope: Construct, id: string, mapArn: string): IMap {
240+
const parsedArn = Stack.of(scope).splitArn(mapArn, ArnFormat.SLASH_RESOURCE_NAME);
241+
242+
if (!parsedArn.resourceName) {
243+
throw new Error(`Map Arn ${mapArn} does not have a resource name.`);
244+
}
245+
246+
class Import extends Resource implements IMap {
247+
public readonly mapName = parsedArn.resourceName!;
248+
public readonly mapArn = mapArn;
249+
}
250+
251+
return new Import(scope, id, {
252+
account: parsedArn.account,
253+
region: parsedArn.region,
254+
});
255+
}
256+
257+
public readonly mapName: string;
258+
259+
public readonly mapArn: string;
260+
261+
/**
262+
* The timestamp for when the map resource was created in ISO 8601 format
263+
*
264+
* @attribute
265+
*/
266+
public readonly mapCreateTime: string;
267+
268+
/**
269+
* The timestamp for when the map resource was last updated in ISO 8601 format
270+
*
271+
* @attribute
272+
*/
273+
public readonly mapUpdateTime: string;
274+
275+
constructor(scope: Construct, id: string, props: MapProps) {
276+
if (props.description && !Token.isUnresolved(props.description) && props.description.length > 1000) {
277+
throw new Error(`\`description\` must be between 0 and 1000 characters, got: ${props.description.length} characters.`);
278+
}
279+
280+
if (props.mapName !== undefined && !Token.isUnresolved(props.mapName)) {
281+
if (props.mapName.length < 1 || props.mapName.length > 100) {
282+
throw new Error(`\`mapName\` must be between 1 and 100 characters, got: ${props.mapName.length} characters.`);
283+
}
284+
285+
if (!/^[-._\w]+$/.test(props.mapName)) {
286+
throw new Error(`\`mapName\` must contain only alphanumeric characters, hyphens, periods and underscores, got: ${props.mapName}.`);
287+
}
288+
}
289+
290+
super(scope, id, {
291+
physicalName: props.mapName ?? Lazy.string({ produce: () => generateUniqueId(this) }),
292+
});
293+
294+
const map = new CfnMap(this, 'Resource', {
295+
configuration: {
296+
style: props.style,
297+
customLayers: props.customLayers,
298+
politicalView: props.politicalView,
299+
},
300+
mapName: this.physicalName,
301+
description: props.description,
302+
});
303+
304+
this.mapName = map.ref;
305+
this.mapArn = map.attrArn;
306+
this.mapCreateTime = map.attrCreateTime;
307+
this.mapUpdateTime = map.attrUpdateTime;
308+
}
309+
310+
/**
311+
* Grant the given principal identity permissions to perform the actions on this map.
312+
*/
313+
public grant(grantee: iam.IGrantable, ...actions: string[]): iam.Grant {
314+
return iam.Grant.addToPrincipal({
315+
grantee: grantee,
316+
actions: actions,
317+
resourceArns: [this.mapArn],
318+
});
319+
}
320+
321+
/**
322+
* Grant the given identity permissions to rendering a map resource
323+
* @See https://docs.aws.amazon.com/location/latest/developerguide/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-get-map-tiles
324+
*/
325+
public grantRendering(grantee: iam.IGrantable): iam.Grant {
326+
return this.grant(grantee,
327+
'geo:GetMapTile',
328+
'geo:GetMapSprites',
329+
'geo:GetMapGlyphs',
330+
'geo:GetMapStyleDescriptor',
331+
);
332+
}
333+
}

Diff for: packages/@aws-cdk/aws-location-alpha/test/integ.map.js.snapshot/MapTestDefaultTestDeployAssert46CB2F9C.assets.json

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)