首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 實現地理位置搜尋與兩點距離計算完整指南

     編輯:PHP 綜合知識

MongoDB 地理位置索引與鄰近搜尋

在開發基於位置的服務(LBS)應用時,高效儲存與查詢地理坐標至關重要。MongoDB 內建強大的地理空間索引,支援平面(2d)與球面(2dsphere)兩種模式,適合處理經緯度資料。

1. 建立儲存地點的集合

首先切換至 lbs 資料庫,並插入幾個範例地點,採用 GeoJSON 格式的 Point 類型:

use lbs;
db.lbs.insert({ loc: { type: "Point", coordinates: [113.332264, 23.156206] }, name: "廣州東站" });
db.lbs.insert({ loc: { type: "Point", coordinates: [113.330611, 23.147234] }, name: "林和西" });
db.lbs.insert({ loc: { type: "Point", coordinates: [113.328095, 23.165376] }, name: "天平架" });

2. 建立 2dsphere 索引

為 loc 欄位建立球面索引,以支援球面幾何查詢:

db.lbs.ensureIndex({ loc: "2dsphere" });

3. 查詢附近地點

假設使用者位於「時代廣場」(經度 113.323568,緯度 23.146436),搜尋半徑 1 公里內的地點,並按距離由近及遠排序:

db.lbs.find({
  loc: {
    $near: {
      $geometry: { type: "Point", coordinates: [113.323568, 23.146436] },
      $maxDistance: 1000
    }
  }
});

查詢結果將回傳符合條件的文件,例如「林和西」。

PHP 整合 MongoDB 完整範例

以下 PHP 程式示範如何連線 MongoDB、插入隨機坐標、並執行鄰近搜尋。請先在 MongoDB 中建立使用者並啟用認證:

use lbs;
db.createUser({ user: "root", pwd: "123456", roles: [] });
db.auth({ user: "root", pwd: "123456" });

核心 PHP 程式碼:

selectDB($dbname);
    } catch (MongoException $e) {
        throw new ErrorException('無法連線資料庫: ' . $e->getMessage(), 31);
    }
}

// 插入坐標
function add($dbconn, $tablename, $longitude, $latitude, $name) {
    $coll = $dbconn->selectCollection($tablename);
    $coll->ensureIndex(['loc' => '2dsphere']);
    $data = [
        'loc' => ['type' => 'Point', 'coordinates' => [floatval($longitude), floatval($latitude)]],
        'name' => $name
    ];
    $result = $coll->insert($data, ['w' => true]);
    return isset($result['ok']) && $result['ok'];
}

// 搜尋附近坐標(公里為單位)
function query($dbconn, $tablename, $longitude, $latitude, $maxdistance, $limit = 10) {
    $coll = $dbconn->selectCollection($tablename);
    $param = [
        'loc' => [
            '$nearSphere' => [
                '$geometry' => ['type' => 'Point', 'coordinates' => [floatval($longitude), floatval($latitude)]],
                '$maxDistance' => $maxdistance * 1000
            ]
        ]
    ];
    $cursor = $coll->find($param)->limit($limit);
    return iterator_to_array($cursor);
}

// 示例執行
$db = conn('localhost', 'lbs', 'root', '123456');

// 批次插入 100 筆隨機測試資料
for ($i = 0; $i < 100; $i++) {
    $longitude = '113.3' . mt_rand(10000, 99999);
    $latitude  = '23.15' . mt_rand(1000, 9999);
    $name      = 'name' . mt_rand(10000, 99999);
    add($db, 'lbs', $longitude, $latitude, $name);
}

// 搜尋 1 公里內地點
$longitude = 113.323568;
$latitude  = 23.146436;
$result = query($db, 'lbs', $longitude, $latitude, 1);
print_r($result);
?>

兩點經緯度球面距離計算

利用球面三角公式(Haversine 公式),根據地球半徑計算兩點間的最短距離。支援公尺與公里兩種單位,並可指定小數位數。

這兩個功能結合起來,即可構建完整的 LBS 核心服務:MongoDB 負責高效的空間索引與篩選,PHP 函數提供精確的距離計算,滿足「附近的人」、「門店查詢」、「物流追蹤」等多種場景需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved