@drawtonomy/sdk 0.6.0 → 0.7.0

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/README.ja.md CHANGED
@@ -118,6 +118,42 @@ https://drawtonomy.com?ext=http://localhost:3001/manifest.json
118
118
  | `getBoundingBox(points)` | バウンディングボックスを取得 |
119
119
  | `distanceToSegment(point, a, b)` | 点からセグメントまでの距離 |
120
120
 
121
+ ### Exporter モジュール
122
+
123
+ `DrawtonomySnapshot` を OpenDRIVE / OpenSCENARIO / Lanelet2 OSM 形式の文字列に変換します。エディタランタイムに依存しないため、ヘッドレスツール、サーバーサイドパイプライン、ブラウザ拡張等から利用可能です。Lanelet2 については OSM XML をエディタが扱える形式(point / linestring / lane)に戻すパーサも提供し、ラウンドトリップを実現します。
124
+
125
+ ```typescript
126
+ import { exporter, createSnapshot } from '@drawtonomy/sdk'
127
+
128
+ const snapshot = createSnapshot(myShapes)
129
+ const xodr = exporter.exportToOpenDrive(snapshot)
130
+ const xosc = exporter.exportToOpenScenario(snapshot, { xodrFilename: 'scene.xodr' })
131
+
132
+ // .xodr + .xosc を 1 つの zip にまとめて esmini で実行可能に
133
+ const { blob, baseName } = exporter.buildEsminiZip(snapshot, { baseName: 'my-scene' })
134
+
135
+ // Lanelet2 (.osm XML) のエクスポート + 再インポート
136
+ const osm = exporter.exportToLanelet2(snapshot, { mapOrigin: { lat: 35.0, lon: 139.0 } })
137
+ const data = exporter.parseOsmXml(osm)
138
+ const imported = exporter.osmToShapes(data)
139
+ ```
140
+
141
+ | 関数 | 説明 |
142
+ |------|------|
143
+ | `exporter.exportToOpenDrive(snapshot)` | OpenDRIVE 1.8 (.xodr) XML |
144
+ | `exporter.exportToOpenScenario(snapshot, options?)` | OpenSCENARIO 1.3 (.xosc) XML |
145
+ | `exporter.buildEsminiZip(snapshot, options?)` | .xodr + .xosc を 1 つの zip にまとめる |
146
+ | `exporter.exportToLanelet2(snapshot, options?)` | Lanelet2 (.osm XML) ドキュメント |
147
+ | `exporter.parseOsmXml(xml)` | Lanelet2 OSM XML を構造化データへパース |
148
+ | `exporter.osmToShapes(data, options?)` | OSM → エディタが使う point / linestring / lane レコード |
149
+ | `exporter.alignBoundaries(left, right)` | レーンの左右境界の反転フラグを判定 |
150
+ | `exporter.createShapeIdAllocator()` | `osmToShapes` で使用する ID アロケータ |
151
+ | `exporter.latLonToCanvas(lat, lon, ...)` / `canvasToLatLon(...)` | 等距円筒投影ヘルパ |
152
+ | `exporter.buildPathTrajectory(input)` | Path → 時刻付き頂点列 |
153
+ | `exporter.computeCenterlineWithWidth(left, right)` | レーン中心線 + 幅サンプル |
154
+ | `exporter.buildZip(entries)` | 純粋な ZIP ビルダー (store mode、依存なし) |
155
+ | `exporter.sanitizeFileBaseName(input)` | OS-safe なベース名サニタイザ |
156
+
121
157
  ## デプロイ
122
158
 
123
159
  エクステンションは任意のHTTPSホスティングサービスにデプロイできます。
package/README.md CHANGED
@@ -129,8 +129,11 @@ http://localhost:3000/?ext=http://localhost:3001/manifest.json
129
129
  ### Exporter Module
130
130
 
131
131
  Convert a `DrawtonomySnapshot` into target-format strings (OpenDRIVE,
132
- OpenSCENARIO) without depending on the editor runtime — useful for headless
133
- tooling, server-side pipelines, or browser extensions.
132
+ OpenSCENARIO, Lanelet2 OSM) without depending on the editor runtime — useful
133
+ for headless tooling, server-side pipelines, or browser extensions. The
134
+ Lanelet2 module additionally exposes a parser that turns OSM XML back into
135
+ editor-ready primitives (points / linestrings / lanes), enabling round-trip
136
+ workflows.
134
137
 
