10

我想知道你的意见。我创建了一个应用程序,用户在其中创建路线,我们跟踪这条路线并将所有路点保存在数据库中。然后,应用程序对用户的路点进行比较。

目前,我使用MSSQL服务器,使用两张表,一张用于路线,另一张用于存储路点(具有空间数据类型)。比较是在存储过程中使用 SQL Server 地理函数(例如 st_distance...

我研究了其他选择。我实现的一个是使用对象的 Oracle 11g。我将所有数据仅存储在一个对象表中,并且路点存储在具有纬度和经度属性的类型的 Varray 中。这种方式非常有效地保存和检索数据,但在比较时会变得有些复杂。

我正在寻找一种NoSQL解决方案、某种算法或方法来有效地做到这一点。你怎么看?

4

1 回答 1

15

对所有 n 条记录使用诸如STDistance 之类的数据库函数是次优的。您的 CPU 开销将成倍增加。

您应该做的是检查您正在搜索的当前震中周围矩形内的点数。这是一个示例(在 MySQL 中):

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

这提供了减少的点,然后应该通过使用Haversine公式superset计算正交距离(相对于地球的曲率)来进一步减少这些点。

不要忘记在和上设置复合索引latitudelongitude

正向距离

这是在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));
}
?>

回顾一下

这是一个示例图像,说明了该怎么做:

以加拿大国家电视塔为例

第一次搜索将涉及边界框碰撞搜索(MySQL 示例)以确定superset,不包括红点。第二个验证过程将涉及使用 Haversine 公式(PHP 示例)计算点是否在适当的正交距离内,并取 a subset(由黑点组成)。

于 2012-09-24T16:07:51.680 回答