Source code for gpmf.gps_plot

import matplotlib.pyplot as plt
import geopandas as gpd
import contextily as ctx
import numpy
import pandas


from .gps import extract_gps_blocks, parse_gps_block


LATLON = "EPSG:4326"
LAMBERT93 = "EPSG:2154"


[docs] def to_dataframe(gps_data_blocks): """Convert a sequence of GPSData into pandas dataframe. Parameters ---------- gps_data_blocks: seq of GPSData A sequence of GPSData objects Returns ------- df_gps: pandas.DataFrame The output dataframe """ df_blocks = [] for i, block in enumerate(gps_data_blocks): df_block = pandas.DataFrame() df_block["latitude"] = block.latitude df_block["longitude"] = block.longitude df_block["altitude"] = block.altitude df_block["time"] = block.timestamp df_block["speed_2d"] = block.speed_2d df_block["speed_3d"] = block.speed_3d df_block["precision"] = block.precision df_block["fix"] = block.fix df_block["block_id"] = i df_blocks.append(df_block) return pandas.concat(df_blocks)
[docs] def filter_outliers(x): """Filter outliers based on 0.01 and 0.99 quantiles""" q01, q50, q99 = numpy.quantile(x, q=[0.01, 0.5, 0.99]) return (q50 - (1.1 * (q50 - q01)) < x) & (x < q50 + (1.1 * (q99 - q50)))
[docs] def plot_gps_trace(latlon, min_tile_size=10, map_provider=None, zoom=12, figsize=(10, 10), proj_crs=LAMBERT93, color="tab:red"): """ Plot a (lat, lon) coordinates on a Map Parameters ---------- latlon: numpy.ndarray Array of (latitude, longitude) coordinates min_tile_size: int, optional (default=10) Minimum size of the map in km map_provider: dict Dictionnary describing a map provider as given by `contextly.providers`. If None `contextily.providers.OpenStreetMap.Mapnik` is used. zoom: int, optional (default=12) The zoom level used. figsize: tuple of int, optional (default=(10, 10)) The matplotlib figure size proj_crs: str or geopandas.CRS object, optional (default="EPSG:2154") The projection system used to compute distances on the map. The default value corresponds to the Lambert 93 system. color: str, optional (default="tab:red") The color used to plot the track. """ if map_provider is None: map_provider = ctx.providers.OpenStreetMap.Mapnik min_tile_size *= 1000 y, x = latlon.T mask = filter_outliers(x) & filter_outliers(y) df = gpd.GeoDataFrame( geometry=gpd.points_from_xy(x[mask], y[mask], crs=LATLON) ) plt.figure(figsize=figsize) ax = plt.gca() df.to_crs(proj_crs).plot(ax=ax, color=color) xmin, xmax = plt.xlim() dx = xmax - xmin if dx < min_tile_size: xc = 0.5 * (xmin + xmax) xmin = xc - min_tile_size / 2 xmax = xc + min_tile_size / 2 plt.xlim(xmin, xmax) ymin, ymax = plt.ylim() dy = ymax - ymin if dy < min_tile_size: yc = 0.5 * (ymin + ymax) ymin = yc - min_tile_size / 2 ymax = yc + min_tile_size / 2 plt.ylim(ymin, ymax) ctx.add_basemap(ax, source=map_provider, zoom=zoom, crs=proj_crs) ax.set_axis_off()
[docs] def plot_gps_trace_from_stream(stream, first_only=False, min_tile_size=10, map_provider=None, zoom=12, figsize=(10, 10), proj_crs=LAMBERT93, output_path=None, precision_max=3.0, color="tab:red"): """ Plot GPS data from a string on a map. Parameters ---------- stream: bytes The raw GPMF binary stream. min_tile_size: int, optional (default=10) Minimum size of the map in km map_provider: dict Dictionnary describing a map provider as given by `contextly.providers`. If None `contextily.providers.OpenStreetMap.Mapnik` is used. zoom: int, optional (default=12) The zoom level used. figsize: tuple of int, optional (default=(10, 10)) The matplotlib figure size proj_crs: str or geopandas.CRS object, optional (default="EPSG:2154") The projection system used to compute distances on the map. The default value corresponds to the Lambert 93 system. color: str, optional (default="tab:red") The color used to plot the track. """ gps_data_blocks = map(parse_gps_block, extract_gps_blocks(stream)) if first_only: latlon = numpy.array([[b.latitude[0], b.longitude[0]] for b in gps_data_blocks if b.precision < precision_max]) else: latlon = numpy.vstack([ numpy.vstack([b.latitude, b.longitude]).T for b in gps_data_blocks if b.precision < precision_max ]) plot_gps_trace(latlon, min_tile_size=min_tile_size, map_provider=map_provider, zoom=zoom, figsize=figsize, proj_crs=proj_crs, color=color) plt.tight_layout() if output_path is not None: plt.savefig(output_path)