@osmix/gtfs 0.0.2 → 0.0.5

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 CHANGED
@@ -1,5 +1,33 @@
1
1
  # @osmix/gtfs
2
2
 
3
+ ## 0.0.5
4
+
5
+ ### Patch Changes
6
+
7
+ - 12728ed: Replace `csv-parse` usage in `@osmix/gtfs` with a browser-friendly shared streaming CSV parser in `@osmix/shared`, adapted from `mafintosh/csv-parser` parsing behavior.
8
+ - Updated dependencies [12728ed]
9
+ - @osmix/shared@0.0.10
10
+ - @osmix/core@0.1.5
11
+
12
+ ## 0.0.4
13
+
14
+ ### Patch Changes
15
+
16
+ - f32e4ee: General cleanup
17
+ - Updated dependencies [f32e4ee]
18
+ - @osmix/core@0.1.4
19
+ - @osmix/shared@0.0.9
20
+
21
+ ## 0.0.3
22
+
23
+ ### Patch Changes
24
+
25
+ - f468db5: Fix publishing (2)
26
+ - 536a3cd: Remove JSR dependency for CSV parsing
27
+ - Updated dependencies [f468db5]
28
+ - @osmix/core@0.1.3
29
+ - @osmix/shared@0.0.8
30
+
3
31
  ## 0.0.2
4
32
 
5
33
  ### 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
