Skip to content

Commit

Permalink
feat: support Map
Browse files Browse the repository at this point in the history
  • Loading branch information
mazyu36 committed Jun 24, 2024
1 parent 3b95777 commit 9d9b731
Show file tree
Hide file tree
Showing 15 changed files with 871 additions and 10 deletions.
30 changes: 30 additions & 0 deletions packages/@aws-cdk/aws-location-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,36 @@ global, trusted providers Esri and HERE. With affordable data, tracking and geof
capabilities, and built-in metrics for health monitoring, you can build sophisticated
location-enabled applications.

## Map

The Amazon Location Service Map resource gives you access to the underlying basemap data for a map.
You use the Map resource with a map rendering library to add an interactive map to your application.
You can add other functionality to your map, such as markers (or pins), routes, and polygon areas, as needed for your application.

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).

To create a map, define a `Map`:

```ts
new location.Map(this, 'Map', {
mapName: 'my-map',
style: Style.VECTOR_ESRI_NAVIGATION,
customLayers: [CustomLayer.POI],
});
```

Use the `grant()` or `grantRendering()` method to grant the given identity permissions to perform actions
on the map:

```ts
declare const role: iam.Role;

const map = new location.Map(this, 'Map', {
style: Style.VECTOR_ESRI_NAVIGATION,
});
map.grantRendering(role);
```

## Place Index

A key function of Amazon Location Service is the ability to search the geolocation information.
Expand Down
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-location-alpha/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './map';
export * from './place-index';

export * from './util';
// AWS::Location CloudFormation Resources:
321 changes: 321 additions & 0 deletions packages/@aws-cdk/aws-location-alpha/lib/map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,321 @@
import * as iam from 'aws-cdk-lib/aws-iam';
import { ArnFormat, IResource, Lazy, Resource, Stack, Token } from 'aws-cdk-lib/core';
import { Construct } from 'constructs';
import { CfnMap } from 'aws-cdk-lib/aws-location';
import { generateUniqueId } from './util';

export interface IMap extends IResource {
/**
* The name of the map
*
* @attribute
*/
readonly mapName: string;

/**
* The Amazon Resource Name (ARN) of the Map
*
* @attribute Arn,MapArn
*/
readonly mapArn: string;
}

/**
* Properties for a map
*/
export interface MapProps {
/**
* A name for the map
*
* @default - A name is automatically generated
*/
readonly mapName?: string;

/**
* A description for the map
*
* @default - no description
*/
readonly description?: string;

/**
* Specifies the map style selected from an available data provider.
*/
readonly style: Style;

/**
* Specifies the custom layers for the style.
*
* @default - no cutom layes
*/
readonly customLayers?: CustomLayer[];

/**
* Specifies the map political view selected from an available data provider.
*
* The political view must be used in compliance with applicable laws, including those laws about mapping of the country or region where the maps,
* images, and other data and third-party content which you access through Amazon Location Service is made available.
*
* @see https://docs.aws.amazon.com/location/latest/developerguide/map-concepts.html#political-views
*
* @default - no political view
*/
readonly politicalView?: PoliticalView;
}

/**
* An additional layer you can enable for a map style.
*/
export enum CustomLayer {
/**
* The POI custom layer adds a richer set of places, such as shops, services, restaurants, attractions, and other points of interest to your map.
* Currently only the VectorEsriNavigation map style supports the POI custom layer.
*/
POI = 'POI',
}

