aisdb.network_graph module
collect vessel transits between domain zones (graph nodes), and aggregate trajectory statistics within the overall domain
- aisdb.network_graph.graph(qry, *, outputfile, domain, dbconn: ~aisdb.database.dbconn.ConnectionType, data_dir: str, trafficDBpath: str, maxdelta: ~datetime.timedelta = datetime.timedelta(days=7), speed_threshold: float = 50, distance_threshold: float = 200000, interp_delta: float = datetime.timedelta(seconds=600), minscore: float = 0, qryfcn=<function crawl_dynamic_static>, decimate: float = 0.0001, verbose: bool = False)[source]
Compute network graph of vessel movements within domain zones. Zone polygons will be used as network nodes, with graph edges represented by movements between zones.
- Parameters:
qry (
aisdb.database.dbqry.DBQuery
) – database query generatordomain (
aisdb.gis.Domain
) – collection of zones defined as polygons, these will be used as nodes in the network graphdbconn (ConnectionType) – Either a
aisdb.database.dbconn.SQLiteDBConn
oraisdb.database.dbconn.PostgresDBConn
database connection objectsdata_dir (string) – location of raster data
trafficDBpath (string) – path to marinetraffic database file
outpufile (string) – filepath for resulting CSV output
maxdelta (datetime.timedelta) – maximum time between vessel messages before considering it to be part of a new trajectory. See
aisdb.track_gen.split_timedelta()
for more infospeed_threshold (int, float) – maximum speed in knots for encoder segmentation. See
aisdb.denoising_encoder.encode_greatcircledistance()
for more infodistance_threshold (int, float) – maximum distance in meters for encoder segmentation. See
aisdb.denoising_encoder.encode_greatcircledistance()
for more infointerp_delta (timedelta) – track positions will be interpolated to the given sample rate
minscore (float) – minimum score for segments to be considered sequential. See
aisdb.denoising_encoder.encode_greatcircledistance()
for more info
Network graph activity is computed following these steps:
Create database query with
aisdb.database.dbqry.DBQuery.gen_qry()
, and supply resulting generator as rowgen arg. Define a domain (aisdb.gis.Domain
) in which to compute movementsVectorize tracks using
aisdb.track_gen.TrackGen()
Append vessel metadata to track vessels with
aisdb.webdata.marinetraffic.vessel_info()
Segment track vectors where time between messages exceeds maxdelta using
aisdb.track_gen.split_timedelta()
Segment track vectors as encoded by
aisdb.denoising_encoder.encode_greatcircledistance()
Perform geofencing on track segments using
aisdb.track_gen.fence_tracks()
to determine zone containmentCheck where zone boundaries are transited and serialize results to
outputfile
. Additional metrics per zone activity is also aggregated at this step.
Example usage:
>>> import os >>> import shapely >>> from datetime import datetime >>> from aisdb import SQLiteDBConn, DBQuery, Domain, graph, decode_msgs >>> from aisdb.database.sqlfcn_callbacks import in_bbox_time
>>> # create example database file >>> dbpath = './example.sqlitedb' >>> filepaths = ['./aisdb/tests/testdata/test_data_20210701.csv', ... './aisdb/tests/testdata/test_data_20211101.nm4'] >>> with SQLiteDBConn(dbpath) as dbconn: ... decode_msgs(filepaths=filepaths, dbconn=dbconn, ... source='TESTING', verbose=False)
Next, configure query area using Domain to compute region boundary
>>> zones = [{ ... 'name': 'Zone1', ... 'geometry': shapely.geometry.Polygon(zip( ... [-170.24, -170.24, -38.5, -38.5, -170.24], ... [29.0, 75.2, 75.2, 29.0, 29.0], ... )) ... }] >>> domain = Domain(name='new_domain', zones=zones) >>> trafficDBpath = './testdata/marinetraffic_test.db' >>> data_dir = os.environ.get('AISDBDATADIR', '/tmp/ais/')
Then, query db for points in domain
>>> with SQLiteDBConn(dbpath) as dbconn: ... qry = DBQuery( ... dbconn=dbconn, ... callback=in_bbox_time, ... start=datetime(2021, 7, 1), ... end=datetime(2021, 7, 3), ... **domain.boundary, ... ) ... graph(qry, ... outputfile=os.path.join('testdata', 'test_graph.csv'), ... dbconn=dbconn, ... domain=domain, ... data_dir=data_dir, ... trafficDBpath=trafficDBpath)
Afterwards, delete the example database file
>>> os.remove(dbpath) >>> os.remove(os.path.join('testdata', 'test_graph.csv'))
process the vessel movement graph edges. caution: this may consume a large amount of memory