How natlabrockies/mappymatch works
1. What the package is
- mappymatch is a pure-Python map-matching library whose core job is to take a GPS trace and align it to a road network.
- The architecture is centered on a small domain model, pluggable map backends, and multiple matcher implementations.
2. Core domain layer
- The constructs package defines the shared data model used by all matchers and maps: Coordinate, Trace, Geofence, Road, and Match.
- These objects are the main boundary between raw inputs, map data, and matcher outputs.
3. Trace ingestion and preprocessing
- Trace data is typically loaded from CSV or geospatial files into Trace objects.
- utils/process_trace.py and related helpers handle trace normalization and preparation steps such as coordinate handling, stationary-point logic, and geometric utilities.
- This layer is where raw GPS points become matcher-ready input.
4. Map abstraction layer
- maps/map_interface.py defines the common map contract.
- There are concrete map adapters for:
- maps/nx/NxMap for NetworkX-based road graphs
- maps/igraph/IGraphMap for igraph-based graphs
- This abstraction lets matchers work against a common map API instead of binding to one graph library.
5. OpenStreetMap acquisition
- maps/nx/readers/osm_readers.py is the OSM ingestion path for the NetworkX backend.
- The typical flow is: build a Geofence around a trace, query OSM data within that boundary, and construct an in-memory road network.
- In practice, the repository’s primary map source is OpenStreetMap.
6. Matcher subsystem
- matchers/matcher_interface.py defines the matcher boundary.
- The repo contains three matcher families:
- LCSSMatcher in matchers/lcss/
- OsrmMatcher
- ValhallaMatcher
- This is the main strategy layer: each matcher consumes the same trace/map abstractions but produces matches through a different algorithm or service.
7. LCSS matcher internals
- The lcss package is the most substantial in-repo algorithm implementation.
- It contains the algorithm, helper operations, and internal constructs used for segmentation/sequence alignment.
- This matcher is local and offline: it runs entirely in Python against the in-memory road graph, making it the repo’s most self-contained matching path.
8. External service-based matchers
- OsrmMatcher and ValhallaMatcher are thin clients over external routing/map-matching engines.
- They introduce a network boundary: trace data is serialized, sent to a running OSRM or Valhalla service, and the returned match result is converted back into the package’s internal Match representation.
- These matchers depend on service availability and remote API compatibility, unlike LCSS.
9. Match results
- matchers/match_result.py is the common output container for all matchers.
- It acts as the integration point for downstream analysis, including conversion to tabular form via pandas-like dataframe workflows.
- This keeps result consumption separate from algorithm execution.
10. Geometry, CRS, and geo utilities
- utils/crs.py, utils/geo.py, and utils/url.py support coordinate system handling, geometric calculations, and request construction.
- These utilities are shared infrastructure used by trace processing, geofence creation, map loading, and service-backed matchers.
11. Plotting and visualization
- utils/plot/ contains visualization helpers for maps, traces, geofences, paths, trajectory segments, and matches.
- This is a presentation layer, not part of the core matching pipeline, but it is important for debugging and explaining results.
12. Data and example assets
- resources/traces/ provides sample trace CSVs used in examples and tests.
- tests/test_assets/ includes OSM graph and geospatial fixtures, showing the intended offline testing path for map and trace behavior.
- These assets indicate the library is designed to be exercised both with real OSM-derived graphs and small reproducible fixtures.
13. Typical end-to-end flow
- The canonical architecture path is:
- load a Trace
- derive a Geofence
- build or load a map backend (NxMap or IGraphMap)
- run a matcher (LCSSMatcher, OSRM, or Valhalla)
- consume a MatchResult
- This is the key pipeline to show in an architecture diagram.
14. Repository boundary and delivery
- The project ships as a Python package with docs and automated testing.
- Documentation lives under docs/, and the test suite covers trace handling, geo logic, OSM integration, matchers, and result behavior.
- The package is therefore a library architecture, not a server or application architecture.
Main entry points: lcss.py LCSSMatcher · process_trace.py Trace prep · match_result.py MatchResult · trace.py Trace
Components 23
Core domain
Shared trace, road, geofence, and match objects used across the library
- Coordinate · Single GPS or projected point used throughout the package
mappymatch/constructs/coordinate.py - Trace · Ordered GPS trajectory input for matching
mappymatch/constructs/trace.py - Geofence · Area of interest derived from a trace or used to constrain map loading
mappymatch/constructs/geofence.py - Road · Road-network element shared by map adapters and matchers
mappymatch/constructs/road.py - Match · Matched trace output emitted by matching algorithms
mappymatch/constructs/match.py
Map backends
Abstract map contract plus concrete graph-based adapters and OSM ingestion
- Map API · Common contract implemented by all map backends
mappymatch/maps/map_interface.py - NxMap · In-memory road graph backend built on NetworkX
mappymatch/maps/nx/nx_map.py - OSM reader · Builds NetworkX road graphs from OpenStreetMap data inside a geofence
mappymatch/maps/nx/readers/osm_readers.py - IGraphMap · In-memory road graph backend built on igraph
mappymatch/maps/igraph/igraph_map.py
Matchers
Local and service-backed matching strategies
- Matcher API · Common interface implemented by all matcher strategies
mappymatch/matchers/matcher_interface.py - LCSSMatcher · Offline Python matcher using LCSS-style sequence alignment over a map graph
mappymatch/matchers/lcss/lcss.py - LCSS ops · Internal alignment and merge operations for the LCSS matcher
mappymatch/matchers/lcss/ops.py - LCSS constructs · Internal constructs and segmentation state used by LCSS
mappymatch/matchers/lcss/constructs.py - OsrmMatcher · Client wrapper for external OSRM map-matching service
mappymatch/matchers/osrm.py - ValhallaMatcher · Client wrapper for external Valhalla map-matching service
mappymatch/matchers/valhalla.py - MatchResult · Common output object returned by matchers and consumed downstream
mappymatch/matchers/match_result.py
Support
Trace processing, geo utilities, plotting, and packaged assets
- Trace prep · Normalizes trace input and handles stationary-point and geometry preparation
mappymatch/utils/process_trace.py - Geo utils · Coordinate system, geometry, and spatial helper functions
mappymatch/utils/geo.py - CRS utils · Coordinate reference system conversion and handling
mappymatch/utils/crs.py - URL utils · Builds service request URLs for external matchers
mappymatch/utils/url.py - Plotting · Helpers for drawing traces, maps, geofences, paths, and matches
mappymatch/utils/plot/map.py - Sample traces · Packaged trace CSV examples used in docs and examples
mappymatch/resources/traces/sample_trace_1.csv - Test assets · GeoJSON, GPX, and graph fixtures for offline validation
tests/test_assets/osmnx_drive_graph.graphml
Connections 30
- Trace → Trace prep: prepared by · Raw trace input is normalized before matching
- Trace prep → Coordinate: emits · Trace preprocessing operates on coordinate objects
- Trace prep → Geofence: derives · A geofence is commonly built around the trace extent
- Geofence → OSM reader: bounds query · OpenStreetMap acquisition is constrained to the geofence
- OSM reader → NxMap: builds · OSM data is converted into an in-memory NetworkX map
- Map API → NxMap: implements · NetworkX backend satisfies the shared map contract
- Map API → IGraphMap: implements · igraph backend satisfies the shared map contract
- NxMap → Road: contains · Road segments are represented inside the graph backend
- IGraphMap → Road: contains · Road segments are represented inside the graph backend
- Matcher API → LCSSMatcher: implements · LCSS is a concrete matcher strategy
- Matcher API → OsrmMatcher: implements · OSRM is a concrete matcher strategy
- Matcher API → ValhallaMatcher: implements · Valhalla is a concrete matcher strategy
- LCSSMatcher → LCSS ops: uses · Core algorithm delegates to internal operations
- LCSSMatcher → LCSS constructs: uses · Alignment state and segmentation constructs support the matcher
- LCSSMatcher → Map API: consumes · Local matching runs against the common map API
- OsrmMatcher → URL utils: serializes · Request construction supports the external service call
- ValhallaMatcher → URL utils: serializes · Request construction supports the external service call
- OsrmMatcher → MatchResult: returns · Service response is converted into the shared result object
- ValhallaMatcher → MatchResult: returns · Service response is converted into the shared result object
- LCSSMatcher → MatchResult: returns · Offline matcher emits the shared result object
- MatchResult → Match: wraps · MatchResult packages the domain match output
- Geo utils → CRS utils: uses · Spatial helpers depend on CRS handling
- Trace prep → Geo utils: uses · Trace preprocessing relies on shared geometry helpers
- Trace prep → CRS utils: uses · Trace preprocessing relies on projection utilities
- Plotting → Trace: renders · Visualization helpers draw traces and trajectories
- Plotting → Geofence: renders · Visualization helpers draw map boundaries
- Plotting → MatchResult: renders · Visualization helpers display matches
- Sample traces → Trace: example input · Packaged CSV traces demonstrate the expected trace format
- Test assets → NxMap: fixture input · Graph fixtures exercise the map backend
- Test assets → Trace: fixture input · Trace fixtures exercise ingestion and preprocessing