/**
* The map style selected from an available data provider.
*
* @see https://docs.aws.amazon.com/location/latest/developerguide/what-is-data-provider.html
*/
export enum Style {

/**
* The Esri Navigation map style, which provides a detailed basemap for the world symbolized
* with a custom navigation map style that's designed for use during the day in mobile devices.
* It also includes a richer set of places, such as shops, services, restaurants, attractions,
* and other points of interest. Enable the POI layer by setting it in CustomLayers to leverage
* the additional places data.
*/
VECTOR_ESRI_NAVIGATION = 'VectorEsriNavigation',

/**
* The Esri Imagery map style. A raster basemap that provides one meter or better
* satellite and aerial imagery in many parts of the world and lower resolution
* satellite imagery worldwide.
*/
RASTER_ESRI_IMAGERY = 'RasterEsriImagery',

/**
* The Esri Light Gray Canvas map style, which provides a detailed vector basemap
* with a light gray, neutral background style with minimal colors, labels, and features
* that's designed to draw attention to your thematic content.
*/
VECTOR_ESRI_LIGHT_GRAY_CANVAS = 'VectorEsriLightGrayCanvas',

/**
* The Esri Light map style, which provides a detailed vector basemap
* with a classic Esri map style.
*/
VECTOR_ESRI_TOPOGRAPHIC = 'VectorEsriTopographic',

/**
* The Esri Street Map style, which provides a detailed vector basemap for the world
* symbolized with a classic Esri street map style. The vector tile layer is similar
* in content and style to the World Street Map raster map.
*/
VECTOR_ESRI_STREETS = 'VectorEsriStreets',

/**
* The Esri Dark Gray Canvas map style. A vector basemap with a dark gray,
* neutral background with minimal colors, labels, and features that's designed
* to draw attention to your thematic content.
*/
VECTOR_ESRI_DARK_GRAY_CANVAS = 'VectorEsriDarkGrayCanvas',

/**
* A default HERE map style containing a neutral, global map and its features
* including roads, buildings, landmarks, and water features. It also now includes
* a fully designed map of Japan.
*/
VECTOR_HERE_EXPLORE = 'VectorHereExplore',

/**
* A global map containing high resolution satellite imagery.
*/
RASTER_HERE_EXPLORE_SATELLITE = 'RasterHereExploreSatellite',

/**
* A global map displaying the road network, street names, and city labels
* over satellite imagery. This style will automatically retrieve both raster
* and vector tiles, and your charges will be based on total tiles retrieved.
*/
HYBRID_HERE_EXPLORE_SATELLITE = 'HybridHereExploreSatellite',

/**
* The HERE Contrast (Berlin) map style is a high contrast detailed base map
* of the world that blends 3D and 2D rendering.
*/
VECTOR_HERE_CONTRAST = 'VectorHereContrast',

/**
* A global map containing truck restrictions and attributes (e.g. width / height / HAZMAT)
* symbolized with highlighted segments and icons on top of HERE Explore to support
* use cases within transport and logistics.
*/
VECTOR_HERE_EXPLORE_TRUCK = 'VectorHereExploreTruck',

/**
* The Grab Standard Light map style provides a basemap with detailed land use coloring,
* area names, roads, landmarks, and points of interest covering Southeast Asia.
*/
VECTOR_GRAB_STANDARD_LIGHT = 'VectorGrabStandardLight',

/**
* The Grab Standard Dark map style provides a dark variation of the standard basemap
* covering Southeast Asia.
*/
VECTOR_GRAB_STANDARD_DARK = 'VectorGrabStandardDark',

/**
* The Open Data Standard Light map style provides a detailed basemap for the world
* suitable for website and mobile application use. The map includes highways major roads,
* minor roads, railways, water features, cities, parks, landmarks, building footprints,
* and administrative boundaries.
*/
VECTOR_OPEN_DATA_STANDARD_LIGHT = 'VectorOpenDataStandardLight',

/**
* Open Data Standard Dark is a dark-themed map style that provides a detailed basemap
* for the world suitable for website and mobile application use. The map includes highways
* major roads, minor roads, railways, water features, cities, parks, landmarks,
* building footprints, and administrative boundaries.
*/
VECTOR_OPEN_DATA_STANDARD_DARK = 'VectorOpenDataStandardDark',

/**
* The Open Data Visualization Light map style is a light-themed style with muted colors
* and fewer features that aids in understanding overlaid data.
*/
VECTOR_OPEN_DATA_VISUALIZATION_LIGHT = 'VectorOpenDataVisualizationLight',

/**
* The Open Data Visualization Dark map style is a dark-themed style with muted colors
* and fewer features that aids in understanding overlaid data.
*/
VECTOR_OPEN_DATA_VISUALIZATION_DARK = 'VectorOpenDataVisualizationDark',

}

/**
* The map political view.
*/
export enum PoliticalView {
/**
* An India (IND) political view
*/
INDIA = 'IND',
}