- - [@std/csv](https://jsr.io/@std/csv) - Streaming CSV parsing (from Deno standard library)
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
@@ -2,7 +2,7 @@
2
2
  * Lazy GTFS archive parser with streaming CSV support.
3
3
  *
4
4
  * Only parses CSV files when they are accessed, not upfront.
5
- * Uses @std/csv CsvParseStream for true line-by-line streaming.
5
+ * Uses shared CsvParseStream for true line-by-line streaming.
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 getter is called for the first time.
28
- * Streaming iterators parse CSV line-by-line without loading
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;AAGhB;;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;;;;;;;GAOG;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;CAoBpD"}
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;AAGhB;;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;CAoBpD"}
@@ -2,20 +2,19 @@
2
2
  * Lazy GTFS archive parser with streaming CSV support.
3
3
  *
4
4
  * Only parses CSV files when they are accessed, not upfront.
5
- * Uses @std/csv CsvParseStream for true line-by-line streaming.
5
+ * Uses shared CsvParseStream for true line-by-line streaming.
6
6
  *
7
7
  * @module
8
8
  */
9
- import { CsvParseStream } from "@std/csv/parse-stream";
9
+ import { CsvParseStream } from "@osmix/shared/csv-parse-stream";
10
10
  import { unzip } from "but-unzip";
11
11
  import { bytesToTextStream } from "./utils";
12
12
  /**
13
13
  * Lazy GTFS archive that only parses files on demand.
14
14
  *
15
15
  * Files are read from the zip and parsed only when their
16
- * corresponding getter is called for the first time.
17
- * Streaming iterators parse CSV line-by-line without loading
18
- * the entire file into memory.
16
+ * corresponding iterator is called for the first time.
17
+ * Iterators yield typed rows one record at a time.
19
18
  */
20
19
  export class GtfsArchive {
21
20
  entries;
@@ -1 +1 @@
1
- {"version":3,"file":"gtfs-archive.js","sourceRoot":"","sources":["../src/gtfs-archive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,KAAK,EAAgB,MAAM,WAAW,CAAA;AAS/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAiB3C;;;;;;;GAOG;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,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAA;QAC3C,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CACvC,IAAI,cAAc,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAC1C,CAAA;QAED,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,EAAE,CAAA;QACpC,IAAI,CAAC;YACJ,OAAO,IAAI,EAAE,CAAC;gBACb,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;gBAC3C,IAAI,IAAI;oBAAE,MAAK;gBACf,MAAM,KAAsC,CAAA;YAC7C,CAAC;QACF,CAAC;gBAAS,CAAC;YACV,MAAM,CAAC,WAAW,EAAE,CAAA;QACrB,CAAC;IACF,CAAC;CACD"}
1
+ {"version":3,"file":"gtfs-archive.js","sourceRoot":"","sources":["../src/gtfs-archive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,KAAK,EAAgB,MAAM,WAAW,CAAA;AAS/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAiB3C;;;;;;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,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAA;QAC3C,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CACvC,IAAI,cAAc,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAC1C,CAAA;QAED,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,EAAE,CAAA;QACpC,IAAI,CAAC;YACJ,OAAO,IAAI,EAAE,CAAC;gBACb,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;gBAC3C,IAAI,IAAI;oBAAE,MAAK;gBACf,MAAM,KAAsC,CAAA;YAC7C,CAAC;QACF,CAAC;gBAAS,CAAC;YACV,MAAM,CAAC,WAAW,EAAE,CAAA;QACrB,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.2",
5
+ "version": "0.0.5",
6
6
  "type": "module",
7
7
  "main": "./src/index.ts",
8
8
  "types": "./src/index.ts",
@@ -47,9 +47,8 @@
47
47
  "typescript": "^5.9.0"
48
48
  },
49
49
  "dependencies": {
50
- "@osmix/core": "0.1.2",
51
- "@osmix/shared": "0.0.7",
52
- "@std/csv": "npm:@jsr/std__csv",
50
+ "@osmix/core": "0.1.5",
51
+ "@osmix/shared": "0.0.10",
53
52
  "but-unzip": "^0.1.7"
54
53
  }
55
54
  }
@@ -2,12 +2,12 @@
2
2
  * Lazy GTFS archive parser with streaming CSV support.
3
3
  *
4
4
  * Only parses CSV files when they are accessed, not upfront.
5
- * Uses @std/csv CsvParseStream for true line-by-line streaming.
5
+ * Uses shared CsvParseStream for true line-by-line streaming.
6
6
  *
7
7
  * @module
8
8
  */
9
9
 
10
- import { CsvParseStream } from "@std/csv/parse-stream"
10
+ import { CsvParseStream } from "@osmix/shared/csv-parse-stream"
11
11
  import { unzip, type ZipItem } from "but-unzip"
12
12
  import type {
13
13
  GtfsAgency,
@@ -38,9 +38,8 @@ export type GtfsFileName = keyof GtfsFileTypeMap
38
38
  * Lazy GTFS archive that only parses files on demand.
39
39
  *
40
40
  * Files are read from the zip and parsed only when their
41
- * corresponding getter is called for the first time.
42
- * Streaming iterators parse CSV line-by-line without loading
43
- * the entire file into memory.
41
+ * corresponding iterator is called for the first time.
42
+ * Iterators yield typed rows one record at a time.
44
43
  */
45
44
  export class GtfsArchive {
46
45
  private entries: Map<string, ZipItem>
@@ -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)
@@ -495,7 +510,5 @@ describe("Monaco GTFS fixture", () => {
495
510
  // Should have both stops and routes
496
511
  expect(osm.nodes.size).toBeGreaterThan(0)
497
512
  expect(osm.ways.size).toBeGreaterThan(0)
498
-
499
- console.log(`Monaco GTFS: ${osm.nodes.size} nodes, ${osm.ways.size} ways`)
500
513
  })
501
514
  })
@@ -1,76 +0,0 @@
1
- /**
2
- * GTFS to OSM conversion utilities.
3
- *
4
- * Imports GTFS transit feeds into Osm indexes, mapping:
5
- * - Stops → Nodes with transit tags
6
- * - Routes → Ways with shape geometry
7
- *
8
- * Uses lazy, on-demand parsing - files are only parsed when needed.
9
- *
10
- * @module
11
- */
12
- import { Osm, type OsmOptions } from "@osmix/core";
13
- import { type ProgressEvent } from "@osmix/shared/progress";
14
- import { GtfsArchive } from "./gtfs-archive";
15
- import type { GtfsConversionOptions } from "./types";
16
- /**
17
- * Create an Osm index from a zipped GTFS file.
18
- *
19
- * Parses the GTFS zip lazily - only reading files when needed.
20
- * Converts stops and routes to OSM entities:
21
- * - Stops become nodes with transit-related tags
22
- * - Routes become ways with shape geometry (if available) or stop sequence
23
- *
24
- * @param zipData - The GTFS zip file as ArrayBuffer or Uint8Array
25
- * @param options - Osm index options (id, header)
26
- * @param gtfsOptions - GTFS conversion options
27
- * @param onProgress - Progress callback for UI feedback
28
- * @returns Populated Osm index with built indexes
29
- *
30
- * @example
31
- * ```ts
32
- * import { fromGtfs } from "@osmix/gtfs"
33
- *
34
- * const response = await fetch("https://example.com/gtfs.zip")
35
- * const zipData = await response.arrayBuffer()
36
- * const osm = await fromGtfs(zipData, { id: "transit" })
37
- *
38
- * console.log(`Imported ${osm.nodes.size} stops`)
39
- * ```
40
- */
41
- export declare function fromGtfs(zipData: ArrayBuffer | Uint8Array, options?: Partial<OsmOptions>, gtfsOptions?: GtfsConversionOptions, onProgress?: (progress: ProgressEvent) => void): Promise<Osm>;
42
- /**
43
- * Builder class for converting GTFS data to OSM entities.
44
- *
45
- * Uses lazy parsing - only reads GTFS files when needed.
46
- */
47
- export declare class GtfsOsmBuilder {
48
- private osm;
49
- private onProgress;
50
- private nextNodeId;
51
- private nextWayId;
52
- private stopIdToNodeId;
53
- constructor(osmOptions?: Partial<OsmOptions>, onProgress?: (progress: ProgressEvent) => void);
54
- /**
55
- * Process GTFS stops into OSM nodes.
56
- * Uses streaming iteration to avoid loading all stops at once.
57
- */
58
- processStops(archive: GtfsArchive): Promise<void>;
59
- /**
60
- * Process GTFS routes into OSM ways.
61
- * Creates one way per unique (shape_id, route_id) pair, so each route gets
62
- * its own way with correct metadata even when routes share the same shape.
63
- *
64
- * @param archive - The GTFS archive
65
- */
66
- processRoutes(archive: GtfsArchive): Promise<void>;
67
- /**
68
- * Create a way from shape points.
69
- */
70
- private createWayFromShape;
71
- /**
72
- * Build the OSM index with all entities.
73
- */
74
- buildOsm(): Osm;
75
- }
76
- //# sourceMappingURL=from-gtfs.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"from-gtfs.d.ts","sourceRoot":"","sources":["../../src/from-gtfs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,GAAG,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAEN,KAAK,aAAa,EAElB,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,qBAAqB,EAAkB,MAAM,SAAS,CAAA;AAGpE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,QAAQ,CAC7B,OAAO,EAAE,WAAW,GAAG,UAAU,EACjC,OAAO,GAAE,OAAO,CAAC,UAAU,CAAM,EACjC,WAAW,GAAE,qBAA0B,EACvC,UAAU,GAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAkB,GACzD,OAAO,CAAC,GAAG,CAAC,CAad;AAED;;;;GAIG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,UAAU,CAAmC;IAErD,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,SAAS,CAAK;IAGtB,OAAO,CAAC,cAAc,CAA4B;gBAGjD,UAAU,GAAE,OAAO,CAAC,UAAU,CAAM,EACpC,UAAU,GAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAkB;IAM5D;;;OAGG;IACG,YAAY,CAAC,OAAO,EAAE,WAAW;IAgCvC;;;;;;OAMG;IACG,aAAa,CAAC,OAAO,EAAE,WAAW;IAmFxC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA6B1B;;OAEG;IACH,QAAQ,IAAI,GAAG;CAMf"}
@@ -1,211 +0,0 @@
1
- /**
2
- * GTFS to OSM conversion utilities.
3
- *
4
- * Imports GTFS transit feeds into Osm indexes, mapping:
5
- * - Stops → Nodes with transit tags
6
- * - Routes → Ways with shape geometry
7
- *
8
- * Uses lazy, on-demand parsing - files are only parsed when needed.
9
- *
10
- * @module
11
- */
12
- import { Osm } from "@osmix/core";
13
- import { logProgress, progressEvent, } from "@osmix/shared/progress";
14
- import { GtfsArchive } from "./gtfs-archive";
15
- import { routeToTags, stopToTags } from "./utils";
16
- /**
17
- * Create an Osm index from a zipped GTFS file.
18
- *
19
- * Parses the GTFS zip lazily - only reading files when needed.
20
- * Converts stops and routes to OSM entities:
21
- * - Stops become nodes with transit-related tags
22
- * - Routes become ways with shape geometry (if available) or stop sequence
23
- *
24
- * @param zipData - The GTFS zip file as ArrayBuffer or Uint8Array
25
- * @param options - Osm index options (id, header)
26
- * @param gtfsOptions - GTFS conversion options
27
- * @param onProgress - Progress callback for UI feedback
28
- * @returns Populated Osm index with built indexes
29
- *
30
- * @example
31
- * ```ts
32
- * import { fromGtfs } from "@osmix/gtfs"
33
- *
34
- * const response = await fetch("https://example.com/gtfs.zip")
35
- * const zipData = await response.arrayBuffer()
36
- * const osm = await fromGtfs(zipData, { id: "transit" })
37
- *
38
- * console.log(`Imported ${osm.nodes.size} stops`)
39
- * ```
40
- */
41
- export async function fromGtfs(zipData, options = {}, gtfsOptions = {}, onProgress = logProgress) {
42
- onProgress(progressEvent("Opening GTFS archive..."));
43
- const archive = GtfsArchive.fromZip(zipData);
44
- const builder = new GtfsOsmBuilder(options, onProgress);
45
- if (gtfsOptions.includeStops ?? true) {
46
- await builder.processStops(archive);
47
- }
48
- if (gtfsOptions.includeRoutes ?? true) {
49
- await builder.processRoutes(archive);
50
- }
51
- return builder.buildOsm();
52
- }
53
- /**
54
- * Builder class for converting GTFS data to OSM entities.
55
- *
56
- * Uses lazy parsing - only reads GTFS files when needed.
57
- */
58
- export class GtfsOsmBuilder {
59
- osm;
60
- onProgress;
61
- nextNodeId = -1;
62
- nextWayId = -1;
63
- // Map GTFS stop_id to OSM node ID
64
- stopIdToNodeId = new Map();
65
- constructor(osmOptions = {}, onProgress = logProgress) {
66
- this.osm = new Osm(osmOptions);
67
- this.onProgress = onProgress;
68
- }
69
- /**
70
- * Process GTFS stops into OSM nodes.
71
- * Uses streaming iteration to avoid loading all stops at once.
72
- */
73
- async processStops(archive) {
74
- let count = 0;
75
- this.onProgress(progressEvent("Processing stops..."));
76
- for await (const stop of archive.iter("stops.txt")) {
77
- const lat = Number.parseFloat(stop.stop_lat);
78
- const lon = Number.parseFloat(stop.stop_lon);
79
- if (Number.isNaN(lat) || Number.isNaN(lon))
80
- continue;
81
- const tags = stopToTags(stop);
82
- const nodeId = this.nextNodeId--;
83
- this.osm.nodes.addNode({
84
- id: nodeId,
85
- lat,
86
- lon,
87
- tags,
88
- });
89
- this.stopIdToNodeId.set(stop.stop_id, nodeId);
90
- count++;
91
- if (count % 1000 === 0) {
92
- this.onProgress(progressEvent(`Processed ${count} stops...`));
93
- }
94
- }
95
- this.onProgress(progressEvent(`Added ${count} stops as nodes`));
96
- }
97
- /**
98
- * Process GTFS routes into OSM ways.
99
- * Creates one way per unique (shape_id, route_id) pair, so each route gets
100
- * its own way with correct metadata even when routes share the same shape.
101
- *
102
- * @param archive - The GTFS archive
103
- */
104
- async processRoutes(archive) {
105
- this.onProgress(progressEvent("Processing routes..."));
106
- // Build shape lookup if shapes exist
107
- const shapeMap = new Map();
108
- if (archive.hasFile("shapes.txt")) {
109
- this.onProgress(progressEvent("Loading shape data..."));
110
- for await (const point of archive.iter("shapes.txt")) {
111
- const points = shapeMap.get(point.shape_id) ?? [];
112
- points.push(point);
113
- shapeMap.set(point.shape_id, points);
114
- }
115
- // Sort each shape by sequence
116
- for (const points of shapeMap.values()) {
117
- points.sort((a, b) => Number.parseInt(a.shape_pt_sequence, 10) -
118
- Number.parseInt(b.shape_pt_sequence, 10));
119
- }
120
- }
121
- else {
122
- throw Error("No shape data found. Cannot process routes.");
123
- }
124
- // Group trips by (shape_id, route_id) to ensure each route gets its own way
125
- // even when multiple routes share the same shape geometry
126
- const shapeRouteToTrips = new Map();
127
- this.onProgress(progressEvent("Loading trip data..."));
128
- for await (const trip of archive.iter("trips.txt")) {
129
- if (!trip.shape_id)
130
- continue;
131
- const key = `${trip.shape_id}:${trip.route_id}`;
132
- const existing = shapeRouteToTrips.get(key);
133
- if (existing) {
134
- existing.tripIds.push(trip.trip_id);
135
- }
136
- else {
137
- shapeRouteToTrips.set(key, { tripIds: [trip.trip_id] });
138
- }
139
- }
140
- // Load routes into a map for lookup
141
- const routeMap = new Map();
142
- for await (const route of archive.iter("routes.txt")) {
143
- routeMap.set(route.route_id, routeToTags(route));
144
- }
145
- // Process unique (shape, route) pairs - one way per combination
146
- let count = 0;
147
- for (const [key, { tripIds }] of shapeRouteToTrips) {
148
- const [shapeId, routeId] = key.split(":");
149
- const routeTags = routeMap.get(routeId);
150
- if (!routeTags)
151
- continue;
152
- const shapePoints = shapeMap.get(shapeId);
153
- if (!shapePoints || shapePoints.length < 2) {
154
- this.onProgress(progressEvent(`No shape data found for shape ${shapeId}`, "error"));
155
- continue;
156
- }
157
- // Build tags with route info and all trip IDs for this route
158
- const tags = {
159
- ...routeTags,
160
- "gtfs:shape_id": shapeId,
161
- "gtfs:trip_ids": tripIds.join(";"),
162
- "gtfs:trip_count": tripIds.length,
163
- };
164
- // Create way from shape points
165
- this.createWayFromShape(tags, shapePoints);
166
- count++;
167
- if (count % 100 === 0) {
168
- this.onProgress(progressEvent(`Processed ${count} shape-route pairs...`));
169
- }
170
- }
171
- this.onProgress(progressEvent(`Added ${count} shape-route pairs as ways`));
172
- }
173
- /**
174
- * Create a way from shape points.
175
- */
176
- createWayFromShape(tags, shapePoints) {
177
- const nodeRefs = [];
178
- for (const point of shapePoints) {
179
- const lat = Number.parseFloat(point.shape_pt_lat);
180
- const lon = Number.parseFloat(point.shape_pt_lon);
181
- if (Number.isNaN(lat) || Number.isNaN(lon))
182
- continue;
183
- // Create a node for this shape point
184
- const nodeId = this.nextNodeId--;
185
- this.osm.nodes.addNode({
186
- id: nodeId,
187
- lat,
188
- lon,
189
- });
190
- nodeRefs.push(nodeId);
191
- }
192
- if (nodeRefs.length >= 2) {
193
- const wayId = this.nextWayId--;
194
- this.osm.ways.addWay({
195
- id: wayId,
196
- refs: nodeRefs,
197
- tags,
198
- });
199
- }
200
- }
201
- /**
202
- * Build the OSM index with all entities.
203
- */
204
- buildOsm() {
205
- this.onProgress(progressEvent("Building indexes..."));
206
- this.osm.buildIndexes();
207
- this.osm.buildSpatialIndexes();
208
- return this.osm;
209
- }
210
- }
211
- //# sourceMappingURL=from-gtfs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"from-gtfs.js","sourceRoot":"","sources":["../../src/from-gtfs.ts"],"names":[],"mappings":"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"}
@@ -1,71 +0,0 @@
1
- /**
2
- * Lazy GTFS archive parser with streaming CSV support.
3
- *
4
- * Only parses CSV files when they are accessed, not upfront.
5
- * Uses @std/csv CsvParseStream for true line-by-line streaming.
6
- *
7
- * @module
8
- */
9
- import type { GtfsAgency, GtfsRoute, GtfsShapePoint, GtfsStop, GtfsStopTime, GtfsTrip } from "./types";
10
- /**
11
- * Map of GTFS filenames to their record types.
12
- */
13
- export interface GtfsFileTypeMap {
14
- "agency.txt": GtfsAgency;
15
- "stops.txt": GtfsStop;
16
- "routes.txt": GtfsRoute;
17
- "trips.txt": GtfsTrip;
18
- "stop_times.txt": GtfsStopTime;
19
- "shapes.txt": GtfsShapePoint;
20
- }
21
- /** Valid GTFS filenames that can be parsed. */
22
- export type GtfsFileName = keyof GtfsFileTypeMap;
23
- /**
24
- * Lazy GTFS archive that only parses files on demand.
25
- *
26
- * Files are read from the zip and parsed only when their
27
- * corresponding getter is called for the first time.
28
- * Streaming iterators parse CSV line-by-line without loading
29
- * the entire file into memory.
30
- */
31
- export declare class GtfsArchive {
32
- private entries;
33
- private constructor();
34
- /**
35
- * Create a GtfsArchive from zip data.
36
- */
37
- static fromZip(zipData: ArrayBuffer | Uint8Array): GtfsArchive;
38
- /**
39
- * Check if a file exists in the archive.
40
- */
41
- hasFile(filename: string): boolean;
42
- /**
43
- * List all files in the archive.
44
- */
45
- listFiles(): string[];
46
- /**
47
- * Get a readable stream of bytes for a file.
48
- */
49
- private getFileBytes;
50
- /**
51
- * Stream parse a CSV file, yielding typed records one at a time.
52
- *
53
- * The return type is automatically inferred based on the filename:
54
- * - `"stops.txt"` → `AsyncGenerator<GtfsStop>`
55
- * - `"routes.txt"` → `AsyncGenerator<GtfsRoute>`
56
- * - `"shapes.txt"` → `AsyncGenerator<GtfsShapePoint>`
57
- * - etc.
58
- *
59
- * @param filename - The GTFS filename to parse (e.g., "stops.txt")
60
- * @returns An async generator yielding typed records
61
- *
62
- * @example
63
- * ```ts
64
- * for await (const stop of archive.iter("stops.txt")) {
65
- * console.log(stop.stop_name) // TypeScript knows this is GtfsStop
66
- * }
67
- * ```
68
- */
69
- iter<F extends GtfsFileName>(filename: F): AsyncGenerator<GtfsFileTypeMap[F], void, unknown>;
70
- }
71
- //# sourceMappingURL=gtfs-archive.d.ts.map
@@ -1 +0,0 @@
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;AAGhB;;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;;;;;;;GAOG;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;CAoBpD"}
@@ -1,102 +0,0 @@
1
- /**
2
- * Lazy GTFS archive parser with streaming CSV support.
3
- *
4
- * Only parses CSV files when they are accessed, not upfront.
5
- * Uses @std/csv CsvParseStream for true line-by-line streaming.
6
- *
7
- * @module
8
- */
9
- import { CsvParseStream } from "@std/csv/parse-stream";
10
- import { unzip } from "but-unzip";
11
- import { bytesToTextStream } from "./utils";
12
- /**
13
- * Lazy GTFS archive that only parses files on demand.
14
- *
15
- * Files are read from the zip and parsed only when their
16
- * corresponding getter is called for the first time.
17
- * Streaming iterators parse CSV line-by-line without loading
18
- * the entire file into memory.
19
- */
20
- export class GtfsArchive {
21
- entries;
22
- constructor(entries) {
23
- this.entries = entries;
24
- }
25
- /**
26
- * Create a GtfsArchive from zip data.
27
- */
28
- static fromZip(zipData) {
29
- const bytes = zipData instanceof Uint8Array ? zipData : new Uint8Array(zipData);
30
- const items = unzip(bytes);
31
- const entries = new Map();
32
- for (const item of items) {
33
- // Remove directory prefix and store by filename
34
- const name = item.filename.replace(/^.*\//, "");
35
- if (name.endsWith(".txt")) {
36
- entries.set(name, item);
37
- }
38
- }
39
- return new GtfsArchive(entries);
40
- }
41
- /**
42
- * Check if a file exists in the archive.
43
- */
44
- hasFile(filename) {
45
- return this.entries.has(filename);
46
- }
47
- /**
48
- * List all files in the archive.
49
- */
50
- listFiles() {
51
- return Array.from(this.entries.keys());
52
- }
53
- /**
54
- * Get a readable stream of bytes for a file.
55
- */
56
- async getFileBytes(filename) {
57
- const entry = this.entries.get(filename);
58
- if (!entry)
59
- return null;
60
- const data = entry.read();
61
- return data instanceof Promise ? await data : data;
62
- }
63
- /**
64
- * Stream parse a CSV file, yielding typed records one at a time.
65
- *
66
- * The return type is automatically inferred based on the filename:
67
- * - `"stops.txt"` → `AsyncGenerator<GtfsStop>`
68
- * - `"routes.txt"` → `AsyncGenerator<GtfsRoute>`
69
- * - `"shapes.txt"` → `AsyncGenerator<GtfsShapePoint>`
70
- * - etc.
71
- *
72
- * @param filename - The GTFS filename to parse (e.g., "stops.txt")
73
- * @returns An async generator yielding typed records
74
- *
75
- * @example
76
- * ```ts
77
- * for await (const stop of archive.iter("stops.txt")) {
78
- * console.log(stop.stop_name) // TypeScript knows this is GtfsStop
79
- * }
80
- * ```
81
- */
82
- async *iter(filename) {
83
- const bytes = await this.getFileBytes(filename);
84
- if (!bytes)
85
- return;
86
- const textStream = bytesToTextStream(bytes);
87
- const csvStream = textStream.pipeThrough(new CsvParseStream({ skipFirstRow: true }));
88
- const reader = csvStream.getReader();
89
- try {
90
- while (true) {
91
- const { value, done } = await reader.read();
92
- if (done)
93
- break;
94
- yield value;
95
- }
96
- }
97
- finally {
98
- reader.releaseLock();
99
- }
100
- }
101
- }
102
- //# sourceMappingURL=gtfs-archive.js.map