netload 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- netload-0.1.0/LICENSE +21 -0
- netload-0.1.0/PKG-INFO +295 -0
- netload-0.1.0/README.md +262 -0
- netload-0.1.0/pyproject.toml +65 -0
- netload-0.1.0/setup.cfg +4 -0
- netload-0.1.0/src/netload/__init__.py +68 -0
- netload-0.1.0/src/netload/cli.py +182 -0
- netload-0.1.0/src/netload/exceptions.py +45 -0
- netload-0.1.0/src/netload/exporters.py +249 -0
- netload-0.1.0/src/netload/network.py +200 -0
- netload-0.1.0/src/netload/parser.py +221 -0
- netload-0.1.0/src/netload/py.typed +0 -0
- netload-0.1.0/src/netload/table.py +55 -0
- netload-0.1.0/src/netload/wkt.py +119 -0
- netload-0.1.0/src/netload.egg-info/PKG-INFO +295 -0
- netload-0.1.0/src/netload.egg-info/SOURCES.txt +22 -0
- netload-0.1.0/src/netload.egg-info/dependency_links.txt +1 -0
- netload-0.1.0/src/netload.egg-info/entry_points.txt +2 -0
- netload-0.1.0/src/netload.egg-info/requires.txt +6 -0
- netload-0.1.0/src/netload.egg-info/top_level.txt +1 -0
- netload-0.1.0/tests/test_exporters.py +215 -0
- netload-0.1.0/tests/test_network.py +91 -0
- netload-0.1.0/tests/test_parser.py +149 -0
- netload-0.1.0/tests/test_wkt.py +67 -0
netload-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Djengoo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
netload-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: netload
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A lightweight Python parser for .net network files (PTV Visum / Simetra), with CSV, JSON and GeoJSON export.
|
|
5
|
+
Author-email: Djengoo <contact@djengoo.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/kupidon06/visum_parser
|
|
8
|
+
Project-URL: Repository, https://github.com/kupidon06/visum_parser
|
|
9
|
+
Project-URL: Documentation, https://github.com/kupidon06/visum_parser#readme
|
|
10
|
+
Project-URL: Issues, https://github.com/kupidon06/visum_parser/issues
|
|
11
|
+
Keywords: visum,ptv,net,parser,network,transportation,pandas
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: pandas>=1.5
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
30
|
+
Requires-Dist: build>=1; extra == "dev"
|
|
31
|
+
Requires-Dist: twine>=5; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# netload
|
|
35
|
+
|
|
36
|
+
A lightweight, dependency-light **Python parser for `.net` network files** (PTV Visum / Simetra
|
|
37
|
+
and other `.net` text exports).
|
|
38
|
+
|
|
39
|
+
It reads the structured text tables of a `.net` file directly, without requiring PTV Visum to be
|
|
40
|
+
installed, exposes every table as a **Pandas `DataFrame`**, and can transform any table (or the whole
|
|
41
|
+
file) into **CSV**, **JSON** or **GeoJSON**.
|
|
42
|
+
|
|
43
|
+
> **Disclaimer:** This project is **independent** and is **not affiliated with, endorsed by, or
|
|
44
|
+
> supported by PTV Group** or its partners. `PTV Visum` is a registered trademark of PTV Group.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Features
|
|
49
|
+
|
|
50
|
+
- Parses `.net` files generically: `NODE`, `LINK`, `ZONE`, `TURN`, `USERATTDEF` and **any other table**
|
|
51
|
+
present in the file.
|
|
52
|
+
- No PTV Visum required.
|
|
53
|
+
- Every table is exposed as a real `pandas.DataFrame`.
|
|
54
|
+
- Automatic encoding detection (UTF-8 with/without BOM, Windows-1251/CP1251, UTF-16), so Russian and
|
|
55
|
+
other non-ASCII content is read correctly.
|
|
56
|
+
- Robust to comments (`*`), blank lines, BOM markers and missing values.
|
|
57
|
+
- Export the whole file to **CSV**, **JSON** or **GeoJSON** in one call.
|
|
58
|
+
- Transform a single table to CSV / JSON / GeoJSON (via the API or the CLI).
|
|
59
|
+
- GeoJSON conversion uses WKT columns (`WKTSURFACE`, `WKTPOLY`, `GEOMETRY`) or `XCOORD`/`YCOORD`
|
|
60
|
+
with a built-in WKT parser (no shapely needed).
|
|
61
|
+
- List every table with its fields (columns).
|
|
62
|
+
- Small command-line interface.
|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install netload
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Quick example
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from netload import read_net
|
|
74
|
+
|
|
75
|
+
network = read_net("model.net")
|
|
76
|
+
|
|
77
|
+
print(network.table_names)
|
|
78
|
+
|
|
79
|
+
print(network.nodes.head())
|
|
80
|
+
|
|
81
|
+
network.export_csv("./output")
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Resulting files:
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
output/
|
|
88
|
+
├── NODE.csv
|
|
89
|
+
├── LINK.csv
|
|
90
|
+
├── ZONE.csv
|
|
91
|
+
└── TURN.csv
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## API
|
|
95
|
+
|
|
96
|
+
### Reading
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from netload import read_net
|
|
100
|
+
|
|
101
|
+
network = read_net("model.net") # auto-detect encoding
|
|
102
|
+
network = read_net("model.net", encoding="cp1251")
|
|
103
|
+
network = read_net("model.net", infer_types=True) # light numeric inference
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The returned `Network` object:
|
|
107
|
+
|
|
108
|
+
| Member | Description |
|
|
109
|
+
| ---------------------- | ------------------------------------------------------ |
|
|
110
|
+
| `network.tables` | `dict` of table name → `Table` (preserves file order) |
|
|
111
|
+
| `network.table_names` | `list[str]` of table names |
|
|
112
|
+
| `network.has_table(x)` | whether table `x` exists |
|
|
113
|
+
| `network.get_table(x)` | DataFrame of table `x` |
|
|
114
|
+
| `network[x]` | DataFrame of table `x` |
|
|
115
|
+
| `network.nodes` | DataFrame of `NODE` (if present) |
|
|
116
|
+
| `network.links` | DataFrame of `LINK` (if present) |
|
|
117
|
+
| `network.zones` | DataFrame of `ZONE` (if present) |
|
|
118
|
+
| `network.turns` | DataFrame of `TURN` (if present) |
|
|
119
|
+
| `network.to_dict()` | `dict[str, pd.DataFrame]` |
|
|
120
|
+
| `network.export_csv()` | writes one CSV per table (see below) |
|
|
121
|
+
| `network.export_json()`| writes one JSON per table (see below) |
|
|
122
|
+
| `network.export_geojson()` | writes GeoJSON for tables with geometry (see below) |
|
|
123
|
+
|
|
124
|
+
### Export CSV
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
network.export_csv("./output", sep=";", encoding="utf-8")
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Tables without any data row are skipped by default (`skip_empty=False` to include them).
|
|
131
|
+
|
|
132
|
+
### Export a single table (or a subset)
|
|
133
|
+
|
|
134
|
+
By default **all tables** are exported. Pass `tables=[...]` to export only specific tables:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
network.export_csv("./output", tables=["NODE"]) # NODE.csv only
|
|
138
|
+
network.export_csv("./output", tables=["NODE", "LINK"]) # NODE.csv + LINK.csv
|
|
139
|
+
network.export_json("./output", tables=["ZONE"])
|
|
140
|
+
network.export_geojson("./output", tables=["ZONE", "LINK"])
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The same applies to the CLI with `--tables NODE,LINK`.
|
|
144
|
+
|
|
145
|
+
### Export JSON
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
network.export_json("./output") # writes NODE.json, LINK.json, ZONE.json, ...
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Each file contains a JSON array of records (Russian characters are kept as-is, not escaped).
|
|
152
|
+
|
|
153
|
+
### Export GeoJSON
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
network.export_geojson("./output") # writes NODE.geojson, ZONE.geojson, LINK.geojson, ...
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Tables that have geometry are exported as GeoJSON `FeatureCollection` files:
|
|
160
|
+
|
|
161
|
+
- tables with a WKT column (`WKTSURFACE`, `WKTPOLY`, `GEOMETRY`) use its geometry
|
|
162
|
+
(e.g. `ZONE` → `MultiPolygon`, `LINK` → `LineString`);
|
|
163
|
+
- tables with `XCOORD`/`YCOORD` become Point features (e.g. `NODE`);
|
|
164
|
+
- tables without any geometry are skipped.
|
|
165
|
+
|
|
166
|
+
### Transform a single table
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
from netload.exporters import export_table_csv, export_table_json, export_table_geojson
|
|
170
|
+
|
|
171
|
+
export_table_json(network["NODE"], "node.json")
|
|
172
|
+
export_table_geojson(network["ZONE"], "zone.geojson")
|
|
173
|
+
export_table_csv(network["LINK"], "link.csv")
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Errors
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from netload import VisumNetError, VisumNetParseError, VisumNetEncodingError
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
- Missing file → `FileNotFoundError`
|
|
183
|
+
- Invalid structure → `VisumNetParseError` (includes file path and line number)
|
|
184
|
+
- Undecodable file → `VisumNetEncodingError`
|
|
185
|
+
|
|
186
|
+
## CLI
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
netload model.net
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
Visum network loaded successfully
|
|
194
|
+
|
|
195
|
+
Tables:
|
|
196
|
+
- NODE: 1542 rows
|
|
197
|
+
- LINK: 3210 rows
|
|
198
|
+
- ZONE: 145 rows
|
|
199
|
+
- TURN: 872 rows
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
List tables with their fields:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
netload model.net --list-tables
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
```text
|
|
209
|
+
Tables and fields:
|
|
210
|
+
- NODE: 1542 rows
|
|
211
|
+
fields: NO, NAME, CONTROLTYPE, T0PRT, ...
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Export everything:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
netload model.net --export-csv ./output
|
|
218
|
+
netload model.net --export-json ./output
|
|
219
|
+
netload model.net --export-geojson ./output
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Export only specific tables (default: all):
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
netload model.net --export-csv ./output --tables NODE,LINK
|
|
226
|
+
netload model.net --export-json ./output --tables ZONE
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Transform a single table:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
netload model.net --table NODE --to-csv node.csv
|
|
233
|
+
netload model.net --table NODE --to-json node.json
|
|
234
|
+
netload model.net --table ZONE --to-geojson zone.geojson
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Force a file encoding:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
netload model.net --encoding cp1251 --list-tables
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Tables
|
|
244
|
+
|
|
245
|
+
The parser is **generic**: it does not hard-code the set of supported tables. Any section starting
|
|
246
|
+
with `$` is parsed and made available, for example:
|
|
247
|
+
|
|
248
|
+
- `NODE`
|
|
249
|
+
- `LINK`
|
|
250
|
+
- `ZONE`
|
|
251
|
+
- `TURN`
|
|
252
|
+
- `MAINTURN`
|
|
253
|
+
- `CONNECTOR`
|
|
254
|
+
- `LINKTYPE`
|
|
255
|
+
- `TSYS`
|
|
256
|
+
- `LINE`, `LINEROUTE`, `TIMEPROFILE`, `VEHJOURNEY`, …
|
|
257
|
+
- `USERATTDEF`
|
|
258
|
+
- `VERSION`, `NETWORK`, …
|
|
259
|
+
|
|
260
|
+
If a file contains a table that is not listed here, it is parsed and exposed the same way.
|
|
261
|
+
|
|
262
|
+
## How it works
|
|
263
|
+
|
|
264
|
+
1. The file bytes are read and the encoding is detected (BOM first, then UTF-8, then CP1251).
|
|
265
|
+
2. The text is scanned line by line.
|
|
266
|
+
3. A line starting with `$NAME:COL1;COL2;...` opens a new table with its columns.
|
|
267
|
+
4. Following non-comment, non-blank lines are parsed as `;`-separated data rows.
|
|
268
|
+
5. Each table becomes a `pandas.DataFrame` (original string values are preserved by default).
|
|
269
|
+
|
|
270
|
+
## Limitations (v0.1.0)
|
|
271
|
+
|
|
272
|
+
- Values are treated as `;`-separated fields; quoted fields containing the separator character are
|
|
273
|
+
not yet supported.
|
|
274
|
+
- Optional light numeric type inference is available via `infer_types=True`, but the default
|
|
275
|
+
preserves the original string values to avoid any data corruption.
|
|
276
|
+
- Multi-line records and nested sub-tables are not supported yet.
|
|
277
|
+
- The built-in WKT parser covers `POINT`, `LINESTRING`, `POLYGON`, `MULTIPOINT`, `MULTILINESTRING`
|
|
278
|
+
and `MULTIPOLYGON` (the geometry types used by `.net` files).
|
|
279
|
+
|
|
280
|
+
## Development
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
python -m venv .venv
|
|
284
|
+
.venv/bin/pip install -e ".[dev]"
|
|
285
|
+
.venv/bin/python -m pytest
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## License
|
|
289
|
+
|
|
290
|
+
MIT. See [LICENSE](LICENSE).
|
|
291
|
+
|
|
292
|
+
## Disclaimer
|
|
293
|
+
|
|
294
|
+
This project is **independent** and **not affiliated with PTV Group**. PTV Visum is a registered
|
|
295
|
+
trademark of PTV Group. This package is provided "as is", without any warranty.
|
netload-0.1.0/README.md
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# netload
|
|
2
|
+
|
|
3
|
+
A lightweight, dependency-light **Python parser for `.net` network files** (PTV Visum / Simetra
|
|
4
|
+
and other `.net` text exports).
|
|
5
|
+
|
|
6
|
+
It reads the structured text tables of a `.net` file directly, without requiring PTV Visum to be
|
|
7
|
+
installed, exposes every table as a **Pandas `DataFrame`**, and can transform any table (or the whole
|
|
8
|
+
file) into **CSV**, **JSON** or **GeoJSON**.
|
|
9
|
+
|
|
10
|
+
> **Disclaimer:** This project is **independent** and is **not affiliated with, endorsed by, or
|
|
11
|
+
> supported by PTV Group** or its partners. `PTV Visum` is a registered trademark of PTV Group.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- Parses `.net` files generically: `NODE`, `LINK`, `ZONE`, `TURN`, `USERATTDEF` and **any other table**
|
|
18
|
+
present in the file.
|
|
19
|
+
- No PTV Visum required.
|
|
20
|
+
- Every table is exposed as a real `pandas.DataFrame`.
|
|
21
|
+
- Automatic encoding detection (UTF-8 with/without BOM, Windows-1251/CP1251, UTF-16), so Russian and
|
|
22
|
+
other non-ASCII content is read correctly.
|
|
23
|
+
- Robust to comments (`*`), blank lines, BOM markers and missing values.
|
|
24
|
+
- Export the whole file to **CSV**, **JSON** or **GeoJSON** in one call.
|
|
25
|
+
- Transform a single table to CSV / JSON / GeoJSON (via the API or the CLI).
|
|
26
|
+
- GeoJSON conversion uses WKT columns (`WKTSURFACE`, `WKTPOLY`, `GEOMETRY`) or `XCOORD`/`YCOORD`
|
|
27
|
+
with a built-in WKT parser (no shapely needed).
|
|
28
|
+
- List every table with its fields (columns).
|
|
29
|
+
- Small command-line interface.
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install netload
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick example
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from netload import read_net
|
|
41
|
+
|
|
42
|
+
network = read_net("model.net")
|
|
43
|
+
|
|
44
|
+
print(network.table_names)
|
|
45
|
+
|
|
46
|
+
print(network.nodes.head())
|
|
47
|
+
|
|
48
|
+
network.export_csv("./output")
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Resulting files:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
output/
|
|
55
|
+
├── NODE.csv
|
|
56
|
+
├── LINK.csv
|
|
57
|
+
├── ZONE.csv
|
|
58
|
+
└── TURN.csv
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## API
|
|
62
|
+
|
|
63
|
+
### Reading
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from netload import read_net
|
|
67
|
+
|
|
68
|
+
network = read_net("model.net") # auto-detect encoding
|
|
69
|
+
network = read_net("model.net", encoding="cp1251")
|
|
70
|
+
network = read_net("model.net", infer_types=True) # light numeric inference
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The returned `Network` object:
|
|
74
|
+
|
|
75
|
+
| Member | Description |
|
|
76
|
+
| ---------------------- | ------------------------------------------------------ |
|
|
77
|
+
| `network.tables` | `dict` of table name → `Table` (preserves file order) |
|
|
78
|
+
| `network.table_names` | `list[str]` of table names |
|
|
79
|
+
| `network.has_table(x)` | whether table `x` exists |
|
|
80
|
+
| `network.get_table(x)` | DataFrame of table `x` |
|
|
81
|
+
| `network[x]` | DataFrame of table `x` |
|
|
82
|
+
| `network.nodes` | DataFrame of `NODE` (if present) |
|
|
83
|
+
| `network.links` | DataFrame of `LINK` (if present) |
|
|
84
|
+
| `network.zones` | DataFrame of `ZONE` (if present) |
|
|
85
|
+
| `network.turns` | DataFrame of `TURN` (if present) |
|
|
86
|
+
| `network.to_dict()` | `dict[str, pd.DataFrame]` |
|
|
87
|
+
| `network.export_csv()` | writes one CSV per table (see below) |
|
|
88
|
+
| `network.export_json()`| writes one JSON per table (see below) |
|
|
89
|
+
| `network.export_geojson()` | writes GeoJSON for tables with geometry (see below) |
|
|
90
|
+
|
|
91
|
+
### Export CSV
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
network.export_csv("./output", sep=";", encoding="utf-8")
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Tables without any data row are skipped by default (`skip_empty=False` to include them).
|
|
98
|
+
|
|
99
|
+
### Export a single table (or a subset)
|
|
100
|
+
|
|
101
|
+
By default **all tables** are exported. Pass `tables=[...]` to export only specific tables:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
network.export_csv("./output", tables=["NODE"]) # NODE.csv only
|
|
105
|
+
network.export_csv("./output", tables=["NODE", "LINK"]) # NODE.csv + LINK.csv
|
|
106
|
+
network.export_json("./output", tables=["ZONE"])
|
|
107
|
+
network.export_geojson("./output", tables=["ZONE", "LINK"])
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The same applies to the CLI with `--tables NODE,LINK`.
|
|
111
|
+
|
|
112
|
+
### Export JSON
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
network.export_json("./output") # writes NODE.json, LINK.json, ZONE.json, ...
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Each file contains a JSON array of records (Russian characters are kept as-is, not escaped).
|
|
119
|
+
|
|
120
|
+
### Export GeoJSON
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
network.export_geojson("./output") # writes NODE.geojson, ZONE.geojson, LINK.geojson, ...
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Tables that have geometry are exported as GeoJSON `FeatureCollection` files:
|
|
127
|
+
|
|
128
|
+
- tables with a WKT column (`WKTSURFACE`, `WKTPOLY`, `GEOMETRY`) use its geometry
|
|
129
|
+
(e.g. `ZONE` → `MultiPolygon`, `LINK` → `LineString`);
|
|
130
|
+
- tables with `XCOORD`/`YCOORD` become Point features (e.g. `NODE`);
|
|
131
|
+
- tables without any geometry are skipped.
|
|
132
|
+
|
|
133
|
+
### Transform a single table
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from netload.exporters import export_table_csv, export_table_json, export_table_geojson
|
|
137
|
+
|
|
138
|
+
export_table_json(network["NODE"], "node.json")
|
|
139
|
+
export_table_geojson(network["ZONE"], "zone.geojson")
|
|
140
|
+
export_table_csv(network["LINK"], "link.csv")
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Errors
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
from netload import VisumNetError, VisumNetParseError, VisumNetEncodingError
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
- Missing file → `FileNotFoundError`
|
|
150
|
+
- Invalid structure → `VisumNetParseError` (includes file path and line number)
|
|
151
|
+
- Undecodable file → `VisumNetEncodingError`
|
|
152
|
+
|
|
153
|
+
## CLI
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
netload model.net
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
```text
|
|
160
|
+
Visum network loaded successfully
|
|
161
|
+
|
|
162
|
+
Tables:
|
|
163
|
+
- NODE: 1542 rows
|
|
164
|
+
- LINK: 3210 rows
|
|
165
|
+
- ZONE: 145 rows
|
|
166
|
+
- TURN: 872 rows
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
List tables with their fields:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
netload model.net --list-tables
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```text
|
|
176
|
+
Tables and fields:
|
|
177
|
+
- NODE: 1542 rows
|
|
178
|
+
fields: NO, NAME, CONTROLTYPE, T0PRT, ...
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Export everything:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
netload model.net --export-csv ./output
|
|
185
|
+
netload model.net --export-json ./output
|
|
186
|
+
netload model.net --export-geojson ./output
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Export only specific tables (default: all):
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
netload model.net --export-csv ./output --tables NODE,LINK
|
|
193
|
+
netload model.net --export-json ./output --tables ZONE
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Transform a single table:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
netload model.net --table NODE --to-csv node.csv
|
|
200
|
+
netload model.net --table NODE --to-json node.json
|
|
201
|
+
netload model.net --table ZONE --to-geojson zone.geojson
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Force a file encoding:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
netload model.net --encoding cp1251 --list-tables
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Tables
|
|
211
|
+
|
|
212
|
+
The parser is **generic**: it does not hard-code the set of supported tables. Any section starting
|
|
213
|
+
with `$` is parsed and made available, for example:
|
|
214
|
+
|
|
215
|
+
- `NODE`
|
|
216
|
+
- `LINK`
|
|
217
|
+
- `ZONE`
|
|
218
|
+
- `TURN`
|
|
219
|
+
- `MAINTURN`
|
|
220
|
+
- `CONNECTOR`
|
|
221
|
+
- `LINKTYPE`
|
|
222
|
+
- `TSYS`
|
|
223
|
+
- `LINE`, `LINEROUTE`, `TIMEPROFILE`, `VEHJOURNEY`, …
|
|
224
|
+
- `USERATTDEF`
|
|
225
|
+
- `VERSION`, `NETWORK`, …
|
|
226
|
+
|
|
227
|
+
If a file contains a table that is not listed here, it is parsed and exposed the same way.
|
|
228
|
+
|
|
229
|
+
## How it works
|
|
230
|
+
|
|
231
|
+
1. The file bytes are read and the encoding is detected (BOM first, then UTF-8, then CP1251).
|
|
232
|
+
2. The text is scanned line by line.
|
|
233
|
+
3. A line starting with `$NAME:COL1;COL2;...` opens a new table with its columns.
|
|
234
|
+
4. Following non-comment, non-blank lines are parsed as `;`-separated data rows.
|
|
235
|
+
5. Each table becomes a `pandas.DataFrame` (original string values are preserved by default).
|
|
236
|
+
|
|
237
|
+
## Limitations (v0.1.0)
|
|
238
|
+
|
|
239
|
+
- Values are treated as `;`-separated fields; quoted fields containing the separator character are
|
|
240
|
+
not yet supported.
|
|
241
|
+
- Optional light numeric type inference is available via `infer_types=True`, but the default
|
|
242
|
+
preserves the original string values to avoid any data corruption.
|
|
243
|
+
- Multi-line records and nested sub-tables are not supported yet.
|
|
244
|
+
- The built-in WKT parser covers `POINT`, `LINESTRING`, `POLYGON`, `MULTIPOINT`, `MULTILINESTRING`
|
|
245
|
+
and `MULTIPOLYGON` (the geometry types used by `.net` files).
|
|
246
|
+
|
|
247
|
+
## Development
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
python -m venv .venv
|
|
251
|
+
.venv/bin/pip install -e ".[dev]"
|
|
252
|
+
.venv/bin/python -m pytest
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## License
|
|
256
|
+
|
|
257
|
+
MIT. See [LICENSE](LICENSE).
|
|
258
|
+
|
|
259
|
+
## Disclaimer
|
|
260
|
+
|
|
261
|
+
This project is **independent** and **not affiliated with PTV Group**. PTV Visum is a registered
|
|
262
|
+
trademark of PTV Group. This package is provided "as is", without any warranty.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "netload"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A lightweight Python parser for .net network files (PTV Visum / Simetra), with CSV, JSON and GeoJSON export."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Djengoo", email = "contact@djengoo.com" },
|
|
14
|
+
]
|
|
15
|
+
keywords = [
|
|
16
|
+
"visum",
|
|
17
|
+
"ptv",
|
|
18
|
+
"net",
|
|
19
|
+
"parser",
|
|
20
|
+
"network",
|
|
21
|
+
"transportation",
|
|
22
|
+
"pandas",
|
|
23
|
+
]
|
|
24
|
+
classifiers = [
|
|
25
|
+
"Development Status :: 3 - Alpha",
|
|
26
|
+
"Intended Audience :: Developers",
|
|
27
|
+
"Intended Audience :: Science/Research",
|
|
28
|
+
"License :: OSI Approved :: MIT License",
|
|
29
|
+
"Operating System :: OS Independent",
|
|
30
|
+
"Programming Language :: Python :: 3",
|
|
31
|
+
"Programming Language :: Python :: 3.10",
|
|
32
|
+
"Programming Language :: Python :: 3.11",
|
|
33
|
+
"Programming Language :: Python :: 3.12",
|
|
34
|
+
"Programming Language :: Python :: 3.13",
|
|
35
|
+
"Topic :: Scientific/Engineering",
|
|
36
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
37
|
+
]
|
|
38
|
+
dependencies = [
|
|
39
|
+
"pandas>=1.5",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.optional-dependencies]
|
|
43
|
+
dev = [
|
|
44
|
+
"pytest>=7",
|
|
45
|
+
"build>=1",
|
|
46
|
+
"twine>=5",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
[project.urls]
|
|
50
|
+
Homepage = "https://github.com/kupidon06/visum_parser"
|
|
51
|
+
Repository = "https://github.com/kupidon06/visum_parser"
|
|
52
|
+
Documentation = "https://github.com/kupidon06/visum_parser#readme"
|
|
53
|
+
Issues = "https://github.com/kupidon06/visum_parser/issues"
|
|
54
|
+
|
|
55
|
+
[project.scripts]
|
|
56
|
+
netload = "netload.cli:main"
|
|
57
|
+
|
|
58
|
+
[tool.setuptools.packages.find]
|
|
59
|
+
where = ["src"]
|
|
60
|
+
|
|
61
|
+
[tool.setuptools.package-data]
|
|
62
|
+
netload = ["py.typed"]
|
|
63
|
+
|
|
64
|
+
[tool.pytest.ini_options]
|
|
65
|
+
testpaths = ["tests"]
|
netload-0.1.0/setup.cfg
ADDED