我有一张运动数据表(来自船只的位置报告)。该表包含以下行:
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时,表示它被锚定,因此不再形成轨迹。
我参与了一个项目,通过首先查看所有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
,其中id1
s对象为id2
和lookahead WHERE newstatus = 'Start'
,这样您就可以获得状态切换之间每个距离的行。该表基本上具有作为观察的轨迹。加入前瞻,您可以使用ST_Makeline(gis_point)
和WHERE newid BETWEEN trajectories.is1 AND trajectories.id2
使用GROUP BY mmsi
制作每个三角形的线几何。
很抱歉没有写出所有代码。
更先进的方法是使用实际的AIS数据来查看每个mmsi
的滚动平均速度和距离,以确定船舶在更长时间内静止不动的位置。区分轨迹分隔符的上述逻辑将以相同的方式应用,只有status
的AIS可变开关被交换用于计算船舶的行为模式。
祝你好运