perda.utils.gps_analysis#

perda.utils.gps_analysis.create_representative_gps_image(lat_raw, lon_raw, vel_raw=None, vel_thresh=0.5, title=None, layout_config=LayoutConfig(width=1200, height=700, margin={'l': 70, 'r': 50, 't': 90, 'b': 70}, plot_bgcolor='white', title_x=0.5, title_xanchor='center', title_yanchor='top', grid_width_per_col=400, grid_height_per_row=350, grid_horizontal_spacing=0.08, grid_vertical_spacing=0.12, max_display_resolution=50), font_config=FontConfig(large=20, medium=14, small=10), gps_map_config=GpsMapConfig(mapbox_style='carto-positron', mapbox_token='', marker_size=3, line_width=2, line_color='red', zoom_padding=0.4, max_radius_m=5000.0, max_jump_m=30.0))[source]#

Generate a GPS trace on an interactive map background.

Outliers (large radius from centroid or sudden jumps) are removed via filter_gps_cartesian(). Uses CARTO Positron tiles by default (free, no API key required).

Parameters:
  • lat_raw (DataInstance) – Raw latitude data instance, timestamp alignment base.

  • lon_raw (DataInstance) – Raw longitude data instance.

  • vel_raw (DataInstance | None, optional) – Raw velocity data instance.

  • vel_thresh (float, optional) – Velocity threshold for trimming, by default 0.5, same unit as velocity.

  • title (str | None, optional) – Title for the plot.

  • layout_config (LayoutConfig, optional)

  • font_config (FontConfig, optional)

  • gps_map_config (GpsMapConfig, optional) – Map overlay and outlier filtering configuration.

Returns:

Plotly figure with map background, or None if velocity never exceeds the threshold or no points remain after filtering.

Return type:

go.Figure | None

Examples

>>> fig = create_representative_gps_image(lat_di, lon_di, vel_raw=vel_di, title="Lap Track")
>>> fig.show()
perda.utils.gps_analysis.filter_gps_cartesian(lat, lon, gps_map_config=GpsMapConfig(mapbox_style='carto-positron', mapbox_token='', marker_size=3, line_width=2, line_color='red', zoom_padding=0.4, max_radius_m=5000.0, max_jump_m=30.0))[source]#

Build a boolean mask that removes Cartesian GPS outliers.

Two independent filters are applied and combined with logical-AND:

  • Radius filter — discards points whose straight-line distance from the centroid of all points exceeds gps_map_config.max_radius_m.

  • Jump filter — discards points where the step distance from the previous point exceeds gps_map_config.max_jump_m.

Parameters:
  • lat (NDArray[np.float64]) – Latitude values in degrees.

  • lon (NDArray[np.float64]) – Longitude values in degrees.

  • gps_map_config (GpsMapConfig, optional)

Returns:

Boolean mask; True where a point should be kept.

Return type:

NDArray[np.bool_]

Examples

>>> mask = filter_gps_cartesian(lat_array, lon_array)
>>> lat_clean, lon_clean = lat_array[mask], lon_array[mask]
perda.utils.gps_analysis.gps_to_enu(lat, lon, lat_ref=None, lon_ref=None)[source]#

Project lat/lon coordinates to a local East-North-Up (ENU) Cartesian frame.

Uses a flat-Earth approximation, accurate to within ~0.1 % for distances up to ~10 km from the reference point.

Parameters:
  • lat (NDArray[np.float64]) – Latitude values in degrees.

  • lon (NDArray[np.float64]) – Longitude values in degrees.

  • lat_ref (float | None, optional) – Reference latitude in degrees. Defaults to the median of lat.

  • lon_ref (float | None, optional) – Reference longitude in degrees. Defaults to the median of lon.

Returns:

(east_m, north_m) arrays giving signed distance in metres from the reference point along the East and North axes respectively.

Return type:

tuple[NDArray[np.float64], NDArray[np.float64]]

Examples

>>> east, north = gps_to_enu(lat_array, lon_array)
perda.utils.gps_analysis.plot_gps_comparison(runs, title=None, gps_map_config=GpsMapConfig(mapbox_style='carto-positron', mapbox_token='', marker_size=3, line_width=2, line_color='red', zoom_padding=0.4, max_radius_m=5000.0, max_jump_m=30.0), layout_config=LayoutConfig(width=1200, height=700, margin={'l': 70, 'r': 50, 't': 90, 'b': 70}, plot_bgcolor='white', title_x=0.5, title_xanchor='center', title_yanchor='top', grid_width_per_col=400, grid_height_per_row=350, grid_horizontal_spacing=0.08, grid_vertical_spacing=0.12, max_display_resolution=50), font_config=FontConfig(large=20, medium=14, small=10))[source]#

Overlay GPS tracks from multiple runs on a shared East/North Cartesian frame.

Each run is projected to ENU coordinates using a single shared reference point (median of all points across all runs), then filtered with filter_gps_cartesian() before plotting.

Parameters:
  • runs (List[tuple[NDArray[np.float64], NDArray[np.float64], str]]) – Each element is (lat_array, lon_array, label) for one run. lat_array and lon_array must be the same length.

  • title (str | None, optional)

  • gps_map_config (GpsMapConfig, optional) – Controls Cartesian outlier thresholds (max_radius_m, max_jump_m) and marker appearance.

  • layout_config (LayoutConfig, optional)

  • font_config (FontConfig, optional)

Returns:

Plotly figure with one scatter trace per run

Return type:

go.Figure

Examples

>>> fig = plot_gps_comparison(
...     [(lat1, lon1, "Run 1"), (lat2, lon2, "Run 2")],
...     title="GPS Comparison",
... )
>>> fig.show()
perda.utils.gps_analysis.plot_gps_trimmer(lat, lon, title=None, layout_config=LayoutConfig(width=1200, height=700, margin={'l': 70, 'r': 50, 't': 90, 'b': 70}, plot_bgcolor='white', title_x=0.5, title_xanchor='center', title_yanchor='top', grid_width_per_col=400, grid_height_per_row=350, grid_horizontal_spacing=0.08, grid_vertical_spacing=0.12, max_display_resolution=50), font_config=FontConfig(large=20, medium=14, small=10), timestamp_unit=Timescale.MS)[source]#

Interactive GPS coordinate trimmer with a dual-handle range slider.

Displays a 2D scatter plot of GPS coordinates (longitude vs latitude) alongside an ipywidgets IntRangeSlider that trims which points are shown. Designed for use in Jupyter notebooks.

Parameters:
  • lat (DataInstance) – Latitude values. Must have the same length and identical timestamps as lon.

  • lon (DataInstance) – Longitude values. Must have the same length and identical timestamps as lat.

  • title (str | None, optional)

  • layout_config (LayoutConfig, optional)

  • font_config (FontConfig, optional)

  • timestamp_unit (Timescale, optional) – Timestamp unit used for the slider timestamp labels.

Return type:

ipywidgets.VBox

Examples

>>> widget = plot_gps_trimmer(lat_di, lon_di, title="GPS Track")
>>> display(widget)