Source code for ecoscope.base.straightrack
import geopandas as gpd # type: ignore[import-untyped]
from pyproj import Geod
[docs]
class StraightTrackProperties:
def __init__(self, gdf: gpd.GeoDataFrame):
self.gdf = gdf
@property
def start_fixes(self):
# unpack xy-coordinates of start fixes
return self.gdf["geometry"].x, self.gdf["geometry"].y
@property
def end_fixes(self):
# unpack xy-coordinates of end fixes
return self.gdf["_geometry"].x, self.gdf["_geometry"].y
@property
def inverse_transformation(self):
# use pyproj geodesic inverse function to compute vectorized distance & heading calculations
return Geod(ellps="WGS84").inv(*self.start_fixes, *self.end_fixes)
@property
def heading(self):
# Forward azimuth(s)
forward_azimuth, _, _ = self.inverse_transformation
forward_azimuth[forward_azimuth < 0] += 360
return forward_azimuth
@property
def dist_meters(self):
_, _, distance = self.inverse_transformation
return distance
@property
def nsd(self):
start_point = self.gdf["geometry"].iloc[0]
geod = Geod(ellps="WGS84")
geod_displacement = [geod.inv(start_point.x, start_point.y, geo.x, geo.y)[2] for geo in self.gdf["_geometry"]]
# meters squared over 1M == km^2
return [(x**2) / (1000**2) for x in geod_displacement]
@property
def timespan_seconds(self):
return (self.gdf["_fixtime"] - self.gdf["fixtime"]).dt.total_seconds()
@property
def speed_kmhr(self):
return (self.dist_meters / self.timespan_seconds) * 3.6