### Install mappymatch from source with conda Source: https://natlabrockies.github.io/mappymatch/_sources/install.md Install mappymatch from source: clone the repository, create a conda environment from the environment.yml file, and activate it. Requires Anaconda or miniconda. ```bash git clone https://github.com/NatLabRockies/mappymatch.git && cd mappymatch ``` ```bash conda env create -f environment.yml ``` ```bash conda activate mappymatch ``` -------------------------------- ### Using ValhallaMatcher with default and custom settings Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.matchers.valhalla.html Shows how to create a ValhallaMatcher with the default demo server, a custom server with a bicycle cost model, and additional attributes. Python code from the module's docstring example. ```python >>> from mappymatch.matchers.valhalla import ValhallaMatcher >>> >>> # Use default demo server (for testing only) >>> matcher = ValhallaMatcher() >>> result = matcher.match_trace(trace) >>> >>> # Use your own Valhalla instance >>> matcher = ValhallaMatcher( ... valhalla_url='http://localhost:8002/trace_attributes', ... cost_model='bicycle' ... ) >>> >>> # Request additional attributes >>> matcher = ValhallaMatcher( ... attributes=['edge.length', 'edge.speed', 'edge.names', 'edge.surface'] ... ) ``` -------------------------------- ### NxMap.from_geofence() Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.maps.nx.nx_map.html Class method to create a NxMap from a geofence (documented in examples). ```APIDOC ## NxMap.from_geofence() ### Description Create a NxMap from a geofence, typically used with OpenStreetMap data. This method is referenced in the class examples. ### Example ```python >>> geofence = Geofence.from_geojson('study_area.geojson') >>> road_map = NxMap.from_geofence( ... geofence, ... network_type=NetworkType.DRIVE, ... xy=True # Use Web Mercator for accurate distances ... ) ``` ``` -------------------------------- ### Module imports and logger setup Source: https://natlabrockies.github.io/mappymatch/_modules/mappymatch/matchers/line_snap.html Imports required modules and initializes a logger for the LineSnapMatcher module. ```python import logging from typing import List from mappymatch.constructs.match import Match from mappymatch.constructs.trace import Trace from mappymatch.maps.map_interface import MapInterface from mappymatch.matchers.matcher_interface import MatcherInterface, MatchResult log = logging.getLogger(__name__) ``` -------------------------------- ### Geofence.from_trace() examples with padding and buffer_res Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.constructs.geofence.html Creates a geofence by buffering a GPS trace. The first call uses a 500m padding with default buffer_res=2; the second uses 2000m padding and buffer_res=8 for a higher-resolution polygon. Requires a Trace object. ```python >>> # Create a 500m buffer around a trace for map download >>> trace = Trace.from_csv('morning_commute.csv') >>> geofence = Geofence.from_trace(trace, padding=500) >>> >>> # Create a larger 2km buffer with higher resolution >>> geofence = Geofence.from_trace(trace, padding=2000, buffer_res=8) ``` -------------------------------- ### Install mappymatch from PyPI Source: https://natlabrockies.github.io/mappymatch/_sources/install.md Install the mappymatch package from PyPI using pip. Note that some geospatial dependencies may be difficult to install via pip; if issues occur, the recommended solution is to install from source using conda. ```bash pip install mappymatch ``` -------------------------------- ### Clone mappymatch repository from GitHub Source: https://natlabrockies.github.io/mappymatch/install.html Clones the mappymatch repository from GitHub and changes into the cloned directory. This is the first step for installing from source. ```bash git clone https://github.com/NatLabRockies/mappymatch.git && cd mappymatch ``` -------------------------------- ### Create and inspect a Match instance Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.constructs.match.html Shows how to create a Match instance for both successful and failed map-matching scenarios. A successful match includes a road, coordinate, and distance; a failed match sets road to None and distance to infinity. The example also demonstrates checking match.road to verify success. ```python >>> from mappymatch.constructs.coordinate import Coordinate >>> from mappymatch.constructs.road import Road, RoadId >>> from mappymatch.constructs.match import Match >>> from shapely.geometry import LineString >>> >>> # Create a successful match >>> coord = Coordinate.from_lat_lon(40.7128, -74.0060) >>> road = Road(RoadId('1', '2', 0), LineString([(0, 0), (1, 1)])) >>> match = Match(road=road, coordinate=coord, distance=5.2) >>> >>> # Check if matching was successful >>> if match.road is not None: ... print(f"Matched to road with distance: {match.distance}m") >>> >>> # Create a failed match (no road found) >>> no_match = Match(road=None, coordinate=coord, distance=float('inf')) ``` -------------------------------- ### Match a GPS trace with ValhallaMatcher Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.matchers.valhalla.html Creates a ValhallaMatcher, loads a trace from a CSV file, and matches it to road segments. The example then prints the number of matched points, the number of road segments in the path, and road metadata (speed and length) for the first five segments. ```python >>> matcher = ValhallaMatcher() >>> trace = Trace.from_csv('gps_data.csv') >>> result = matcher.match_trace(trace) >>> >>> # Access results >>> print(f"Matched {len(result.matches)} points") >>> print(f"Path has {len(result.path)} road segments") >>> >>> # Check road metadata from Valhalla >>> for road in result.path[:5]: ... print(f"Speed: {road.metadata['speed_mph']} mph") ... print(f"Length: {road.metadata['length_miles']} miles") ``` -------------------------------- ### Geofence.to_geojson() example with file write Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.constructs.geofence.html Converts a geofence to a GeoJSON string and writes it to a file. The geofence is automatically transformed to WGS84 (EPSG:4326) if it is in a different CRS. ```python >>> geofence = Geofence.from_trace(trace, padding=1000) >>> geojson_str = geofence.to_geojson() >>> # Write to file >>> with open('boundary.geojson', 'w') as f: ... f.write(geojson_str) ``` -------------------------------- ### Geofence.from_geojson() example Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.constructs.geofence.html Loads a geofence from a GeoJSON file containing a single polygon feature with CRS information. Raises TypeError if the file contains multiple polygons or lacks CRS information. ```python >>> # Load a boundary polygon >>> geofence = Geofence.from_geojson('study_area.geojson') >>> print(geofence.crs) # EPSG:4326 ``` -------------------------------- ### Create conda environment from environment.yml Source: https://natlabrockies.github.io/mappymatch/install.html Creates a conda environment using the environment.yml file provided in the repository. This installs the necessary dependencies for mappymatch. ```bash conda env create -f environment.yml ``` -------------------------------- ### Instantiate a matcher and match a trace Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.matchers.matcher_interface.html Shows that all matchers in mappymatch implement the same interface, using LCSSMatcher as an example. Requires a road_map and a trace object. ```python >>> from mappymatch.matchers.lcss import LCSSMatcher >>> from mappymatch.matchers.valhalla import ValhallaMatcher >>> >>> # All matchers follow the same interface >>> matcher = LCSSMatcher(road_map) >>> result = matcher.match_trace(trace) ``` -------------------------------- ### Create NxMap from geofence with OSMnx Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.maps.nx.nx_map.html Shows how to create an NxMap from a geofence using OSMnx. The geofence must be in EPSG:4326; by default the network is converted to Web Mercator (EPSG:3857). The example includes downloading a driving network, adding metadata keys, and using a custom filter for major roads. ```python >>> from mappymatch.maps.nx import NxMap, NetworkType >>> from mappymatch.constructs.geofence import Geofence >>> >>> # Download driving network for a city >>> geofence = Geofence.from_geojson('city_boundary.geojson') >>> road_map = NxMap.from_geofence(geofence, network_type=NetworkType.DRIVE) >>> >>> # Download with additional metadata >>> road_map = NxMap.from_geofence( ... geofence, ... network_type=NetworkType.DRIVE, ... additional_metadata_keys={'maxspeed', 'lanes', 'name'} ... ) >>> >>> # Custom filter for only highways >>> road_map = NxMap.from_geofence( ... geofence, ... network_type=NetworkType.DRIVE, ... custom_filter='["highway"~"motorway|trunk|primary"]' ... ) ``` -------------------------------- ### Download OSM network with nx_graph_from_osmnx (network type and custom filter) Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.maps.nx.readers.osm_readers.html Download and process an OSM road network with nx_graph_from_osmnx. The first call uses NetworkType.DRIVE and projects to Web Mercator (xy=True). The second overrides the network type with a custom_filter and preserves extra OSM tags via additional_metadata_keys. Raises MapException if OSMnx is not installed. ```python >>> from mappymatch.maps.nx.readers.osm_readers import nx_graph_from_osmnx, NetworkType >>> >>> # Download a driving network >>> graph = nx_graph_from_osmnx( ... geofence=my_geofence, ... network_type=NetworkType.DRIVE, ... xy=True ... ) >>> >>> # Download with custom filter and metadata >>> graph = nx_graph_from_osmnx( ... geofence=my_geofence, ... network_type=NetworkType.DRIVE, ... custom_filter='["highway"~"motorway|primary|secondary"]', ... additional_metadata_keys={'maxspeed', 'lanes', 'name'} ... ) ``` -------------------------------- ### Create OsrmMatcher with default or custom OSRM settings Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.matchers.osrm.html Shows how to instantiate OsrmMatcher with default settings or with a custom OSRM address and profile. The default uses the public demo server, which is rate-limited and not recommended for production. ```python >>> from mappymatch.matchers.osrm import OsrmMatcher >>> >>> # Use default public OSRM server (for testing only) >>> matcher = OsrmMatcher() >>> result = matcher.match_trace(trace) >>> >>> # Use your own OSRM instance >>> matcher = OsrmMatcher( ... osrm_address='http://localhost:5000', ... osrm_profile='cycling' ... ) ``` -------------------------------- ### NxMap.road_by_id(road_id) Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.maps.nx.nx_map.html Get a road by its id. ```APIDOC ## NxMap.road_by_id(road_id) ### Description Get a road by its id. ### Parameters - **road_id** (RoadId) - Required - The id of the road to get ### Returns - **Road | None** - The road with the given id, or None if it does not exist ``` -------------------------------- ### RoadId.start Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.constructs.road.html The start junction identifier of the road segment. ```APIDOC ## RoadId.start ### Description Returns the start junction identifier of the road segment. ### Attributes - **start** (int | str | None) - The start junction identifier. ``` -------------------------------- ### NxMap.to_file() Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.maps.nx.nx_map.html Method to save the NxMap to a file (documented in examples). ```APIDOC ## NxMap.to_file() ### Description Save the NxMap to a file for later use. This method is referenced in the class examples. ### Example ```python >>> road_map.to_file('network.pickle') ``` ``` -------------------------------- ### ValhallaMatcher.__init__ Source: https://natlabrockies.github.io/mappymatch/_modules/mappymatch/matchers/valhalla.html Initializes a ValhallaMatcher instance with configurable Valhalla server URL, cost model, shape matching algorithm, and requested edge attributes. ```APIDOC ## ValhallaMatcher.__init__ ### Description Initializes a ValhallaMatcher instance with configurable Valhalla server URL, cost model, shape matching algorithm, and requested edge attributes. ### Method Constructor ### Signature ```python ValhallaMatcher( valhalla_url=DEMO_VALHALLA_ADDRESS, cost_model="auto", shape_match="map_snap", attributes=DEFAULT_ATTRIBUTES ) ``` ### Parameters - **valhalla_url** (str) - Optional - The Valhalla API endpoint URL. Defaults to the demo server. - **cost_model** (str) - Optional - The routing cost model to use (e.g., 'auto', 'bicycle'). Defaults to 'auto'. - **shape_match** (str) - Optional - The shape matching algorithm. Defaults to 'map_snap'. - **attributes** (list) - Optional - Additional edge attributes to request. Defaults to DEFAULT_ATTRIBUTES. ### Example ```python >>> matcher = ValhallaMatcher() >>> matcher = ValhallaMatcher( ... valhalla_url='http://localhost:8002/trace_attributes', ... cost_model='bicycle' ... ) >>> matcher = ValhallaMatcher( ... attributes=['edge.length', 'edge.speed', 'edge.names', 'edge.surface'] ... ) ``` ``` -------------------------------- ### NxMap.nearest_road Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.maps.nx.nx_map.html A helper function to get the nearest road to a given coordinate. ```APIDOC ## NxMap.nearest_road ### Description A helper function to get the nearest road to a given coordinate. ### Method Instance method ### Signature `nearest_road(coord: Coordinate) -> Road` ### Parameters - **coord** (Coordinate) - Required - The coordinate to find the nearest road to. ### Returns - **Road** - The nearest road to the coordinate. ``` -------------------------------- ### Create LCSSMatcher and match a trace Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.matchers.lcss.lcss.html Shows how to instantiate an LCSSMatcher with a road network loaded from a pickle file and run match_trace on a trace. Uses default parameters. ```python >>> from mappymatch.matchers.lcss import LCSSMatcher >>> from mappymatch.maps.nx import NxMap >>> >>> # Load a road network >>> road_map = NxMap.from_file('network.pickle') >>> >>> # Create matcher with default parameters >>> matcher = LCSSMatcher(road_map) >>> result = matcher.match_trace(trace) ``` -------------------------------- ### NxMap.nearest_road() Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.maps.nx.nx_map.html Method to find the nearest road to a coordinate (documented in examples). ```APIDOC ## NxMap.nearest_road() ### Description Find the nearest road to a given coordinate. This method is referenced in the class examples. ### Example ```python >>> nearest = road_map.nearest_road(coordinate) ``` ``` -------------------------------- ### Download road network with NxMap.from_geofence Source: https://natlabrockies.github.io/mappymatch/examples/lcss_example.html Downloads a road network using the NxMap class, which uses networkx under the hood. The network_type defaults to DRIVE but can be set to BIKE or WALK. ```python from mappymatch.maps.nx.nx_map import NxMap, NetworkType nx_map = NxMap.from_geofence( geofence, network_type=NetworkType.DRIVE, ) ``` -------------------------------- ### NxMap.shortest_path() Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.maps.nx.nx_map.html Method to compute the shortest path between two points (documented in examples). ```APIDOC ## NxMap.shortest_path() ### Description Compute the shortest path between an origin and destination. This method is referenced in the class examples. ### Example ```python >>> path = road_map.shortest_path(origin, destination) ``` ``` -------------------------------- ### Get road by ID Source: https://natlabrockies.github.io/mappymatch/_modules/mappymatch/maps/nx/nx_map.html Returns the Road object for the given RoadId, or None if it does not exist. ```python def road_by_id(self, road_id: RoadId) -> Optional[Road]: """ Get a road by its id Args: road_id: The id of the road to get Returns: The road with the given id, or None if it does not exist """ if self._has_road_id(road_id): return self._build_road(road_id) else: return None ``` -------------------------------- ### Load a GeoParquet trace with Trace.from_parquet Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.constructs.trace.html Shows how to create a Trace from a GeoParquet file. The file must contain a geometry column with Point geometries and a valid CRS. ```python >>> # Load from a GeoParquet file >>> trace = Trace.from_parquet('trajectory.parquet') ``` -------------------------------- ### Geofence.from_trace() Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.constructs.geofence.html Creates a geofence by buffering around a GPS trace. This method creates a polygonal boundary around a trace by converting the trace to a LineString, creating a buffer zone around the line, and transforming to the specified CRS. ```APIDOC ## Geofence.from_trace(trace, padding=1000.0, crs=EPSG:4326, buffer_res=2) ### Description Creates a geofence by buffering around a GPS trace. This method creates a polygonal boundary around a trace by converting the trace to a LineString, creating a buffer zone around the line, and transforming to the specified CRS. This is particularly useful for downloading map data that covers a GPS trajectory, ensuring you get all relevant roads while minimizing unnecessary data. ### Method classmethod ### Signature `from_trace(trace: Trace, padding: float = 1000.0, crs: CRS = , buffer_res: int = 2) -> Geofence` ### Parameters - **trace** (Trace) - Required - The GPS trace to create a boundary around - **padding** (float) - Optional - The buffer distance in meters around the trace. Default is 1000m (1km). - **crs** (CRS) - Optional - The target coordinate reference system for the geofence. Default is WGS84 (EPSG:4326). - **buffer_res** (int) - Optional - The resolution of the buffer polygon (number of segments per quadrant). Lower values create simpler polygons. Default is 2. ### Returns - A new Geofence encompassing the trace with the specified padding ### Example ```python >>> trace = Trace.from_csv('morning_commute.csv') >>> geofence = Geofence.from_trace(trace, padding=500) >>> geofence = Geofence.from_trace(trace, padding=2000, buffer_res=8) ``` ``` -------------------------------- ### Geofence class usage: from_trace, from_geojson, to_geojson Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.constructs.geofence.html Shows the main usage of the Geofence class: creating a geofence from a GPX trace with a 1km buffer, loading one from a GeoJSON file, and exporting to a GeoJSON string. Requires a Trace object and a valid GeoJSON file with CRS information. ```python >>> from mappymatch.constructs.geofence import Geofence >>> >>> # Create a geofence from a trace to download relevant map data >>> trace = Trace.from_gpx('route.gpx') >>> geofence = Geofence.from_trace(trace, padding=1000) # 1km buffer >>> >>> # Load a geofence from a GeoJSON file >>> geofence = Geofence.from_geojson('city_boundary.geojson') >>> >>> # Export to GeoJSON >>> geojson_str = geofence.to_geojson() ``` -------------------------------- ### Basic LineSnapMatcher usage Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.matchers.line_snap.html Shows how to load a road network, create a LineSnapMatcher, and match a trace. Each point is matched independently to the nearest road segment, and the distance to the road is printed for each match. ```python >>> from mappymatch.matchers.line_snap import LineSnapMatcher >>> from mappymatch.maps.nx import NxMap >>> >>> # Load a road network >>> road_map = NxMap.from_file('network.pickle') >>> >>> # Create the matcher >>> matcher = LineSnapMatcher(road_map) >>> result = matcher.match_trace(trace) >>> >>> # Each point is matched independently >>> for match in result.matches: ... print(f"Distance to road: {match.distance}m") ``` -------------------------------- ### LineSnapMatcher class definition and constructor Source: https://natlabrockies.github.io/mappymatch/_modules/mappymatch/matchers/line_snap.html Defines the LineSnapMatcher class with its constructor. The class docstring explains its purpose, use cases, and provides a usage example. ```python class LineSnapMatcher(MatcherInterface): """ A simple, fast map matcher that snaps each GPS point to the nearest road segment. This is the most basic matching approach - it independently matches each GPS coordinate to its nearest road without considering the overall trajectory or road network topology. While fast and simple to implement, it may produce unrealistic results where the matched path jumps between disconnected roads. Use this matcher when: - You need very fast matching performance - GPS data is very accurate and roads are well-separated - You only need point-to-road snapping, not path reconstruction For more sophisticated matching that considers path continuity and network topology, use LCSSMatcher, ValhallaMatcher, or OsrmMatcher instead. Args: road_map: The road network to match against (must implement MapInterface) Attributes: map: The road network being used for matching Examples: >>> from mappymatch.matchers.line_snap import LineSnapMatcher >>> from mappymatch.maps.nx import NxMap >>> >>> # Load a road network >>> road_map = NxMap.from_file('network.pickle') >>> >>> # Create the matcher >>> matcher = LineSnapMatcher(road_map) >>> result = matcher.match_trace(trace) >>> >>> # Each point is matched independently >>> for match in result.matches: ... print(f"Distance to road: {match.distance}m") """ def __init__(self, road_map: MapInterface): self.map = road_map ``` -------------------------------- ### Load a GPX trace with Trace.from_gpx Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.constructs.trace.html Shows how to create a Trace from a GPX file. The xy parameter controls whether coordinates are reprojected to Web Mercator (EPSG:3857) for distance calculations (default True) or kept in lat/lon. ```python >>> # Load a GPX track from a file >>> trace = Trace.from_gpx('morning_run.gpx') >>> >>> # Keep in lat/lon instead of projecting >>> trace_latlon = Trace.from_gpx('bike_ride.gpx', xy=False) ``` -------------------------------- ### Write a Trace to a GeoJSON file Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.constructs.trace.html Exports a Trace as a GeoJSON FeatureCollection with Point geometry, preserving CRS and index data. The example writes to 'output.geojson'. ```python >>> trace = Trace.from_csv('input.csv') >>> trace.to_geojson('output.geojson') ``` -------------------------------- ### NxMap.from_file: load from pickle or JSON Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.maps.nx.nx_map.html Shows loading a NxMap from pickle or JSON files. Pickle is recommended for large networks; JSON is human-readable and portable. Raises TypeError if the extension is not .pickle or .json. ```python >>> # Load from pickle (recommended for large networks) >>> road_map = NxMap.from_file('network.pickle') >>> >>> # Load from JSON >>> road_map = NxMap.from_file('network.json') ``` -------------------------------- ### LCSSMatcher.__init__ Source: https://natlabrockies.github.io/mappymatch/_modules/mappymatch/matchers/lcss/lcss.html Initializes an LCSSMatcher instance with the given road map and tuning parameters. The road map must implement the MapInterface. Parameters control distance matching, similarity thresholds, and cutting behavior. ```APIDOC ## LCSSMatcher.__init__ ### Description Initializes an LCSSMatcher instance with the given road map and tuning parameters. ### Method Constructor ### Signature ```python LCSSMatcher( road_map: MapInterface, distance_epsilon: float = 50.0, similarity_cutoff: float = 0.9, cutting_threshold: float = 10.0, random_cuts: int = 0, distance_threshold: float = 10000 ) ``` ### Parameters - **road_map** (MapInterface) - Required - The road network to match against. Must implement MapInterface. - **distance_epsilon** (float) - Optional - Maximum distance (in meters) for a GPS point to be considered near a road segment. Points beyond this distance contribute less to similarity. Default is 50 meters. - **similarity_cutoff** (float) - Optional - Minimum similarity score (0-1) to stop iterative refinement. Higher values demand better matching quality. Default is 0.9. - **cutting_threshold** (float) - Optional - Distance threshold (in meters) for identifying potential cutting points where trajectory should be split. Default is 10 meters. - **random_cuts** (int) - Optional - Number of random cutting points to add at each iteration for exploration. Usually 0 for deterministic results. Default is 0. - **distance_threshold** (float) - Optional - Maximum distance (in meters) for matching a point to a road. Points beyond this are left unmatched. Default is 10000 meters (10km). ### Returns None ``` -------------------------------- ### Transform a Trace to a different CRS Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.constructs.trace.html Reprojects all coordinates in a Trace to a target CRS. The example converts from EPSG:3857 to EPSG:4326, then to a UTM zone using a pyproj.CRS object. ```python >>> # Convert from Web Mercator to WGS84 lat/lon >>> trace_xy = Trace.from_csv('data.csv', xy=True) # In EPSG:3857 >>> trace_latlon = trace_xy.to_crs('EPSG:4326') >>> >>> # Convert to a UTM zone >>> from pyproj import CRS >>> utm_crs = CRS('EPSG:32618') # UTM Zone 18N >>> trace_utm = trace_latlon.to_crs(utm_crs) ``` -------------------------------- ### Downsample a trace with Trace.downsample Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.constructs.trace.html Shows how to reduce a trace to a specified number of evenly-spaced points using linear interpolation. The example reduces a 1000-point trace to 100 points. ```python >>> # Reduce a 1000-point trace to 100 points >>> long_trace = Trace.from_csv('detailed_track.csv') >>> print(len(long_trace)) # 1000 >>> short_trace = long_trace.downsample(100) >>> print(len(short_trace)) # 100 ``` -------------------------------- ### Create geofence from trace Source: https://natlabrockies.github.io/mappymatch/_sources/examples/lcss_example.ipynb Builds a geofence around the trace with a padding of 2000 meters (in the trace's projected units). ```python from mappymatch.constructs.geofence import Geofence geofence = Geofence.from_trace(trace, padding=2e3) ``` -------------------------------- ### Coordinate class definition and methods (Python) Source: https://natlabrockies.github.io/mappymatch/_modules/mappymatch/constructs/coordinate.html Full source code of the Coordinate class, including attributes, constructor, property methods, and to_crs transformation. The example demonstrates usage of Coordinate.from_lat_lon and to_crs in docstrings. ```python from __future__ import annotations import math from typing import Any, NamedTuple from pyproj import CRS, Transformer from pyproj.exceptions import ProjError from shapely.geometry import Point from mappymatch.utils.crs import LATLON_CRS [docs] class Coordinate(NamedTuple): """ Represents a single geographic coordinate point with a coordinate reference system (CRS). A Coordinate is an immutable object that combines a spatial point geometry with its coordinate reference system, allowing for accurate coordinate transformations between different projection systems. Attributes: coordinate_id: The unique identifier for this coordinate (can be any hashable type) geom: The Shapely Point geometry representing the spatial location crs: The pyproj CRS (Coordinate Reference System) defining the coordinate space x: The x-coordinate value (longitude in lat/lon systems, easting in projected systems) y: The y-coordinate value (latitude in lat/lon systems, northing in projected systems) Examples: >>> from mappymatch.constructs.coordinate import Coordinate >>> # Create a coordinate from latitude and longitude >>> coord = Coordinate.from_lat_lon(40.7128, -74.0060) >>> print(coord.x, coord.y) -74.0060 40.7128 >>> # Transform to a different CRS (Web Mercator) >>> web_mercator = coord.to_crs('EPSG:3857') >>> print(web_mercator.crs.to_epsg()) 3857 """ coordinate_id: Any geom: Point crs: CRS def __repr__(self): crs_a = self.crs.to_authority() if self.crs else "Null" return f"Coordinate(coordinate_id={self.coordinate_id}, x={self.x}, y={self.y}, crs={crs_a})" [docs] @classmethod def from_lat_lon(cls, lat: float, lon: float) -> Coordinate: """ Create a coordinate from latitude and longitude values in WGS84 (EPSG:4326). This is a convenience method for creating coordinates from standard GPS coordinates. The resulting coordinate will use the LATLON_CRS (EPSG:4326) coordinate system. Args: lat: The latitude in decimal degrees (range: -90 to 90) lon: The longitude in decimal degrees (range: -180 to 180) Returns: A new Coordinate instance in EPSG:4326 CRS with no coordinate_id Examples: >>> # New York City coordinates >>> nyc = Coordinate.from_lat_lon(40.7128, -74.0060) >>> print(f"Lat: {nyc.y}, Lon: {nyc.x}") Lat: 40.7128, Lon: -74.0060 """ return cls(coordinate_id=None, geom=Point(lon, lat), crs=LATLON_CRS) @property def x(self) -> float: return self.geom.x @property def y(self) -> float: return self.geom.y [docs] def to_crs(self, new_crs: Any) -> Coordinate: """ Transform this coordinate to a different coordinate reference system (CRS). This method reprojects the coordinate geometry from its current CRS to the target CRS using pyproj transformations. If the target CRS is the same as the current CRS, the original coordinate is returned unchanged. Args: new_crs: The target CRS. Can be a pyproj.CRS object, an EPSG code as a string (e.g., 'EPSG:4326'), an integer EPSG code, or any CRS format that pyproj.CRS() accepts Returns: A new Coordinate instance with transformed geometry in the target CRS. The coordinate_id is preserved from the original coordinate. Raises: ValueError: If the new_crs cannot be parsed into a valid CRS, or if the transformation results in infinite coordinate values (indicating an invalid transformation) Examples: >>> # Transform from lat/lon to Web Mercator >>> coord = Coordinate.from_lat_lon(40.7128, -74.0060) >>> mercator_coord = coord.to_crs('EPSG:3857') >>> >>> # Transform using EPSG integer code >>> utm_coord = coord.to_crs(32618) # UTM Zone 18N """ # convert the incoming crs to an pyproj.crs.CRS object; this could fail try: new_crs = CRS(new_crs) except ProjError as e: raise ValueError( f"Could not parse incoming `new_crs` parameter: {new_crs}" ) from e if new_crs == self.crs: return self transformer = Transformer.from_crs(self.crs, new_crs) new_x, new_y = transformer.transform(self.geom.y, self.geom.x) if math.isinf(new_x) or math.isinf(new_y): raise ValueError( f"Unable to convert {self.crs} ({self.geom.x}, {self.geom.y}) -> {new_crs} ({new_x}, {new_y})" ) return Coordinate( coordinate_id=self.coordinate_id, geom=Point(new_x, new_y), crs=new_crs, ) ``` -------------------------------- ### Trace.__init__ Source: https://natlabrockies.github.io/mappymatch/_modules/mappymatch/constructs/trace.html Initializes a Trace instance from a GeoDataFrame, validating that the index has no duplicates. ```APIDOC ## Trace.__init__ ### Description Initializes a Trace instance from a GeoDataFrame. Raises an IndexError if the index contains duplicate values. ### Method Constructor ### Parameters - **frame** (GeoDataFrame) - Required - The GeoDataFrame containing point geometries for the trajectory. ### Exceptions - **IndexError** - If the index of the frame contains duplicate values. ### Example ```python trace = Trace(frame) ``` ``` -------------------------------- ### NxMap basic usage: load, create, query, save Source: https://natlabrockies.github.io/mappymatch/_autosummary/mappymatch.maps.nx.nx_map.html Shows typical NxMap usage: loading from a pickle, creating from a geofence with OSMnx data, performing routing and nearest-road queries, and saving back to a file. Requires a pyproj CRS in graph.graph['crs'] and road geometries. ```python >>> from mappymatch.maps.nx import NxMap >>> from mappymatch.constructs.geofence import Geofence >>> >>> # Load from a saved file >>> road_map = NxMap.from_file('network.pickle') >>> >>> # Create from OpenStreetMap data >>> geofence = Geofence.from_geojson('study_area.geojson') >>> road_map = NxMap.from_geofence( ... geofence, ... network_type=NetworkType.DRIVE, ... xy=True # Use Web Mercator for accurate distances ... ) >>> >>> # Use the map for routing and queries >>> nearest = road_map.nearest_road(coordinate) >>> path = road_map.shortest_path(origin, destination) >>> >>> # Save for later use >>> road_map.to_file('network.pickle') ```