geocoding 返回的坐标不能直接画静态图,因为百度地理编码接口返回的是 bd09ll 坐标系,而静态图接口仅接受该坐标系;若原始坐标为 wgs84 或 gcj02,必须调用 /geoconv/v1/ 转换,不可用简单偏移。

PHP 无法直接调用百度地图 JavaScript API,必须走服务端 HTTP 接口;静态图生成需注意坐标系(BD09)和 referrer 白名单限制。
为什么 geocoding 返回的坐标不能直接画静态图?
百度地图的地理编码(geocoding)接口返回的是 bd09ll 坐标系(百度自有偏移),但很多开发者误用 gcj02 或 wgs84 坐标去请求静态图,结果位置明显偏移(常见偏差 300–500 米)。
- 所有百度地图服务端接口(包括
/geocoder/v2/和/staticimage/v2)默认只接受bd09ll坐标 - 若原始数据是高德或 GPS 设备采集的
wgs84,必须先调用百度的/geoconv/v1/转换,不能靠简单加减偏移量 - 静态图 URL 中的
center、markers参数都必须是bd09ll格式,例如39.915,116.404
PHP 调用 geocoding 接口获取经纬度的最小可行代码
注意:必须带 ak(API Key)且启用「地理编码服务」权限;地址参数需 URL 编码,否则中文会失败。
```php
$address = urlencode('北京市海淀区上地十街10号');
$ak = 'your_real_ak_here';
$url = "https://api.map.baidu.com/geocoder/v2/?address={$address}&output=json&ak={$ak}";
<p>$response = file_get_contents($url);
$data = json_decode($response, true);</p><p>if ($data['status'] === 0 && !empty($data['result']['location'])) {
$lng = $data['result']['location']['lng']; // bd09ll 经度
$lat = $data['result']['location']['lat']; // bd09ll 纬度
}</p><pre class="brush:language-;toolbar:false;">
- 不要用
curl_init()手动设User-Agent,百度不校验这个,但某些代理环境可能拦截空 UA -
status为1表示配额超限,3表示ak无效或未开通服务 - 返回的
level字段可判断地址精度(如“道路”“门牌”“城市”),用于过滤低置信度结果
生成静态图时被 400 或白屏的几个硬性条件
百度静态图接口(/staticimage/v2)不是“填完参数就能出图”,它有三道关卡:
- 域名必须在控制台「静态图服务」中添加到
Referer 白名单(支持通配符,如*.example.com);本地file://或无 Referer 请求一律拒绝 - URL 中的
ak必须和申请白名单时绑定的ak完全一致(区分大小写) - 图片尺寸最大为
1024x1024,超出返回 400;缩放级别zoom有效范围是3–19,传20也会 400 - 示例可用 URL:
https://api.map.baidu.com/staticimage/v2?ak=xxx¢er=116.404,39.915&width=400&height=300&zoom=14
坐标转换:从 wgs84 到 bd09ll 的 PHP 安全做法
网上流传的“加固定偏移值”算法已被百度多次升级失效,2023 年后基本不准。唯一可靠方式是调用百度官方转换接口。
```php
function wgs84ToBd09($lng, $lat, $ak) {
$url = "https://api.map.baidu.com/geoconv/v1/?coords={$lng},{$lat}&from=1&to=5&ak={$ak}";
$json = file_get_contents($url);
$data = json_decode($json, true);
return $data['status'] === 0 ? $data['result'][0] : null;
}
```
-
from=1表示输入是wgs84,to=5表示输出为bd09ll(别用to=3,那是gcj02) - 该接口有日调用量限制(免费版 2000 次/天),高频场景建议缓存转换结果(键为
"wgs84:{$lng},{$lat}") - 如果原始坐标来自微信 JS-SDK 的
getLocation,它返回的是gcj02,此时from=3
真正容易被忽略的点是:百度所有服务端接口的坐标系一致性是硬约束,不是“差不多就行”。哪怕只是少调一次 geoconv,静态图上的标记就可能落在隔壁区。调试时建议用已知精确坐标的地点(如百度大厦)交叉验证返回值。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











