aisdb.gis module

Geometry and GIS utilities

class aisdb.gis.Domain(name, zones=None)[source]

Bases: object

collection of zone geometry dictionaries, with additional statistics such as hull bounding box

Parameters:
  • name – string Domain name

  • zones – list of dictionaries Collection of zone geometry dictionaries. Must have keys ‘name’ (string) and ‘geometry’ (shapely.geometry.Polygon). MultiPolygon geometries will be split into their component polygons, named by suffixing the zone name with the part index

>>> domain = Domain(name='example', zones=[{
...     'name': 'zone1',
...     'geometry': shapely.geometry.Polygon([(-40,60), (-40, 61), (-41, 61), (-41, 60), (-40, 60)])
...     }, ])
attr:

self.name self.zones self.boundary self.minX self.minY self.maxX self.maxY

classmethod from_geodataframe(gdf, name_column: str | None = None, name: str = 'domain') Domain[source]

build a Domain from a geopandas GeoDataFrame.

geometries are reprojected to EPSG:4326 when the GeoDataFrame CRS differs. multi-part geometries are exploded into their component polygons, named by suffixing the zone name with the part index.

Parameters:
  • gdf (geopandas.GeoDataFrame) – zone geometries

  • name_column (str, optional) – column containing zone names. row index is used when not given

  • name (str) – domain name

nearest_polygons_to_point(x, y)[source]

compute great circle distance for this point to each polygon centroid, subtracting the maximum polygon radius. returns all zones with distances less than zero meters, sorted by nearest first

point_in_polygon(x, y)[source]

Returns the zone containing the given coordinates. if there are multiple zones containing the coordinates, the zone with the nearest centroid will be selected.

Parameters:
  • x (float) – longitude value

  • y (float) – latitude value

split_geom(zone)[source]

Ensure that the zone doesn’t intersect longitude 180 or -180. If it does, divide it into two zones.

class aisdb.gis.DomainFromPoints(points, radial_distances, names=None, domainName='domain')[source]

Bases: Domain

Subclass of aisdb.gis.Domain. Used for convenience to generate bounding box polygons from longitude/latitude pairs and radial distances, where the minimum radius is specified in meters.

class aisdb.gis.DomainFromTxts(domainName, folder, ext='txt')[source]

Bases: Domain

subclass of aisdb.gis.Domain. used for convenience to load zone geometry from .txt files directly

example:

>>> folder = os.path.join('aisdb/tests/test_zones')
>>> zipf = os.path.join(folder, 'test_zones.zip')
>>> with zipfile.ZipFile(zipf, 'r') as zip_ref:
...    members = list(
...        set(zip_ref.namelist()) - set(sorted(os.listdir(folder))))
>>>    zip_ref.extractall(path=folder, members=members)
>>> domain = DomainFromTxts(domainName='test', folder=folder)
aisdb.gis.delta_knots(track, rng=None)[source]

compute speed over ground in knots between track positions for a given track using (haversine distance / time)

Parameters:
  • track (dict) – track vector dictionary

  • rng (range) – optionally restrict computed values to given index range

Example

>>> import numpy as np
>>> import aisdb
>>> y1, x1 = -66.84683, 44.96421
>>> y2, x2 = -66.83036, 44.9679
>>> y3, x3 = -66.81388, 44.9716
>>> # creating a sample track
>>> tracks_short = [
...   dict(
...            lon=np.array([x1,x2,x3]),
...            lat=np.array([y1,y2,y3]),
...            time=[0,1,2],
...            dynamic=set(['time']),
...        )
... ]
>>> trk_1 = tracks_short[0]
>>> rt_ = aisdb.gis.delta_knots(trk_1)
aisdb.gis.delta_meters(track, rng=None)[source]

compute haversine distance in meters between track positions for a given track

Parameters:
  • track (dict) – track vector dictionary

  • rng (range) – optionally restrict computed values to given index range

