@osmix/gtfs 0.0.2 → 0.0.3
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.
- package/CHANGELOG.md +10 -0
- package/README.md +2 -1
- package/dist/gtfs-archive.d.ts +4 -5
- package/dist/gtfs-archive.d.ts.map +1 -1
- package/dist/gtfs-archive.js +13 -20
- package/dist/gtfs-archive.js.map +1 -1
- package/package.json +5 -5
- package/src/gtfs-archive.ts +13 -20
- package/test/from-gtfs.test.ts +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @osmix/gtfs
|
|
2
2
|
|
|
3
|
+
## 0.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f468db5: Fix publishing (2)
|
|
8
|
+
- 536a3cd: Remove JSR dependency for CSV parsing
|
|
9
|
+
- Updated dependencies [f468db5]
|
|
10
|
+
- @osmix/core@0.1.3
|
|
11
|
+
- @osmix/shared@0.0.8
|
|
12
|
+
|
|
3
13
|
## 0.0.2
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -196,5 +196,6 @@ Class for more fine-grained control over the conversion process.
|
|
|
196
196
|
## Dependencies
|
|
197
197
|
|
|
198
198
|
- [but-unzip](https://github.com/nicolo-ribaudo/but-unzip) - ZIP file parsing
|
|
199
|
-
- [
|
|
199
|
+
- [csv-parse](https://www.npmjs.com/package/csv-parse) - CSV parsing from the csv npm
|
|
200
|
+
project
|
|
200
201
|
- [@osmix/core](../core) - OSM data structures
|
package/dist/gtfs-archive.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Lazy GTFS archive parser
|
|
2
|
+
* Lazy GTFS archive parser.
|
|
3
3
|
*
|
|
4
4
|
* Only parses CSV files when they are accessed, not upfront.
|
|
5
|
-
* Uses
|
|
5
|
+
* Uses csv-parse from npm for CSV parsing.
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
@@ -24,9 +24,8 @@ export type GtfsFileName = keyof GtfsFileTypeMap;
|
|
|
24
24
|
* Lazy GTFS archive that only parses files on demand.
|
|
25
25
|
*
|
|
26
26
|
* Files are read from the zip and parsed only when their
|
|
27
|
-
* corresponding
|
|
28
|
-
*
|
|
29
|
-
* the entire file into memory.
|
|
27
|
+
* corresponding iterator is called for the first time.
|
|
28
|
+
* Iterators yield typed rows one record at a time.
|
|
30
29
|
*/
|
|
31
30
|
export declare class GtfsArchive {
|
|
32
31
|
private entries;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gtfs-archive.d.ts","sourceRoot":"","sources":["../src/gtfs-archive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EACX,UAAU,EACV,SAAS,EACT,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"gtfs-archive.d.ts","sourceRoot":"","sources":["../src/gtfs-archive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EACX,UAAU,EACV,SAAS,EACT,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,MAAM,SAAS,CAAA;AAEhB;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,YAAY,EAAE,UAAU,CAAA;IACxB,WAAW,EAAE,QAAQ,CAAA;IACrB,YAAY,EAAE,SAAS,CAAA;IACvB,WAAW,EAAE,QAAQ,CAAA;IACrB,gBAAgB,EAAE,YAAY,CAAA;IAC9B,YAAY,EAAE,cAAc,CAAA;CAC5B;AAED,+CAA+C;AAC/C,MAAM,MAAM,YAAY,GAAG,MAAM,eAAe,CAAA;AAEhD;;;;;;GAMG;AACH,qBAAa,WAAW;IACvB,OAAO,CAAC,OAAO,CAAsB;IAErC,OAAO;IAIP;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,GAAG,WAAW;IAiB9D;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIlC;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE;IAIrB;;OAEG;YACW,YAAY;IAQ1B;;;;;;;;;;;;;;;;;;OAkBG;IACI,IAAI,CAAC,CAAC,SAAS,YAAY,EACjC,QAAQ,EAAE,CAAC,GACT,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC;CAepD"}
|
package/dist/gtfs-archive.js
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Lazy GTFS archive parser
|
|
2
|
+
* Lazy GTFS archive parser.
|
|
3
3
|
*
|
|
4
4
|
* Only parses CSV files when they are accessed, not upfront.
|
|
5
|
-
* Uses
|
|
5
|
+
* Uses csv-parse from npm for CSV parsing.
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
9
|
+
import { parse } from "csv-parse/sync";
|
|
10
10
|
import { unzip } from "but-unzip";
|
|
11
|
-
import { bytesToTextStream } from "./utils";
|
|
12
11
|
/**
|
|
13
12
|
* Lazy GTFS archive that only parses files on demand.
|
|
14
13
|
*
|
|
15
14
|
* Files are read from the zip and parsed only when their
|
|
16
|
-
* corresponding
|
|
17
|
-
*
|
|
18
|
-
* the entire file into memory.
|
|
15
|
+
* corresponding iterator is called for the first time.
|
|
16
|
+
* Iterators yield typed rows one record at a time.
|
|
19
17
|
*/
|
|
20
18
|
export class GtfsArchive {
|
|
21
19
|
entries;
|
|
@@ -83,19 +81,14 @@ export class GtfsArchive {
|
|
|
83
81
|
const bytes = await this.getFileBytes(filename);
|
|
84
82
|
if (!bytes)
|
|
85
83
|
return;
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
yield value;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
finally {
|
|
98
|
-
reader.releaseLock();
|
|
84
|
+
const csvText = new TextDecoder().decode(bytes);
|
|
85
|
+
const rows = parse(csvText, {
|
|
86
|
+
bom: true,
|
|
87
|
+
columns: true,
|
|
88
|
+
skip_empty_lines: true,
|
|
89
|
+
});
|
|
90
|
+
for (const row of rows) {
|
|
91
|
+
yield row;
|
|
99
92
|
}
|
|
100
93
|
}
|
|
101
94
|
}
|
package/dist/gtfs-archive.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gtfs-archive.js","sourceRoot":"","sources":["../src/gtfs-archive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"gtfs-archive.js","sourceRoot":"","sources":["../src/gtfs-archive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AACtC,OAAO,EAAE,KAAK,EAAgB,MAAM,WAAW,CAAA;AAyB/C;;;;;;GAMG;AACH,MAAM,OAAO,WAAW;IACf,OAAO,CAAsB;IAErC,YAAoB,OAA6B;QAChD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACvB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAiC;QAC/C,MAAM,KAAK,GACV,OAAO,YAAY,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAA;QAClE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;QAE1B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAA;QAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAC1B,gDAAgD;YAChD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;YAC/C,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YACxB,CAAC;QACF,CAAC;QAED,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAA;IAChC,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,QAAgB;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAClC,CAAC;IAED;;OAEG;IACH,SAAS;QACR,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IACvC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY,CAAC,QAAgB;QAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACxC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QAEvB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;QACzB,OAAO,IAAI,YAAY,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;IACnD,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK,CAAC,CAAC,IAAI,CACV,QAAW;QAEX,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;QAC/C,IAAI,CAAC,KAAK;YAAE,OAAM;QAElB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC/C,MAAM,IAAI,GAAG,KAAK,CAAyB,OAAO,EAAE;YACnD,GAAG,EAAE,IAAI;YACT,OAAO,EAAE,IAAI;YACb,gBAAgB,EAAE,IAAI;SACtB,CAAC,CAAA;QAEF,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACxB,MAAM,GAAoC,CAAA;QAC3C,CAAC;IACF,CAAC;CACD"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "@osmix/gtfs",
|
|
4
4
|
"description": "Convert GTFS transit feeds to OSM format.",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.3",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./src/index.ts",
|
|
8
8
|
"types": "./src/index.ts",
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"typescript": "^5.9.0"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@osmix/core": "0.1.
|
|
51
|
-
"@osmix/shared": "0.0.
|
|
52
|
-
"
|
|
53
|
-
"
|
|
50
|
+
"@osmix/core": "0.1.3",
|
|
51
|
+
"@osmix/shared": "0.0.8",
|
|
52
|
+
"but-unzip": "^0.1.7",
|
|
53
|
+
"csv-parse": "^6.1.0"
|
|
54
54
|
}
|
|
55
55
|
}
|
package/src/gtfs-archive.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Lazy GTFS archive parser
|
|
2
|
+
* Lazy GTFS archive parser.
|
|
3
3
|
*
|
|
4
4
|
* Only parses CSV files when they are accessed, not upfront.
|
|
5
|
-
* Uses
|
|
5
|
+
* Uses csv-parse from npm for CSV parsing.
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { parse } from "csv-parse/sync"
|
|
11
11
|
import { unzip, type ZipItem } from "but-unzip"
|
|
12
12
|
import type {
|
|
13
13
|
GtfsAgency,
|
|
@@ -17,7 +17,6 @@ import type {
|
|
|
17
17
|
GtfsStopTime,
|
|
18
18
|
GtfsTrip,
|
|
19
19
|
} from "./types"
|
|
20
|
-
import { bytesToTextStream } from "./utils"
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
22
|
* Map of GTFS filenames to their record types.
|
|
@@ -38,9 +37,8 @@ export type GtfsFileName = keyof GtfsFileTypeMap
|
|
|
38
37
|
* Lazy GTFS archive that only parses files on demand.
|
|
39
38
|
*
|
|
40
39
|
* Files are read from the zip and parsed only when their
|
|
41
|
-
* corresponding
|
|
42
|
-
*
|
|
43
|
-
* the entire file into memory.
|
|
40
|
+
* corresponding iterator is called for the first time.
|
|
41
|
+
* Iterators yield typed rows one record at a time.
|
|
44
42
|
*/
|
|
45
43
|
export class GtfsArchive {
|
|
46
44
|
private entries: Map<string, ZipItem>
|
|
@@ -119,20 +117,15 @@ export class GtfsArchive {
|
|
|
119
117
|
const bytes = await this.getFileBytes(filename)
|
|
120
118
|
if (!bytes) return
|
|
121
119
|
|
|
122
|
-
const
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
120
|
+
const csvText = new TextDecoder().decode(bytes)
|
|
121
|
+
const rows = parse<Record<string, string>>(csvText, {
|
|
122
|
+
bom: true,
|
|
123
|
+
columns: true,
|
|
124
|
+
skip_empty_lines: true,
|
|
125
|
+
})
|
|
126
126
|
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
while (true) {
|
|
130
|
-
const { value, done } = await reader.read()
|
|
131
|
-
if (done) break
|
|
132
|
-
yield value as unknown as GtfsFileTypeMap[F]
|
|
133
|
-
}
|
|
134
|
-
} finally {
|
|
135
|
-
reader.releaseLock()
|
|
127
|
+
for (const row of rows) {
|
|
128
|
+
yield row as unknown as GtfsFileTypeMap[F]
|
|
136
129
|
}
|
|
137
130
|
}
|
|
138
131
|
}
|
package/test/from-gtfs.test.ts
CHANGED
|
@@ -201,6 +201,21 @@ describe("GtfsArchive", () => {
|
|
|
201
201
|
expect(routes[0]?.route_short_name).toBe("1")
|
|
202
202
|
})
|
|
203
203
|
|
|
204
|
+
test("parses quoted CSV fields", async () => {
|
|
205
|
+
const { zipSync } = await import("fflate")
|
|
206
|
+
const encoder = new TextEncoder()
|
|
207
|
+
const zipData = zipSync({
|
|
208
|
+
"stops.txt": encoder.encode(`stop_id,stop_name,stop_lat,stop_lon
|
|
209
|
+
stop1,"Main ""Central"", Downtown",40.7128,-74.0060`),
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
const archive = GtfsArchive.fromZip(zipData)
|
|
213
|
+
const stops = await Array.fromAsync(archive.iter("stops.txt"))
|
|
214
|
+
|
|
215
|
+
expect(stops.length).toBe(1)
|
|
216
|
+
expect(stops[0]?.stop_name).toBe('Main "Central", Downtown')
|
|
217
|
+
})
|
|
218
|
+
|
|
204
219
|
test("iterates stops without loading all at once", async () => {
|
|
205
220
|
const zipData = await createTestGtfsZip()
|
|
206
221
|
const archive = GtfsArchive.fromZip(zipData)
|