135
138
  ```typescript
136
139
  import { exporter, createSnapshot } from '@drawtonomy/sdk'
@@ -141,6 +144,11 @@ const xosc = exporter.exportToOpenScenario(snapshot, { xodrFilename: 'scene.xodr
141
144
 
142
145
  // Bundle both into a single .zip ready for esmini.
143
146
  const { blob, baseName } = exporter.buildEsminiZip(snapshot, { baseName: 'my-scene' })
147
+
148
+ // Lanelet2 (.osm XML) export and round-trip.
149
+ const osm = exporter.exportToLanelet2(snapshot, { mapOrigin: { lat: 35.0, lon: 139.0 } })
150
+ const data = exporter.parseOsmXml(osm)
151
+ const imported = exporter.osmToShapes(data)
144
152
  ```
145
153
 
146
154
  | Function | Description |
@@ -148,6 +156,12 @@ const { blob, baseName } = exporter.buildEsminiZip(snapshot, { baseName: 'my-sce
148
156
  | `exporter.exportToOpenDrive(snapshot)` | OpenDRIVE 1.8 (.xodr) XML |
149
157
  | `exporter.exportToOpenScenario(snapshot, options?)` | OpenSCENARIO 1.3 (.xosc) XML |
150
158
  | `exporter.buildEsminiZip(snapshot, options?)` | One-shot zip bundling .xodr + .xosc |
159
+ | `exporter.exportToLanelet2(snapshot, options?)` | Lanelet2 (.osm XML) document |
160
+ | `exporter.parseOsmXml(xml)` | Parse Lanelet2 OSM XML into structured data |
161
+ | `exporter.osmToShapes(data, options?)` | OSM → editor-ready point / linestring / lane records |
162
+ | `exporter.alignBoundaries(left, right)` | Decide invert flags for a lane's left / right boundary |
163
+ | `exporter.createShapeIdAllocator()` | Pluggable id allocator used by `osmToShapes` |
164
+ | `exporter.latLonToCanvas(lat, lon, ...)` / `canvasToLatLon(...)` | Equirectangular projection helpers |
151
165
  | `exporter.buildPathTrajectory(input)` | Path → time-stamped vertex sequence |
152
166
  | `exporter.computeCenterlineWithWidth(left, right)` | Lane centerline + width samples |
153
167
  | `exporter.buildZip(entries)` | Pure ZIP builder (store mode, no deps) |
@@ -6,4 +6,7 @@ export { buildEsminiZip, type EsminiPackageOptions, type EsminiPackageResult } f
6
6
  export { buildZip, type ZipEntry } from './zip';
7
7
  export { sanitizeFileBaseName } from './sanitize';
8
8
  export { PIXELS_PER_METER } from './units';
9
+ export { exportToLanelet2, DEFAULT_ORIGIN_LAT, DEFAULT_ORIGIN_LON, type Lanelet2ExportOptions, type OsmSidecar, type MapOrigin, } from './lanelet2';
10
+ export { parseOsmXml, latLonToCanvas, canvasToLatLon, type OsmData, type OsmNode, type OsmWay, type OsmRelation, } from './osmParser';
11
+ export { osmToShapes, alignBoundaries, createShapeIdAllocator, type ImportedShapes, type ImportedPoint, type ImportedLinestring, type ImportedLane, type ImportBounds, type OsmToShapesOptions, type ShapeIdAllocator, } from './osmToShapes';
9
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/exporter/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,mBAAmB,GACzB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,KAAK,OAAO,EACZ,KAAK,gBAAgB,GACtB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrG,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/exporter/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,mBAAmB,GACzB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,0BAA0B,EAC1B,aAAa,EACb,eAAe,EACf,KAAK,OAAO,EACZ,KAAK,gBAAgB,GACtB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrG,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,KAAK,UAAU,EACf,KAAK,SAAS,GACf,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,cAAc,EACd,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,KAAK,MAAM,EACX,KAAK,WAAW,GACjB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAA"}
@@ -1,9 +1,11 @@
1
1
  // drawtonomy SDK — exporter modules.
2
2
  //
3
3
  // These exporters convert a `DrawtonomySnapshot` into target-format strings
4
- // (OpenDRIVE / OpenSCENARIO) without depending on the editor runtime, so
5
- // they can be used in headless tooling, server-side pipelines, or browser
6
- // extensions.
4
+ // (OpenDRIVE / OpenSCENARIO / Lanelet2 OSM) without depending on the editor
5
+ // runtime, so they can be used in headless tooling, server-side pipelines, or
6
+ // browser extensions. The Lanelet2 module additionally exposes a parser that
7
+ // turns OSM XML back into editor-ready primitives (points / linestrings /
8
+ // lanes), enabling round-trip workflows.
7
9
  export { exportToOpenDrive } from './opendrive';
8
10
  export { exportToOpenScenario, templateIdToVehicleCategory, } from './openscenario';
9
11
  export { buildPathTrajectory, DEFAULT_PATH_SPEED_MPS, } from './trajectory';
@@ -12,4 +14,7 @@ export { buildEsminiZip } from './packageEsmini';
12
14
  export { buildZip } from './zip';
13
15
  export { sanitizeFileBaseName } from './sanitize';
14
16
  export { PIXELS_PER_METER } from './units';
17
+ export { exportToLanelet2, DEFAULT_ORIGIN_LAT, DEFAULT_ORIGIN_LON, } from './lanelet2';
18
+ export { parseOsmXml, latLonToCanvas, canvasToLatLon, } from './osmParser';
19
+ export { osmToShapes, alignBoundaries, createShapeIdAllocator, } from './osmToShapes';
15
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exporter/index.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,EAAE;AACF,4EAA4E;AAC5E,yEAAyE;AACzE,0EAA0E;AAC1E,cAAc;AAEd,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EACL,oBAAoB,EACpB,2BAA2B,GAG5B,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,GAGvB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,0BAA0B,EAC1B,aAAa,EACb,eAAe,GAGhB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,cAAc,EAAuD,MAAM,iBAAiB,CAAA;AACrG,OAAO,EAAE,QAAQ,EAAiB,MAAM,OAAO,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exporter/index.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,0EAA0E;AAC1E,yCAAyC;AAEzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EACL,oBAAoB,EACpB,2BAA2B,GAG5B,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,GAGvB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,0BAA0B,EAC1B,aAAa,EACb,eAAe,GAGhB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,cAAc,EAAuD,MAAM,iBAAiB,CAAA;AACrG,OAAO,EAAE,QAAQ,EAAiB,MAAM,OAAO,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,GAInB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,cAAc,GAKf,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,WAAW,EACX,eAAe,EACf,sBAAsB,GAQvB,MAAM,eAAe,CAAA"}
@@ -0,0 +1,26 @@
1
+ import type { DrawtonomySnapshot } from '../types';
2
+ /** Sidecar captured at OSM import time. Used to round-trip tags / `ele`. */
3
+ export interface OsmSidecar {
4
+ rawXml: string;
5
+ originLat: number;
6
+ originLon: number;
7
+ }
8
+ /** Origin to use when no sidecar is provided. */
9
+ export interface MapOrigin {
10
+ lat: number | null;
11
+ lon: number | null;
12
+ }
13
+ export interface Lanelet2ExportOptions {
14
+ sidecar?: OsmSidecar | null;
15
+ mapOrigin?: MapOrigin | null;
16
+ }
17
+ /**
18
+ * Default origin used when neither a sidecar nor a map origin is supplied.
19
+ * Tokyo Teleport Station — picked because it is in a flat area visible at
20
+ * default zoom on most map providers.
21
+ */
22
+ export declare const DEFAULT_ORIGIN_LAT = 35.62614;
23
+ export declare const DEFAULT_ORIGIN_LON = 139.77525;
24
+ /** Build a Lanelet2 OSM XML document from a snapshot. */
25
+ export declare function exportToLanelet2(snapshot: DrawtonomySnapshot, options?: Lanelet2ExportOptions): string;
26
+ //# sourceMappingURL=lanelet2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lanelet2.d.ts","sourceRoot":"","sources":["../../src/exporter/lanelet2.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAEV,kBAAkB,EAInB,MAAM,UAAU,CAAA;AAOjB,4EAA4E;AAC5E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,iDAAiD;AACjD,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAAA;IAC3B,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAA;CAC7B;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,WAAW,CAAA;AAC1C,eAAO,MAAM,kBAAkB,YAAY,CAAA;AAwN3C,yDAAyD;AACzD,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,GAAE,qBAA0B,GAClC,MAAM,CAiDR"}
@@ -0,0 +1,261 @@
1
+ // Lanelet2 (.osm XML) exporter — emits an OSM document from a snapshot.
2
+ // No external library dependencies.
3
+ //
4
+ // Behavior summary:
5
+ // - Each PointShape becomes a `<node>`
6
+ // - Each LinestringShape becomes a `<way>` referencing its point nodes
7
+ // - Each LaneShape becomes a `<relation type=lanelet>` referencing its
8
+ // left/right way as members
9
+ // - When a sidecar (the original OSM XML captured at import time) is supplied,
10
+ // tags / `ele` / unrelated relations (regulatory_element etc.) are
11
+ // round-tripped: shape-derived entries override the sidecar copies for the
12
+ // same OSM IDs, and untouched entries are emitted verbatim in the original
13
+ // order.
14
+ // - The root `<osm>` element carries `drawtonomy_origin_lat` /
15
+ // `drawtonomy_origin_lon` so re-importing the file restores the same canvas
16
+ // origin. Standard OSM consumers ignore unknown attributes.
17
+ import { canvasToLatLon, parseOsmXml } from './osmParser';
18
+ /**
19
+ * Default origin used when neither a sidecar nor a map origin is supplied.
20
+ * Tokyo Teleport Station — picked because it is in a flat area visible at
21
+ * default zoom on most map providers.
22
+ */
23
+ export const DEFAULT_ORIGIN_LAT = 35.62614;
24
+ export const DEFAULT_ORIGIN_LON = 139.77525;
25
+ function escapeXml(s) {
26
+ return s
27
+ .replace(/&/g, '&amp;')
28
+ .replace(/</g, '&lt;')
29
+ .replace(/>/g, '&gt;')
30
+ .replace(/"/g, '&quot;')
31
+ .replace(/'/g, '&apos;');
32
+ }
33
+ function formatLatLon(v) {
34
+ // 11 decimal places ≈ 0.1 mm precision.
35
+ return v.toFixed(11);
36
+ }
37
+ function formatEle(v) {
38
+ // 3 decimal places = 1 mm precision.
39
+ return v.toFixed(3);
40
+ }
41
+ function buildShapeMap(shapes) {
42
+ const map = new Map();
43
+ for (const s of shapes)
44
+ map.set(s.id, s);
45
+ return map;
46
+ }
47
+ function buildFromShapes(shapes, originLat, originLon, sidecarData) {
48
+ const shapeMap = buildShapeMap(shapes);
49
+ const points = [];
50
+ const linestrings = [];
51
+ const lanes = [];
52
+ for (const s of shapes) {
53
+ if (s.type === 'point')
54
+ points.push(s);
55
+ else if (s.type === 'linestring')
56
+ linestrings.push(s);
57
+ else if (s.type === 'lane')
58
+ lanes.push(s);
59
+ }
60
+ const nodesOut = new Map();
61
+ const waysOut = new Map();
62
+ const relationsOut = [];
63
+ const shapeNodeOsmIds = new Set();
64
+ const shapeWayOsmIds = new Set();
65
+ const shapeRelationOsmIds = new Set();
66
+ // Resolve a shape -> OSM ID. Empty `osmId` (newly drawn shape) gets a fresh
67
+ // negative ID, matching the OSM convention for unsubmitted edits.
68
+ let nextNewId = -1;
69
+ const newIdFor = new Map();
70
+ const resolveOsmId = (shapeId, propsOsmId) => {
71
+ if (propsOsmId && propsOsmId.length > 0)
72
+ return propsOsmId;
73
+ const cached = newIdFor.get(shapeId);
74
+ if (cached !== undefined)
75
+ return cached;
76
+ const id = String(nextNewId--);
77
+ newIdFor.set(shapeId, id);
78
+ return id;
79
+ };
80
+ // Points -> nodes.
81
+ for (const p of points) {
82
+ const osmId = resolveOsmId(p.id, p.props.osmId);
83
+ shapeNodeOsmIds.add(osmId);
84
+ const { lat, lon } = canvasToLatLon(p.x, p.y, originLat, originLon);
85
+ const original = sidecarData?.nodes.get(osmId);
86
+ const tags = original ? { ...original.tags } : {};
87
+ const ele = original?.ele;
88
+ nodesOut.set(osmId, { id: osmId, lat, lon, ele, tags });
89
+ }
90
+ // Linestrings -> ways.
91
+ for (const ls of linestrings) {
92
+ const osmId = resolveOsmId(ls.id, ls.props.osmId);
93
+ shapeWayOsmIds.add(osmId);
94
+ const nodeRefs = [];
95
+ for (const pid of ls.props.pointIds) {
96
+ const point = shapeMap.get(pid);
97
+ if (!point)
98
+ continue;
99
+ nodeRefs.push(resolveOsmId(point.id, point.props.osmId));
100
+ }
101
+ const original = sidecarData?.ways.get(osmId);
102
+ const tags = original ? { ...original.tags } : {};
103
+ if (ls.props.attributes) {
104
+ for (const [k, v] of Object.entries(ls.props.attributes)) {
105
+ if (v !== undefined && v !== null && v !== '')
106
+ tags[k] = String(v);
107
+ }
108
+ }
109
+ if (!tags.type)
110
+ tags.type = 'line_thin';
111
+ waysOut.set(osmId, { id: osmId, nodeRefs, tags });
112
+ }
113
+ // Lanes -> relations (type=lanelet).
114
+ for (const lane of lanes) {
115
+ const osmId = resolveOsmId(lane.id, lane.props.osmId);
116
+ shapeRelationOsmIds.add(osmId);
117
+ const original = sidecarData?.relations.find(r => r.id === osmId);
118
+ const members = [];
119
+ let leftWayId = null;
120
+ let rightWayId = null;
121
+ if (lane.props.leftBoundaryId) {
122
+ const leftLs = shapeMap.get(lane.props.leftBoundaryId);
123
+ if (leftLs)
124
+ leftWayId = resolveOsmId(leftLs.id, leftLs.props.osmId);
125
+ }
126
+ if (lane.props.rightBoundaryId) {
127
+ const rightLs = shapeMap.get(lane.props.rightBoundaryId);
128
+ if (rightLs)
129
+ rightWayId = resolveOsmId(rightLs.id, rightLs.props.osmId);
130
+ }
131
+ if (original) {
132
+ // Preserve the original member order; only refresh left/right refs.
133
+ for (const m of original.members) {
134
+ if (m.type === 'way' && m.role === 'left' && leftWayId) {
135
+ members.push({ type: 'way', ref: leftWayId, role: 'left' });
136
+ }
137
+ else if (m.type === 'way' && m.role === 'right' && rightWayId) {
138
+ members.push({ type: 'way', ref: rightWayId, role: 'right' });
139
+ }
140
+ else {
141
+ members.push({ ...m });
142
+ }
143
+ }
144
+ }
145
+ else {
146
+ if (leftWayId)
147
+ members.push({ type: 'way', ref: leftWayId, role: 'left' });
148
+ if (rightWayId)
149
+ members.push({ type: 'way', ref: rightWayId, role: 'right' });
150
+ }
151
+ const tags = original ? { ...original.tags } : {};
152
+ if (lane.props.attributes) {
153
+ for (const [k, v] of Object.entries(lane.props.attributes)) {
154
+ if (v !== undefined && v !== null && v !== '')
155
+ tags[k] = String(v);
156
+ }
157
+ }
158
+ if (!tags.type)
159
+ tags.type = 'lanelet';
160
+ relationsOut.push({ id: osmId, members, tags });
161
+ }
162
+ return { nodes: nodesOut, ways: waysOut, relations: relationsOut, shapeNodeOsmIds, shapeWayOsmIds, shapeRelationOsmIds };
163
+ }
164
+ function nodeToXml(node) {
165
+ const tags = [];
166
+ // `ele` is emitted as a tag (Lanelet2 OSM convention).
167
+ const tagEntries = Object.entries(node.tags).filter(([k]) => k !== 'ele');
168
+ if (node.ele !== undefined) {
169
+ tags.push(` <tag k='ele' v='${escapeXml(formatEle(node.ele))}' />`);
170
+ }
171
+ else if (node.tags.ele !== undefined) {
172
+ tags.push(` <tag k='ele' v='${escapeXml(node.tags.ele)}' />`);
173
+ }
174
+ for (const [k, v] of tagEntries) {
175
+ tags.push(` <tag k='${escapeXml(k)}' v='${escapeXml(v)}' />`);
176
+ }
177
+ if (tags.length === 0) {
178
+ return ` <node id='${escapeXml(node.id)}' visible='true' version='1' lat='${formatLatLon(node.lat)}' lon='${formatLatLon(node.lon)}' />\n`;
179
+ }
180
+ let xml = ` <node id='${escapeXml(node.id)}' visible='true' version='1' lat='${formatLatLon(node.lat)}' lon='${formatLatLon(node.lon)}'>\n`;
181
+ xml += tags.join('\n') + '\n';
182
+ xml += ` </node>\n`;
183
+ return xml;
184
+ }
185
+ function wayToXml(way) {
186
+ let xml = ` <way id='${escapeXml(way.id)}' visible='true' version='1'>\n`;
187
+ for (const ref of way.nodeRefs) {
188
+ xml += ` <nd ref='${escapeXml(ref)}' />\n`;
189
+ }
190
+ for (const [k, v] of Object.entries(way.tags)) {
191
+ xml += ` <tag k='${escapeXml(k)}' v='${escapeXml(v)}' />\n`;
192
+ }
193
+ xml += ` </way>\n`;
194
+ return xml;
195
+ }
196
+ function relationToXml(rel) {
197
+ let xml = ` <relation id='${escapeXml(rel.id)}' visible='true' version='1'>\n`;
198
+ for (const m of rel.members) {
199
+ xml += ` <member type='${escapeXml(m.type)}' ref='${escapeXml(m.ref)}' role='${escapeXml(m.role)}' />\n`;
200
+ }
201
+ for (const [k, v] of Object.entries(rel.tags)) {
202
+ xml += ` <tag k='${escapeXml(k)}' v='${escapeXml(v)}' />\n`;
203
+ }
204
+ xml += ` </relation>\n`;
205
+ return xml;
206
+ }
207
+ /** Build a Lanelet2 OSM XML document from a snapshot. */
208
+ export function exportToLanelet2(snapshot, options = {}) {
209
+ const { sidecar = null, mapOrigin = null } = options;
210
+ // Sidecar wins (= round-trip from import). Otherwise fall back to the
211
+ // current map origin, then DEFAULT.
212
+ let originLat;
213
+ let originLon;
214
+ if (sidecar) {
215
+ originLat = sidecar.originLat;
216
+ originLon = sidecar.originLon;
217
+ }
218
+ else {
219
+ originLat = mapOrigin?.lat ?? DEFAULT_ORIGIN_LAT;
220
+ originLon = mapOrigin?.lon ?? DEFAULT_ORIGIN_LON;
221
+ }
222
+ const sidecarData = sidecar ? parseOsmXml(sidecar.rawXml) : null;
223
+ const fromShapes = buildFromShapes(snapshot.shapes, originLat, originLon, sidecarData);
224
+ // Combine: sidecar entries (skipping IDs that shapes overwrite) + shape-derived entries.
225
+ // Sidecar order is preserved to keep round-trips stable.
226
+ const finalNodes = [];
227
+ const finalWays = [];
228
+ const finalRelations = [];
229
+ if (sidecarData) {
230
+ sidecarData.nodes.forEach((n, id) => {
231
+ if (fromShapes.shapeNodeOsmIds.has(id))
232
+ return;
233
+ finalNodes.push({ id, lat: n.lat, lon: n.lon, ele: n.ele, tags: n.tags });
234
+ });
235
+ sidecarData.ways.forEach((w, id) => {
236
+ if (fromShapes.shapeWayOsmIds.has(id))
237
+ return;
238
+ finalWays.push({ id, nodeRefs: w.nodeRefs, tags: w.tags });
239
+ });
240
+ for (const r of sidecarData.relations) {
241
+ if (fromShapes.shapeRelationOsmIds.has(r.id))
242
+ continue;
243
+ finalRelations.push({ id: r.id, members: r.members.map(m => ({ ...m })), tags: r.tags });
244
+ }
245
+ }
246
+ fromShapes.nodes.forEach(n => finalNodes.push(n));
247
+ fromShapes.ways.forEach(w => finalWays.push(w));
248
+ for (const r of fromShapes.relations)
249
+ finalRelations.push(r);
250
+ let xml = `<?xml version='1.0' encoding='UTF-8'?>\n`;
251
+ xml += `<osm version='0.6' generator='drawtonomy' drawtonomy_origin_lat='${formatLatLon(originLat)}' drawtonomy_origin_lon='${formatLatLon(originLon)}'>\n`;
252
+ for (const n of finalNodes)
253
+ xml += nodeToXml(n);
254
+ for (const w of finalWays)
255
+ xml += wayToXml(w);
256
+ for (const r of finalRelations)
257
+ xml += relationToXml(r);
258
+ xml += `</osm>\n`;
259
+ return xml;
260
+ }
261
+ //# sourceMappingURL=lanelet2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lanelet2.js","sourceRoot":"","sources":["../../src/exporter/lanelet2.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ export interface OsmNode {
2
+ id: string;
3
+ lat: number;
4
+ lon: number;
5
+ ele?: number;
6
+ tags: Record<string, string>;
7
+ }
8
+ export interface OsmWay {
9
+ id: string;
10
+ nodeRefs: string[];
11
+ tags: Record<string, string>;
12
+ }
13
+ export interface OsmRelation {
14
+ id: string;
15
+ members: {
16
+ type: string;
17
+ ref: string;
18
+ role: string;
19
+ }[];
20
+ tags: Record<string, string>;
21
+ }
22
+ export interface OsmData {
23
+ nodes: Map<string, OsmNode>;
24
+ ways: Map<string, OsmWay>;
25
+ relations: OsmRelation[];
26
+ /**
27
+ * drawtonomy-emitted `<osm drawtonomy_origin_lat=... drawtonomy_origin_lon=...>`.
28
+ * Honored on import to restore exact page coordinates; absent for files
29
+ * produced by other tools.
30
+ */
31
+ drawtonomyOrigin?: {
32
+ lat: number;
33
+ lon: number;
34
+ };
35
+ }
36
+ /** Parse a Lanelet2 OSM XML string into structured data. */
37
+ export declare function parseOsmXml(xmlString: string): OsmData;
38
+ /**
39
+ * Project lat/lon onto canvas (page) coordinates using a simple
40
+ * equirectangular projection centered at (centerLat, centerLon).
41
+ *
42
+ * The default scale matches drawtonomy's visual sizing convention: a 3 m wide
43
+ * lane renders as 50 px (16.67 px/m), so `scale = 16.67 * 111320 ≈ 1,855,000`.
44
+ */
45
+ export declare function latLonToCanvas(lat: number, lon: number, centerLat: number, centerLon: number, scale?: number): {
46
+ x: number;
47
+ y: number;
48
+ };
49
+ /** Inverse of `latLonToCanvas`: page coordinates back to lat/lon. */
50
+ export declare function canvasToLatLon(x: number, y: number, centerLat: number, centerLon: number, scale?: number): {
51
+ lat: number;
52
+ lon: number;
53
+ };
54
+ //# sourceMappingURL=osmParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osmParser.d.ts","sourceRoot":"","sources":["../../src/exporter/osmParser.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7B;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACtD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7B;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC3B,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzB,SAAS,EAAE,WAAW,EAAE,CAAA;IACxB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAChD;AA6ND,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAUtD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAkB,GACxB;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAK1B;AAED,qEAAqE;AACrE,wBAAgB,cAAc,CAC5B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAkB,GACxB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAI9B"}