AMap Map Google Maps Migration Skill
Guides developers migrating from Google Maps Platform to AMap (高德地图). Covers Web Service APIs (14 endpoints), JavaScript API, and mobile SDK (Android/iOS).
Version & Update Notice / 版本与更新提示
AI Assistant Instruction: At the start of every conversation involving this skill, inform the developer:
"This skill is from the amap-map-agent-skills repository (current version: 1.0.0). Skills in this repo are continuously updated with new APIs, bug fixes, and improvements. To ensure you have the latest version, run:
npx skills add AMap-Web/amap-map-agent-skills
If you experience unexpected behavior, updating first is recommended."
npx skills add is the official installation method provided by skills.sh and installs from the verified AMap-Web GitHub organization.
本 Skill 来自 amap-map-agent-skills 仓库(当前版本:1.0.0)。仓库内的 Skill 持续更新中,涵盖新增 API、问题修复与改进。建议开发者定期执行上述命令获取最新版本。
Core Philosophy / 核心设计理念
AMap and Google Maps share the same imperative, object-oriented design. Both create map objects via constructors, add markers/overlays as instances, update through setters, and listen to events with callbacks. Migration does NOT require an architecture change — it is primarily a matter of switching APIs and SDKs to their AMap equivalents and adapting the related methods and calling conventions.
高德与 Google Maps 采用相同的命令式、面向对象设计。迁移不需要架构变更——主要工作是将接口和 SDK 切换为高德对应项,并适配相关方法及调用方式。
Interactive Migration Flow / 交互式迁移流程
You MUST follow this 3-step flow:
Step 1: Ask Developer Region / 确认区域
Ask: "Are you a Mainland China developer or a Non-Mainland developer?"
This determines endpoints and coordinate system:
- Mainland China (incl. HK/MO/TW) / 中国大陆(含港澳台): Web API
restapi.amap.com, JS CDN webapi.amap.com, coords GCJ-02
- Non-Mainland (excl. HK/MO/TW) / 中国大陆及港澳台以外地区: Web API
sg-restapi.opnavi.com, JS CDN sg-webapi.opnavi.com, coords WGS-84 (same as Google)
Step 2: Ask Development Type / 确认开发类型
Ask: "Web Service API (server-side), JS API (frontend map), or SDK (mobile)?"
Step 3: Generate Migration Output / 生成迁移内容
Produce: (1) API mapping table with BOTH Google and AMap names/paths, (2) migration code with field-level mapping. Use the correct endpoints for the developer's region.
Authentication & Keys / 认证与密钥
AMap provides free public API keys — zero signup and zero cost — so developers can start testing immediately as a limited-time promotional benefit. Each key carries a daily free quota on a first-come, first-served basis. If an API call fails with a quota error, the day's allowance has been exhausted — try again the next day, or contact AMap sales for dedicated capacity by visiting AMap Overseas and submitting a Contact Sales inquiry.
高德为所有开发者提供限时免费公共 API Key——无需注册、零成本——可直接用于开发测试。每个 Key 拥有每日免费额度,先到先得。若调用返回配额错误,说明当日额度已用尽——可次日重试,或访问 高德海外版官网 提交 Contact Sales 表单联系销售获取专属支持。
| Service | Key | Scope |
|---|
| Web Service API | 40ffec9172a0dd65b7e224bb252b7e0b | All 14 REST endpoints (Mainland & Non-Mainland) |
| JS API | b87b3d194a024295b1b17be020659457 | Frontend map rendering (Mainland & Non-Mainland) |
| Mobile SDK | (create your own) | Android & iOS native SDK — Web/JS keys do NOT work for mobile |
Security Note / 安全说明: The keys above are official public promotional keys provided by AMap for development and testing purposes. They are intentionally embedded to enable zero-friction evaluation. For production use, create your own dedicated key at AMap Developer Console to ensure quota, security, and traceability.
以上 Key 为高德官方提供的公共推广测试 Key,仅供开发验证使用。生产环境请自行申请专属 Key,以确保配额、安全性和可追溯性。
Mobile SDK keys: Sign in at AMap Developer Console, navigate to the console, and create your own key. A daily free quota is included.
移动端 SDK Key:前往 高德开发者控制台 登录后进入控制台自行创建 Key,同样每日提供一定免费额度。Web/JS 公共 Key 不适用于移动端 SDK。
Pricing Advantage / 价格优势
Same capabilities, half the price — AMap's pricing tiers align with Google Maps but cost roughly 50% less.
同等能力,一半价格——高德的定价层级与 Google Maps 对齐,费用约低 50%。
Web Service API Migration / Web 服务接口迁移
Mapping Table / 映射总表
Google domain: https://maps.googleapis.com (Geolocation: https://www.googleapis.com)
AMap Non-Mainland domain: https://sg-restapi.opnavi.com | AMap Mainland domain: https://restapi.amap.com
| # | Google API | Google Path | AMap API (EN/CN) | AMap Non-Mainland Path | AMap Mainland Path |
|---|
| 1 | Places Autocomplete | /maps/api/place/autocomplete/json | Autocomplete / 输入提示 | /v3/assistant/inputtips | /v3/assistant/inputtips |
| 2 | Text Search | /maps/api/place/textsearch/json | Keyword Search / 关键字搜索 | /v3/place/text | /v3/place/text |
| 3 | Nearby Search | /maps/api/place/nearbysearch/json | Nearby Search / 周边搜索 | /v3/place/around | /v3/place/around |
| 4 | Place Details | /maps/api/place/details/json | ID Search / ID搜索 | /v3/place/detail | /v3/place/detail |
| 5 | (none) | — | Polygon Search / 多边形搜索 | /v3/place/polygon | /v3/place/polygon |
| 6 | Geocoding | /maps/api/geocode/json (address=) | Geocoding / 地理编码 | /v3/geocode/geo | /v3/geocode/geo |
| 7 | Reverse Geocoding | /maps/api/geocode/json (latlng=) | Reverse Geocoding / 逆地理编码 | /v3/geocode/regeo | /v3/geocode/regeo |
| 8 | Geolocation | /geolocation/v1/geolocate | Geolocation / 网络定位 | sg-apilocate.opnavi.com/position ⚠️ | /v3/position |
| 9 | Directions (driving) | /maps/api/directions/json (mode=driving) | Driving / 驾车路径规划 | /v3/direction/driving | /v3/direction/driving |
| 10 | Directions (walking) | /maps/api/directions/json (mode=walking) | Walking / 步行路径规划 | /v3/direction/walking | /v3/direction/walking |
| 11 | Directions (transit) | /maps/api/directions/json (mode=transit) | Transit / 公交路径规划 | /v5/direction/transit/integrated/abroad | /v3/direction/transit/integrated |
| 12 | Distance Matrix | /maps/api/distancematrix/json | Distance Matrix / 矩阵距离 | /v5/distance/matrix (POST) | /v5/distance/matrix (POST) |
| 13 | (none) | — | Admin Division / 行政区划查询 | /v5/district/global | /v3/config/district |
| 14 | Time Zone | /maps/api/timezone/json | Time Zone / 时区 | /v5/timezone | /v5/timezone |
Critical Migration Differences / 关键差异
-
Coordinate order reversed: Google lat,lng → AMap lng,lat
-
Non-Mainland city param REQUIRED: AMap Non-Mainland search/geocoding needs adcode (e.g. USA=840000000, Japan=392000000). Google doesn't need this.
-
Response format: Google returns location as {lat, lng} object. AMap returns "lng,lat" string — must split(',').
-
Distance Matrix: Google is GET with | separator. AMap is POST with ; separator.
-
POI IDs: AMap Non-Mainland IDs start with P (e.g. P0JAK55X50). Google uses place_id.
-
Multi-language: AMap langCode supports zh/en/ja/ko and 18 more languages.
-
Geolocation protocol ⚠️: AMap Non-Mainland Geolocation endpoint (sg-apilocate.opnavi.com) currently uses HTTP. This API accepts device identifiers (MAC/IMEI). Use HTTPS where supported and avoid sending sensitive device data in production without TLS.
⚠️ 非大陆定位接口目前为 HTTP 协议,且接受 MAC/IMEI 等设备标识。生产环境建议优先使用 HTTPS,避免明文传输敏感数据。
Code Migration Examples / 代码迁移示例
Geocoding: 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
Text Search: 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); });
Driving Directions: 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`
Distance Matrix: 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}`
});
Full parameter-by-parameter and response-field mapping for all 14 APIs: load references/web-api-params.md
JS API Migration / JS API 迁移
Initialization: Google → AMap
<!-- GOOGLE -->
<script src="https://maps.googleapis.com/maps/api/js?key=GOOGLE_KEY&callback=initMap" async defer></script>
<!-- AMAP (Non-Mainland) — requires dual auth: securityJsCode + key -->
<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>
<!-- AMAP (Mainland) -->
<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>
Class Mapping: Google → AMap
| Google Maps JS | AMap JS API v2 | Migration Notes |
|---|
new google.maps.Map(el, opts) | new AMap.Map('containerId', opts) | Takes string ID, not element. center order reversed. |
new google.maps.Marker({position, map}) | new AMap.Marker({position: [lng,lat], map}) | Coord order reversed |
new google.maps.InfoWindow({content}) | new AMap.InfoWindow({content}) | .open(map, position) not .open(map, marker) |
new google.maps.Polyline({path, ...}) | new AMap.Polyline({path, ...}) | path arrays: {lat,lng} → [lng,lat] |
new google.maps.Polygon({paths, ...}) | new AMap.Polygon({path, ...}) | paths → path (singular) |
new google.maps.Circle({center, radius}) | new AMap.Circle({center, radius}) | center reversed |
new google.maps.LatLng(lat, lng) | new AMap.LngLat(lng, lat) | Both name and param order differ |
new google.maps.Geocoder() | AMap.plugin('AMap.Geocoder', cb) | Must load plugin first |
new google.maps.DirectionsService() | AMap.plugin('AMap.Driving', cb) | Separate plugins per mode |
new google.maps.places.PlacesService(map) | AMap.plugin('AMap.PlaceSearch', cb) | Plugin |
new google.maps.places.Autocomplete(input) | AMap.plugin('AMap.Autocomplete', cb) | Plugin |
marker.setMap(null) | marker.setMap(null) or map.remove(marker) | Same or cleaner |
map.setCenter({lat, lng}) | map.setCenter([lng, lat]) | Coord order |
map.fitBounds(bounds) | map.setBounds(bounds) | Method name differs |
Event Mapping: Google → AMap
| Google Event | AMap Event | Google Access | AMap Access |
|---|
'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 syntax: google.maps.event.addListener(map, 'click', fn) → AMap: map.on('click', fn)
Plugin System
Google loads all services with the main script. AMap requires explicit loading:
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
});
Full JS API migration details (method-by-method, overlays, controls, complete before/after HTML): load references/js-api-detail.md
SDK Migration / SDK 迁移
Android: Google Maps SDK → AMap Android SDK
AMap Android SDK mirrors Google's architecture closely. Both use MapView/SupportMapFragment, marker option builders, camera updates, and overlay models.
Class Mapping: Google → AMap Android
| Google Maps Android SDK | AMap Android SDK | Notes |
|---|
com.google.android.gms.maps.GoogleMap | com.amap.api.maps.AMap | Core map controller |
com.google.android.gms.maps.MapView | com.amap.api.maps.MapView | Map widget |
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 | Same name but AMap constructor is LatLng(lat, lng) — same as Google on Android |
com.google.android.gms.maps.model.Marker | com.amap.api.maps.model.Marker | Same pattern |
com.google.android.gms.maps.model.MarkerOptions | com.amap.api.maps.model.MarkerOptions | Same builder pattern |
com.google.android.gms.maps.model.Polyline | com.amap.api.maps.model.Polyline | Same |
com.google.android.gms.maps.model.PolylineOptions | com.amap.api.maps.model.PolylineOptions | Same |
com.google.android.gms.maps.model.Polygon | com.amap.api.maps.model.Polygon | Same |
com.google.android.gms.maps.model.Circle | com.amap.api.maps.model.Circle | Same |
com.google.android.gms.maps.model.CircleOptions | com.amap.api.maps.model.CircleOptions | Same |
com.google.android.gms.maps.model.CameraPosition | com.amap.api.maps.model.CameraPosition | Same builder |
com.google.android.gms.maps.CameraUpdateFactory | com.amap.api.maps.CameraUpdateFactory | Same factory |
com.google.android.gms.maps.model.BitmapDescriptorFactory | com.amap.api.maps.model.BitmapDescriptorFactory | Same |
GoogleMap.OnMapClickListener | AMap.OnMapClickListener | Same interface pattern |
GoogleMap.OnMarkerClickListener | AMap.OnMarkerClickListener | Same |
com.google.android.gms.maps.model.GroundOverlay | com.amap.api.maps.model.GroundOverlay | Same |
AMap Search/Route (separate SDK):
| Google Play Services | AMap Services SDK | Notes |
|---|
com.google.android.libraries.places.api.model.Place | com.amap.api.services.core.PoiItem | POI result |
com.google.maps.GeocodingApi | com.amap.api.services.geocoder.GeocodeSearch | Geocoding |
com.google.maps.DirectionsApi | com.amap.api.services.route.RouteSearch | Route planning |
com.google.maps.DistanceMatrixApi | com.amap.api.services.route.DistanceSearch | Distance |
Code Migration: Android Map + Marker
// ──── 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.
Code Migration: Android Geocoding
// ──── 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 uses MA prefix for map classes and AMap prefix for search/route models.
Class Mapping: Google → AMap iOS
| Google Maps iOS SDK | AMap iOS SDK | Notes |
|---|
GMSMapView | MAMapView | Core map view |
GMSMarker | MAPointAnnotation + MAAnnotationView | AMap separates data model from view |
GMSPolyline | MAPolyline + MAPolylineRenderer | AMap separates overlay from renderer |
GMSPolygon | MAPolygon + MAPolygonRenderer | Same pattern |
GMSCircle | MACircle + MACircleRenderer | Same pattern |
GMSCameraPosition | MAMapStatus | Camera state |
GMSCoordinateBounds | MACoordinateRegion | Bounds |
CLLocationCoordinate2D | CLLocationCoordinate2D | Same (both use CoreLocation) |
GMSGeocoder | AMapSearchAPI + AMapGeocodeSearchRequest | Search SDK |
GMSPath | MAPolyline coordinates | Different approach |
GMSMapViewDelegate | MAMapViewDelegate | Same delegate pattern |
AMap iOS Search SDK:
| Google | AMap iOS Search SDK | Notes |
|---|
Places SDK GMSPlacesClient | AMapSearchAPI + AMapPOIKeywordsSearchRequest | POI search |
| Directions | AMapSearchAPI + AMapDrivingRouteSearchRequest | Route |
| Geocoding | AMapSearchAPI + AMapGeocodeSearchRequest | Geocode |
Code Migration: iOS Map + Annotation
// ──── 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];
Non-Mainland SDK / 非中国大陆及港澳台以外地区 SDK
Native mobile SDK for Non-Mainland is coming soon / 敬请期待. Non-Mainland mobile developers can currently use the JS API in WebView or call Web Service APIs from native code.
Quick Migration Checklist / 快速迁移清单
- Coordinates —
{lat, lng} → [lng, lat] everywhere (JS API, Web API). Android SDK LatLng stays (lat, lng).
- Endpoints — Use correct endpoints for developer region
- Auth — Replace Google key with AMap key. JS API also needs
securityJsCode.
city param — Required for Non-Mainland search/geocoding APIs (adcode)
- Response parsing — AMap location is
"lng,lat" string, not {lat, lng} object
- Events —
zoom_changed→zoomchange, center_changed→moveend
- Plugins — AMap JS API needs
AMap.plugin() for Geocoder, Driving, PlaceSearch, etc.
- Android imports — Change package from
com.google.android.gms.maps → com.amap.api.maps
- iOS classes —
GMS* → MA*, marker model/view separation
Reference Files / 参考文件
references/web-api-params.md — All 14 APIs: Google request params → AMap request params, Google response fields → AMap response fields, complete code examples
references/js-api-detail.md — Full JS API migration: every class method-by-method, overlays, controls, complete before/after HTML pages
references/sdk-migration.md — Android & iOS SDK: dependency setup, lifecycle, advanced patterns (clustering, heatmap, custom overlays)
Installation & Updates / 安装与更新
This skill is part of the amap-map-agent-skills repository, which hosts multiple AMap skills and is continuously updated.
本 Skill 属于 amap-map-agent-skills 仓库,仓库内包含多个高德地图 Skill,持续更新中。
# Install or update to the latest version / 安装或更新到最新版本
npx skills add AMap-Web/amap-map-agent-skills