高德地圖JS-SDK實現(xiàn)詳細教程(定位、地圖選點、地址解析等)
更新時間:2025年07月23日 09:02:40 作者:mr.Darker
在移動應用開發(fā)中,地圖服務是不可或缺的組件之一,尤其在構(gòu)建位置相關(guān)功能時,這篇文章主要介紹了高德地圖JS-SDK實現(xiàn)的相關(guān)資料,包括定位、地圖選點、地址解析等,需要的朋友可以參考下
前言
適用地點選擇、地址顯示、表單填寫等場景,全面支持移動端、手機瀏覽器和 PC端環(huán)境
一、創(chuàng)建應用&Key
前端(JS-SDK、地圖組件)
- 登陸 高德開放平臺
- 創(chuàng)建應用,示例名:
MapSelectorApp - 添加 Key:選擇“Web端(JS API)”
- 配置域名白名單(如
yourdomain.com、*.yourdomain.com)
后端(Web服務 API)
- 方便在后端調(diào)用
https://restapi.amap.com/v3/geocode/regeo - 選擇服務平臺為 Web服務
- 推薦單獨創(chuàng)建一個 Web 服務 Key,與前端分離管理
- 配置 IP 白名單
二、前端 HTML 實現(xiàn)
環(huán)境依賴
<script src="https://webapi.amap.com/maps?v=2.0&key=替換為你的高德地圖 JSAPI KEY"></script>
基礎組件
<div id="controls">
<button onclick="locateUser()">?? 定位當前位置</button>
<button onclick="confirmSelection()">? 確認選點</button>
<div id="address">地址信息:-</div>
</div>
<div id="container"></div>
核心 JS 邏輯 (amap.js)
let map, marker, selectedLngLat;
window.onload = function () {
map = new AMap.Map("container", { resizeEnable: true, zoom: 14 });
locateUser();
map.on("click", e => {
selectedLngLat = e.lnglat;
addMarker(e.lnglat);
reverseGeocode(e.lnglat);
});
};
function addMarker(pos) {
if (!marker) marker = new AMap.Marker({ position: pos, map });
else marker.setPosition(pos);
}
function locateUser() {
AMap.plugin('AMap.Geolocation', function () {
const geo = new AMap.Geolocation({ enableHighAccuracy: true, timeout: 10000 });
map.addControl(geo);
geo.getCurrentPosition((status, result) => {
if (status === 'complete') {
const pos = result.position;
map.setCenter(pos);
addMarker(pos);
selectedLngLat = pos;
reverseGeocode(pos);
} else {
alert("定位失敗:" + result.message);
}
});
});
}
function reverseGeocode(lnglat) {
fetch(`/amap/reverse-geocode?lng=${lnglat.lng}&lat=${lnglat.lat}`)
.then(res => res.json())
.then(data => {
document.getElementById("address").innerText = data.address ? `地址信息:${data.address}` : `?? 地址解析失敗`
})
.catch(err => {
console.error(err);
document.getElementById("address").innerText = "?? 網(wǎng)絡或服務器錯誤";
});
}
function confirmSelection() {
if (!selectedLngLat) return alert("請選擇地點");
const text = document.getElementById("address").innerText;
alert(`? 選點結(jié)果\n經(jīng)緯度: ${selectedLngLat.lng}, ${selectedLngLat.lat}\n${text}`);
}
三、Spring Boot 后端 API
接口 URL
GET /amap/reverse-geocode?lng=113.83&lat=22.79
管理 Controller
@RestController
@RequestMapping("/amap")
public class AmapController {
@Autowired private AmapService amapService;
@GetMapping("/reverse-geocode")
public ResponseEntity<?> reverseGeocode(@RequestParam("lng") double lng, @RequestParam("lat") double lat) {
try {
String address = amapService.getAddressFromCoordinates(lng, lat);
return ResponseEntity.ok(Map.of("address", address));
} catch (Exception e) {
return ResponseEntity.status(500).body("\u5730\u5740\u89e3\u6790\u5931\u8d25: " + e.getMessage());
}
}
}
地址解析 Service
@Service
public class AmapService {
private static final String AMAP_KEY = "替換你的Web服務Key";
private static final String GEOCODE_URL = "https://restapi.amap.com/v3/geocode/regeo";
public String getAddressFromCoordinates(double lng, double lat) {
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(GEOCODE_URL)
.queryParam("key", AMAP_KEY)
.queryParam("location", lng + "," + lat)
.queryParam("output", "json");
RestTemplate restTemplate = new RestTemplate();
Map<String, Object> response = restTemplate.getForObject(builder.toUriString(), Map.class);
if (response == null || !"1".equals(response.get("status"))) {
throw new RuntimeException("\u5730\u5740\u89e3\u6790API\u5931\u8d25:" + response);
}
Map<String, Object> regeocode = (Map<String, Object>) response.get("regeocode");
if (regeocode == null || regeocode.get("formatted_address") == null) {
throw new RuntimeException("\u65e0\u6709\u6548\u5730\u5740");
}
return (String) regeocode.get("formatted_address");
}
}
四、配置 WireGuard 分流網(wǎng)絡
目標:僅展前后端 API 請求進入高德手機服務器
WireGuard 配置示例
[Peer] AllowedIPs = 120.77.134.0/24, 2408:4003::/32 Endpoint = [你的防火墻服務器]:51820
可用 nslookup restapi.amap.com 查看實際服務器 IP
五、如何獲取域名的 IP 地址
為了精準設置 WireGuard 的路由規(guī)則,我們需要獲取目標域名的實際 IP。
? 方法一:命令行使用nslookup
nslookup restapi.amap.com
返回示例:
服務器: dns.google
Address: 8.8.8.8
非權(quán)威應答:
名稱: restapi.amap.com.gds.alibabadns.com
Addresses: 2408:4003:1f10::2b4
2408:4003:1f40::2e5
120.77.134.57
Aliases: restapi.amap.com
? 方法二:使用 ping
ping restapi.amap.com
輸出結(jié)果將包含類似:
正在 Ping restapi.amap.com.gds.alibabadns.com [120.77.134.169] 具有 32 字節(jié)的數(shù)據(jù):
來自 120.77.134.169 的回復: 字節(jié)=32 時間=59ms TTL=95
來自 120.77.134.169 的回復: 字節(jié)=32 時間=70ms TTL=95
來自 120.77.134.169 的回復: 字節(jié)=32 時間=76ms TTL=95
來自 120.77.134.169 的回復: 字節(jié)=32 時間=58ms TTL=95
120.77.134.169 的 Ping 統(tǒng)計信息:
數(shù)據(jù)包: 已發(fā)送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒為單位):
最短 = 58ms,最長 = 76ms,平均 = 65ms
? 方法三:使用在線工具查詢 IP
- https://tool.chinaz.com/dns
- https://dnschecker.org
- https://ip138.com
? 如何使用這些 IP
將得到的 IPv4 地址(如 120.77.134.57)用于你的代理配置中:
AllowedIPs = 120.77.134.57/32
結(jié)論
| 組件 | Key類型 | 權(quán)限 | 簡述 |
|---|---|---|---|
| 前端 JS SDK | Web端 JS API | 需配置域名 | 顯示地圖,選點,定位 |
| 后端 API | Web 服務 Key | 需配置 IP | 進行地址解析 |
附錄:完整文件(可自行補全代碼)
pom.xml ?
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>DemoAPI</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<!-- Spring Boot 父項目 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- Spring Boot Web 模塊(包含內(nèi)嵌 Tomcat) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 開發(fā)工具(自動重啟,非必須) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
amap.html ?
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>地圖選點</title>
<style>
html, body, #container {
height: 100%; width: 100%; margin: 0; padding: 0;
}
#controls {
position: absolute;
top: 10px;
left: 10px;
z-index: 999;
background: rgba(255, 255, 255, 0.9);
padding: 8px 12px;
border-radius: 6px;
box-shadow: 0 0 5px #ccc;
}
#controls button {
margin-right: 10px;
padding: 6px 12px;
font-size: 14px;
cursor: pointer;
}
</style>
<!-- 替換為你的高德地圖 JSAPI KEY -->
<script src="https://webapi.amap.com/maps?v=2.0&key=替換為你的高德地圖 JSAPI KEY"></script>
</head>
<body>
<div id="controls">
<button onclick="locateUser()">?? 定位當前位置</button>
<button onclick="confirmSelection()">? 確認選點</button>
<div id="address">地址信息:-</div>
</div>
<div id="container"></div>
<!-- 引入地圖邏輯 JS -->
<script src="../js/amap.js"></script>
</body>
</html>
amap.js ?
let map;
let marker = null;
let selectedLngLat = null;
window.onload = function () {
map = new AMap.Map("container", {
resizeEnable: true,
zoom: 14
});
// 自動定位
locateUser();
// 地圖點擊選點
map.on("click", function (e) {
const lnglat = e.lnglat;
addMarker(lnglat);
selectedLngLat = lnglat;
reverseGeocode(lnglat);
});
};
function addMarker(lnglat) {
if (!marker) {
marker = new AMap.Marker({
position: lnglat,
map: map
});
} else {
marker.setPosition(lnglat);
}
}
function locateUser() {
AMap.plugin('AMap.Geolocation', function () {
const geo = new AMap.Geolocation({
enableHighAccuracy: true,
timeout: 10000,
showButton: false
});
map.addControl(geo);
geo.getCurrentPosition(function (status, result) {
if (status === 'complete') {
const position = result.position;
map.setCenter(position);
addMarker(position);
selectedLngLat = position;
reverseGeocode(position);
} else {
alert("定位失?。? + result.message);
}
});
});
}
function reverseGeocode(lnglat) {
fetch(`/amap/reverse-geocode?lng=${lnglat.lng}&lat=${lnglat.lat}`)
.then(res => res.json())
.then(data => {
if (data.address) {
document.getElementById("address").innerText = "地址信息:" + data.address;
} else {
document.getElementById("address").innerText = "?? 地址解析失敗,僅返回坐標";
}
})
.catch(err => {
console.error(err);
document.getElementById("address").innerText = "?? 網(wǎng)絡或服務器錯誤";
});
}
function confirmSelection() {
if (!selectedLngLat) {
alert("請先在地圖上點擊選點或使用定位");
return;
}
const text = document.getElementById("address").innerText;
alert("? 選點結(jié)果:\n經(jīng)緯度:" + selectedLngLat.lng + ", " + selectedLngLat.lat + "\n" + text);
}
AmapService ?
package org.example.service;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.HashMap;
import java.util.Map;
/**
* ==================================================
* This class AmapService is responsible for [高德地圖服務類].
*
* @author Darker
* @version 1.0
* ==================================================
*/
@Service
public class AmapService {
private static final String AMAP_KEY = "替換你的高德地圖的 WEB KEY";
private static final String GEOCODE_URL = "https://restapi.amap.com/v3/geocode/regeo";
public String getAddressFromCoordinates(double lng, double lat) {
RestTemplate restTemplate = new RestTemplate();
UriComponentsBuilder builder = UriComponentsBuilder
.fromHttpUrl(GEOCODE_URL)
.queryParam("key", AMAP_KEY)
.queryParam("location", lng + "," + lat)
.queryParam("output", "json");
Map<String, Object> response = restTemplate.getForObject(builder.toUriString(), Map.class);
if (response == null || !"1".equals(response.get("status"))) {
throw new RuntimeException("高德地址解析失敗,返回狀態(tài):" + response);
}
// 解析 formatted_address
Map<String, Object> regeocode = (Map<String, Object>) response.get("regeocode");
if (regeocode == null || regeocode.get("formatted_address") == null) {
throw new RuntimeException("未能獲取到地址信息");
}
return (String) regeocode.get("formatted_address");
}
}
AmapController ?
package org.example.controller;
import org.example.service.AmapService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Collections;
/**
* ==================================================
* This class AmapController is responsible for [功能描述].
*
* @author Darker
* @version 1.0
* ==================================================
*/
@RestController
@RequestMapping("/amap")
public class AmapController {
@Autowired
private AmapService amapService;
@GetMapping("/reverse-geocode")
public ResponseEntity<?> reverseGeocode(@RequestParam("lng") double lng, @RequestParam("lat") double lat) {
try {
String address = amapService.getAddressFromCoordinates(lng, lat);
return ResponseEntity.ok(Collections.singletonMap("address", address));
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("地址解析失敗: " + e.getMessage());
}
}
}
總結(jié)
到此這篇關(guān)于高德地圖JS-SDK實現(xiàn)詳細教程的文章就介紹到這了,更多相關(guān)高德地圖JS-SDK實現(xiàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:
相關(guān)文章
基于javascript bootstrap實現(xiàn)生日日期聯(lián)動選擇
這篇文章主要介紹了基于javascript bootstrap實現(xiàn)生日日期聯(lián)動選擇的相關(guān)資料,需要的朋友可以參考下2016-04-04

