我们如何计算两个坐标之间的距离。 ArangoDB

时间:2016-05-30 09:46:59

标签: node.js distance arangodb aql

我有一个Users表,其中包含每个用户的纬度和经度属性。所以我需要在AQL查询中计算两个用户之间的距离。

我在Orientdb中使用以下查询完成了相同的操作。

TypeError: 'NoneType' object is not iterable

2 个答案:

答案 0 :(得分:2)

首先,创建一个js文件distance.js(或任何你想要命名的文件)并将代码放在下面。

/* distance.js */
'use strict';

function gdistance(latitude1, longitude1, latitude2, longitude2, radius) {
    if (!latitude1 || !longitude1 || !latitude2 || !longitude2) { 
        return null; 
    };

    var lat1 = Number(latitude1), lon1 = Number(longitude1);
    var lat2 = Number(latitude2), lon2 = Number(longitude2);

    radius = (radius === undefined) ? 6371e3 : Number(radius);

    var R = radius;
    var φ1 = (lat1 * Math.PI / 180), λ1 = (lon1 * Math.PI / 180);
    var φ2 = (lat2 * Math.PI / 180), λ2 = (lon2 * Math.PI / 180);
    var Δφ = φ2 - φ1;
    var Δλ = λ2 - λ1;

    var a = Math.sin(Δφ/2) * Math.sin(Δφ/2)
          + Math.cos(φ1) * Math.cos(φ2)
          * Math.sin(Δλ/2) * Math.sin(Δλ/2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    var d = R * c;     // Meters
    var d2 = d / 1000; // Meters to KM
    return d2; 
}

module.exports = gdistance;

现在使用arangosh打开Arango控制台。默认情况下,这将打开_system数据库。所以,如果你有像我这样的数据库,那么使用db._useDatabase("myDatabase")命令来更改数据库。

现在写下面的命令,将自定义添加到所需的数据库。

版本2.8

db._useDatabase("myDatabase");
var aqlfunctions = require("org/arangodb/aql/functions");
var f = require("/path/to/file/distance.js");
aqlfunctions.register("geo::gdistance", f, true)

版本3.0 +

db._useDatabase("myDatabase");
var aqlfunctions = require("@arangodb/aql/functions");
var f = require("/path/to/distance.js");

i.e.
var f = require("/home/ubuntu/distance.js");
var f = require("distance.js");

# If you want to remove this group's UDFs (User defined functions)
# aqlfunctions.unregisterGroup("geo");
aqlfunctions.register("geo::gdistance", f, true);

现在使用您的AQL查询,如下所示。

LET distance = geo::gdistance(attrbute_name.latitude, attrbute_name.longitude, @your_latitude, @your_longitude)

有关here的更多参考资料。

答案 1 :(得分:1)

目前ArangoDB只能在您使用地理位置索引时为您提供距离,以便将搜索开始的距离返回到符合您条件的点:

FOR doc IN WITHIN(@@collection, @lat, @long, @radius, @distanceAttributeName)
  RETURN doc

但是你可以use a user defined AQL function来扩展AQL。用户定义的函数在Javascript中实现,幸运的是Chris Veness to explain howto calculate distances

使用ArangoDB 3.0,我们很可能会支持算术运算以在AQL中计算它。

我将很快编辑这篇文章的详细信息和示例。