位置信息与地图 - 通过 Amazon Location Service 和 Amplify 实现地理空间应用程序
介绍利用 Amazon Location Service 和 AWS Amplify 构建位置信息和地图应用程序的方法。
构成位置信息应用的 4 个组件
网约车、外卖配送、物流追踪、房产搜索、门店查找。处理位置信息的应用即使用途不同,所需的组件也大体相同。在屏幕上绘制地图;把地址和地名转换为经纬度(地理编码);计算地点之间的路线和所需时间;以及持续记录移动对象的位置,检测其进出特定区域。就是这 4 个。 如果要自行准备,地图数据的采购与许可确认、瓦片的生成与分发、基于道路网络的路径搜索实现、保存位置历史的数据存储的运维,全都会成为自己的工作。Amazon Location Service 将这些组件作为托管服务提供,让地图绘制、地点搜索、路线计算、位置追踪和地理围栏都能作为 AWS 的 API 来调用。 需要把握的一点是,这项服务的使用方式在 2024 年 11 月发生了很大变化。以前在开始使用之前必须先创建资源,而现行一代取消了这一步骤,只需准备 1 个 API 密钥即可调用。本文以现行一代的 API 为前提,从实际的调用方法一直讲到费用的计算思路。对于手头有用上一代构建的应用的情况,后半部分也专门设有一节介绍迁移。
2024 年 11 月的换代:从创建资源到 API 密钥
要理解现行一代的入口,捷径是先弄清楚哪些东西消失了。在上一代中,想做地址搜索就要先创建名为地点索引的资源,路线计算要创建路线计算器,地图显示要创建地图资源,都需要事先分别创建,再按名称引用。其设计是在创建资源的阶段选择数据提供商,之后的调用都绑定到该资源。 在 2024 年 11 月发布的新 API 群中,这一前提被取消了。官方说明也明确指出,以前必需的资源创建步骤已不再需要,通过设置 API 密钥即可使用各类 API。当时发布的是 10 个更新的 API 和 7 个新 API,合计 17 个新增或增强的 API。 与此同时,SDK 中的命名空间也被拆分了。地点搜索归入 geo-places,路线计算归入 geo-routes,地图获取归入 geo-maps,各自成为独立的系列,应用只需引入所需的系列。 API 密钥通过 CreateKey 创建,此外还提供 DescribeKey、ListKeys、UpdateKey、DeleteKey。密钥的值是以 v1.public. 开头的字符串,设计上是嵌入前端代码中使用的。正因为以嵌入为前提,密钥可以设置任意的有效期,并且在 Web 上可以按 HTTP 引用来源、在移动端可以按应用标识符来限制使用范围。 不过,API 密钥能调用的范围是有界线的。地图、地点、路线的查询类操作可以用密钥调用,但向追踪器写入位置、管理地理围栏以及管理密钥本身等操作,需要通过 IAM 或 Amazon Cognito 进行授权。把可以公开的查询与不宜公开的写入和管理操作,连同授权机制一起分开考虑,这就是现行一代的设计。
Places、Routes、Maps 的 3 个系列与首次调用
现行一代的 API 整理为 3 个系列。 处理地点的 Places 有 7 个操作。分别是根据地址字符串求经纬度的 Geocode、根据经纬度求地址的 ReverseGeocode、自由输入文本搜索的 SearchText、查找周边设施的 SearchNearby、用于输入补全的 Autocomplete 和 Suggest,以及根据标识符获取详细信息的 GetPlace。输入补全分成 2 个,是因为返回已确定的地址候选和返回搜索词本身的候选,是不同的场景。 处理路线的 Routes 有 5 个。分别是计算路线的 CalculateRoutes、生成多对多所需时间表的 CalculateRouteMatrix、以面的形式返回指定时间内可到达范围的 CalculateIsolines、优化多个停靠点顺序的 OptimizeWaypoints,以及把 GPS 点列校正到道路上的 SnapToRoads。对应关系是:配送计划用 CalculateRouteMatrix 和 OptimizeWaypoints,商圈分析用 CalculateIsolines,行驶记录的整理用 SnapToRoads。出行方式的取值因操作而异。CalculateRoutes 在 Car、Pedestrian、Scooter、Truck 之外加上公共交通的 Transit 和多式联运的 Intermodal,共 6 种;到达范围、道路吸附等其他 4 个操作则是 Car、Pedestrian、Scooter、Truck 这 4 种。无论哪种操作,未指定时均为 Car,Scooter 被视为包含摩托车的类别。 处理地图的 Maps 有 5 个:返回样式定义的 GetStyleDescriptor、获取矢量瓦片的 GetTile、返回标签绘制用字体的 GetGlyphs、获取图标图像的 GetSprites,以及以 1 张图像返回地图的 GetStaticMap。如果只是想在邮件或 PDF 中贴一张地图,用 GetStaticMap 就能完成。 首次调用用 CLI 来确认,简单便捷。使用 API 密钥时不需要签名,因此要加上 --no-sign-request。
aws geo-places geocode \
--query-text '東京都渋谷区神宮前 1-1-1' \
--language ja \
--key "$ALS_API_KEY" \
--no-sign-request \
--region ap-northeast-1如果通过 HTTP 直接调用,就向 POST /v2/geocode 发送请求,用查询参数 key 传递密钥,并在请求体中以 JSON 放入 QueryText 和 Language 等。官方文档的表述为:请求需要 API 密钥或有效的 SigV4 签名其中之一。从服务器端调用时使用常规的 IAM 认证,从浏览器或应用调用时使用 API 密钥,这就是分工。 如果想批量验证大量地址,不必逐条发送请求,而是有一条途径可通过 Amazon Location Service Jobs 异步处理 Amazon S3 上的文件。另外,位置追踪和地理围栏在现行一代中同样需要先创建名为追踪器和地理围栏集合的资源再使用。准确的理解是:不再需要创建资源的,是地图、地点、路线的查询类操作。
地图渲染与前端集成
地图的绘制本身由 MapLibre 负责。Web 端的 MapLibre GL JS 和移动端的 MapLibre Native 是官方推荐的渲染器,Amazon Location Service 一方的角色是提供样式定义和瓦片。 在 Web 上实现时,只需把样式描述符的 URL 传给 MapLibre 的样式设置即可运行。
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
const region = 'ap-northeast-1';
const apiKey = import.meta.env.VITE_ALS_API_KEY;
const map = new maplibregl.Map({
container: 'map',
style: `https://maps.geo.${region}.amazonaws.com/v2/styles/Standard/descriptor?key=${apiKey}&color-scheme=Dark`,
center: [139.7671, 35.6812],
zoom: 14
});
map.addControl(new maplibregl.NavigationControl());样式从 Standard、Monochrome、Hybrid、Satellite 这 4 种中选择。色调可以通过 color-scheme 参数在 Light 和 Dark 之间切换,默认为 Light。该值区分大小写,写成 dark 将无法生效。此外,建筑物的 3D 显示、地形阴影、等高线密度、交通状况叠加等表现,也可以通过附加在描述符 URL 上的参数来控制。也就是说,改变外观不需要改写应用端的代码,只需改变 URL 的组装方式。 端点的主机名有 2 种格式。仅支持 IPv4 的传统格式是 service-code.geo.region-code.amazonaws.com,同时支持 IPv4 和 IPv6 的双栈格式是 service-code.geo.region-code.api.aws。service code 方面,地图是 maps,地点是 places,路线是 routes,地理围栏是 geofencing,追踪器是 tracking,批量处理作业所属的系列是 metadata。在要求 IPv6 连接的环境中,选择后一种格式。 如果在 React 中使用 AWS Amplify,也可以用 Amplify Geo 的 UI 组件来显示地图。
import { MapView, Marker } from '@aws-amplify/ui-react-geo';
import '@aws-amplify/ui-react-geo/styles.css';
export default function StoreLocator() {
return (
<MapView
initialViewState={{ latitude: 35.6812, longitude: 139.7671, zoom: 14 }}
>
<Marker latitude={35.6812} longitude={139.7671} />
</MapView>
);
}不过,这种写法以 Amplify 构建的地图资源和 Amazon Cognito 的授权为前提,在凭证的处理思路上与前面介绍的 API 密钥方式不同。给现有的 Amplify 应用添加地图时用这种方式,直接使用现行一代的 API 时则把带密钥的描述符 URL 传给 MapLibre,事先这样梳理清楚,就能避免授权设计半途混杂。如果想按用户控制可操作的范围,或者要处理涉及写入的操作,无论哪种构成,最终都要依靠 Cognito 和 IAM。
从上一代 API 迁移与旧步骤的定位
如果现有应用运行在上一代上,代码的样子会有相当大的不同。上一代的地理编码采用指定预先创建的地点索引名称的形式。
aws location search-place-index-for-text \
--index-name MyPlaceIndex \
--text '東京都渋谷区神宮前 1-1' \
--language ja \
--region ap-northeast-1在这种形式下,创建索引时选择的数据提供商决定了之后的搜索结果。想更换提供商就必须重新创建索引,即使只是想比较搜索质量,也会牵涉到资源管理。现行一代的 API 中没有相当于 --index-name 的指定项。路线计算的路线计算器名称、地图资源名称这类指定项同样不存在,因此迁移工作的实质就是“删掉传递资源名称的地方,把调用目标替换为新的操作名”。 出行方式的取值也变了。上一代有 Bicycle、Car、Motorcycle、Truck、Walking 这 5 种。现行一代以 Car、Pedestrian、Scooter、Truck 为基础,仅在路线计算(CalculateRoutes)中增加公共交通的 Transit 和多式联运的 Intermodal。Walking 改读为 Pedestrian,Motorcycle 改读为 Scooter。现行一代中没有对应自行车的取值,因此原本返回以自行车为前提的路线的应用,需要在迁移时决定替代的处理方式。 上一代的文档并没有消失,而是集中在 docs.aws.amazon.com/location/previous/ 之下。在搜索中找到的步骤是现行的还是上一代的,可以根据 URL 中是否包含 previous 来判断。在迁移过程中想确认旧步骤时,就要看这个位置。 如果是从用 Google Maps JavaScript API 编写的应用迁移过来,可以选择 AWS 公开的 Amazon Location Migration SDK。这个工具的思路是插入一层模仿 Google Maps 调用接口的中间层,在不大幅改写应用业务逻辑的前提下,把地图绘制和地点搜索逐步替换到 Amazon Location Service 一侧。对于规模大到无法一次性全面改写的应用,先用这一层确认替换的范围,是现实的做法。
数据提供商的选择与使用条件
地图和地理编码的结果本身并不是 AWS 独自制作的,而是由数据提供商供应的。截至 2026 年 8 月,提供方为 Esri、HERE,以及面向东南亚的 GrabMaps。关于地图瓦片,仅在经由上一代地图资源时,除这些之外还可以选择源自 Open Data 的样式。Open Data 用于地图绘制,不用于地点搜索和路线计算。如果把提供方理解为从 2 家中选择,就会漏看面向东南亚的选项和 Open Data 的瓦片。 在选型中首先起作用的,与其说是质量,不如说是使用条件。而且,这些条件不是在服务文档中,而是在 AWS 服务条款中规定的。除非获得 AWS 的书面同意,否则 Esri 的数据不能用于自有业务资产(如公司车辆或自有设施)的追踪,也不能用于为此进行的路线计算。HERE 的数据不能保存日本的结果。GrabMaps 是面向东南亚的提供方,可用的区域有限。此外,不同区域可用的操作和样式也有差异。在负责东南亚的 ap-southeast-1(新加坡)和 ap-southeast-5(马来西亚),不提供 Geocode,地图样式也仅限 Standard 和 Monochrome。对象地区的区域是否提供所需的操作,在开始实现之前查阅按区域列出的提供情况一览进行确认,较为稳妥。 能否保存也直接关系到计费。Places 的 API 中有一个名为 IntendedUse 的参数,可指定 SingleUse(单次使用)和 Storage(保存)中的一种。如果要把响应保存到自己的数据库中,为遵守服务条款必须指定 Storage,此时单价会更高。如果只在画面上显示而不保存,就用 SingleUse。不要用“位置信息不会离开 AWS”这样的一般论来了结,而是从各提供方的保存限制和 IntendedUse 的指定这 2 点进行确认,才是实用的梳理方式。
Location Service 的定价
(截至 2026 年 8 月,已在美国东部(弗吉尼亚北部)和亚太地区(东京)2 个区域分别确认。两个区域价格相同) 地图、地点、路线查询类的费用,不是按持有资源的时间,而是按调用次数决定的。这些系列不需要创建地图或索引资源,因此在不使用的期间不会产生固定费用。如后文所述,只有地理围栏存在对持有本身的计费。 地图瓦片在现行一代的 GetTile 中,不论样式,每 1,000 个瓦片 0.04 美元。按提供方区分的单价保留在经由上一代地图资源的获取中,只有 Open Data 的样式为每 1,000 个瓦片 0.035 美元。以 1 张图像返回地图的 GetStaticMap 为每 1,000 次请求 0.50 美元。需要注意的是,显示 1 个画面会获取多个瓦片,缩放和平移操作越多的 UI,瓦片数就越多。 地点搜索每 1,000 次请求,Core 为 0.50 美元,Advanced 为 1.50 美元。输入补全的 Autocomplete 和 Suggest 的轻量响应有一个名为 Label 的单独档位,每 1,000 次请求 0.20 美元。伴随保存的用途(在 IntendedUse 中指定 Storage 的调用)为每 1,000 次请求 4.00 美元。批量验证地址的用途适用阶梯单价。以 Advanced 为例,最初的 10 万条为每 1,000 条 12.50 美元,接下来的 40 万条为 9.00 美元,再接下来的 50 万条为 6.50 美元,再接下来的 400 万条为 3.00 美元,超过 500 万条的部分为 1.50 美元。Core 则另有一套从 10.50 美元降至 1.00 美元的阶梯单价。 路线计算(CalculateRoutes)每 1,000 次请求,Core 为 0.50 美元,Advanced 为 1.50 美元,Premium 为 4.00 美元。单价水平在其他操作中也是共通的,但可选的档位因操作而异。所需时间表(CalculateRouteMatrix)只有 Core 和 Advanced,到达范围、道路吸附、途经点优化只有 Advanced 和 Premium。因此后 3 个操作没有 0.50 美元的 Core,最低单价为每 1,000 次请求 1.50 美元。 位置追踪不是按每台设备的月费,而是按发送的位置条数决定的。位置写入最初的 50 万条为每 1,000 条 0.05 美元,接下来的 450 万条为 0.035 美元,再接下来的 4,500 万条为 0.025 美元,超过 5,000 万条的部分为 0.0125 美元。位置读取和设备删除各为每 1,000 条 0.05 美元,位置完整性评估为每 1,000 条 1.00 美元。如果让 100 辆每 10 秒发送一次位置的车辆运行,1 天就会超过 86 万条,可见发送间隔的设计会直接体现在费用上。 地理围栏是唯一在调用计费之外还有持有计费的组件,每 1,000 个已登记的地理围栏每月 0.20 美元。位置与地理围栏的匹配(位置评估)为阶梯制,最初的 25 万条为每 1,000 条 0.16 美元,接下来的 175 万条为 0.11 美元,再接下来的 2,300 万条为 0.07 美元,超过 2,500 万条的部分为 0.06 美元。此外,地理围栏的创建、更新等管理操作为每 1,000 条 0.05 美元,到达预测为每 1,000 条 1.75 美元。 按 Core、Advanced、Premium 中的哪一档计费,取决于请求附加的选项。实际适用的档位会在响应的 PricingBucket 字段中返回,因此在制作估算之前,先实测开发中的请求落在哪个档位,就能避免预期与账单之间的偏差。对于月使用额超过 5,000 美元的规模,官方定价页面上有批量折扣的说明。 关于可以免费试用的范围,需要了解目前有 2 种说法并存。面向 AWS 整体新账户的免费套餐已于 2025 年 7 月 15 日改为抵扣金方式,可获得最多价值 200 美元的抵扣金,免费计划可使用 6 个月,抵扣金需在 12 个月内用完。另一方面,Location Service 的定价页面上还并列着前 3 个月每月在一定用量内免费的传统表格。适用于自己账户的是哪一种,取决于账户的创建时间,因此先在账单控制面板的免费套餐页面确认实际剩余量,再制定估算,这样比较稳妥。
总结
现行一代的 Amazon Location Service 不是先创建地点索引或路线计算器再使用的服务。只需准备 1 个 API 密钥,就能调用 Places 的 7 个操作、Routes 的 5 个操作和 Maps 的 5 个操作。遇到按上一代步骤编写的文章或示例时,确认 URL 中是否包含 previous,就不会弄错世代。 设计时需要把握的要点可以归结为 3 点。第 1 点是授权的划分:可以公开的查询交给 API 密钥,写入和管理交给 IAM 或 Amazon Cognito。第 2 点是数据提供商:在 Esri、HERE、GrabMaps 以及面向地图瓦片的 Open Data 中,选择服务条款允许自己用途的提供方,如果要保存结果,就在 IntendedUse 中指定 Storage。第 3 点是计费单位:费用由请求数和适用的档位决定,因此一边查看 PricingBucket 一边调整选项的附加方式,会很见效。 地图绘制交给 MapLibre,外观通过样式描述符 URL 的参数来切换。理解了这种分工,从门店查找这样的小画面,到持续追踪车辆规模的构成,都可以用同样的思路来搭建。
参考资料(AWS 官方)
本页的第一手信息来源是 AWS 官方网站及官方文档。最新的规格与价格请以下列官方页面为准。
如本页内容与官方文档不一致,请以官方文档为准。