PIG:计算纬度和经度对之间的最大距离



我在pig中有一个袋子,它已按键分组,其值为纬度和经度。我想为每个键计算任意两个(lat,long)对之间的最大距离;如果小于2,则输出应该为0。

例如,如果我的包是

{(1): (1.1, 1.1),
 (1): (2.1, 2.1),
 (1): (3.1, 3.1),
 (2): (1.1, 1.1)
}

我的答案是

{(1): 314 (km)
 (2): 0
}

计算两个(长、宽)对之间距离的方程式为:

(((lat1 - lat2) * pi() * 3959 / 180)^2 + ((long1 - long2) * 2 * pi() * 3959 * cos(((lat2 + lat1) / 2) * .0174533) / 360)^2)^(1/2) 

有没有一种简单的方法可以创建一个python udf来实现这一点?谢谢你的帮助。

以下是我想到的步骤:

  1. 打开袋子。这将使用生成元组(在您的示例中)

    (1,1.1,1.1)(1,2.1,2.1)(1,3.1,3.1)(2,1.1,1.1)

  2. 执行上面的步骤两次,将得到的关系命名为两个不同的名称:r1和r2。

  3. 通过关键字字段将r1和r2连接起来。这将为每个关键创建一个笛卡尔乘积

通过密钥加入r1,通过密钥加入r2

这将导致

(1,1.1,1.1,1,1.1,1.1)
(1,1.1,1.1,1,2.1,2.1)
(1,1.1,1.1,1,3.1,3.1)
(1,2.1,2.1,1,1.1,1.1)
(1,2.1,2.1,1,2.1,2.1)
(1,2.1,2.1,1,3.1,3.1)
(1,3.1,3.1,1,1.1,1.1)
(1,3.1,3.1,1,2.1,2.1)
(1,3.1,3.1,1,3.1,3.1)
(2,1.1,1.1,2,1.1,1.1)

此列表包含每个键的所有可能配对。作为奖励,对于只有一个坐标的关键帧,您还可以获得一对该坐标。

  1. 使用数据流中的HaversineDistInMiles UDFhttp://datafu.incubator.apache.org/docs/datafu/1.2.0/datafu/pig/geo/HaversineDistInMiles.html

以计算每对坐标之间的距离。对于具有相同坐标的对,可以得到距离==0。

(datau是LinkedIn的一个很棒的实用程序UDF包。点击此处阅读:https://datafu.incubator.apache.org)

  1. 按键分组,并为每个键生成MAX(距离)。这将为您提供以英里为单位的最大距离。乘以1.6093,得到以KM为单位的距离

假设你的文件是这样的:

1   {(1.1,1.1),(2.1,2.1),(3.1,3.1)}
2   {(1.1,1.1)}

使用这个pig脚本:

register '/path/to/datafu-1.2.0.jar';
a = LOAD 'pigcoords.tsv' using PigStorage() as (A1:int, B1:bag{T:tuple(longitude:double, latitude:double)});
b = foreach a generate A1, FLATTEN(B1);
c = foreach a generate A1, FLATTEN(B1);
d = foreach (join b by A1, c by A1) generate $0..;
op = FOREACH d GENERATE b::A1 as key, datafu.pig.geo.HaversineDistInMiles(b::B1::latitude, b::B1::longitude, c::B1::latitude, c::B1::longitude) as distance;
res = FOREACH (group op by key) generate MAX(op.distance)*1.6093;
dump res;

检查我的github repo:https://github.com/csabakecskemeti/geo_clustering/tree/master/src/main/java/kecso/geotools/geodistance

这是一个用于地理距离计算的java UDF。您可以使用它来计算pairn上的距离,然后应用MAX函数。我希望这能有所帮助。

最新更新