zl程序教程

您现在的位置是:首页 >  IT要闻

当前栏目

PostgreSQL计算影响某地的台风

2023-02-18 16:26:49 时间

已爬取了十几年来的全国台风数据,现要获取影响某地的台风,想法比较粗糙,就是以某地的中心点为半径和台风路径中心点距离的求解,一般某地区是以点带面的有个地区半径,台风一般取七级台风风圈半径。

现在的问题点转换为了,两点之间求距离。

Postgresql有两种办法可实现,一种是自定义函数,一种是利用Postgresql扩展包

第一种自定义函数的方式,参见代码:

create or replace function getdistance
(
    ilngbegin real,
    ilatbegin real,
    ilngend real,
    ilatend real
)
returns float
as
$body$

declare
    vdistance real;
    vearthradius real;
    vradlatbegin real;
    vradlatend real;
    vradlatdiff real;
    vradlngdiff real;
begin
    --地球半径
    vearthradius:=6378.137;
    -经纬度转换
    vradlatbegin := ilatbegin * pi()/180.0;
    vradlatend := ilatend * pi()/180.0;
    vradlatdiff := vradlatbegin - vradlatend;
    vradlngdiff := ilngbegin * pi()/180.0 - ilngend * pi()/180.0;
    --求距离
    vdistance :=  * asin(sqrt(power(sin(vradlatdiff / ), ) + cos(vradlatbegin) * cos(vradlatend) * power(sin(vradlngdiff/),)));
    vdistance := vdistance * vearthradius*;
    return vdistance;
end;
$body$
language 'plpgsql' volatile;

Postgresql内置了地理计算的一些功能,需要在应用时赋权即可。

CREATE EXTENSION cube;
CREATE EXTENSION earthdistance;

这两种方法的调用如下:

select a.tfid,a.pointlat,pointlng,getdistance(a.pointlat,a.pointlng,19.137154,109.876876) as distance,a.* 
  from typhoon_his_point_info a
 where getdistance(a.pointlat,pointlng,19.137154,109.876876)<=  
 order  by a.tfid,a.pointtime;

select a.tfid,a.pointlat,pointlng,earth_distance(ll_to_earth (109.876876, 19.137154),ll_to_earth(a.pointlng, a.pointlat)) as distance,a.*
  from typhoon_his_point_info a
 where getdistance(a.pointlat,pointlng,19.137154,109.876876)<=  
 order  by a.tfid,a.pointtime;

结论:两种计算方法的误差在十万分之一,当然直接使用Postgresql的会更精准一些。