abstract class MapBase extends Resource implements IMap {
public abstract readonly mapName: string;
public abstract readonly mapArn: string;

/**
* Grant the given principal identity permissions to perform the actions on this map.
*/
public grant(grantee: iam.IGrantable, ...actions: string[]): iam.Grant {
return iam.Grant.addToPrincipal({
grantee: grantee,
actions: actions,
resourceArns: [this.mapArn],
});
}

/**
* Grant the given identity permissions to rendering a map resource
* 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
*/
public grantRendering(grantee: iam.IGrantable): iam.Grant {
return this.grant(grantee,
'geo:GetMapTile',
'geo:GetMapSprites',
'geo:GetMapGlyphs',
'geo:GetMapStyleDescriptor',
);
}
}

/**
* A map is a collection of map data.
*/
export class Map extends MapBase {
/**
* Use an existing map by name
*/
public static fromMapName(scope: Construct, id: string, mapName: string): IMap {
const mapArn = Stack.of(scope).formatArn({
service: 'geo',
resource: 'map',
resourceName: mapName,
});

return Map.fromMapArn(scope, id, mapArn);
}

/**
* Use an existing map by ARN
*/
public static fromMapArn(scope: Construct, id: string, mapArn: string): IMap {
const parsedArn = Stack.of(scope).splitArn(mapArn, ArnFormat.SLASH_RESOURCE_NAME);

if (!parsedArn.resourceName) {
throw new Error(`Map Arn ${mapArn} does not have a resource name.`);
}

class Import extends MapBase {
public readonly mapName = parsedArn.resourceName!;
public readonly mapArn = mapArn;
}

return new Import(scope, id, {
account: parsedArn.account,
region: parsedArn.region,
});
}

public readonly mapName: string;

public readonly mapArn: string;

/**
* The timestamp for when the map resource was created in ISO 8601 forma
*
* @attribute
*/
public readonly mapCreateTime: string;

/**
* The timestamp for when the map resource was last updated in ISO 8601 format
*
* @attribute
*/
public readonly mapUpdateTime: string;

constructor(scope: Construct, id: string, props: MapProps) {
if (props.mapName && !Token.isUnresolved(props.mapName) && !/^[-.\w]{1,100}$/.test(props.mapName)) {
throw new Error(`Invalid map name. The map index name must be between 1 and 100 characters and contain only alphanumeric characters, hyphens, periods and underscores. Received: ${props.mapName}`);
}

super(scope, id, {
physicalName: props.mapName ?? Lazy.string({ produce: () => generateUniqueId(this) }),
});

const map = new CfnMap(this, 'Resource', {
configuration: {
style: props.style,
customLayers: props.customLayers,
politicalView: props.politicalView,
},
mapName: this.physicalName,
description: props.description,
});

this.mapName = map.ref;
this.mapArn = map.attrArn;
this.mapCreateTime = map.attrCreateTime;
this.mapUpdateTime = map.attrUpdateTime;
}

}
12 changes: 3 additions & 9 deletions packages/@aws-cdk/aws-location-alpha/lib/place-index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as iam from 'aws-cdk-lib/aws-iam';
import { ArnFormat, IResource, Lazy, Names, Resource, Stack, Token } from 'aws-cdk-lib/core';
import { ArnFormat, IResource, Lazy, Resource, Stack, Token } from 'aws-cdk-lib/core';
import { Construct } from 'constructs';
import { CfnPlaceIndex } from 'aws-cdk-lib/aws-location';
import { generateUniqueId } from './util';

/**
* A Place Index
Expand Down Expand Up @@ -180,7 +181,7 @@ export class PlaceIndex extends PlaceIndexBase {
}

super(scope, id, {
physicalName: props.placeIndexName ?? Lazy.string({ produce: () => this.generateUniqueId() }),
physicalName: props.placeIndexName ?? Lazy.string({ produce: () => generateUniqueId(this) }),
});

const placeIndex = new CfnPlaceIndex(this, 'Resource', {
Expand All @@ -198,11 +199,4 @@ export class PlaceIndex extends PlaceIndexBase {
this.placeIndexUpdateTime = placeIndex.attrUpdateTime;
}

private generateUniqueId(): string {
const name = Names.uniqueId(this);
if (name.length > 100) {
return name.substring(0, 50) + name.substring(name.length - 50);
}
return name;
}
}
Loading

0 comments on commit 9d9b731

Please sign in to comment.