本文目录导读:

- 方案一:使用高德地图API(推荐,国内数据最准确)
- 方案二:使用百度地图API
- 方案三:使用谷歌地图API(适合海外地址)
- 方案四:离线方案(仅限中国,需要数据库)
- 注意事项
- 简单坐标转换(GCJ-02 与 BD-09)
- 总结建议
在PHP项目中,将地址(如“北京市朝阳区”)转换为经纬度坐标,通常需要借助第三方地理编码服务的API,PHP本身没有内置地址转坐标的功能。
以下是几种主流且常用的实现方案:
使用高德地图API(推荐,国内数据最准确)
高德地图的“地理编码/逆地理编码”API是国内最常用的方案之一。
准备工作:
- 前往 高德开放平台 注册开发者账号。
- 创建应用,申请 Web服务API Key(注意:不是Android/iOS的Key)。
PHP代码实现:
<?php
function geocodeAddressToCoordinates($address, $key) {
$url = "https://restapi.amap.com/v3/geocode/geo";
$params = [
'key' => $key,
'address' => $address, // "北京市朝阳区望京SOHO"
'output' => 'JSON',
'city' => '' // 可选:指定城市,提高精度
];
$queryString = http_build_query($params);
$fullUrl = $url . '?' . $queryString;
// 使用cURL或file_get_contents发起请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $fullUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if ($data['status'] == 1 && $data['count'] > 0) {
$location = $data['geocodes'][0]['location']; // "116.480881,39.989410"
list($lng, $lat) = explode(',', $location);
return [
'lng' => $lng,
'lat' => $lat
];
} else {
return false;
}
}
// 使用示例
$apiKey = "你的高德Web服务Key";
$result = geocodeAddressToCoordinates("北京市朝阳区望京SOHO", $apiKey);
if ($result) {
echo "经度:" . $result['lng'] . "\n";
echo "纬度:" . $result['lat'] . "\n";
} else {
echo "地址解析失败";
}
?>
使用百度地图API
百度地图的坐标系统(bd09ll)与高德/谷歌(GCJ-02)不同,如果需要与其他地图服务互通,可能需要坐标转换。
准备工作:
- 前往 百度地图开放平台 注册。
- 创建应用,获取服务端 AK。
PHP代码实现:
<?php
function baiduGeocode($address, $ak) {
$url = "https://api.map.baidu.com/geocoding/v3/";
$params = [
'address' => $address,
'output' => 'json',
'ak' => $ak,
'ret_coordtype' => 'gcj02ll' // 可选:返回国测局坐标,方便与其他国内服务统一
];
$queryString = http_build_query($params);
$fullUrl = $url . '?' . $queryString;
$response = file_get_contents($fullUrl);
$data = json_decode($response, true);
if ($data['status'] == 0) {
$lat = $data['result']['location']['lat'];
$lng = $data['result']['location']['lng'];
return ['lng' => $lng, 'lat' => $lat];
}
return false;
}
?>
使用谷歌地图API(适合海外地址)
如果项目面向全球用户,Google Maps Geocoding API是最佳选择。
准备工作:
- 前往 Google Cloud Console 启用 Geocoding API。
- 创建 API 密钥(建议设置IP限制和配额)。
PHP代码实现:
<?php
function googleGeocode($address, $apiKey) {
$url = "https://maps.googleapis.com/maps/api/geocode/json?address=" . urlencode($address) . "&key=" . $apiKey;
$response = file_get_contents($url);
$data = json_decode($response, true);
if ($data['status'] == 'OK') {
$location = $data['results'][0]['geometry']['location'];
return [
'lat' => $location['lat'],
'lng' => $location['lng']
];
}
return false;
}
?>
离线方案(仅限中国,需要数据库)
如果不想依赖外部API(如在内网环境),可以购买或下载离线地址库。
常见产品:
- 阿里云DataWorks的数据服务
- 专业GIS数据商提供的地址编码库(通常需要购买)
实现思路:
- 购买或下载包含地址-经纬度对应关系的数据库(SQL/SQLite)。
- 在PHP中使用模糊匹配(LIKE查询)或索引搜索来查找地址。
- 缺点:覆盖不全,且地址文本变化快,维护成本高。
注意事项
| 注意事项 | 说明 |
|---|---|
| API配额 | 免费版有每日调用上限(高德日5000次,百度日6000次)。 |
| 坐标系统 | 高德和谷歌使用 GCJ-02 国内坐标系,百度使用 BD-09,如果混用,需要坐标转换。 |
| 地址纯净度 | 地址越完整(含省份、城市、区、街道、门牌号),解析成功率越高。 |
| 错误处理 | 建议对API返回的 status 字段进行处理,如 INVALID_REQUEST、OVER_QUERY_LIMIT。 |
| 缓存 | 对于重复查询的地址,建议将结果存入Redis或数据库缓存,减少API调用。 |
简单坐标转换(GCJ-02 与 BD-09)
如果你在高德拿到坐标,但需要在百度地图展示(或反之),需要坐标转换:
<?php
// GCJ-02 转为 BD-09 (高德转百度)
function gcj02_to_bd09($lat, $lng) {
$x_pi = 3.14159265358979324 * 3000.0 / 180.0;
$x = $lng;
$y = $lat;
$z = sqrt($x * $x + $y * $y) + 0.00002 * sin($y * $x_pi);
$theta = atan2($y, $x) + 0.000003 * cos($x * $x_pi);
$bd_lng = $z * cos($theta) + 0.0065;
$bd_lat = $z * sin($theta) + 0.006;
return ['lat' => $bd_lat, 'lng' => $bd_lng];
}
// BD-09 转为 GCJ-02 (百度转高德)
function bd09_to_gcj02($lat, $lng) {
// 算法略复杂,建议使用现成库或调用API
// 实际项目中可以直接用高德提供的坐标转换API
}
?>
总结建议
- 国内项目:优先使用 高德地图 API,数据最详细,免费额度适中。
- 海外项目:使用 Google Maps API 或 OpenStreetMap 的 Nominatim。
- 高并发/内网:考虑购买商业离线地址库。
- 生产环境:务必添加缓存层(Redis/MySQL)和异常重试机制。