

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 开始使用 Amazon Location Service
<a name="getting-started"></a>

本主题可帮助您开始使用 Amazon Location Service。按照以下步骤创建您的第一个应用程序，并了解如何根据常见使用案例选择合适的 Amazon Location API。

1. **设置 AWS 账户和访问权限。**

   如果您还没有账户，系统会提示您创建一个。通过 AWS 免费套餐计划，您可以获得为期三个月的 Amazon Location Service 免费套餐。

   如果您已有账户，则需要提供对 Amazon Location Service 的访问权限。

   继续讨论[设置您的 账户](set-up.md)主题。

1. **了解并设置身份验证。**

   要使用 Amazon Location，必须向用户授予访问构成 Amazon Location 的资源和 API 的权限。API 密钥、Amazon Cognito 和 AWS Identity and Access Management（IAM）是授予资源和操作（API）访问权限的三个选项。

   继续讨论[使用 Amazon Location Service 进行身份验证](access.md)主题。

1. **创建您的第一个位置应用程序。**

   请参阅[创建您的第一个 Amazon Location 地图和地点应用程序](first-app.md)以构建您的第一个“Hello World”应用程序。

1. **选择正确的 API。**

   Amazon Location 提供了一组丰富的 API，涵盖地点、路线、地图、地理围栏和追踪器，以解决各种业务使用案例的需求。

   要了解有关如何选择 Amazon Location API 的更多信息，请参阅[选择正确的 API](choose-an-api.md)。

# 设置您的 账户
<a name="set-up"></a>

本部分介绍您需要执行哪些操作才能使用 Amazon Location Service。对于想要使用 Amazon Location 的用户，您必须拥有 AWS 账户 并已设置访问 Amazon Location 的权限。

## 我是新手 AWS
<a name="new-user"></a>

### 注册获取 AWS 账户
<a name="sign-up-for-aws"></a>

如果您没有 AWS 账户，请完成以下步骤来创建一个。

**要注册 AWS 账户**

