根据AIS数据集计算每艘船的轨迹

时间:2017-06-25 16:22:51

标签: postgresql postgis

我有一张运动数据表(来自船只的位置报告)。该表包含以下行:

row name:   type:               Description:
timestamp   double precision    timestamp in UNIX epochs (seconds from 1/1/1970)
type        integer             AIS message type 
mmsi        integer             MMSI identifier for vessel
status      integer             Navigational status
lon         double precision    Longitude (georeference: WGS 1984)
lat         double precision    Latitude  (georeference: WGS 1984)
heading     integer             True heading in degrees (0-359), relative to true north
turn        double precision    Rate of turn, right or left, 0 to 720 degrees per minute
speed       double precision    Speed over ground in knots (allowed values: 0-102.2 knots)
course      double precision    Course over ground (allowed values: 0-359.9 degrees).

导入数据后,我再添加了一行使用lon,lat和timestamp行形成的几何类型:

SELECT AddGeometryColumn ('public', 'gis_may', 'geom_time', 4326, 'POINTZ', 3);
UPDATE public.gis_may SET geom_time = ST_Transform(ST_SetSRID(ST_MakePoint(lon, lat, gis_may.timestamp ), 4326),4326);

我必须根据这些数据计算每艘船的轨迹。我尝试使用以下代码:

CREATE TABLE ship_trajectories AS SELECT st_makeline(st_setsrid(st_makepoint(lon::REAL, lat::REAL, gis_may.timestamp), 4326)) as traj
FROM gis_may
GROUP BY mmsi;

...但问题是,此代码仅根据每艘船的坐标返回一个线串/轨迹,并未考虑船停止移动的时间。

我认为解决方法是使用行:status(我搜索并找到了导航状态:https://help.marinetraffic.com/hc/en-us/articles/203990998-What-is-the-significance-of-the-AIS-Navigational-Status-Values-)。当status为0时,表示船正在移动,当它为1时,表示它已锚定,因此不再形成轨迹。

1 个答案:

答案 0 :(得分:0)

我参与了一个项目,通过首先查看所有AIS点来确定轨迹断点来解决同样的问题。如果您认为AIS变量status足以满足您的需求,那么对您有好处。您可以检查每个状态实例更改为0.请注意,AIS数据也具有其他状态值。请参阅this

如果在每个mmsi中,当船舶从状态1变为状态0时,您想要标记该行。这将为您的轨迹开始创建分界点。首先将经度 - 纬度协调添加为名为gis_point几何体后,请查看此内容:

-- Make a point geometry and work with those.
SELECT AddGeometryColumn('public', 'gis_may', 'gis_point', 4326, 'POINT', 2);
UPDATE gis_may SET gis_point = ST_Transform(ST_SetSRID(
                ST_MakePoint(longitude, latitude),
                4326), 4326);

-- Look ahead to keep stuff within the same mmsi. Create a switch for when the status changes:
CREATE TABLE lookahead AS
SELECT aislag.mmsi, aislag.timestamp1, aislag.gis_point, EXTRACT(EPOCH FROM (aislag.ts2 - aislag.ts1)) AS timediff, aislag.g,
       CASE WHEN aislag.status = '1' AND aislag.newstatus ='0' THEN 'Start' ELSE '.' END AS newtrajectory
FROM
    (SELECT mmsi, timestamp as timestamp1, status, gis_point,
            LEAD(mini_c.timestamp) OVER (ORDER BY mmsi, timestamp) AS timestamp2,
            LEAD(mini_c.mmsi) OVER (ORDER BY mmsi, timestamp) AS mmsi2,
            mini_c.status AS status,
            LEAD(mini_c.status) OVER (ORDER BY mmsi, timestamp) AS newstatus
     FROM mini_c) AS aislag
     WHERE aislag.mmsi = aislag.mmsi2

我也添加了一个滞后的时间变量。也许你想扩大状态切换器,将观察到的时间差异包括在同一艘船的下一个AIS点。现在您已经拥有了分隔符,可以为id之后lookahead - 排序的行创建新的mmsi, ts。然后从trajectories上的滞后选择中创建一个新表id,其中id1id2lookahead WHERE newstatus = 'Start'成对,这样您就可以获得一行状态切换之间的距离。该表基本上具有作为观察的轨迹。加入前瞻,您可以使用ST_Makeline(gis_point)WHERE newid BETWEEN trajectories.is1 AND trajectories.id2 GROUP BY mmsi为每个三等分线制作线条几何图形。

很抱歉没有写出所有代码。

更先进的方法是使用实​​际的AIS数据来查看每个mmsi的滚动平均速度和距离,以确定船舶在更长时间内静止不动的位置。区分轨迹分隔符的上述逻辑将以相同的方式应用,只有status的AIS变量开关被用于计算船舶的行为模式。

祝你好运