通过地址查行政区划和当地政府驻地php

试用:https://wolfccb.com/c.php

如果你需要搞经济统计,你一定知道我在做什么。在一些统计标准里,城乡划分的标准是:看它在不在县级政府驻地所在的街道办事处。这就需要我们通过地址查询它属于哪个街道,然后再判断所在的区县政府驻地是不是也在这个街道。

搜了半天,好像没有方便的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>

以上。

造轮子的老狼

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注