Example

>>> import numpy as np
>>> import aisdb
>>> y1, x1 = -66.84683, 44.96421
>>> y2, x2 = -66.83036, 44.9679
>>> y3, x3 = -66.81388, 44.9716
>>> # creating a sample track
>>> tracks_short = [
...     dict( lon=np.array([x1,x2,x3]),
...     lat=np.array([y1,y2,y3]),
...     time=[0,1,2], dynamic=set(['time']), ) ]
>>> trk_1 = tracks_short[0]
>>> rt_ = aisdb.gis.delta_meters(trk_1)
aisdb.gis.delta_seconds(track, rng=None)[source]

compute elapsed time between track positions for a given track

Parameters:
  • track (dict) – track vector dictionary

  • rng (range) – optionally restrict computed values to given index range

aisdb.gis.distance3D(x1, y1, x2, y2, depth_metres)[source]

haversine/pythagoras approximation of vessel distance to point at given depth

aisdb.gis.dt_2_epoch(dt_arr, t0=datetime.datetime(1970, 1, 1, 0, 0))[source]

convert datetime.datetime to unix epoch seconds

Example

>>> import numpy as np
>>> from datetime import timedelta, datetime
>>> y1, x1 = -66.84683, -61.10595523571155
>>> y2, x2 = -66.83036, -61.11595523571155
>>> y3, x3 = -66.82036, -61.12595523571155
>>> t1 = dt_2_epoch( datetime(2021, 1, 1, 1) )
>>> t2 = dt_2_epoch( datetime(2021, 1, 1, 2) )
>>> t3 = dt_2_epoch(datetime(2021, 1, 1, 3))
>>> # creating a sample track
>>> tracks_short = [
...    dict(
...        lon=np.array([x1, x2, x3]),
...        lat=np.array([y1, y2, y3]),
...        time=np.array([t1, t2, t3]),
...        dynamic=set(['lon', 'lat', 'time']),
...        static = set()
...    )
... ]
>>> tracks__ = aisdb.interp.interp_time(tracks_short, timedelta(minutes=10))
aisdb.gis.epoch_2_dt(ep_arr, t0=datetime.datetime(1970, 1, 1, 0, 0), unit='seconds')[source]

convert unix epoch seconds to datetime.datetime

aisdb.gis.mask_in_radius_2D(tracks, xy, distance_meters)[source]

radial filtering using great circle distance at surface level

tracks (aisdb.track_gen.TrackGen)

track dictionary iterator

xy (tuple of floats)

target longitude and latitude coordinate pair

distance_meters (int)

maximum distance in meters

aisdb.gis.radial_coordinate_boundary(x, y, radius=100000)[source]

Defines a bounding box area for a given point and radial distance in meters. Returns degree boundaries with a minimum diameter of approximately 2 * radius meters.

The boundaries are approximated by converting input coordinates from degrees to radians, and computing a radial delta by dividing an input value by the earth radius. The radial delta is added or subtracted from the input point for each cardinal direction, and then converted back from radians to degrees.

Parameters:
  • x (float) – longitude

  • y (float) – latitude

  • radius (int, float) – minimum radial distance

returns: dict({xmin, xmax, ymin, ymax})

aisdb.gis.shiftcoord(x, rng=180)[source]

Correct longitude coordinates to be within range(-180, 180) using a linear shift and modulus. For latitude coordinate correction, set rng to 90.

For example: longitude 181 would be corrected to -179 deg.

aisdb.gis.vesseltrack_3D_dist(tracks, x1, y1, z1, colname='distance_metres')[source]

appends approximate distance to a submerged point at every surface-level position. distance is approximated using the haversine function and pythagoras.

x1 (float)

point longitude

y1 (float)

point latitude

z1 (float)

point depth (metres)

colname (string)

track dictionary key for which depth values will be set. by default, distances are appended to the ‘distance_metres’ key