高德地图JS-SDK实现详细教程(定位、地图选点、地址解析等)
作者:mr.Darker
在移动应用开发中,地图服务是不可或缺的组件之一,尤其在构建位置相关功能时,这篇文章主要介绍了高德地图JS-SDK实现的相关资料,包括定位、地图选点、地址解析等,需要的朋友可以参考下
前言
适用地点选择、地址显示、表单填写等场景,全面支持移动端、手机浏览器和 PC端环境
一、创建应用&Key
前端(JS-SDK、地图组件)
- 登陆 高德开放平台
- 创建应用,示例名:
MapSelectorApp
- 添加 Key:选择“Web端(JS API)”
- 配置域名白名单(如
yourdomain.com
、*.yourdomain.com
)
后端(Web服务 API)
- 方便在后端调用
https://restapi.amap.com/v3/geocode/regeo
- 选择服务平台为 Web服务
- 推荐单独创建一个 Web 服务 Key,与前端分离管理
- 配置 IP 白名单
二、前端 HTML 实现
环境依赖
<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 = "⚠️ 网络或服务器错误"; }); } function confirmSelection() { if (!selectedLngLat) return alert("请选择地点"); const text = document.getElementById("address").innerText; alert(`✅ 选点结果\n经纬度: ${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 分流网络
目标:仅展前后端 API 请求进入高德手机服务器
WireGuard 配置示例
[Peer] AllowedIPs = 120.77.134.0/24, 2408:4003::/32 Endpoint = [你的防火墙服务器]:51820
可用 nslookup restapi.amap.com 查看实际服务器 IP
五、如何获取域名的 IP 地址
为了精准设置 WireGuard 的路由规则,我们需要获取目标域名的实际 IP。
✅ 方法一:命令行使用nslookup
nslookup restapi.amap.com
返回示例:
服务器: dns.google Address: 8.8.8.8 非权威应答: 名称: 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
输出结果将包含类似:
正在 Ping restapi.amap.com.gds.alibabadns.com [120.77.134.169] 具有 32 字节的数据: 来自 120.77.134.169 的回复: 字节=32 时间=59ms TTL=95 来自 120.77.134.169 的回复: 字节=32 时间=70ms TTL=95 来自 120.77.134.169 的回复: 字节=32 时间=76ms TTL=95 来自 120.77.134.169 的回复: 字节=32 时间=58ms TTL=95 120.77.134.169 的 Ping 统计信息: 数据包: 已发送 = 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
结论
组件 | Key类型 | 权限 | 简述 |
---|---|---|---|
前端 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 模块(包含内嵌 Tomcat) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 开发工具(自动重启,非必须) --> <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 = "⚠️ 网络或服务器错误"; }); } function confirmSelection() { if (!selectedLngLat) { alert("请先在地图上点击选点或使用定位"); return; } const text = document.getElementById("address").innerText; alert("✅ 选点结果:\n经纬度:" + 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("高德地址解析失败,返回状态:" + 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()); } } }
总结
到此这篇关于高德地图JS-SDK实现详细教程的文章就介绍到这了,更多相关高德地图JS-SDK实现内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!