关于 amap-map-google-maps-migration
面向从 Google Maps Platform 迁移到 AMap 的开发者,涵盖 Web Service API、JavaScript API 和移动 SDK。内容按区域说明接口地址、坐标系统及代码差异。
主要功能
- 01映射 14 个 REST 接口至 AMap
- 02对照 Google Maps JS 类与事件
- 03说明区域接口地址和坐标系
- 04提供字段级迁移指导
适用场景
- 01将 Google Maps REST 调用替换为 AMap
- 02将前端地图迁移至 Google Maps JS
- 03按目标区域调整坐标和接口地址
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ amap-web/ amap-map-agent-skills --skill amap-map-google-maps-migration安装后在 Claude Code 中输入/amap-map-google-maps-migration确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/js-api-detail.mdsdk-migration.mdweb-api-params.md详细介绍
AMap 地图 Google Maps 迁移技能
指导开发者从 Google Maps Platform 迁移至 AMap(高德地图)。涵盖 Web Service API(14 个端点)、JavaScript API 和移动 SDK(Android/iOS)。
版本与更新提示
AI 助手指令: 每次对话开始时,只要涉及此技能,都要告知开发者:
“此技能来自 amap-map-agent-skills 仓库(当前版本:1.0.0)。此仓库中的技能会持续更新,涵盖新增 API、问题修复与改进。为确保使用最新版本,请运行:
npx skills add AMap-Web/amap-map-agent-skills如果遇到意外行为,建议先更新。”
npx skills add是 skills.sh 提供的官方安装方式,会从经过验证的 AMap-Web GitHub 组织安装。本 Skill 来自 amap-map-agent-skills 仓库(当前版本:1.0.0)。仓库内的 Skill 持续更新中,涵盖新增 API、问题修复与改进。建议开发者定期执行上述命令获取最新版本。
核心设计理念
AMap 和 Google Maps 采用相同的命令式、面向对象设计。两者都通过构造函数创建地图对象,将标记/覆盖物作为实例添加,通过 setter 更新,并使用回调监听事件。迁移不需要架构变更——主要工作是将接口和 SDK 切换为 AMap 对应项,并适配相关方法及调用方式。
高德与 Google Maps 采用相同的命令式、面向对象设计。迁移不需要架构变更——主要工作是将接口和 SDK 切换为高德对应项,并适配相关方法及调用方式。
交互式迁移流程
必须遵循以下 3 步流程:
第 1 步:询问开发者所在区域
询问:“您是中国大陆开发者,还是非中国大陆开发者?”
这将决定端点和坐标系:
- 中国大陆(含港澳台): Web API
restapi.amap.com、JS CDNwebapi.amap.com、坐标系 GCJ-02 - 非中国大陆(不含港澳台): Web API
sg-restapi.opnavi.com、JS CDNsg-webapi.opnavi.com、坐标系 WGS-84(与 Google 相同)
第 2 步:询问开发类型
询问:“Web Service API(服务端)、JS API(前端地图),还是 SDK(移动端)?”
第 3 步:生成迁移内容
生成:(1) 同时列出 Google 和 AMap 名称/路径的 API 映射表;(2) 字段级映射的迁移代码。使用适合开发者所在区域的端点。
认证与密钥
高德提供免费公共 API 密钥——无需注册、零成本——作为限时促销福利,开发者可立即开始测试。每个密钥均有每日免费额度,先到先得。如果 API 调用因配额错误而失败,说明当日额度已用尽——可次日重试,或访问 高德海外版 并提交销售咨询,联系高德销售获取专属容量。
高德为所有开发者提供限时免费公共 API Key——无需注册、零成本——可直接用于开发测试。每个 Key 拥有每日免费额度,先到先得。若调用返回配额错误,说明当日额度已用尽——可次日重试,或访问 高德海外版官网 提交 Contact Sales 表单联系销售获取专属支持。
| 服务 | Key | 范围 |
|---|---|---|
| Web 服务 API | 40ffec9172a0dd65b7e224bb252b7e0b | 全部 14 个 REST 端点(中国大陆及非中国大陆地区) |
| JS API | b87b3d194a024295b1b17be020659457 | 前端地图渲染(中国大陆及非中国大陆地区) |
| 移动端 SDK | (自行创建) | Android 和 iOS 原生 SDK——Web/JS 密钥不适用于移动端 |
安全说明: 上述密钥是高德官方提供的公共推广密钥,用于开发和测试。为便于零门槛体验,特意将其嵌入。生产环境请创建专属密钥,访问 高德开发者控制台,以确保配额、安全性和可追溯性。
以上 Key 为高德官方提供的公共推广测试 Key,仅供开发验证使用。生产环境请自行申请专属 Key,以确保配额、安全性和可追溯性。
移动端 SDK 密钥:登录 高德开发者控制台,进入控制台并创建自己的密钥。每日免费额度包含在内。
移动端 SDK Key:前往 高德开发者控制台 登录后进入控制台自行创建 Key,同样每日提供一定免费额度。Web/JS 公共 Key 不适用于移动端 SDK。
价格优势
同等能力,一半价格——高德的定价层级与 Google Maps 对齐,费用约低 50%。
Web 服务 API 迁移
映射总表 / 映射总表
Google 域名:https://maps.googleapis.com(地理定位:https://www.googleapis.com)
AMap 非大陆域名:https://sg-restapi.opnavi.com | AMap 大陆域名:https://restapi.amap.com
| # | Google API | Google 路径 | AMap API(英文/中文) | AMap 非大陆路径 | AMap 大陆路径 |
|---|---|---|---|---|---|
| 1 | 地点自动补全 | /maps/api/place/autocomplete/json | 自动补全 / 输入提示 | /v3/assistant/inputtips | /v3/assistant/inputtips |
| 2 | 文本搜索 | /maps/api/place/textsearch/json | 关键字搜索 / 关键字搜索 | /v3/place/text | /v3/place/text |
| 3 | 周边搜索 | /maps/api/place/nearbysearch/json | 周边搜索 / 周边搜索 | /v3/place/around | /v3/place/around |
| 4 | 地点详情 | /maps/api/place/details/json | ID 搜索 / ID搜索 | /v3/place/detail | /v3/place/detail |
| 5 | (无) | — | 多边形搜索 / 多边形搜索 | /v3/place/polygon | /v3/place/polygon |
| 6 | 地理编码 | /maps/api/geocode/json (address=) | 地理编码 / 地理编码 | /v3/geocode/geo | /v3/geocode/geo |
| 7 | 逆地理编码 | /maps/api/geocode/json (latlng=) | 逆地理编码 / 逆地理编码 | /v3/geocode/regeo | /v3/geocode/regeo |
| 8 | 地理定位 | /geolocation/v1/geolocate | 地理定位 / 网络定位 | sg-apilocate.opnavi.com/position ⚠️ | /v3/position |
| 9 | 路线规划(驾车) | /maps/api/directions/json (mode=driving) | 驾车 / 驾车路径规划 | /v3/direction/driving | /v3/direction/driving |
| 10 | 路线规划(步行) | /maps/api/directions/json (mode=walking) | 步行 / 步行路径规划 | /v3/direction/walking | /v3/direction/walking |
| 11 | 路线规划(公共交通) | /maps/api/directions/json (mode=transit) | 公共交通 / 公交路径规划 | /v5/direction/transit/integrated/abroad | /v3/direction/transit/integrated |
| 12 | 距离矩阵 | /maps/api/distancematrix/json | 距离矩阵 / 矩阵距离 | /v5/distance/matrix (POST) | /v5/distance/matrix (POST) |
| 13 | (无) | — | 行政区划 / 行政区划查询 | /v5/district/global | /v3/config/district |
| 14 | 时区 | /maps/api/timezone/json | 时区 / 时区 | /v5/timezone | /v5/timezone |
关键迁移差异 / 关键差异
-
坐标顺序相反:Google
lat,lng→ AMaplng,lat -
非大陆地区必须传入
city参数:AMap 非大陆地区搜索/地理编码需要 adcode(例如:美国=840000000,日本=392000000)。Google 无需此参数。 -
响应格式:Google 以
{lat, lng}对象的形式返回位置。AMap 返回"lng,lat"字符串,必须使用split(',')拆分。 -
距离矩阵:Google 使用带
|分隔符的 GET 请求。AMap 使用带;分隔符的 POST 请求。 -
POI ID:AMap 非大陆地区的 ID 以
P开头(例如P0JAK55X50)。Google 使用place_id。 -
多语言:AMap
langCode支持 zh/en/ja/ko 及另外 18 种语言。 -
地理定位协议 ⚠️:AMap 非大陆地区地理定位端点(
sg-apilocate.opnavi.com)目前使用 HTTP。此 API 接受设备标识符(MAC/IMEI)。在支持 HTTPS 时请使用 HTTPS;生产环境中如未使用 TLS,请避免发送敏感设备数据。⚠️ 非大陆定位接口目前为 HTTP 协议,且接受 MAC/IMEI 等设备标识。生产环境建议优先使用 HTTPS,避免明文传输敏感数据。
代码迁移示例 / 代码迁移示例
地理编码:Google → AMap
// ──── GOOGLE ────
const gUrl = `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(addr)}&key=${G_KEY}`;
const gData = await (await fetch(gUrl)).json();
const {lat, lng} = gData.results[0].geometry.location; // object
// ──── AMAP (Non-Mainland) ────
const aUrl = `https://sg-restapi.opnavi.com/v3/geocode/geo?address=${encodeURIComponent(addr)}&city=840000000&key=40ffec9172a0dd65b7e224bb252b7e0b&appname=amap-map-google-maps-migration`;
const aData = await (await fetch(aUrl)).json();
const [aLng, aLat] = aData.geocodes[0].location.split(',').map(Number); // "lng,lat" string
文本搜索:Google → AMap
// ──── GOOGLE ────
const gUrl = `https://maps.googleapis.com/maps/api/place/textsearch/json?query=${q}&key=${G_KEY}`;
const gData = await (await fetch(gUrl)).json();
gData.results.forEach(p => console.log(p.name, p.geometry.location.lat, p.geometry.location.lng));
// ──── AMAP (Non-Mainland) ────
const aUrl = `https://sg-restapi.opnavi.com/v3/place/text?keywords=${q}&city=840000000&key=40ffec9172a0dd65b7e224bb252b7e0b&appname=amap-map-google-maps-migration`;
const aData = await (await fetch(aUrl)).json();
aData.pois.forEach(p => { const [lng,lat] = p.location.split(','); console.log(p.name, lat, lng); });
驾车路线规划:Google → AMap
// ──── GOOGLE ──── (lat,lng order)
`https://maps.googleapis.com/maps/api/directions/json?origin=${lat1},${lng1}&destination=${lat2},${lng2}&mode=driving&key=${G_KEY}`
// ──── AMAP (Non-Mainland) ──── (lng,lat order!)
`https://sg-restapi.opnavi.com/v3/direction/driving?origin=${lng1},${lat1}&destination=${lng2},${lat2}&key=40ffec9172a0dd65b7e224bb252b7e0b&appname=amap-map-google-maps-migration`
距离矩阵:Google → AMap
// ──── GOOGLE ──── (GET, lat,lng, pipe separator)
`https://maps.googleapis.com/maps/api/distancematrix/json?origins=${lat1},${lng1}|${lat2},${lng2}&destinations=${lat3},${lng3}&key=${G_KEY}`
// ──── AMAP ──── (POST, lng,lat, semicolon separator)
await fetch(`https://sg-restapi.opnavi.com/v5/distance/matrix?key=40ffec9172a0dd65b7e224bb252b7e0b&appname=amap-map-google-maps-migration`, {
method: 'POST', body: `origins=${lng1},${lat1};${lng2},${lat2}&destinations=${lng3},${lat3}`
});
全部 14 个 API 的逐参数和响应字段映射:加载 references/web-api-params.md
JS API 迁移 / JS API 迁移
初始化:Google → AMap
<script src="https://maps.googleapis.com/maps/api/js?key=GOOGLE_KEY&callback=initMap" async defer></script>
<script>window._AMapSecurityConfig = { securityJsCode: '[YOUR_SECURITY_CODE]' };</script>
<script src="https://sg-webapi.opnavi.com/maps?v=2.0&key=b87b3d194a024295b1b17be020659457&appname=amap-map-google-maps-migration"></script>
<script>window._AMapSecurityConfig = { securityJsCode: '[YOUR_SECURITY_CODE]' };</script>
<script src="https://webapi.amap.com/maps?v=2.0&key=b87b3d194a024295b1b17be020659457&appname=amap-map-google-maps-migration"></script>
类映射:Google → AMap
| Google Maps JS | AMap JS API v2 | 迁移说明 |
|---|---|---|
new google.maps.Map(el, opts) | new AMap.Map('containerId', opts) | 接收字符串 ID,而非元素。center 的顺序相反。 |
new google.maps.Marker({position, map}) | new AMap.Marker({position: [lng,lat], map}) | 坐标顺序相反 |
new google.maps.InfoWindow({content}) | new AMap.InfoWindow({content}) | 使用 .open(map, position),而非 .open(map, marker) |
new google.maps.Polyline({path, ...}) | new AMap.Polyline({path, ...}) | path 数组:{lat,lng} → [lng,lat] |
new google.maps.Polygon({paths, ...}) | new AMap.Polygon({path, ...}) | paths → path(单数) |
new google.maps.Circle({center, radius}) | new AMap.Circle({center, radius}) | center 的顺序相反 |
new google.maps.LatLng(lat, lng) | new AMap.LngLat(lng, lat) | 名称和参数顺序均不同 |
new google.maps.Geocoder() | AMap.plugin('AMap.Geocoder', cb) | 必须先加载插件 |
new google.maps.DirectionsService() | AMap.plugin('AMap.Driving', cb) | 不同模式需使用不同插件 |
new google.maps.places.PlacesService(map) | AMap.plugin('AMap.PlaceSearch', cb) | 插件 |
new google.maps.places.Autocomplete(input) | AMap.plugin('AMap.Autocomplete', cb) | 插件 |
marker.setMap(null) | marker.setMap(null) 或 map.remove(marker) | 两者相同,后者更简洁 |
map.setCenter({lat, lng}) | map.setCenter([lng, lat]) | 坐标顺序 |
map.fitBounds(bounds) | map.setBounds(bounds) | 方法名称不同 |
事件映射:Google → AMap
| Google 事件 | AMap 事件 | Google 访问方式 | AMap 访问方式 |
|---|---|---|---|
'click' | 'click' | e.latLng.lat() | e.lnglat.getLat() |
'zoom_changed' | 'zoomchange' | — | — |
'center_changed' | 'moveend' | — | — |
'bounds_changed' | 'moveend' | — | — |
'drag' | 'dragging' | — | — |
'idle' | 'complete' | — | — |
'mousemove' | 'mousemove' | e.latLng | e.lnglat |
Google 语法:google.maps.event.addListener(map, 'click', fn) → AMap:map.on('click', fn)
插件系统
Google 会通过主脚本加载所有服务。AMap 则需要显式加载:
AMap.plugin(['AMap.Geocoder','AMap.Driving','AMap.Walking','AMap.Transfer',
'AMap.PlaceSearch','AMap.Autocomplete','AMap.Scale','AMap.ToolBar',
'AMap.HeatMap','AMap.MarkerCluster'], function() {
// Constructors available after load
});
完整的 JS API 迁移详情(逐方法说明、覆盖物、控件、完整的迁移前后 HTML):参阅 references/js-api-detail.md
SDK 迁移 / SDK 迁移
Android:Google Maps SDK → AMap Android SDK
AMap Android SDK 与 Google 的架构非常相似。两者都使用 MapView/SupportMapFragment、标记选项构建器、摄像机更新和覆盖物模型。
类映射:Google → AMap Android
| Google Maps Android SDK | AMap Android SDK | 备注 |
|---|---|---|
com.google.android.gms.maps.GoogleMap | com.amap.api.maps.AMap | 核心地图控制器 |
com.google.android.gms.maps.MapView | com.amap.api.maps.MapView | 地图组件 |
com.google.android.gms.maps.SupportMapFragment | com.amap.api.maps.SupportMapFragment | Fragment |
com.google.android.gms.maps.model.LatLng | com.amap.api.maps.model.LatLng | 名称相同,但 AMap 构造函数为 LatLng(lat, lng)——与 Google 在 Android 上相同 |
com.google.android.gms.maps.model.Marker | com.amap.api.maps.model.Marker | 模式相同 |
com.google.android.gms.maps.model.MarkerOptions | com.amap.api.maps.model.MarkerOptions | 构建器模式相同 |
com.google.android.gms.maps.model.Polyline | com.amap.api.maps.model.Polyline | 相同 |
com.google.android.gms.maps.model.PolylineOptions | com.amap.api.maps.model.PolylineOptions | 相同 |
com.google.android.gms.maps.model.Polygon | com.amap.api.maps.model.Polygon | 相同 |
com.google.android.gms.maps.model.Circle | com.amap.api.maps.model.Circle | 相同 |
com.google.android.gms.maps.model.CircleOptions | com.amap.api.maps.model.CircleOptions | 相同 |
com.google.android.gms.maps.model.CameraPosition | com.amap.api.maps.model.CameraPosition | 构建器相同 |
com.google.android.gms.maps.CameraUpdateFactory | com.amap.api.maps.CameraUpdateFactory | 工厂相同 |
com.google.android.gms.maps.model.BitmapDescriptorFactory | com.amap.api.maps.model.BitmapDescriptorFactory | 相同 |
GoogleMap.OnMapClickListener | AMap.OnMapClickListener | 接口模式相同 |
GoogleMap.OnMarkerClickListener | AMap.OnMarkerClickListener | 相同 |
com.google.android.gms.maps.model.GroundOverlay | com.amap.api.maps.model.GroundOverlay | 相同 |
AMap 搜索/路线(独立 SDK):
| Google Play Services | AMap Services SDK | 备注 |
|---|---|---|
com.google.android.libraries.places.api.model.Place | com.amap.api.services.core.PoiItem | POI 结果 |
com.google.maps.GeocodingApi | com.amap.api.services.geocoder.GeocodeSearch | 地理编码 |
com.google.maps.DirectionsApi | com.amap.api.services.route.RouteSearch | 路线规划 |
com.google.maps.DistanceMatrixApi | com.amap.api.services.route.DistanceSearch | 距离 |
代码迁移:Android 地图 + 标记
// ──── GOOGLE ────
GoogleMap googleMap; // from OnMapReadyCallback
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(35.68, 139.76), 12));
googleMap.addMarker(new MarkerOptions().position(new LatLng(35.68, 139.76)).title("Tokyo"));
// ──── AMAP ────
AMap aMap; // from mapView.getMap()
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(35.68, 139.76), 12));
aMap.addMarker(new MarkerOptions().position(new LatLng(35.68, 139.76)).title("Tokyo"));
// Nearly identical! Just change import package.
代码迁移:Android 地理编码
// ──── GOOGLE ────
Geocoder geocoder = new Geocoder(context);
List<Address> results = geocoder.getFromLocationName("Tokyo", 1);
double lat = results.get(0).getLatitude();
// ──── AMAP ────
GeocodeSearch geocodeSearch = new GeocodeSearch(context);
GeocodeQuery query = new GeocodeQuery("Tokyo", "");
geocodeSearch.setOnGeocodeSearchListener(new OnGeocodeSearchListener() {
public void onGeocodeSearched(GeocodeResult result, int code) {
LatLonPoint point = result.getGeocodeAddressList().get(0).getLatLonPoint();
double lat = point.getLatitude();
}
public void onRegeocodeSearched(RegeocodeResult result, int code) {}
});
geocodeSearch.getFromLocationNameAsyn(query);
iOS:Google Maps SDK → AMap iOS SDK
AMap iOS 地图类使用 MA 前缀,搜索/路线模型使用 AMap 前缀。
类映射:Google → AMap iOS
| Google Maps iOS SDK | AMap iOS SDK | 备注 |
|---|---|---|
GMSMapView | MAMapView | 核心地图视图 |
GMSMarker | MAPointAnnotation + MAAnnotationView | AMap 将数据模型与视图分开 |
GMSPolyline | MAPolyline + MAPolylineRenderer | AMap 将覆盖物与渲染器分开 |
GMSPolygon | MAPolygon + MAPolygonRenderer | 模式相同 |
GMSCircle | MACircle + MACircleRenderer | 模式相同 |
GMSCameraPosition | MAMapStatus | 摄像机状态 |
GMSCoordinateBounds | MACoordinateRegion | 边界 |
CLLocationCoordinate2D | CLLocationCoordinate2D | 相同(两者都使用 CoreLocation) |
GMSGeocoder | AMapSearchAPI + AMapGeocodeSearchRequest | 搜索 SDK |
GMSPath | MAPolyline 坐标 | 方式不同 |
GMSMapViewDelegate | MAMapViewDelegate | 委托模式相同 |
AMap iOS 搜索 SDK:
| AMap iOS Search SDK | 备注 | |
|---|---|---|
Places SDK GMSPlacesClient | AMapSearchAPI + AMapPOIKeywordsSearchRequest | POI 搜索 |
| Directions | AMapSearchAPI + AMapDrivingRouteSearchRequest | 路线 |
| Geocoding | AMapSearchAPI + AMapGeocodeSearchRequest | 地理编码 |
代码迁移:iOS 地图 + 标注
// ──── GOOGLE ────
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:35.68 longitude:139.76 zoom:12];
GMSMapView *mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(35.68, 139.76);
marker.title = @"Tokyo";
marker.map = mapView;
// ──── AMAP ────
MAMapView *mapView = [[MAMapView alloc] initWithFrame:self.view.bounds];
[mapView setCenterCoordinate:CLLocationCoordinate2DMake(35.68, 139.76) animated:NO];
[mapView setZoomLevel:12 animated:NO];
MAPointAnnotation *annotation = [[MAPointAnnotation alloc] init];
annotation.coordinate = CLLocationCoordinate2DMake(35.68, 139.76);
annotation.title = @"Tokyo";
[mapView addAnnotation:annotation];
非中国大陆及港澳台以外地区 SDK
非中国大陆地区原生移动 SDK 即将推出 / 敬请期待。非中国大陆地区的移动开发者目前可以在 WebView 中使用 JS API,或通过原生代码调用 Web Service API。
快速迁移清单 / 快速迁移清单
- 坐标 — 所有位置(JS API、Web API)均从
{lat, lng}改为[lng, lat]。Android SDK 的 LatLng 仍使用(lat, lng)。 - 端点 — 根据开发者所在地区使用正确的端点
- 身份验证 — 将 Google key 替换为 AMap key。JS API 还需要
securityJsCode。 city参数 — 非中国大陆地区的搜索/地理编码 API 必填(adcode)- 响应解析 — AMap 位置是
"lng,lat"字符串,而不是{lat, lng}对象 - 事件 —
zoom_changed→zoomchange,center_changed→moveend - 插件 — AMap JS API 需要通过
AMap.plugin()加载 Geocoder、Driving、PlaceSearch 等插件。 - Android 导入项 — 将包从
com.google.android.gms.maps改为com.amap.api.maps - iOS 类 —
GMS*→MA*,标记模型与视图分离
参考文件 / 参考文件
references/web-api-params.md— 全部 14 个 API:Google 请求参数 → AMap 请求参数、Google 响应字段 → AMap 响应字段,以及完整代码示例references/js-api-detail.md— 完整的 JS API 迁移指南:逐一介绍每个类的方法、覆盖层、控件,以及迁移前后的完整 HTML 页面references/sdk-migration.md— Android 和 iOS SDK:依赖项配置、生命周期、高级模式(聚合、热力图、自定义覆盖层)
安装与更新 / 安装与更新
此 Skill 属于 amap-map-agent-skills 仓库,该仓库托管多个 AMap Skill,并持续更新。
本 Skill 属于 amap-map-agent-skills 仓库,仓库内包含多个高德地图 Skill,持续更新中。
# Install or update to the latest version / 安装或更新到最新版本
npx skills add AMap-Web/amap-map-agent-skills