@drawtonomy/sdk 0.5.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 +36 -0
- package/README.md +22 -2
- package/dist/exporter/index.d.ts +3 -0
- package/dist/exporter/index.d.ts.map +1 -1
- package/dist/exporter/index.js +8 -3
- package/dist/exporter/index.js.map +1 -1
- package/dist/exporter/lanelet2.d.ts +26 -0
- package/dist/exporter/lanelet2.d.ts.map +1 -0
- package/dist/exporter/lanelet2.js +261 -0
- package/dist/exporter/lanelet2.js.map +1 -0
- package/dist/exporter/osmParser.d.ts +54 -0
- package/dist/exporter/osmParser.d.ts.map +1 -0
- package/dist/exporter/osmParser.js +247 -0
- package/dist/exporter/osmParser.js.map +1 -0
- package/dist/exporter/osmToShapes.d.ts +107 -0
- package/dist/exporter/osmToShapes.d.ts.map +1 -0
- package/dist/exporter/osmToShapes.js +370 -0
- package/dist/exporter/osmToShapes.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/snapshot.d.ts +9 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +60 -0
- package/dist/snapshot.js.map +1 -0
- package/package.json +7 -6
- package/LICENSE +0 -190
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
|
@@ -120,11 +120,20 @@ http://localhost:3000/?ext=http://localhost:3001/manifest.json
|
|
|
120
120
|
| `getBoundingBox(points)` | Get bounding box |
|
|
121
121
|
| `distanceToSegment(point, a, b)` | Point-to-segment distance |
|
|
122
122
|
|
|
123
|
+
### Snapshot
|
|
124
|
+
|
|
125
|
+
| Function | Description |
|
|
126
|
+
|----------|-------------|
|
|
127
|
+
| `parseDrawtonomySvg(svg)` | Read a `.drawtonomy.svg` source string and return the embedded `DrawtonomySnapshot`, or `null` if absent / malformed |
|
|
128
|
+
|
|
123
129
|
### Exporter Module
|
|
124
130
|
|
|
125
131
|
Convert a `DrawtonomySnapshot` into target-format strings (OpenDRIVE,
|
|
126
|
-
OpenSCENARIO) without depending on the editor runtime — useful
|
|
127
|
-
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.
|
|
128
137
|
|
|
129
138
|
```typescript
|
|
130
139
|
import { exporter, createSnapshot } from '@drawtonomy/sdk'
|
|
@@ -135,6 +144,11 @@ const xosc = exporter.exportToOpenScenario(snapshot, { xodrFilename: 'scene.xodr
|
|
|
135
144
|
|
|
136
145
|
// Bundle both into a single .zip ready for esmini.
|
|
137
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)
|
|
138
152
|
```
|
|
139
153
|
|
|
140
154
|
| Function | Description |
|
|
@@ -142,6 +156,12 @@ const { blob, baseName } = exporter.buildEsminiZip(snapshot, { baseName: 'my-sce
|
|
|
142
156
|
| `exporter.exportToOpenDrive(snapshot)` | OpenDRIVE 1.8 (.xodr) XML |
|
|
143
157
|
| `exporter.exportToOpenScenario(snapshot, options?)` | OpenSCENARIO 1.3 (.xosc) XML |
|
|
144
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 |
|
|
145
165
|
| `exporter.buildPathTrajectory(input)` | Path → time-stamped vertex sequence |
|
|
146
166
|
| `exporter.computeCenterlineWithWidth(left, right)` | Lane centerline + width samples |
|
|
147
167
|
| `exporter.buildZip(entries)` | Pure ZIP builder (store mode, no deps) |
|
package/dist/exporter/index.d.ts
CHANGED
|
@@ -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":"
|
|
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"}
|
package/dist/exporter/index.js
CHANGED
|
@@ -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
|
|
5
|
-
// they can be used in headless tooling, server-side pipelines, or
|
|
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,
|
|
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, '&')
|
|
28
|
+
.replace(/</g, '<')
|
|
29
|
+
.replace(/>/g, '>')
|
|
30
|
+
.replace(/"/g, '"')
|
|
31
|
+
.replace(/'/g, ''');
|
|
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"}
|