1. 打开[https://portal.aws.amazon.com/billing/注册。](https://portal.aws.amazon.com/billing/signup)

1. 按照屏幕上的说明操作。

   在注册时，将接到电话或收到短信，要求使用电话键盘输入一个验证码。

   当您注册时 AWS 账户，就会创建*AWS 账户根用户*一个。根用户有权访问该账户中的所有 AWS 服务 和资源。作为最佳安全实践，请为用户分配管理访问权限，并且只使用根用户来执行[需要根用户访问权限的任务](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#root-user-tasks)。

AWS 注册过程完成后会向您发送一封确认电子邮件。您可以随时前往 [https://aws.amazon.com/](https://aws.amazon.com/)并选择 “**我的账户”，查看当前账户活动并管理您的账户**。

### 创建具有管理访问权限的用户
<a name="create-an-admin"></a>

注册后，请保护您的安全 AWS 账户 AWS 账户根用户 AWS IAM Identity Center，启用并创建管理用户，这样您就不会使用 root 用户执行日常任务。

**保护你的 AWS 账户根用户**

1.  选择 **Root 用户**并输入您的 AWS 账户 电子邮件地址，以账户所有者的身份登录。[AWS 管理控制台](https://console.aws.amazon.com/)在下一页上，输入您的密码。

   要获取使用根用户登录方面的帮助，请参阅《AWS 登录 用户指南》**中的 [Signing in as the root user](https://docs.aws.amazon.com/signin/latest/userguide/console-sign-in-tutorials.html#introduction-to-root-user-sign-in-tutorial)。

1. 为您的根用户启用多重身份验证（MFA）。

   有关说明，请参阅 I [A *M* 用户指南中的为 AWS 账户 根用户启用虚拟 MFA 设备（控制台）](https://docs.aws.amazon.com/IAM/latest/UserGuide/enable-virt-mfa-for-root.html)。

**创建具有管理访问权限的用户**

1. 启用 IAM Identity Center。

   有关说明，请参阅**《AWS IAM Identity Center 用户指南》中的[启用 AWS IAM Identity Center](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-set-up-for-idc.html)。

1. 在 IAM Identity Center 中，为用户授予管理访问权限。

   有关使用 IAM Identity Center 目录 作为身份源的教程，请参阅《[用户*指南》 IAM Identity Center 目录中的使用默认设置配置AWS IAM Identity Center 用户*访问权限](https://docs.aws.amazon.com//singlesignon/latest/userguide/quick-start-default-idc.html)。

**以具有管理访问权限的用户身份登录**
+ 要使用您的 IAM Identity Center 用户身份登录，请使用您在创建 IAM Identity Center 用户时发送到您的电子邮件地址的登录 URL。

  有关使用 IAM Identity Center 用户[登录的帮助，请参阅*AWS 登录 用户指南*中的登录 AWS 访问门户](https://docs.aws.amazon.com/signin/latest/userguide/iam-id-center-sign-in-tutorial.html)。

**将访问权限分配给其他用户**

1. 在 IAM Identity Center 中，创建一个权限集，该权限集遵循应用最低权限的最佳做法。

   有关说明，请参阅《AWS IAM Identity Center 用户指南》**中的 [Create a permission set](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-started-create-a-permission-set.html)。

1. 将用户分配到一个组，然后为该组分配单点登录访问权限。

   有关说明，请参阅《AWS IAM Identity Center 用户指南》**中的 [Add groups](https://docs.aws.amazon.com//singlesignon/latest/userguide/addgroups.html)。

## 我已经有 AWS 账号了
<a name="existing-user"></a>

**授予访问亚马逊 Location Service 的权限**

默认状态下，您的非管理员用户没有权限。在他们访问 Amazon Location 之前，您必须通过附加具有特定权限的 IAM policy 来授予权限。在授予对资源的访问权限时，请务必遵循最低权限原则。

**注意**  
有关向未经身份验证的用户授予访问 Amazon Location Service 功能的权限（例如，在基于 Web 的应用程序中）的信息，请参阅 [使用 Amazon Location Service 进行身份验证](access.md)。

以下示例策略授予用户访问所有 Amazon Location 操作的权限。有关更多示例，请参阅[Amazon Location Service 基于身份的策略示例](security-iam.md#security_iam_id-based-policy-examples)。

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Action": [
        "geo:*",
        "geo-maps:*",
        "geo-places:*",
        "geo-routes:*"
      ],
      "Resource": "*",
      "Effect": "Allow"
    }
  ]
}
```

要提供访问权限，请为您的用户、组或角色添加权限：
+ 中的用户和群组 AWS IAM Identity Center：

  创建权限集合。按照《AWS IAM Identity Center 用户指南》**中[创建权限集](https://docs.aws.amazon.com//singlesignon/latest/userguide/howtocreatepermissionset.html)的说明进行操作。
+ 通过身份提供者在 IAM 中托管的用户：

  创建适用于身份联合验证的角色。按照《IAM 用户指南》**中[针对第三方身份提供者创建角色（联合身份验证）](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_create_for-idp.html)的说明进行操作。
+ IAM 用户：
  + 创建您的用户可以担任的角色。按照《IAM 用户指南》**中[为 IAM 用户创建角色](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_create_for-user.html)的说明进行操作。
  + （不推荐使用）将策略直接附加到用户或将用户添加到用户组。按照《IAM 用户指南》**中[向用户添加权限（控制台）](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_users_change-permissions.html#users_change_permissions-add-console)中的说明进行操作。

在创建使用 Amazon Location Service 的应用程序时，您可能需要一些用户拥有未经身份验证的访问权限。有关这些使用案例，请参阅使用 [Amazon Cognito 启用未经身份验证的访问](authenticating-using-cognito.md)。

# 使用 Amazon Location Service 控制台进行身份验证
<a name="set-up-auth"></a>

**注意**  
要了解有关身份验证的更多信息，请参阅[使用 Amazon Location Service 进行身份验证](access.md)。

要使用 Amazon Location Service，必须向用户授予访问构成Amazon Location 的资源和 API 的权限。默认情况下，Amazon Location API 需要身份验证才能使用。您可以使用 Amazon Cognito 或 API 密钥为匿名用户提供身份验证和授权。

在[创建您的第一个 Amazon Location 地图和地点应用程序](first-app.md)教程中，该应用程序是匿名使用的，这意味着您的用户无需登录。在该教程中，您创建用于示例应用程序的 API 密钥。

按照以下过程创建您的第一个 API 密钥。

1. 在 [https://console.aws.amazon.com/location](https://console.aws.amazon.com/location)中，从左侧菜单中选择 **API 密钥**。

1. 在 **API 密钥**页面上，选择**创建 API 密钥**。

1. 在**创建 API 密钥**页面中，填写以下信息：
   + **名称**——您的 API 密钥的名称，例如 `MyHelloWorldApp`。
   + **描述** – API 密钥的可选描述。
   + **操作**——指定您要使用此 API 密钥授权的操作。您必须至少选择 **geo-maps:Get\$1** 和 **geo-places:Search\$1**。
   + **到期时间** – （可选）添加 API 密钥的到期日期和时间。有关更多信息，请参阅 [API 密钥最佳实践](using-apikeys.md#api-keys-best-practices)。
   + **客户端限制** –（可选）添加一个或多个 Web 域或者一个或多个 Android 或 Apple 应用程序，以便在其中使用 API 密钥。例如，如果 API 密钥是为了允许应用程序在网站 `example.com` 上运行，那么您可以将 `*.example.com/` 设置为允许的引用站点。
   + **标签** – （可选）向 API 密钥添加标签。
**重要**  
建议您通过设置到期时间或引用站点（如果不是两者兼而有之）来保护 API 密钥的使用。

1. 选择**创建 API 密钥**以创建 API 密钥。

1. 在 API 密钥的详情页面上，您可以看到有关您创建的 API 密钥的信息。

   选择**显示 API 密钥**，然后复制密钥值以供[创建您的第一个 Amazon Location 地图和地点应用程序](first-app.md)教程稍后使用。密钥值的格式为 `v1.public.a1b2c3d4...`。

# 选择正确的 API
<a name="choose-an-api"></a>

本主题可帮助您根据常见使用案例（您可能希望使用基于位置的数据和服务解决这些使用案例）来选择 Amazon Location Service API。

地图  
地图 API 提供对动态和静态地图类型的访问权限，适用于各种应用程序。有关更多信息，请参阅[Amazon Location Service 地图](maps.md)。  
+ **动态地图**：可实时自定义的交互式地图，支持用户平移、缩放和叠加数据。有关更多信息，请参阅[动态地图](dynamic-maps.md)。
+ **静态地图**：显示特定位置或路线的地图的静态图像（不含交互式元素），适用于交互性有限的应用程序。有关更多信息，请参阅[静态地图](static-maps.md)。

Routes  
路线 API 可计算不同地点之间的优化路径。这些功能支持需要进行物流规划、距离计算和路线优化的应用程序。用户还可以将位置点与道路对齐，以提高准确性。有关更多信息，请参阅[Amazon Location Service 路线](routes.md)。  
+ **CalculateIsolines**：根据行驶时间或距离生成等值线，可用于定义服务区或可达区域。有关更多信息，请参阅[计算等值线](calculate-isolines.md)。
+ **CalculateRouteMatrix**：提供多个出发地和目的地之间的距离和行程时间的矩阵，为后勤和行程计划提供支持。有关更多信息，请参阅[计算路线矩阵](calculate-route-matrix.md)。
+ **CalculateRoutes**：计算多站导航的 point-to-point优化路线，包括可自定义的路线偏好。有关更多信息，请参阅[计算路线](calculate-routes.md)。
+ **OptimizeWaypoints**：优化航点顺序以获得最高效的行驶路线，从而最大限度地减少距离或时间。有关更多信息，请参阅[优化航点](actions-optimize-waypoints.md)。
+ **SnapToRoads**：将坐标与最近的道路对齐，通过将点捕捉到已知道路来提高 GPS 精度。有关更多信息，请参阅[与道路对齐](snap-to-roads.md)。

地点  
地点 API 使应用程序能够搜索、查找和检索有关兴趣点、地址和特定位置的详细信息。这些功能可提供上下文并改善用户使用搜索功能的体验，从而增强基于位置的服务。有关更多信息，请参阅[Amazon Location Service 地点](places.md)。  
+ **地理编码**：将地址或地名转换为地理坐标（经度、纬度），支持需要 address-to-location转换才能进行制图和空间分析的应用程序。有关更多信息，请参阅 [地理编码](geocode.md)。
+ **反向地理编码**：将地理坐标转换为最接近的地址或地名，为某个位置提供上下文。有关更多信息，请参阅[反向地理编码](reverse-geocode.md)。
+ **自动补全**：为用户输入的文本建议可能的补全内容，从而提高搜索输入的效率。有关更多信息，请参阅[Autocomplete](autocomplete.md)。
+ **GetPlace**：检索有关指定地点的详细信息，包括地址、联系方式和营业时间等属性。有关更多信息，请参阅[GetPlace](get-place.md)。
+ **SearchNearby**：在给定地理点的指定半径范围内查找适合 “我附近” 搜索的地方。有关更多信息，请参阅[周边搜索](search-nearby.md)。
+ **SearchText**：允许基于关键字或短语的文本搜索地点或兴趣点，非常适合按名称或描述查找地点。有关更多信息，请参阅[搜索文本](search-text.md)。
+ **建议**：在用户键入时提供搜索词建议，从而增强搜索相关性并改善用户体验。有关更多信息，请参阅[Suggest](suggest.md)。

地理围栏  
地理围栏允许应用程序定义地理边界并监控这些区域内的进入或退出事件。功能包括创建、更新和删除地理围栏，以及配置通知或触发器，以便在被跟踪的设备跨越地理围栏边界时执行基于位置的操作。非常适合在预定义区域内进行基于邻近度的通知、安全监控和资产跟踪。有关更多信息，请参阅[Amazon Location Service 地理围栏](geofences.md)。

跟踪器  
通过跟踪，可以实时监控设备或资产随时间变化的位置。功能包括添加被跟踪的设备、更新其位置数据以及检索历史位置数据。跟踪器可用于管理车队、监控人员以及通过提供 up-to-date位置数据和移动模式来确保贵重资产的安全。有关更多信息，请参阅[Amazon Location Service 跟踪器](trackers.md)。

# 创建您的第一个 Amazon Location 地图和地点应用程序
<a name="first-app"></a>

在本节中，您将使用地图和地点功能创建第一个应用程序。

**先决条件：**

如果您已在[使用 Amazon Location Service 控制台进行身份验证](set-up-auth.md)步骤中创建 API 密钥，那么可以立即开始。

如果您尚未创建 API 密钥，请先遵循[使用 Amazon Location Service 控制台进行身份验证](set-up-auth.md)，然后继续构建应用程序。如有任何疑问，请参阅[使用 API 密钥进行身份验证](using-apikeys.md)和 [Amazon Location 支持的区域](location-regions.md)了解更多信息。

## Web
<a name="qs-web"></a>

以下是使用 MapLibre GL JS 创建 Amazon Location Service 地图应用程序的 step-by-step教程。本指南将引导您完成设置地图、添加样式设置选项和启用地点搜索功能的过程。

### 设置初始页面
<a name="qs-initial-page"></a>

在本节中，我们将设置初始页面和文件夹结构。

#### 添加所需的库和样式表
<a name="qs-initial-add-library"></a>

创建 `index.html` 文件。要渲染地图，你需要 MapLibre GL JS 和 MapLibre GL Geocoder。您将添加 MapLibre 和 Geocoder 样式表和脚本。 JavaScript 

复制以下代码并粘贴到 `index.html` 文件中。

```
<!DOCTYPE html>
<html lang="en">
<head>

    <title>Amazon Location Service - Getting Started with First Map App</title>
    <meta charset='utf-8'>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Interactive map application using Amazon Location Service">

    <!--Link to MapLibre CSS and JavaScript library for map rendering and visualization -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/maplibre-gl@5.x/dist/maplibre-gl.css" />
    <script src="https://cdn.jsdelivr.net/npm/maplibre-gl@5.x/dist/maplibre-gl.js"></script>
    
    <!--Link to MapLibre Geocoder CSS and JavaScript library for place search and geocoding -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@maplibre/maplibre-gl-geocoder@1.7.0/dist/maplibre-gl-geocoder.css" />
    <script src="https://cdn.jsdelivr.net/npm/@maplibre/maplibre-gl-geocoder@1.7.0/dist/maplibre-gl-geocoder.js"></script>
    
    <!--Link to amazon-location JavaScript librarie -->
    <script src="https://cdn.jsdelivr.net/npm/@aws/amazon-location-utilities-auth-helper@1"></script>
    <script src="https://cdn.jsdelivr.net/npm/@aws/amazon-location-client@1.2"></script>
    
    <!-- Link to the first Amazon Location Map App's CSS and JavaScript -->
    <script src="utils.js"></script>
    <link rel="stylesheet" href="style.css"/>
   

</head>
<body>
    <main> 
        
    </main>
    <script> 
        // Step 1: Setup API Key and AWS Region 
        // Step 2.1 Add maps to application
        // Step 2.2 initialize the map
        // Step 3: Add places features to application
        // Step 3.1: Get GeoPlaces instance. It will be used for addion search box and map click functionality
        // Step 3.2: Add search box to the map
        // Step 3.3.: Setup map click functionality
        // Add functions
    </script>
</body>
</html>
```

#### 创建地图容器
<a name="qs-create-map-container"></a>

 在 HTML 文件的 `<body>` 元素下，在 HTML 中创建一个用于保存地图的 `<div>` 元素。您可以在 CSS 中设置此 `<div>` 的样式，以根据应用程序需求设置尺寸。您必须从我们的 GitHub 存储库中下载 CSS 文件。`style.css`这将有助于您专注于业务逻辑。

 将 `style.css` 和 `index.html` 文件保存在同一文件夹中。

 从中下载`style.css`文件[GitHub](https://github.com/aws-geospatial/amazon-location-samples-js/blob/quick_start_sample_js/quick-start/style.css)。

```
<main role="main" aria-label="Map Container">
    <div id="map"></div>
</main>
```

#### 添加 API 密钥和 AWS 区域详情
<a name="qs-create-add-key"></a>

将您在中[使用 API 密钥进行身份验证](using-apikeys.md)创建的 API 密钥以及创建密钥的 AWS 区域添加到此文件中。

```
<!DOCTYPE html>
<html lang="en">
.....
.....
<body>
    <main role="main" aria-label="Map Container">
        <div id="map"></div>
    </main>
    <script>
        // Step 1: Setup API Key and AWS Region 
        const API_KEY = "Your_API_Key";
        const AWS_REGION = "Region_where_you_created_API_Key";
        // Step 2: Add maps to application
            // Step 2.1 initialize the map
            // Step 2.2 Add navigation controls to the map
        // Step 3: Add places feature to application        
            // Step 3.1: Get GeoPlaces instance. It will be used for addion search box and map click functionality
            // Step 3.2: Add search box to the map
            // Step 3.3.: Setup map click functionality
    </script>
</body>
</html>
```

### 向应用程序添加地图
<a name="qs-add-map"></a>

在本节中，我们将向应用程序添加地图功能。开始之前，您的文件应采用以下文件夹结构。

 如果尚未这样做，请从中下载该`style.css`文件[GitHub](https://github.com/aws-geospatial/amazon-location-samples-js/blob/quick_start_sample_js/quick-start/style.css)。

```
|---FirstApp [Folder]
|-------------- index.html [File]
|-------------- style.css [File]
```

#### 创建一个函数来初始化地图
<a name="qs-initialize-map-function"></a>

要设置地图，请在行 `//Add functions` 后创建函数 `initializeMap(...)`。

选择初始中心位置和缩放级别。在本示例中，我们将地图的中心定位在加拿大温哥华，缩放级别为 10。添加导航控件以便于缩放。

```
/**
 * Initializes the map with the specified style and color scheme.
 */
function initializeMap(mapStyle = "Standard", colorScheme = "Dark") {
     const styleUrl = `https://maps.geo.${AWS_REGION}.amazonaws.com/v2/styles/${mapStyle}/descriptor?key=${API_KEY}&color-scheme=${colorScheme}`;
     const map = new maplibregl.Map({
         container: 'map',                 // The ID of the map container
         style: styleUrl,                  // The style URL for the map
         center: [-123.116226, 49.246292], // Starting center coordinates
         zoom: 10,                         // Initial zoom level
         validateStyle: false              // Disable style validation
     });
     return map;                           // Return the initialized map
}
```

#### 初始化地图
<a name="qs-initialize-map"></a>

调用 `initializeMap(...)` 以初始化地图。或者，可以在 `initializeMap` 函数之后，用您喜欢的样式和颜色方案对其进行初始化。有关更多样式选项，请参阅 [AWS 地图样式和功能](map-styles.md)。

```
// Step 1: Setup API Key and AWS Region 
const API_KEY = "Your_API_Key";
const AWS_REGION = "Region_where_you_created_API_Key";

// Step 2.1 Add maps to application
// Step 2.2 initialize the map
const map = initializeMap("Standard","Light");

// Step 3: Add places features to application
```

在浏览器中打开 `index.html` 以查看地图的实际效果。

#### 添加导航控件
<a name="qs-add-navigation"></a>

或者，可以向地图添加导航控件（缩放和旋转）。这应在调用 `initializeMap(...)` 之后完成。

```
// Step 2.1 initialize the map
const map = initializeMap("Standard","Light");

// Step 2.2 Add navigation controls to the map
map.addControl(new maplibregl.NavigationControl());

// Step 3: Add places features to application
```

#### 查看地图代码
<a name="qs-add-final"></a>

恭喜您！您的第一个应用程序已准备好使用地图。在浏览器中打开 `index.html`。确保 `style.css` 与 `index.html` 位于同一文件夹中。

您的最终 HTML 应如下所示：

```
<!DOCTYPE html>
<html lang="en">
<head>

   <title>Amazon Location Service - Getting Started with First Map App</title>
   <meta charset='utf-8'>
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <meta name="description" content="Interactive map application using Amazon Location Service">

   <!-- Link to MapLibre CSS and JavaScript library for map rendering and visualization -->
   <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/maplibre-gl@5.x/dist/maplibre-gl.css" />
   <script src="https://cdn.jsdelivr.net/npm/maplibre-gl@5.x/dist/maplibre-gl.js"></script>
   
   <!-- Link to MapLibre Geocoder CSS and JavaScript library for place search and geocoding -->
   <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@maplibre/maplibre-gl-geocoder@1.7.0/dist/maplibre-gl-geocoder.css" />
   <script src="https://cdn.jsdelivr.net/npm/@maplibre/maplibre-gl-geocoder@1.7.0/dist/maplibre-gl-geocoder.js"></script>
   
   <!-- Link to amazon-location JavaScript library -->
   <script src="https://cdn.jsdelivr.net/npm/@aws/amazon-location-utilities-auth-helper@1"></script>
   <script src="https://cdn.jsdelivr.net/npm/@aws/amazon-location-client@1.2"></script>
   
   <!-- Link to the first Amazon Location Map App's CSS and JavaScript -->
   <script src="utils.js"></script>
   <link rel="stylesheet" href="style.css"/>
</head>

<body>
    <main role="main" aria-label="Map Container">
        <div id="map"></div>
    </main>
    <script>
        const API_KEY = "Your_API_Key";
        const AWS_REGION = "Region_where_you_created_API_Key";
        
        function initializeMap(mapStyle, colorScheme) {
            const styleUrl = `https://maps.geo.${AWS_REGION}.amazonaws.com/v2/styles/${mapStyle}/descriptor?key=${API_KEY}&color-scheme=${colorScheme}`;
        
            const map = new maplibregl.Map({
                container: 'map',                 // ID of the HTML element for the map
                style: styleUrl,                  // URL for the map style
                center: [-123.116226, 49.246292], // Initial map center [longitude, latitude]
                zoom: 10                          // Initial zoom level
            });
            map.addControl(new maplibregl.NavigationControl());    
            return map;
        }
        
        const map = initializeMap("Standard", "Light");
        
    </script>
</body>
</html>
```

### 向应用程序添加地点
<a name="qs-add-places"></a>

在本节中，我们将设置向应用程序添加地点功能。从下载 JavaScript 文件 GitHub，[https://github.com/aws-geospatial/amazon-location-samples-js/blob/quick_start_sample_js/quick-start/utils.js](https://github.com/aws-geospatial/amazon-location-samples-js/blob/quick_start_sample_js/quick-start/utils.js)。

开始之前，您的文件应采用以下文件夹结构：

```
|---FirstApp [Folder]
|-------------- index.html [File]
|-------------- style.css [File]
|-------------- utils.js [File]
```

#### 创建要创建的函数 GeoPlaces
<a name="qs-create-geoplaces"></a>

要添加搜索功能，请使用 `AuthHelper` 和 `AmazonLocationClient` 初始化 `GeoPlaces` 类。在 `index.html` 中的 `</script>` 标签前添加以下 `getGeoPlaces(map)` 函数。

```
/**
 * Gets a GeoPlaces instance for Places operations.
 */
function getGeoPlaces(map) {
    const authHelper = amazonLocationClient.withAPIKey(API_KEY, AWS_REGION);                      // Authenticate using the API key and AWS region
    const locationClient = new amazonLocationClient.GeoPlacesClient(authHelper.getClientConfig()); // Create a GeoPlaces client
    const geoPlaces = new GeoPlaces(locationClient, map);                                          // Create GeoPlaces instance
    return geoPlaces;                                                                              // Return the GeoPlaces instance
}
```

#### 创建向应用程序添加搜索框的函数
<a name="qs-add-searchbox"></a>

在 `index.html` 中的 `</script>` 标签前添加以下 `addSearchBox(map, geoPlaces)`、`renderPopup(feature)` 和 `createPopup(feature)` 函数，以完成搜索功能设置。

```
/**
 * Adds search box to the map.
 */
function addSearchBox(map, geoPlaces) {
    const searchBox = new MaplibreGeocoder(geoPlaces, {
        maplibregl,
        showResultsWhileTyping: true,                    // Show results while typing
        debounceSearch: 300,                             // Debounce search requests
        limit: 30,                                       // Limit number of results
        popuprender: renderPopup,                        // Function to render popup
        reverseGeocode: true,                            // Enable reverse geocoding
        zoom: 14,                                        // Zoom level on result selection
        placeholder: "Search text or nearby (lat,long)"  // Placeholder text for search box.
    });
    
    // Add the search box to the map
    map.addControl(searchBox, 'top-left'); 

    // Event listener for when a search result is selected
    searchBox.on('result', async (event) => {
        const { id, result_type } = event.result;                     // Get result ID and type
        if (result_type === "Place") {                                // Check if the result is a place
            const placeResults = await geoPlaces.searchByPlaceId(id); // Fetch details for the selected place
            if (placeResults.features.length) {
                createPopup(placeResults.features[0]).addTo(map);     // Create and add popup for the place
            }
        }
    });
}

/**
 * Renders the popup content for a given feature.
 */
function renderPopup(feature) {
    return `
        <div class="popup-content">
            <span class="${feature.place_type.toLowerCase()} badge">${feature.place_type}</span><br>
            ${feature.place_name}
        </div>`;
}

/**
 * Creates a popup for a given feature and sets its position.
 */
function createPopup(feature) {
    return new maplibregl.Popup({ offset: 30 })      // Create a new popup
        .setLngLat(feature.geometry.coordinates)     // Set the popup position
        .setHTML(renderPopup(feature));              // Set the popup content
}
```

#### 向应用程序添加搜索框
<a name="qs-add-searchbox-to-application"></a>

按照第 3.1 节中的定义，通过调用 `getGeoPlaces(map)` 来创建 `GeoPlaces` 对象，然后调用 `addSearchBox(map, geoPlaces)` 以向应用程序添加搜索框。

```
// Step 2: Add maps to application
// Step 2.1 initialize the map
const map = initializeMap("Standard","Light");
// Step 2.2 Add navigation controls to the map
map.addControl(new maplibregl.NavigationControl()); 

// Step 3: Add places feature to application        
// Step 3.1: Get GeoPlaces instance. It will be used for adding search box and map click functionality
const geoPlaces = getGeoPlaces(map);
// Step 3.2: Add search box to the map
addSearchBox(map, geoPlaces);
```

地点搜索已准备就绪，可供使用。在浏览器中打开 `index.html` 以查看其实际效果。

#### 添加在用户点击地图时显示弹出窗口的函数
<a name="qs-add-map-click-feature"></a>

创建在用户点击地图时显示弹出窗口的函数 `addMapClick(map, geoPlaces)`。此函数应添加到 `</script>` 标签前面。

```
/**
 * Sets up reverse geocoding on map click events.
 */
function addMapClick(map, geoPlaces) {
    map.on('click', async ({ lngLat }) => {                     // Listen for click events on the map
        const response = await geoPlaces.reverseGeocode({ query: [lngLat.lng, lngLat.lat], limit: 1, click: true }); // Perform reverse geocoding

        if (response.features.length) {                         // If there are results
            const clickMarker = new maplibregl.Marker({ color: "orange" }); // Create a marker
            const feature = response.features[0];               // Get the clicked feature
            const clickedPopup = createPopup(feature);          // Create popup for the clicked feature
            clickMarker.setLngLat(feature.geometry.coordinates) // Set marker position
                .setPopup(clickedPopup)                         // Attach popup to marker
                .addTo(map);                                    // Add marker to the map

            clickedPopup.on('close', () => clickMarker.remove()).addTo(map); // Remove marker when popup is closed
        }
    });
}
```

#### 调用函数以添加地图点击功能
<a name="qs-call-map-click-feature"></a>

要启用地图点击操作，请在包含 `addSearchBox(map, geoPlaces)` 的行之后调用 `addMapClick(map, geoPlaces)`。

```
// Step 3: Add places feature to application        
// Step 3.1: Get GeoPlaces instance. It will be used for adding search box and map click functionality
const geoPlaces = getGeoPlaces(map);
// Step 3.2: Add search box to the map
addSearchBox(map, geoPlaces);
// Step 3.3: Setup map click functionality
addMapClick(map, geoPlaces);
```

#### 查看地图和地点应用程序
<a name="qs-review-places"></a>

恭喜您！您的第一个应用程序已准备就绪，可以使用地图和地点。在浏览器中打开 `index.html`。确保 `style.css` 和 `utils.js` 与 `index.html` 位于同一文件夹中。

您的最终 HTML 应如下所示：

```
<!DOCTYPE html>
<html lang="en">
<head>

   <title>Amazon Location Service - Getting Started with First Map App</title>
    <meta charset='utf-8'>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Interactive map application using Amazon Location Service">

    <!--Link to MapLibre CSS and JavaScript library for map rendering and visualization -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/maplibre-gl@5.x/dist/maplibre-gl.css" />
    <script src="https://cdn.jsdelivr.net/npm/maplibre-gl@5.x/dist/maplibre-gl.js"></script>
    
    <!--Link to MapLibre Geocoder CSS and JavaScript library for place search and geocoding -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@maplibre/maplibre-gl-geocoder@1.7.0/dist/maplibre-gl-geocoder.css" />
    <script src="https://cdn.jsdelivr.net/npm/@maplibre/maplibre-gl-geocoder@1.7.0/dist/maplibre-gl-geocoder.js"></script>
    
    <!--Link to amazon-location JavaScript librarie -->
    <script src="https://cdn.jsdelivr.net/npm/@aws/amazon-location-utilities-auth-helper@1"></script>
    <script src="https://cdn.jsdelivr.net/npm/@aws/amazon-location-client@1.2"></script>
    
    <!-- Link to the first Amazon Location Map App's CSS and JavaScript -->
    <script src="utils.js"></script>
    <link rel="stylesheet" href="style.css"/>
   

</head>
<body>
    <main role="main" aria-label="Map Container">
        <div id="map"></div>
    </main>
    <script>
        // Step 1: Setup API Key and AWS Region
        const API_KEY = "Your_API_Key";
        const AWS_REGION = "Region_where_you_created_API_Key";
        
        
        // Step 2: Add maps to application
        // Step 2.1 initialize the map
        const map = initializeMap("Standard","Light");
        // Step 2.2 Add navigation controls to the map
        map.addControl(new maplibregl.NavigationControl()); 

        // Step 3: Add places feature to application        
        // Step 3.1: Get GeoPlaces instance. It will be used for addion search box and map click functionality
        const geoPlaces =  getGeoPlaces(map);
        // Step 3.2: Add search box to the map
        addSearchBox(map, geoPlaces);
        // Step 3.3.: Setup map click functionality
        addMapClick(map, geoPlaces); 
                
 

        /**
         * Functions to add maps and places feature.
         */
         
         /**
         * Initializes the map with the specified style and color scheme.
         */ 
        function initializeMap(mapStyle = "Standard", colorScheme = "Dark") {
            const styleUrl = `https://maps.geo.${AWS_REGION}.amazonaws.com/v2/styles/${mapStyle}/descriptor?key=${API_KEY}&color-scheme=${colorScheme}`;
            const map = new maplibregl.Map({
                container: 'map',                   // The ID of the map container
                style: styleUrl,                    // The style URL for the map
                center: [-123.116226, 49.246292],   // Starting center coordinates
                zoom: 10,                           // Initial zoom level
                validateStyle: false                // Disable style validation
            });
            return map;                             // Return the initialized map
        }
        
        /**
         * Gets a GeoPlaces instance for Places operations.
         */
        function getGeoPlaces(map) {
            const authHelper =  amazonLocationClient.withAPIKey(API_KEY, AWS_REGION);                      // Authenticate using the API key and AWS region
            const locationClient = new amazonLocationClient.GeoPlacesClient(authHelper.getClientConfig()); // Create a GeoPlaces client
            const geoPlaces = new GeoPlaces(locationClient, map);                                          // Create GeoPlaces instance
                return geoPlaces;                                                                          // Return the GeoPlaces instance
        }
        
         /**
         * Adds search box to the map.
         */
        
        function addSearchBox(map, geoPlaces) {
            const searchBox = new MaplibreGeocoder(geoPlaces, {
                maplibregl,
                showResultsWhileTyping: true,                    // Show results while typing
                debounceSearch: 300,                             // Debounce search requests
                limit: 30,                                       // Limit number of results
                popuprender: renderPopup,                        // Function to render popup
                reverseGeocode: true,                            // Enable reverse geocoding
                zoom: 14,                                        // Zoom level on result selection
                placeholder: "Search text or nearby (lat,long)"  // Place holder text for search box.  
            });
            
            // Add the search box to the map
            map.addControl(searchBox, 'top-left'); 

            // Event listener for when a search result is selected
            searchBox.on('result', async (event) => {
                const { id, result_type } = event.result;                     // Get result ID and type
                if (result_type === "Place") {                                // Check if the result is a place
                    const placeResults = await geoPlaces.searchByPlaceId(id); // Fetch details for the selected place
                    if (placeResults.features.length) {
                        createPopup(placeResults.features[0]).addTo(map);     // Create and add popup for the place
                    }
                }
            });
        }

        /**
         * Renders the popup content for a given feature.
         */
        function renderPopup(feature) {
            return `
                <div class="popup-content">
                    <span class="${feature.place_type.toLowerCase()} badge">${feature.place_type}</span><br>
                    ${feature.place_name}
                </div>`;
        }

        /**
         * Creates a popup for a given feature and sets its position.
         */
        function createPopup(feature) {
            return new maplibregl.Popup({ offset: 30 })      // Create a new popup
                .setLngLat(feature.geometry.coordinates)     // Set the popup position
                .setHTML(renderPopup(feature));              // Set the popup content
        }
        
        /**
         * Sets up reverse geocoding on map click events.
         */
        function addMapClick(map, geoPlaces) {
            map.on('click', async ({ lngLat }) => {                     // Listen for click events on the map
                const response = await geoPlaces.reverseGeocode({ query: [lngLat.lng, lngLat.lat], limit: 1, click:true }); // Perform reverse geocoding

                if (response.features.length) {                         // If there are results
                    const clickMarker = new maplibregl.Marker({ color: "orange" }); // Create a marker
                    const feature = response.features[0];               // Get the clicked feature
                    const clickedPopup = createPopup(feature);          // Create popup for the clicked feature
                    clickMarker.setLngLat(feature.geometry.coordinates) // Set marker position
                        .setPopup(clickedPopup)                         // Attach popup to marker
                        .addTo(map);                                    // Add marker to the map

                    clickedPopup.on('close', () => clickMarker.remove()).addTo(map); // Remove marker when popup is closed
                }
            });
        }
        
    </script>
</body>
</html>
```

### 了解更多
<a name="qs-whats-next"></a>

您已经完成了快速入门教程，应该对如何使用 Amazon Location Service 来构建应用程序有所了解。要了解更多关于 Amazon Location 的信息，您可以查看以下资源：
+ **查询建议详细信息** - 考虑扩展 `GeoPlaces` 类或使用与 `ReverseGeocode` 类似的方法，来获取有关 `Suggestion` API 返回的结果的更多详细信息。
+ **选择满足您业务需求的恰当 API** - 要确定最能满足您需求的 Amazon Location API，请查看此资源：[选择正确的 API](choose-an-api.md)。
+ **查看 Amazon Location“操作方法”指南** - 访问[《Amazon Location Service 开发人员指南》](https://docs.aws.amazon.com/location/)，获取教程和其他资源。
+ **文档和产品信息** - 如需获取完整文档，请访问[《Amazon Location Service 开发人员指南》](https://docs.aws.amazon.com/location/)。要了解有关该产品的更多信息，请前往 [Amazon Location Service 产品](https://aws.amazon.com/location)页面。

# 创建您的第一个地理围栏和跟踪器应用程序
<a name="first-geofence-app"></a>

在本节中，您将创建应用程序来演示如何使用 Amazon Location 地理围栏和跟踪器的主要功能。这些应用程序演示了跟踪器和地理围栏如何使用 Lambda、 AWS IoT和 Amazon Location 功能的组合进行交互。选择 iOS 或 Android 平台开始创建。

开始构建应用程序之前，请按照[使用 Amazon Location Service 控制台进行身份验证](set-up-auth.md)中的步骤授予适当的访问权限。

**Topics**
+ [创建 iOS 应用程序](ios-geofence-app.md)
+ [创建 Android 应用程序](android-geofence-app.md)

# 创建 iOS 应用程序
<a name="ios-geofence-app"></a>

按照以下步骤使用 Amazon Location Service 构建 iOS 应用程序。

从中克隆项目文件[GitHub](https://github.com/aws-geospatial/amazon-location-samples-ios/tree/main/tracking-with-geofence-notifications)。

## 为您的应用程序创建 Amazon Location 资源
<a name="qs-ios-tracking-resources"></a>

 AWS 账户准备就绪后，您可以生成 Amazon Location Service 资源。这些资源对于执行提供的代码段至关重要。

**注意**  
如果您还没有创建 AWS 账户，请[创建一个 AWS 账户](https://portal.aws.amazon.com/billing/signup#/start/email)。

首先，您需要创建 Amazon Cognito 身份池 ID，请按以下步骤进行操作：

1. 在 AWS 控制台中，导航到 Amazon Cognito 服务，然后从左侧菜单中选择**身份池**，然后选择**创建身份**池。

1. 确保选中**访客访问权限**，然后按**下一步**继续。

1. 接下来，创建一个新 IAM 角色或使用现有 IAM 角色。

1. 输入身份池名称，并确保身份池可以访问您将在接下来的步骤中创建的地图和跟踪器的 Amazon Location `(geo)` 资源。

1. 

现在，您需要在 AWS Amazon Location 控制台中创建地图并设置地图样式，请按以下步骤操作：

1. 导航至 Amazon Location 控制台的[地图](https://console.aws.amazon.com/location/maps/home)部分，然后选择**创建地图**，预览可用的地图样式。

1. 为新地图资源提供**名称**和**描述**。记录您分配给地图资源的名称，因为稍后本教程会使用该名称。

1. 选择地图样式时，请考虑地图数据提供程序。有关更多详细信息，请参阅 [AWS 服务条款](https://aws.amazon.com/service-terms)的第 82 节。

1.  接受 [Amazon Location 条款和条件](https://aws.amazon.com/service-terms/#:~:text=82.%20Amazon%20Location%20Service)，然后选择**创建地图**。创建地图后，您可以通过放大、缩小或向任意方向平移来与地图进行交互。

使用 Amazon Location 控制台创建跟踪器

1.  打开 [Amazon Location Service 控制台](https://console.aws.amazon.com/location/)。

1.  在左侧导航窗格中，选择**跟踪器**。

1.  选择**创建跟踪器**。

1.  填写所有必填字段。

1.  在**位置筛选**下，选择最适合您打算如何使用跟踪器资源的选项。如果未设置位置筛选，则默认设置为 TimeBased。有关更多信息，请参阅本指南和 Amazon Location Service 追踪器 API 参考 PositionFiltering中的追踪器。

1.  选择**创建跟踪器**完成操作。

## 创建地理围栏集合
<a name="qs-ios-tracking-geofence"></a>

创建地理围栏集合时，您可以使用控制台、API 或 CLI。以下步骤将指导您完成每个选项。

使用 Amazon Location 控制台创建地理围栏集合：

1.  打开 Amazon Location Service 控制台，网址为 https://console.aws.amazon.com/location/。

1.  在左侧导航窗格中，选择“地理围栏集合”。

1.  选择创建地理围栏集合。

1.  为集合提供名称和描述。

1.  在以目标 CloudWatch 为目标的 EventBridge 规则下，您可以创建一条可选 EventBridge 规则来开始对地理围栏事件做出反应。这样，Amazon Location 就可以将事件发布到亚马逊 CloudWatch 日志。

1.  选择创建地理围栏集合。

使用 Amazon 位置创建地理围栏集合： APIs

使用 Amazon 定位地理围 APIs栏中的 CreateGeofenceCollection 操作。以下示例使用 API 请求创建名为 `GOECOLLECTION_NAME` 的地理围栏集合。

```
POST /geofencing/v0/collections
Content-type: application/json
    {
        "CollectionName": "GOECOLLECTION_NAME",
        "Description": "Geofence collection 1 for shopping center",
        "Tags": { 
            "Tag1" : "Value1"
                }
    }
```

使用 AWS CLI 以下命令创建地理围栏集合：

使用 create-geofence-collection 命令。以下示例使用 AWS CLI 创建名为 `GOECOLLECTION_NAME` 的地理围栏集合。

```
aws location \ create-geofence-collection \
    --collection-name "GOECOLLECTION_NAME" \
    --description "Shopping center geofence collection" \
    --tags Tag1=Value1                 
```

## 将跟踪器关联到地理围栏集合
<a name="qs-ios-tracking-link-geofence"></a>

要将跟踪器链接到地理围栏集合，您可以使用控制台、API 或 CLI。以下步骤将指导您完成每个选项。

使用 Amazon Location Service 控制台将跟踪器资源链接到地理围栏集合：

1. 打开 Amazon Location 控制台。

1. 在左侧导航窗格中，选择**跟踪器**。

1. 在**设备跟踪器**下，选择目标跟踪器的名称链接。

1. 在**链接的地理围栏集合下**，选择**链接地理围栏集合**。

1. 在**链接的地理围栏集合**窗口中，从下拉菜单中选择一个地理围栏集合。

1. 选择**链接**。

1. 在您关联跟踪器资源后，它将处于活动状态。

使用 Amazon 位置将追踪器资源链接到地理围栏集合： APIs

使用 Amazon 位置追踪器 APIs中的``AsssociateTrackerConsumer 操作。以下示例使用一个 API 请求，该请求使用其亚马逊资源名称 (ARN) ExampleTracker 与地理围栏集合相关联。

```
POST /tracking/v0/trackers/ExampleTracker/consumers
Content-type: application/json
        {
           "ConsumerArn": "arn:aws:geo:us-west-2:123456789012:geofence-collection/GOECOLLECTION_NAME"
        }
```

使用 AWS CLI 命令将跟踪器资源链接到地理围栏集合：

使用 `associate-tracker-consumer ` 命令。以下示例使用创建名 AWS CLI 为的地理围栏集合。`GOECOLLECTION_NAME`

```
aws location \
associate-tracker-consumer \
    --consumer-arn "arn:aws:geo:us-west-2:123456789012:geofence-collection/GOECOLLECTION_NAME" \
    --tracker-name "ExampleTracker"
```

## 将 AWS Lambda 与 MQTT 配合使用
<a name="qs-ios-tracking-lambda"></a>

创建 Lambda 函数：

要在 AWS IoT Core 和 Amazon Location Service 之间建立连接，您需要一个 AWS Lambda 函数来处理由 EventBridge CloudWatch 事件转发的消息。此函数将提取所有位置数据，将其格式化为 Amazon Location Service，然后通过 Amazon Location 跟踪器 API 提交。您可以通过 AWS Lambda 控制台创建此函数，也可以使用 AWS Command Line Interface (AWS CLI) 或 AWS Lambda APIs。要使用控制台创建 Lambda 函数，将位置更新发布到 Amazon Location，请执行以下操作：

1.  打开 AWS Lambda 控制台，网址为 https://console.aws.amazon.com/lambda/。

1. 从左侧导航窗格中，选择函数。

1. 选择创建函数，并确保选择从头开始创作。

1. 填写以下选框：
   + 函数名称
   + 对于**运行时**选项，选择“Node.js 16.x”。

1. 选择“创建函数”。

1. 选择“代码”选项卡以打开编辑器。

1. 在 index.js 中使用以下内容覆盖占位符代码：

   ```
   const AWS = require('aws-sdk')
   const iot = new AWS.Iot();
   exports.handler =  function(event) {
                 console.log("event===>>>", JSON.stringify(event));
                 var param = {
                   endpointType: "iot:Data-ATS"
                 };
                 iot.describeEndpoint(param, function(err, data) {
                   if (err) {
                     console.log("error===>>>", err, err.stack); // an error occurred
                   } else {
                     var endp = data['endpointAddress'];
                     const iotdata = new AWS.IotData({endpoint: endp});    
                     const trackerEvent = event["detail"]["EventType"];
                     const src = event["source"];
                     const time = event["time"];
                     const gfId = event["detail"]["GeofenceId"];
                     const resources = event["resources"][0];  
                     const splitResources = resources.split(".");  
                     const geofenceCollection = splitResources[splitResources.length - 1];
                     const coordinates = event["detail"]["Position"];                               
                     const deviceId = event["detail"]["DeviceId"]; 
                     console.log("deviceId===>>>", deviceId);
                     const msg =  {
                         "trackerEventType" : trackerEvent,
                         "source" : src,
                         "eventTime" : time,
                         "geofenceId" : gfId,
                         "coordinates": coordinates, 
                         "geofenceCollection": geofenceCollection
                       };
                     const params = {
                       topic: `${deviceId}/tracker`,
                       payload: JSON.stringify(msg),
                       qos: 0
                     };
                     iotdata.publish(params, function(err, data) {
                         if (err) {
                           console.log("error===>>>", err, err.stack); // an error occurred
                         } else {
                           console.log("Ladmbda triggered===>>>", trackerEvent);  // successful response 
                         }
                     }); 
                   }
                 });
               }
   ```

1. 选择部署以保存您更新的函数。

1. 选择配置选项卡。

1. 在“触发器”部分中，单击“添加触发器”。

1. 在 “来源” 字段中选择 EventBridge （CloudWatch 事件）。

1. 选择“现有规则”单选选项。

1. 输入这样的规则名称 `-GEOFENCECOLLECTION\$1NAM AmazonLocationMonitor E`。

1. 单击“添加”按钮。

1. 此时，系统还会在“权限”选项卡中附加“基于资源的策略声明”

MQTT 测试客户端

1. 打开 [https://console.aws.amazon.com/iot/](https://console.aws.amazon.com/iot/)。

1. 在左侧导航窗格中，选择 MQTT 测试客户端。

1. 您将看到标题为 **MQTT 测试客户端**的部分，您可以在其中配置 MQTT 连接。

1. 配置必要的设置后，单击**连接**按钮，使用提供的参数建立与 MQTT 代理的连接。

1. 记下端点值。

连接后，您可以使用 MQTT 测试客户端界面中提供的各个输入字段订阅 MQTT 主题或向主题发布消息。接下来，您将附加 MQTT 策略：

1.  在左侧菜单的**管理**下，展开**安全性**选项，然后单击**策略**。

1. 单击**创建策略**按钮。

1. 输入策略名称。

1. 在**策略文档**上，选择 **JSON** 选项卡。

1. 复制粘贴下面显示的策略，但请务必使用您的 `REGION` 和 `ACCOUNT_ID` 更新所有元素：

   ```
   {
       "Version": "2012-10-17",		 	 	 
       "Statement": [
                   {
                     "Action": [
                       "iot:Connect",
                       "iot:Publish",
                       "iot:Subscribe",
                       "iot:Receive"
                     ],
                     "Resource": [
                       "arn:aws:iot:REGION:ACCOUNT_ID:client/${cognito-identity.amazonaws.com:sub}",
                       "arn:aws:iot:REGION:ACCOUNT_ID:topic/${cognito-identity.amazonaws.com:sub}",
                       "arn:aws:iot:REGION:ACCOUNT_ID:topicfilter/${cognito-identity.amazonaws.com:sub}/",
                       "arn:aws:iot:REGION:ACCOUNT_ID:topic/${cognito-identity.amazonaws.com:sub}/tracker"
                      ],
                      "Effect": "Allow"
                    }
                  ]
   }
   ```

1. 选择**创建**按钮完成操作。

## 设置示例应用程序代码
<a name="qs-ios-tracking-setup-sample"></a>

为了设置示例代码，您必须安装以下工具：
+ Git
+ XCode 15.3 或更高版本
+ iOS 模拟器 16 或更高版本

使用以下步骤设置示例应用程序代码：

1. 从这个网址克隆 git 存储库：[https://github.com/aws-geospatial/amazon-location-samples-ios/tree/main/tracking-with-geofence-notifications](https://github.com/aws-geospatial/amazon-location-samples-ios/tree/main/tracking-with-geofence-notifications)。

1. 打开 `AWSLocationSampleApp.xcodeproj` 项目文件。

1. 等待程序包解析过程完成。

1. **可选**：在项目导航菜单上，将 `ConfigTemplate.xcconfig` 重命名为 `Config.xcconfig` 并填写以下值：

   ```
   IDENTITY_POOL_ID = `YOUR_IDENTITY_POOL_ID`
   MAP_NAME = `YOUR_MAP_NAME`
   TRACKER_NAME = `YOUR_TRACKER_NAME`
   WEBSOCKET_URL = `YOUR_MQTT_TEST_CLIENT_ENDPOINT`
   GEOFENCE_ARN = `YOUR_GEOFENCE_COLLECTION_NAME`
   ```

## 使用示例应用程序
<a name="qs-ios-tracking-usage"></a>

设置示例代码后，您现在可以在 iOS 模拟器或物理设备上运行该应用程序。

1. 构建并运行应用程序。

1. 该应用程序将要求您提供位置和通知权限。您需要允许这些权限。

1. 点击“Cognito 配置”按钮。

1. 如果您尚未填写“Config.xcconfig”文件中的值，则需要使用您之前在配置屏幕中创建的资源值填写该字段。

   ```
   IDENTITY_POOL_ID = `YOUR_IDENTITY_POOL_ID`
   MAP_NAME = `YOUR_MAP_NAME`
   TRACKER_NAME = `YOUR_TRACKER_NAME`
   WEBSOCKET_URL = `YOUR_MQTT_TEST_CLIENT_ENDPOINT`
   GEOFENCE_ARN = `YOUR_GEOFENCE_COLLECTION_NAME`
   ```

1. 保存配置

1. 现在，您将能够看到时间、距离和精度的筛选选项。根据需要使用这些选项。

1. 转到应用程序中的“跟踪”选项卡，您将看到地图和“开始跟踪”按钮。

1. 如果您已在模拟器上安装该应用程序，则可能需要模拟位置更改。可以在“功能”->“位置”菜单选项中完成此操作。例如，选择“功能”->“位置”->“高速公路驾车”。

1. 点击“开始跟踪”按钮。此时，您应该会在地图上看到跟踪点。

1. 该应用程序还会在后台跟踪位置。因此，当您在后台移动应用程序时，它会要求您提供在后台模式下继续跟踪的权限。

1. 您可以通过点击“停止跟踪”按钮来停止跟踪。

# 创建 Android 应用程序
<a name="android-geofence-app"></a>

按照以下步骤使用 Amazon Location Service 构建 iOS 应用程序。

从中克隆项目文件[GitHub](https://github.com/aws-geospatial/amazon-location-samples-android/tree/main/tracking-with-geofence-notifications)。

## 为您的应用程序创建 Amazon Location 资源
<a name="qs-android-tracking-resources"></a>

 AWS 账户准备就绪后，您可以生成 Amazon Location Service 资源。这些资源对于执行提供的代码段至关重要。

**注意**  
如果您还没有创建 AWS 账户，请[创建一个 AWS 账户](https://portal.aws.amazon.com/billing/signup#/start/email)。

首先，您需要创建 Amazon Cognito 身份池 ID，请按以下步骤进行操作：

1. 在 AWS 控制台中，导航到 Amazon Cognito 服务，然后从左侧菜单中选择**身份池**，然后选择**创建身份**池。

1. 确保选中**访客访问权限**，然后按**下一步**继续。

1. 接下来，创建一个新 IAM 角色或使用现有 IAM 角色。

1. 输入身份池名称，并确保身份池可以访问您将在接下来的步骤中创建的地图和跟踪器的 Amazon Location `(geo)` 资源。

1. 

现在，您需要在 AWS Amazon Location 控制台中创建地图并设置地图样式，请按以下步骤操作：

1. 导航至 Amazon Location 控制台的[地图](https://console.aws.amazon.com/location/maps/home)部分，然后选择**创建地图**，预览可用的地图样式。

1. 为新地图资源提供**名称**和**描述**。记录您分配给地图资源的名称，因为稍后本教程会使用该名称。

1. 选择地图样式时，请考虑地图数据提供程序。有关更多详细信息，请参阅 [AWS 服务条款](https://aws.amazon.com/service-terms)的第 82 节。

1. 接受 [Amazon Location 条款和条件](https://aws.amazon.com/service-terms/#:~:text=82.%20Amazon%20Location%20Service)，然后选择**创建地图**。创建地图后，您可以通过放大、缩小或向任意方向平移来与地图进行交互。

使用 Amazon Location 控制台创建跟踪器

1.  打开 [Amazon Location Service 控制台](https://console.aws.amazon.com/location/)。

1. 在左侧导航窗格中，选择**跟踪器**。

1. 选择**创建跟踪器**。

1. 填写所有必填字段。

1. 在**位置筛选**下，选择最适合您打算如何使用跟踪器资源的选项。如果未设置位置筛选，则默认设置为 TimeBased。有关更多信息，请参阅本指南和 Amazon Location Service 追踪器 API 参考 PositionFiltering中的追踪器。

1. 选择**创建跟踪器**完成操作。

## 创建地理围栏集合
<a name="qs-android-tracking-geofence"></a>

创建地理围栏集合时，您可以使用控制台、API 或 CLI。以下步骤将指导您完成每个选项。

使用 Amazon Location 控制台创建地理围栏集合：

1. 打开 Amazon Location Service 控制台，网址为 https://console.aws.amazon.com/location/。

1. 在左侧导航窗格中，选择“地理围栏集合”。

1. 选择创建地理围栏集合。

1. 为集合提供名称和描述。

1. 在以目标 CloudWatch 为目标的 EventBridge 规则下，您可以创建一条可选 EventBridge 规则来开始对地理围栏事件做出反应。这样，Amazon Location 就可以将事件发布到亚马逊 CloudWatch 日志。

1. 选择创建地理围栏集合。

使用 Amazon 位置创建地理围栏集合： APIs

使用 Amazon 定位地理围 APIs栏中的 CreateGeofenceCollection 操作。以下示例使用 API 请求创建名为 `GOECOLLECTION_NAME` 的地理围栏集合。

```
POST /geofencing/v0/collections
Content-type: application/json
    {
    "CollectionName": "GOECOLLECTION_NAME",
    "Description": "Geofence collection 1 for shopping center",
    "Tags": { 
        "Tag1" : "Value1"
            }
    }
```

使用 AWS CLI 以下命令创建地理围栏集合：

使用 create-geofence-collection 命令。以下示例使用 AWS CLI 创建名为 `GOECOLLECTION_NAME` 的地理围栏集合。

```
aws location \ create-geofence-collection \
    --collection-name "GOECOLLECTION_NAME" \
    --description "Shopping center geofence collection" \
    --tags Tag1=Value1               
```

## 将跟踪器关联到地理围栏集合
<a name="qs-android-tracking-link-geofence"></a>

要将跟踪器链接到地理围栏集合，您可以使用控制台、API 或 CLI。以下步骤将指导您完成每个选项。

使用 Amazon Location Service 控制台将跟踪器资源链接到地理围栏集合：

1. 打开 Amazon Location 控制台。

1. 在左侧导航窗格中，选择**跟踪器**。

1. 在**设备跟踪器**下，选择目标跟踪器的名称链接。

1. 在**链接的地理围栏集合下**，选择**链接地理围栏集合**。

1. 在**链接的地理围栏集合**窗口中，从下拉菜单中选择一个地理围栏集合。

1. 选择**链接**。

1. 在您关联跟踪器资源后，它将处于活动状态。

使用 Amazon 位置将追踪器资源链接到地理围栏集合： APIs

使用 Amazon 位置追踪器 APIs中的``AsssociateTrackerConsumer 操作。以下示例使用一个 API 请求，该请求使用其亚马逊资源名称 (ARN) ExampleTracker 与地理围栏集合相关联。

```
POST /tracking/v0/trackers/ExampleTracker/consumers
Content-type: application/json
    {
    "ConsumerArn": "arn:aws:geo:us-west-2:123456789012:geofence-collection/GOECOLLECTION_NAME"
    }
```

使用 AWS CLI 命令将跟踪器资源链接到地理围栏集合：

使用 `associate-tracker-consumer ` 命令。以下示例使用创建名 AWS CLI 为的地理围栏集合。`GOECOLLECTION_NAME`

```
aws location \
associate-tracker-consumer \
    --consumer-arn "arn:aws:geo:us-west-2:123456789012:geofence-collection/GOECOLLECTION_NAME" \
    --tracker-name "ExampleTracker"
```

## 将 AWS Lambda 与 MQTT 配合使用
<a name="qs-android-tracking-lambda"></a>

创建 Lambda 函数：

要在 AWS IoT Core 和 Amazon Location Service 之间建立连接，您需要一个 AWS Lambda 函数来处理由 EventBridge CloudWatch 事件转发的消息。此函数将提取所有位置数据，将其格式化为 Amazon Location Service，然后通过 Amazon Location 跟踪器 API 提交。您可以通过 AWS Lambda 控制台创建此函数，也可以使用 AWS Command Line Interface (AWS CLI) 或 AWS Lambda APIs。要使用控制台创建 Lambda 函数，将位置更新发布到 Amazon Location，请执行以下操作：

1.  打开 AWS Lambda 控制台，网址为 https://console.aws.amazon.com/lambda/。

1. 从左侧导航窗格中，选择函数。

1. 选择创建函数，并确保选择从头开始创作。

1. 填写以下选框：
   + 函数名称
   + 对于**运行时**选项，选择“Node.js 16.x”。

1. 选择“创建函数”。

1. 选择“代码”选项卡以打开编辑器。

1. 在 index.js 中使用以下内容覆盖占位符代码：

   ```
   const AWS = require('aws-sdk')
   const iot = new AWS.Iot();
   exports.handler =  function(event) {
       console.log("event===>>>", JSON.stringify(event));
       var param = {
           endpointType: "iot:Data-ATS"
           };
       iot.describeEndpoint(param, function(err, data) {
           if (err) {
               console.log("error===>>>", err, err.stack); // an error occurred
            } else {
                     var endp = data['endpointAddress'];
                     const iotdata = new AWS.IotData({endpoint: endp});    
                     const trackerEvent = event["detail"]["EventType"];
                     const src = event["source"];
                     const time = event["time"];
                     const gfId = event["detail"]["GeofenceId"];
                     const resources = event["resources"][0];  
                     const splitResources = resources.split(".");  
                     const geofenceCollection = splitResources[splitResources.length - 1];
                     const coordinates = event["detail"]["Position"];                               
                     const deviceId = event["detail"]["DeviceId"]; 
                     console.log("deviceId===>>>", deviceId);
                     const msg =  {
                         "trackerEventType" : trackerEvent,
                         "source" : src,
                         "eventTime" : time,
                         "geofenceId" : gfId,
                         "coordinates": coordinates, 
                         "geofenceCollection": geofenceCollection
                     };
       const params = {
           topic: `${deviceId}/tracker`,
           payload: JSON.stringify(msg),
           qos: 0
                };
       iotdata.publish(params, function(err, data) {
           if (err) {
               console.log("error===>>>", err, err.stack); // an error occurred
           } else {
               console.log("Ladmbda triggered===>>>", trackerEvent);  // successful response 
                  }
           }); 
          }
         });
        }
   ```

1. 选择部署以保存您更新的函数。

1. 选择配置选项卡。

1. 在“触发器”部分中，单击“添加触发器”。

1. 在 “来源” 字段中选择 EventBridge （CloudWatch 事件）。

1. 选择“现有规则”单选选项。

1. 输入这样的规则名称 `-GEOFENCECOLLECTION\$1NAM AmazonLocationMonitor E`。

1. 单击“添加”按钮。

1. 此时，系统还会在“权限”选项卡中附加“基于资源的策略声明”

MQTT 测试客户端

1. 打开 [https://console.aws.amazon.com/iot/](https://console.aws.amazon.com/iot/)。

1. 在左侧导航窗格中，选择 MQTT 测试客户端。

1. 您将看到标题为 **MQTT 测试客户端**的部分，您可以在其中配置 MQTT 连接。

1. 配置必要的设置后，单击**连接**按钮，使用提供的参数建立与 MQTT 代理的连接。

1. 记下端点值。

连接后，您可以使用 MQTT 测试客户端界面中提供的各个输入字段订阅 MQTT 主题或向主题发布消息。接下来，您将附加 MQTT 策略：

1.  在左侧菜单的**管理**下，展开**安全性**选项，然后单击**策略**。

1. 单击**创建策略**按钮。

1. 输入策略名称。

1. 在**策略文档**上，选择 **JSON** 选项卡。

1. 复制粘贴下面显示的策略，但请务必使用您的 `REGION` 和 `ACCOUNT_ID` 更新所有元素：

   ```
   {
    "Version": "2012-10-17",		 	 	 
    "Statement": [
                   {
                     "Action": [
                       "iot:Connect",
                       "iot:Publish",
                       "iot:Subscribe",
                       "iot:Receive"
                        ],
                     "Resource": [
                       "arn:aws:iot:REGION:ACCOUNT_ID:client/${cognito-identity.amazonaws.com:sub}",
                       "arn:aws:iot:REGION:ACCOUNT_ID:topic/${cognito-identity.amazonaws.com:sub}",
                       "arn:aws:iot:REGION:ACCOUNT_ID:topicfilter/${cognito-identity.amazonaws.com:sub}/",
                       "arn:aws:iot:REGION:ACCOUNT_ID:topic/${cognito-identity.amazonaws.com:sub}/tracker"
                       ],
                     "Effect": "Allow"
                   }
                 ]
   }
   ```
**注意**  
记录策略名称和主题名称，以便在后续步骤中使用。

1. 选择**创建**按钮完成操作。

完成上述步骤后，现在，您将按如下方式更新访客角色的权限：

1. 导航至 Amazon Cognito 并打开您的身份池。然后，继续设置用户访问权限并选择访客角色。

1. 单击权限策略以启用编辑。

   ```
   {
       'Version': '2012-10-17		 	 	 ',
       'Statement': [
           {
               'Action': [
                   'geo:GetMap*',
                   'geo:BatchUpdateDevicePosition',
                   'geo:BatchEvaluateGeofences',
                   'iot:Subscribe',
                   'iot:Publish',
                   'iot:Connect',
                   'iot:Receive',
                   'iot:AttachPrincipalPolicy',
                   'iot:AttachPolicy',
                   'iot:DetachPrincipalPolicy',
                   'iot:DetachPolicy'
               ],
               'Resource': [
                   'arn:aws:geo:us-east-1:{USER_ID}:map/{MAP_NAME}',
                   'arn:aws:geo:us-east-1:{USER_ID}:tracker/{TRACKER_NAME}',
                   'arn:aws:geo:us-east-1:{USER_ID}:geofence-collection/{GEOFENCE_COLLECTION_NAME}',
                   'arn:aws:iot:us-east-1:{USER_ID}:client/${cognito-identity.amazonaws.com:sub}',
                   'arn:aws:iot:us-east-1:{USER_ID}:topic/${cognito-identity.amazonaws.com:sub}',
                   'arn:aws:iot:us-east-1:{USER_ID}:topicfilter/${cognito-identity.amazonaws.com:sub}/*',
                   'arn:aws:iot:us-east-1:{USER_ID}:topic/${cognito-identity.amazonaws.com:sub}/tracker'
               ],
               'Effect': 'Allow'
           },
           {
               'Condition': {
                   'StringEquals': {
                       'cognito-identity.amazonaws.com:sub': '${cognito-identity.amazonaws.com:sub}'
                   }
               },
               'Action': [
                   'iot:AttachPolicy',
                   'iot:DetachPolicy',
                   'iot:AttachPrincipalPolicy',
                   'iot:DetachPrincipalPolicy'
               ],
               'Resource': [
                   '*'
               ],
               'Effect': 'Allow'
           }
       ]
   }
   ```

1. 通过上述策略更改，现在已为应用程序正确配置了所有必要的 AWS 资源。

## 设置示例应用程序代码
<a name="qs-android-tracking-sample-app-code"></a>



1. 打开 Android Studio，选择**新建**，然后选择**版本控制中的项目**。

1. 导航至 Android Studio 左上角的**文件**菜单。

1. 从下拉菜单中选择“新建”。

1. 选择“版本控制中的项目”。

1. 输入存储库 URL。在出现的对话框中，找到标有“URL”的字段。

1. 将示例应用程序的以下 URL 复制并粘贴到此字段中：[https://github.com/aws-geospatial/amazon-location-samples-android.git](https://github.com/aws-geospatial/amazon-location-samples-android.git)

1. 确定要将存储库克隆到哪个目录。使用默认目录，或选择自定义位置。

1. 设置存储库 URL 和目录首选项后，点击“克隆”按钮。Android Studio 会继续将存储库克隆到您指定的位置。

1. 现在，您已将应用程序克隆到计算机上，可以开始使用它了。

## 使用示例应用程序
<a name="qs-android-tracking-use"></a>

要使用该示例，请按照以下步骤进行操作：
+ **创建 `custom.properties`**：

  要配置 `custom.properties` 文件，请按照以下步骤进行操作：

  1. 打开您的首选文本编辑器或 IDE。

  1. 创建新的文件。

  1. 使用文件名 `custom.properties` 保存该文件。

  1. 使用以下代码示例更新 `custom.properties`，并将 `MQTT_END_POINT`、`POLICY_NAME`、`GEOFENCE_COLLECTION_NAME` 和 `TOPIC_TRACKER` 替换为实际值：

     ```
     MQTT_END_POINT=xxxxxxxxxxxxx-xxx.xxx.us-east-1.amazonaws.com
     POLICY_NAME=xxxxxxxxx
     GEOFENCE_COLLECTION_NAME=xxxxxxxxxxxxxxxxx
     TOPIC_TRACKER=xxxxxxxxxx
     ```

  1. 清理并重新构建项目。之后，您可以运行项目。
+ **登录**：

  要登录应用程序，请按照以下步骤进行操作：

  1. 按**登录**按钮。

  1. 提供**身份池 ID**、**跟踪器名称**和**地图名称**。

  1. 再次按**登录**完成操作。
+ **管理筛选器**：

  打开配置屏幕，然后执行以下操作：

  1.  on/off 使用切换界面切换过滤器。

  1. 需要时更新时间和距离筛选器。
+ **跟踪操作**：

  打开跟踪屏幕，然后执行以下操作：
  + 您可以通过按下相应的按钮，在前景、后台或省电模式下开始和停止跟踪。