netload
A lightweight, dependency-light Python parser for .net network files (PTV Visum / Simetra
and other .net text exports).
It reads the structured text tables of a .net file directly, without requiring PTV Visum to be
installed, exposes every table as a Pandas DataFrame, and can transform any table (or the whole
file) into CSV, JSON or GeoJSON.
Disclaimer: This project is independent and is not affiliated with, endorsed by, or supported by PTV Group or its partners.
PTV Visumis a registered trademark of PTV Group.
Features
- Parses
.netfiles generically:NODE,LINK,ZONE,TURN,USERATTDEFand any other table present in the file. - No PTV Visum required.
- Every table is exposed as a real
pandas.DataFrame. - Automatic encoding detection (UTF-8 with/without BOM, Windows-1251/CP1251, UTF-16), so Russian and other non-ASCII content is read correctly.
- Robust to comments (
*), blank lines, BOM markers and missing values. - Export the whole file to CSV, JSON or GeoJSON in one call.
- Transform a single table to CSV / JSON / GeoJSON (via the API or the CLI).
- GeoJSON conversion uses WKT columns (
WKTSURFACE,WKTPOLY,GEOMETRY) orXCOORD/YCOORDwith a built-in WKT parser (no shapely needed). - List every table with its fields (columns).
- Small command-line interface.
Installation
pip install netload
Quick example
from netload import read_net
network = read_net("model.net")
print(network.table_names)
print(network.nodes.head())
network.export_csv("./output")
Resulting files:
output/
├── NODE.csv
├── LINK.csv
├── ZONE.csv
└── TURN.csv
API
Reading
from netload import read_net
network = read_net("model.net") # auto-detect encoding
network = read_net("model.net", encoding="cp1251")
network = read_net("model.net", infer_types=True) # light numeric inference
The returned Network object:
| Member | Description |
|---|---|
network.tables |
dict of table name → Table (preserves file order) |
network.table_names |
list[str] of table names |
network.has_table(x) |
whether table x exists |
network.get_table(x) |
DataFrame of table x |
network[x] |
DataFrame of table x |
network.nodes |
DataFrame of NODE (if present) |
network.links |
DataFrame of LINK (if present) |
network.zones |
DataFrame of ZONE (if present) |
network.turns |
DataFrame of TURN (if present) |
network.to_dict() |
dict[str, pd.DataFrame] |
network.export_csv() |
writes one CSV per table (see below) |
network.export_json() |
writes one JSON per table (see below) |
network.export_geojson() |
writes GeoJSON for tables with geometry (see below) |
Export CSV
network.export_csv("./output", sep=";", encoding="utf-8")
Tables without any data row are skipped by default (skip_empty=False to include them).
Export a single table (or a subset)
By default all tables are exported. Pass tables=[...] to export only specific tables:
network.export_csv("./output", tables=["NODE"]) # NODE.csv only
network.export_csv("./output", tables=["NODE", "LINK"]) # NODE.csv + LINK.csv
network.export_json("./output", tables=["ZONE"])
network.export_geojson("./output", tables=["ZONE", "LINK"])
The same applies to the CLI with --tables NODE,LINK.
Export JSON
network.export_json("./output") # writes NODE.json, LINK.json, ZONE.json, ...
Each file contains a JSON array of records (Russian characters are kept as-is, not escaped).
Export GeoJSON
network.export_geojson("./output") # writes NODE.geojson, ZONE.geojson, LINK.geojson, ...
Tables that have geometry are exported as GeoJSON FeatureCollection files:
- tables with a WKT column (
WKTSURFACE,WKTPOLY,GEOMETRY) use its geometry (e.g.ZONE→MultiPolygon,LINK→LineString); - tables with
XCOORD/YCOORDbecome Point features (e.g.NODE); - tables without any geometry are skipped.
Transform a single table
from netload.exporters import export_table_csv, export_table_json, export_table_geojson
export_table_json(network["NODE"], "node.json")
export_table_geojson(network["ZONE"], "zone.geojson")
export_table_csv(network["LINK"], "link.csv")
Errors
from netload import VisumNetError, VisumNetParseError, VisumNetEncodingError
- Missing file →
FileNotFoundError - Invalid structure →
VisumNetParseError(includes file path and line number) - Undecodable file →
VisumNetEncodingError
CLI
netload model.net
Visum network loaded successfully
Tables:
- NODE: 1542 rows
- LINK: 3210 rows
- ZONE: 145 rows
- TURN: 872 rows
List tables with their fields:
netload model.net --list-tables
Tables and fields:
- NODE: 1542 rows
fields: NO, NAME, CONTROLTYPE, T0PRT, ...
Preview a table (fields + first 5 rows by default):
netload model.net --preview NODE
netload model.net --preview NODE --rows 10
Export everything:
netload model.net --export-csv ./output
netload model.net --export-json ./output
netload model.net --export-geojson ./output
Export only specific tables (default: all):
netload model.net --export-csv ./output --tables NODE,LINK
netload model.net --export-json ./output --tables ZONE
Transform a single table:
netload model.net --table NODE --to-csv node.csv
netload model.net --table NODE --to-json node.json
netload model.net --table ZONE --to-geojson zone.geojson
Force a file encoding:
netload model.net --encoding cp1251 --list-tables
Tables
The parser is generic: it does not hard-code the set of supported tables. Any section starting
with $ is parsed and made available, for example:
NODELINKZONETURNMAINTURNCONNECTORLINKTYPETSYSLINE,LINEROUTE,TIMEPROFILE,VEHJOURNEY, …USERATTDEFVERSION,NETWORK, …
If a file contains a table that is not listed here, it is parsed and exposed the same way.
How it works
- The file bytes are read and the encoding is detected (BOM first, then UTF-8, then CP1251).
- The text is scanned line by line.
- A line starting with
$NAME:COL1;COL2;...opens a new table with its columns. - Following non-comment, non-blank lines are parsed as
;-separated data rows. - Each table becomes a
pandas.DataFrame(original string values are preserved by default).
Limitations (v0.1.0)
- Values are treated as
;-separated fields; quoted fields containing the separator character are not yet supported. - Optional light numeric type inference is available via
infer_types=True, but the default preserves the original string values to avoid any data corruption. - Multi-line records and nested sub-tables are not supported yet.
- The built-in WKT parser covers
POINT,LINESTRING,POLYGON,MULTIPOINT,MULTILINESTRINGandMULTIPOLYGON(the geometry types used by.netfiles).
Development
python -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/python -m pytest
License
MIT. See LICENSE.
Disclaimer
This project is independent and not affiliated with PTV Group. PTV Visum is a registered trademark of PTV Group. This package is provided "as is", without any warranty.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file netload-0.1.1.tar.gz.
File metadata
- Download URL: netload-0.1.1.tar.gz
- Upload date:
- Size: 21.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7713dab180485bc9f70ae43e76a6efe6301eeafd0310a7bc1e9f30d144be350
|
|
| MD5 |
2fe7040d20e0d9088e4b1e531b25fbf1
|
|
| BLAKE2b-256 |
a726dfe3fbf61a3c9bb5543aa8c2df6afda4acdf4fa7390ede2be29d7ebf6a69
|
File details
Details for the file netload-0.1.1-py3-none-any.whl.
File metadata
- Download URL: netload-0.1.1-py3-none-any.whl
- Upload date:
- Size: 18.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5595fab3c6958c4d9e1718414655cca39e94f0a98b25c5d56efae0a367e583ad
|
|
| MD5 |
4b42e87107af5c2819cf9c97b29c533b
|
|
| BLAKE2b-256 |
8e03ab3faf5855fe461cbf9985a5acd26e9fdac9127147a0083b0b2ddaa387e8
|