2012-09-24 101 views
10

我想知道您的意見。我創建了一個應用程序,用戶創建路線並跟蹤此路線並將所有路點保存在數據庫中。然後,應用程序會比較用戶的方式點。最有效的方法來保存方式點和做比較?

目前,我使用一個MSSQL服務器,使用兩個表,一個用於路由,另一個用於存儲路徑點(具有空間數據類型)。在使用SQL Server地理功能(如st_distance)的存儲過程中進行比較...

我調查了其他選項。我實現的一個是使用對象的Oracle 11g。我只將所有數據存儲在一個對象表中,並且方式點存儲在具有緯度和經度屬性的Varray類型中。這種方式非常有效地保存和檢索數據,但比較時會變得複雜。

我正在尋找一個NoSQL解決方案,一些算法或方法來有效地做到這一點。你怎麼看?

+0

我的回答對你有幫助嗎? –

+0

是的,它幫助,謝謝!我認爲解決方案不是以我存儲信息的方式,而是以比較航點的算法。爲此,我首先必須將航點的數量減少到與其他航線相匹配的最相關和統一航點,然後進行比較(如您的答案所述)。我沒有真正測試過,如果結果更好,我會發布我的解決方案。 –

回答

15

對所有n個記錄使用數據庫函數STDistance並不理想。您的CPU開銷將會呈指數增長。

你應該做的是檢查你正在搜索的當前震中周圍矩形內的點數。下面是一個例子(在MySQL):

SELECT * FROM `points` 
    WHERE `latitude` >= X1 AND `latitude` <= X2 
    AND `longitude` >= Y1 AND `longitude` <= Y2 

這提供點的減小的superset應該然後可以進一步通過計算順距離(相對於地球的曲率),使用Haversine formula降低。

別忘了latitudelongitude上設置composite index

Orthodromic distance

這是在PHP中:

<?php 
function haversine($latitude1, $longitude1, 
        $latitude2, $longitude2, $unit = 'Mi') { 
    $theta = $longitude1 - $longitude2; 
    $distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) + 
    (cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta))); 
    $distance = acos($distance); 
    $distance = rad2deg($distance); 
    $distance = $distance * 60 * 1.1515; 
    switch ($unit) { 
    case 'Mi': 
     break; 
    case 'Km': 
     $distance = $distance * 1.609344; 
    } 
    return (round($distance, 2)); 
} 
?> 

回顧一下

這裏的說明做什麼的示例圖像:

Example with CN Tower

第一次搜索將涉及一個包圍盒碰撞搜索(MySQL示例)以確定superset,排除紅點。第二個驗證過程將涉及計算點與Haversine公式(PHP示例)是否在適當的正向距離內並採取subset(由黑點組成)。

+0

謝謝你的回答,我將考慮實施這個想法的解決方案!我對這個解決方案感到擔憂,我認爲它適用於非常接近的點,當我們談論更大的距離時,點擴大到更大的區域,它變得複雜,因爲它不適合我一個非常大的矩形,路線之間的匹配標準必須更加精確。謝謝! –

+0

沒問題,祝你算法好運。 –

相關問題