@osm-editor-kit/osm-data 0.1.0-alpha.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.md ADDED
@@ -0,0 +1,18 @@
1
+ # `@osm-editor-kit/osm-data`
2
+
3
+ **Status:** First npm **alpha** (`0.1.0-alpha.0`). Publish with `bun run packages:release -- --publish-only` after `npm login`.
4
+
5
+ ## What it does
6
+
7
+ Download OSM JSON from a URL (Overpass or API) and parse it into indexed in-memory stores for ways, relations, tagged nodes, node coordinates, and ways-in-relation lookup. Exports shared TypeScript types and merges multiple fetches with version-aware updates.
8
+
9
+ ## Usage
10
+
11
+ ```ts
12
+ import { downloadOsmData, parseOsmResp, mergeParsedOsm } from '@osm-editor-kit/osm-data'
13
+
14
+ const parsed = await downloadOsmData(overpassUrl)
15
+ const combined = mergeParsedOsm(parsed, parseOsmResp(rawOsmResp))
16
+ ```
17
+
18
+ Fetch/parse/index only — not an OSM editor or tag writer.
@@ -0,0 +1,10 @@
1
+ import { type RawOsmData } from './types/osm-data';
2
+ import { type ParsedOsmData } from './types/osm-data-storage';
3
+ export declare function emptyParsedOsmData(): ParsedOsmData;
4
+ export declare function mergeParsedOsm(existing: ParsedOsmData, incoming: ParsedOsmData): ParsedOsmData;
5
+ /**
6
+ * Download and parse OSM data from a URL.
7
+ * @throws {Error} Throws error when HTTP request fails (eg. HTTP 429 when too many requests)
8
+ */
9
+ export declare function downloadOsmData(url: string): Promise<ParsedOsmData>;
10
+ export declare function parseOsmResp(osmResp: RawOsmData): ParsedOsmData;
@@ -0,0 +1,4 @@
1
+ export { downloadOsmData, emptyParsedOsmData, mergeParsedOsm, parseOsmResp } from './data-client';
2
+ export type { LatLngLiteral, MapBounds } from './types/geo';
3
+ export type { OsmElement, OsmNode, OsmObject, OsmRelation, OsmTags, OsmWay, RawOsmData, } from './types/osm-data';
4
+ export type { ParsedOsmData, WaysInRelation } from './types/osm-data-storage';
package/dist/index.js ADDED
@@ -0,0 +1,75 @@
1
+ import axios from 'axios';
2
+
3
+ // src/data-client.ts
4
+ function emptyParsedOsmData() {
5
+ return {
6
+ relations: {},
7
+ ways: {},
8
+ nodes: {},
9
+ nodeCoords: {},
10
+ waysInRelation: {}
11
+ };
12
+ }
13
+ function mergeParsedOsm(existing, incoming) {
14
+ const merged = {
15
+ relations: { ...existing.relations },
16
+ ways: { ...existing.ways },
17
+ nodes: { ...existing.nodes },
18
+ nodeCoords: { ...existing.nodeCoords },
19
+ waysInRelation: { ...existing.waysInRelation }
20
+ };
21
+ Object.assign(merged.nodes, incoming.nodes);
22
+ Object.assign(merged.nodeCoords, incoming.nodeCoords);
23
+ Object.assign(merged.waysInRelation, incoming.waysInRelation);
24
+ for (const wayId in incoming.ways) {
25
+ const incomingWay = incoming.ways[wayId];
26
+ const existingWay = merged.ways[wayId];
27
+ if (existingWay && existingWay.version >= incomingWay.version) continue;
28
+ merged.ways[wayId] = incomingWay;
29
+ }
30
+ for (const relationId in incoming.relations) {
31
+ const incomingRelation = incoming.relations[relationId];
32
+ const existingRelation = merged.relations[relationId];
33
+ if (existingRelation && existingRelation.version >= incomingRelation.version) continue;
34
+ merged.relations[relationId] = incomingRelation;
35
+ }
36
+ return merged;
37
+ }
38
+ async function downloadOsmData(url) {
39
+ const osmResp = await downloadContent(url);
40
+ return parseOsmResp(osmResp);
41
+ }
42
+ async function downloadContent(url) {
43
+ const resp = await axios.get(url, {
44
+ headers: {
45
+ Accept: "application/json"
46
+ }
47
+ });
48
+ return resp.data;
49
+ }
50
+ function parseOsmResp(osmResp) {
51
+ const newData = emptyParsedOsmData();
52
+ for (const el of osmResp.elements) {
53
+ switch (el.type) {
54
+ case "node":
55
+ newData.nodeCoords[el.id] = [el.lat, el.lon];
56
+ if (el.tags) newData.nodes[el.id] = el;
57
+ break;
58
+ case "way":
59
+ newData.ways[el.id] = el;
60
+ break;
61
+ case "relation":
62
+ newData.relations[el.id] = el;
63
+ for (const member of el.members) {
64
+ if (member.type === "way" && newData.ways[member.ref])
65
+ newData.waysInRelation[member.ref] = true;
66
+ }
67
+ break;
68
+ default:
69
+ throw new Error("Not supported osm type " + el.type);
70
+ }
71
+ }
72
+ return newData;
73
+ }
74
+
75
+ export { downloadOsmData, emptyParsedOsmData, mergeParsedOsm, parseOsmResp };
@@ -0,0 +1,10 @@
1
+ export interface MapBounds {
2
+ south: number;
3
+ west: number;
4
+ north: number;
5
+ east: number;
6
+ }
7
+ export interface LatLngLiteral {
8
+ lat: number;
9
+ lng: number;
10
+ }
@@ -0,0 +1,17 @@
1
+ import { type OsmNode, type OsmRelation, type OsmWay } from './osm-data';
2
+ export type WaysInRelation = Record<number, boolean>;
3
+ export interface ParsedOsmData {
4
+ relations: {
5
+ [relationId: number]: OsmRelation;
6
+ };
7
+ ways: {
8
+ [wayId: number]: OsmWay;
9
+ };
10
+ nodes: {
11
+ [nodeId: number]: OsmNode;
12
+ };
13
+ nodeCoords: {
14
+ [nodeId: number]: [number, number];
15
+ };
16
+ waysInRelation: WaysInRelation;
17
+ }
@@ -0,0 +1,36 @@
1
+ export type OsmTags = Record<string, string>;
2
+ type OsmType = 'node' | 'way' | 'relation';
3
+ export interface OsmObject {
4
+ id: number;
5
+ type: OsmType;
6
+ uid?: number;
7
+ user?: string;
8
+ /** ISO8601 string */
9
+ timestamp?: string;
10
+ version: number;
11
+ changeset: number;
12
+ tags: OsmTags;
13
+ }
14
+ interface RelationMember {
15
+ type: OsmType;
16
+ ref: number;
17
+ role: string;
18
+ }
19
+ export interface OsmRelation extends OsmObject {
20
+ type: 'relation';
21
+ members: RelationMember[];
22
+ }
23
+ export interface OsmNode extends OsmObject {
24
+ type: 'node';
25
+ lat: number;
26
+ lon: number;
27
+ }
28
+ export interface OsmWay extends OsmObject {
29
+ type: 'way';
30
+ nodes: number[];
31
+ }
32
+ export type OsmElement = OsmNode | OsmWay | OsmRelation;
33
+ export interface RawOsmData {
34
+ elements: OsmElement[];
35
+ }
36
+ export {};
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@osm-editor-kit/osm-data",
3
+ "version": "0.1.0-alpha.0",
4
+ "description": "Download, parse, and merge OSM API/Overpass responses into an indexed in-memory store.",
5
+ "license": "MIT",
6
+ "author": "Tobias Jordans",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/osmberlin/street-space-editor.git",
10
+ "directory": "packages/osm-data"
11
+ },
12
+ "type": "module",
13
+ "sideEffects": false,
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js"
21
+ },
22
+ "./package.json": "./package.json"
23
+ },
24
+ "publishConfig": {
25
+ "access": "public",
26
+ "tag": "alpha"
27
+ },
28
+ "scripts": {
29
+ "build": "tsup && rm -f .tsbuildinfo && tsc -p tsconfig.build.json",
30
+ "type-check": "tsc --noEmit",
31
+ "test-run": "bun test src/test",
32
+ "prepublishOnly": "bun run build && bun ../../scripts/package-exports-for-publish.ts",
33
+ "postpublish": "bun ../../scripts/package-exports-restore.ts",
34
+ "prepack": "bun ../../scripts/package-exports-for-publish.ts",
35
+ "postpack": "bun ../../scripts/package-exports-restore.ts"
36
+ },
37
+ "dependencies": {
38
+ "axios": "^1.11.0"
39
+ },
40
+ "devDependencies": {
41
+ "bun-types": "^1.2.20",
42
+ "tsup": "^8.5.1",
43
+ "typescript": "^7.0.0"
44
+ },
45
+ "publishExports": {
46
+ ".": {
47
+ "types": "./dist/index.d.ts",
48
+ "import": "./dist/index.js"
49
+ },
50
+ "./package.json": "./package.json"
51
+ }
52
+ }