MapMatcher4GMNS
A high-performance map matching tool for GPS trajectories on GMNS (General Modeling Network Specification) networks.
Features
- High-Performance Map Matching: Efficient Hidden Markov Model (HMM) based map matching algorithm
- GMNS Network Support: Native support for GMNS network format (node.csv, link.csv)
- Multi-Core Processing: Built-in parallel processing support for large-scale GPS data
- Flexible Configuration: Comprehensive parameters for fine-tuning matching quality
- Route Generation: Automatic generation of complete routes between matched points
- GMNS Identifier Preservation: Supports numeric, alphanumeric, and zero-padded
link_idvalues - Robust Time Parsing: Supports offset-aware text timestamps and numeric Unix epochs across pandas versions
Installation
From PyPI
pip install mapmatcher4gmns
Quick Start
import mapmatcher4gmns as m4g
def main():
# Load network from GMNS format
net = m4g.LoadNetFromCSV(
folder='path/to/network',
node_file='node.csv',
link_file='link.csv'
)
# Create matcher
matcher = m4g.MapMatcher(
network=net,
time_field='timestamp',
time_format='%Y-%m-%dT%H:%M:%S.%fZ',
out_dir='output',
result_file='matched_result.csv',
route_file='matched_route.csv',
)
# Perform map matching (pass CSV path)
matcher.match('gps_data.csv')
# Note: match(...) accepts CSV path string input.
if __name__ == '__main__':
main()
Input Data Requirements
Network Files (GMNS Format)
node.csv (required fields):
node_id: Unique node identifierx_coord: Longitude (if coordinate_type='lonlat') or X coordinatey_coord: Latitude (if coordinate_type='lonlat') or Y coordinate
link.csv (required fields):
link_id: Unique integer or string identifier. Values such as193912ABand zero-padded IDs such as0007are preserved.from_node_id: Starting node IDto_node_id: Ending node IDlanes: Number of lanesgeometry: LineString geometry in WKT format
GPS Data
Required fields:
journey_id(or custom agent_field): Unique identifier for each GPS trajectorylongitude: GPS longitudelatitude: GPS latitude
Optional but recommended:
time(or custom time_field): Timestamp for temporal orderingspeed: Speedheading: Heading direction in degrees
Timestamp Handling
Set time_format when the input uses a known text format. If time_format is
omitted, text timestamps are parsed automatically and normalized to UTC
internally. Numeric values, including numeric strings, are treated as Unix
epochs; the package infers seconds, milliseconds, microseconds, or nanoseconds
from their magnitude. This prevents Unix seconds from being silently treated as
nanoseconds.
Configuration Parameters
Core Matching Parameters
search_radius(default: 15.0): Search radius in meters for candidate linksnoise_sigma(default: 8.0): GPS noise standard deviation in meterstrans_weight(default: 12.0): Weight for transition probabilitymax_candidates(default: 10): Maximum number of candidate links per GPS point
Movement Consistency
turn_sigma(default: 45.0): Turn angle standard deviation in degreesheading_sigma(default: 30.0): Heading difference standard deviationuse_heading(default: True): Whether to use heading information
Filtering
filter_dwell(default: False): Filter out stationary pointsdwell_dist(default: 5.0): Distance threshold for dwell detection in metersdwell_count(default: 2): Minimum consecutive points to be considered dwellingmax_gap_seconds(default: 45.0): Maximum time gap allowed between consecutive pointsfused_point: If this input column exists, rows withfused_point=Trueare automatically excluded from matching
Performance
core_num: Number of CPU cores to use (default: 1). If set aboveos.cpu_count(), it is capped to available CPU cores. Each process builds its own network graph and spatial index, so start with one worker for large networks and increase only after measuring memory and runtime.max_agents(default: None): Maximum number of trajectories to process (useful for testing/debugging). If set, only the first N trajectories will be matched
Output
The tool generates two main output files:
1. Matched Results (matched_result.csv)
Contains the matched GPS points with:
journey_id: Trajectory identifierseq: Sequence numbertime: Timestamplink_id: Matched link IDfrom_node_id,to_node_id: Link endpointslongitude,latitude: Original GPS coordinatesspeed_mph: Speed (if provided)match_heading: Heading of matched linkroute_dis: Cumulative route distance
2. Route File (matched_route.csv)
Contains the complete route for each journey:
journey_id: Trajectory identifierlink_ids: Comma-separated list of link IDs forming the complete route
3. Run Summary (summary.txt)
Contains run-level summary statistics:
- Input/kept/dropped/matched journeys
- Input/matched data points and match rate
- Total elapsed time
Advanced Usage
Note: When using multiprocessing features, wrap your code in if __name__ == '__main__': to avoid issues, especially on Windows.
Multi-Core Processing
matcher = m4g.MapMatcher(
network=net,
core_num=2, # Use 2 CPU cores
# ... other parameters
)
Multiprocessing is most useful when the network is modest relative to available memory. For very large GMNS networks, worker-local copies of the NetworkX graph and spatial index can make several workers slower than one.
Large CSV (Memory-Safe Streaming)
For very large GPS files (for example, 100M+ rows), avoid loading all rows
into memory at once. Pass CSV path directly to match(...).
In streaming mode, the matcher internally hashes journey_id into temporary
partitions first, then processes partition files. This keeps the same
journey_id in one partition without requiring a global CSV sort.
matcher = m4g.MapMatcher(
network=net,
time_field='local_time',
time_format='%Y-%m-%dT%H:%M:%S%z',
out_dir='output',
result_file='matched_result.csv',
route_file='matched_route.csv',
core_num=1,
)
matcher.match('data.csv')
Custom Field Names
matcher = m4g.MapMatcher(
network=net,
agent_field='vehicle_id', # Custom trajectory ID field
lng_field='lon', # Custom longitude field
lat_field='lat', # Custom latitude field
time_field='timestamp', # Custom time field
# ... other parameters
)
Extra Fields
Keep additional fields from input GPS data in the output:
matcher = m4g.MapMatcher(
network=net,
extra_fields=['vehicle_type', 'driver_id', 'trip_purpose'],
# ... other parameters
)
Requirements
- Python >= 3.8
- numpy >= 1.20.0
- pandas >= 1.3.0
- shapely >= 2.0.0
- geopandas >= 0.10.0
- networkx >= 2.6.0
- tqdm >= 4.60.0
Citation
If you use this tool in your research, please cite this tool.
Suggested citation:
Liu, Y., & Zhou, X. (2026). MapMatcher4GMNS: A high-performance map matching tool for GMNS networks (Version 0.2.1) [Computer software]. https://github.com/yajunliu99/mapmatcher4gmns
BibTeX:
@software{liu_zhou_mapmatcher4gmns_2026,
author = {Liu, Yajun and Zhou, Xuesong (Simon)},
title = {MapMatcher4GMNS: A High-Performance Map Matching Tool for GMNS Networks},
year = {2026},
version = {0.2.1},
url = {https://github.com/yajunliu99/mapmatcher4gmns},
note = {Python software package}
}
Authors
- Yajun Liu (
yajunliu@asu.edu) - Xuesong (Simon) Zhou (
xzhou74@asu.edu)
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Acknowledgments
This package was inspired by and references the excellent work of the TrackIt (GoTrackIt) project. We are grateful for their contributions to the open-source map matching community and their innovative approach to HMM-based map matching algorithms.
References
- TrackIt/GoTrackIt: A comprehensive map matching Python package based on Hidden Markov Model (HMM)
- GitHub: https://github.com/zdsjjtTLG/TrackIt
- Documentation: https://gotrackit.readthedocs.io/
- Developed by: TangKai and contributors at Hangzhou Zecheng Data Technology Co., Ltd.
This tool is designed to work with the General Modeling Network Specification (GMNS) format, supporting transportation network analysis and GPS trajectory processing.
Support
For questions, issues, or feature requests, please use the
GitHub repository or contact
Yajun Liu (yajunliu@asu.edu) and Xuesong (Simon) Zhou (xzhou74@asu.edu).
Metadata
Release files for mapmatcher4gmns 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mapmatcher4gmns-0.2.1.tar.gz | 48.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mapmatcher4gmns-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 96.5 kB
Release files / mapmatcher4gmns-0.2.1.tar.gz
| Download URL | mapmatcher4gmns-0.2.1.tar.gz |
|---|---|
| Size | 48.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f8921093f891e315ac3ea7a86bc5bcb1494b5945dba1758dc7d056e85b86b6d3
|
|
BLAKE2b-256 checksum How to use checksums |
009a037c830d3066bfbbf2b6dca443e71a59d621da247611dab5df7f5803296c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.0
|
Release files / mapmatcher4gmns-0.2.1-py3-none-any.whl
| Download URL | mapmatcher4gmns-0.2.1-py3-none-any.whl |
|---|---|
| Size | 47.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
02cc4d77d982615f4800048ac9cfa23ccdd986350a61232f1344e0bdd0513b9b
|
|
BLAKE2b-256 checksum How to use checksums |
9adc6f3859b312404d8601725cdec282813667d1ee95998571ebb1c06eb36f5f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.0
|
Security for mapmatcher4gmns 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.