如果你需要搞经济统计,你一定知道我在做什么。在一些统计标准里,城乡划分的标准是:看它在不在县级政府驻地所在的街道办事处。这就需要我们通过地址查询它属于哪个街道,然后再判断所在的区县政府驻地是不是也在这个街道。
搜了半天,好像没有方便的GIS查询途径。好在利用高德和百度的api,可以转圜实现这个功能:先通过地址查经纬度,再通过经纬度反查poi和行政区划。
高德识别地址的能力比百度强很多,但也有些冷门地址百度认识,所以两个都用上了。高德api每天可以用5000次,百度只有300次。
页面适配桌面和手机,长这样:

以下是php代码,单页面,不用数据库(但我删掉了页面里的县级政府驻地):
<?php
// 单文件 PHP 页面,已适配移动(响应式、无额外样式文件)
// 功能:输入地址 → 输出经纬度 + 所属街道办事处 + 完整原始 JSON + 当地政府驻地
define('AMAP_KEY', '你的高德key');
define('BAIDU_AK', '你的百度ak'); // ① key
function calculateErrDev($confidence) {
$thresholds = [
100 => 20, // confidence=100时,误差<20m
90 => 50, // confidence≥90时,误差<50m
80 => 100, // confidence≥80时,误差<100m
75 => 200, // confidence≥75时,误差<200m
70 => 300, // confidence≥70时,误差<300m
60 => 500, // confidence≥60时,误差<500m
50 => 1000, // confidence≥50时,误差<1000m
40 => 2000, // confidence≥40时,误差<2000m
30 => 5000, // confidence≥30时,误差<5000m
25 => 8000, // confidence≥25时,误差<8000m
20 => 10000 // confidence≥20时,误差<10000m
];
foreach ($thresholds as $threshold => $errdev) {
if ($confidence >= $threshold) {
return $errdev;
}
}
// 默认情况(confidence<20)
return 10000;
}
function findAdminAddress($searchTerm) {
$tableData = [
["110000","通州区"],["110101","景山街道"],["110102","金融街街道"]
];
$results = [];
if (!empty($searchTerm)) {
foreach ($tableData as $row) {
if (stripos($row[0], $searchTerm) !== false) {
$results[] = $row[1];
}
}
}
return implode("; ",$results);
}
$addr = $_POST['addr'] ?? '';
$lng = '';
$lat = '';
$town = '';
$geoJson = ''; // 地理编码原始 JSON
$regeoJson = ''; // 逆地理编码原始 JSON
if ($addr !== '') {
// ② baidu地理编码:门牌号 → 经纬度
$geoUrl = 'https://api.map.baidu.com/geocoding/v3/?address=' . urlencode($addr) . '&output=json&ak=' . BAIDU_AK;
$geoJson = file_get_contents($geoUrl);
$geo = json_decode($geoJson, true);
if (!empty($geo['result']['location'])) {
$lng = $geo['result']['location']['lng'];
$lat = $geo['result']['location']['lat'];
$confidence = $geo['result']['confidence'];
$errdev = calculateErrDev($confidence);
// ③ baidu逆地理编码:经纬度 → 乡镇/街道
$regeoUrl = "https://api.map.baidu.com/reverse_geocoding/v3/?location={$lat},{$lng}&output=json&ak=" . BAIDU_AK;
$regeoJson = file_get_contents($regeoUrl);
$regeo = json_decode($regeoJson, true);
$formatted_address = $regeo['result']['formatted_address'] ?? '';
$province = $regeo['result']['addressComponent']['province'] ?? '';
$city = $regeo['result']['addressComponent']['city'] ?? '';
$district = $regeo['result']['addressComponent']['district'] ?? '';
$adcode = $regeo['result']['addressComponent']['adcode'] ?? '';
$edz = $regeo['result']['edz']['name'] ?? '';
$town = $regeo['result']['addressComponent']['town'] ?? '';
}
// ④ 高德地理编码:门牌号 → 经纬度
$geoUrl_gd = 'https://restapi.amap.com/v5/place/text?keywords=' . urlencode($addr) . '&key=' . AMAP_KEY;
$geoJson_gd = file_get_contents($geoUrl_gd);
$geo_gd = json_decode($geoJson_gd, true);
if (!empty($geo_gd['pois']['0']['location'])) {
$location_gd = $geo_gd['pois']['0']['location'];
// ⑤ 高德逆地理编码:经纬度 → 乡镇/街道
$regeoUrl_gd = 'https://restapi.amap.com/v3/geocode/regeo?location=' . $location_gd . '&key=' . AMAP_KEY;
$regeoJson_gd = file_get_contents($regeoUrl_gd);
$regeo_gd = json_decode($regeoJson_gd, true);
$formatted_address_gd = ($regeo_gd['regeocode']['formatted_address'] ?? '') . '-' . ($geo_gd['pois']['0']['name'] ?? '');
$province_gd = $regeo_gd['regeocode']['addressComponent']['province'] ?? '';
$city_gd = $regeo_gd['regeocode']['addressComponent']['city'] ?? '';
$district_gd = $regeo_gd['regeocode']['addressComponent']['district'] ?? '';
$adcode_gd = $regeo_gd['regeocode']['addressComponent']['adcode'] ?? '';
$town_gd = $regeo_gd['regeocode']['addressComponent']['township'] ?? '';
}
}
?>
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>孙悟空-土地老儿出来</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<style>
/* 极简移动适配 */
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background: #f5f5f5; color: #333; line-height: 1.5; padding: 15px; }
h1 { font-size: 1.3rem; margin-bottom: 12px; text-align: center; }
form { display: flex; gap: 8px; margin-bottom: 15px; }
input[type="text"] { flex: 1; padding: 10px; font-size: 1rem; border: 1px solid #ccc; border-radius: 4px; }
button { padding: 10px 14px; font-size: 1rem; background: #0066ff; color: #fff; border: none;
border-radius: 4px; cursor: pointer; }
button:active { background: #0053d9; }
.result { background: #fff; border-radius: 6px; padding: 12px; margin-bottom: 12px; }
.result p { margin: 4px 0; }
pre { background: #f0f0f0; padding: 10px; border-radius: 4px; overflow-x: auto;
font-size: 0.8rem; white-space: pre-wrap; word-break: break-all; }
</style>
</head>
<body>
<h1>孙悟空-土地老儿出来-地址查街道</h1>
<form method="post">
<input type="text" name="addr" value="<?=htmlspecialchars($addr)?>" placeholder="请输入详细地址" required>
<button type="submit">查询</button>
</form>
<?php if ($_SERVER['REQUEST_METHOD'] === 'POST'): ?>
<div class="result">
<p><strong><font color="blue">高德</font></strong></p>
<p><strong>经纬度:</strong><?=htmlspecialchars($location_gd ?: '未识别到结果')?></p>
<p><strong>最接近地址:</strong><?=htmlspecialchars($formatted_address_gd ?: '未识别到结果')?></p>
<p><strong>所属区县:</strong><?=htmlspecialchars($province_gd ?: '未识别到结果')?> <?=htmlspecialchars($city_gd ?: '未识别到结果')?> <?=htmlspecialchars($district_gd ?: '未识别到结果')?> (<?=htmlspecialchars($adcode_gd ?: '未识别到结果')?>)</p>
<p><strong>街道乡镇(仅供参考):</strong><?=htmlspecialchars($town_gd ?: '未识别到结果')?></p>
<p><strong><?=htmlspecialchars($district_gd ?: '未识别到结果')?>政府驻地(仅供参考):</strong><?=htmlspecialchars(findAdminAddress($adcode_gd) ?: '未识别到结果')?></p>
</div>
<div class="result">
<p><strong><font color="blue">百度</font></strong></p>
<p><strong>识别误差</strong>:小于<?=htmlspecialchars($errdev ?: '未识别到结果')?>米
<?php
if ($errdev >= 1000): ?>
<font color="red"> !警惕!</font>
<?php endif; ?>
</p>
<p><strong>经纬度:</strong><?=htmlspecialchars("{$lng}, {$lat}")?></p>
<p><strong>最接近地址:</strong><?=htmlspecialchars($formatted_address ?: '未识别到结果')?></p>
<p><strong>所属区县:</strong><?=htmlspecialchars($province ?: '未识别到结果')?> <?=htmlspecialchars($city ?: '未识别到结果')?> <?=htmlspecialchars($district ?: '未识别到结果')?> (<?=htmlspecialchars($adcode ?: '未识别到结果')?>)</p>
<p><strong>街道乡镇(仅供参考):</strong><?=htmlspecialchars($town ?: '未识别到结果')?></p>
<p><strong><?=htmlspecialchars($district ?: '未识别到结果')?>政府驻地(仅供参考):</strong><?=htmlspecialchars(findAdminAddress($adcode) ?: '未识别到结果')?></p>
<p><strong>是否开发区:</strong><?=htmlspecialchars($edz ?: '未识别到结果')?></p>
</div>
<button onclick="document.getElementById('oJSON').hidden = !document.getElementById('oJSON').hidden;">查看JSON</button>
<div hidden id="oJSON">
<p><strong><font color="blue">高德地理编码原始 JSON</font></strong></p>
<pre><?=htmlspecialchars($geoJson_gd)?></pre>
<p><strong><font color="blue">高德逆地理编码原始 JSON</font></strong></p>
<pre><?=htmlspecialchars($regeoJson_gd)?></pre>
<p><strong><font color="blue">百度地理编码原始 JSON</font></strong></p>
<pre><?=htmlspecialchars($geoJson)?></pre>
<p><strong><font color="blue">百度逆地理编码原始 JSON</font></strong></p>
<pre><?=htmlspecialchars($regeoJson)?></pre>
</div>
<?php endif; ?>
</body>
</html>
以上。
造轮子的老狼