@nshiab/simple-data-analysis-core 2.0.1 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/esm/class/SimpleTable.d.ts +50 -32
  2. package/esm/class/SimpleTable.d.ts.map +1 -1
  3. package/esm/class/SimpleTable.js +46 -32
  4. package/esm/helpers/loadOsmFile.d.ts +1 -3
  5. package/esm/helpers/loadOsmFile.d.ts.map +1 -1
  6. package/esm/helpers/loadOsmFile.js +3 -11
  7. package/esm/helpers/osmCache.d.ts +10 -13
  8. package/esm/helpers/osmCache.d.ts.map +1 -1
  9. package/esm/helpers/osmCache.js +177 -32
  10. package/esm/helpers/osmFiles.d.ts +9 -0
  11. package/esm/helpers/osmFiles.d.ts.map +1 -1
  12. package/esm/helpers/osmFiles.js +234 -23
  13. package/esm/methods/loadGeoData.d.ts.map +1 -1
  14. package/esm/methods/loadGeoData.js +4 -39
  15. package/esm/methods/loadOpenStreetMap.d.ts +24 -0
  16. package/esm/methods/loadOpenStreetMap.d.ts.map +1 -0
  17. package/esm/methods/loadOpenStreetMap.js +368 -0
  18. package/llm.md +79 -46
  19. package/llms.txt +3 -0
  20. package/package.json +1 -1
  21. package/script/class/SimpleTable.d.ts +50 -32
  22. package/script/class/SimpleTable.d.ts.map +1 -1
  23. package/script/class/SimpleTable.js +46 -32
  24. package/script/helpers/loadOsmFile.d.ts +1 -3
  25. package/script/helpers/loadOsmFile.d.ts.map +1 -1
  26. package/script/helpers/loadOsmFile.js +3 -11
  27. package/script/helpers/osmCache.d.ts +10 -13
  28. package/script/helpers/osmCache.d.ts.map +1 -1
  29. package/script/helpers/osmCache.js +177 -65
  30. package/script/helpers/osmFiles.d.ts +9 -0
  31. package/script/helpers/osmFiles.d.ts.map +1 -1
  32. package/script/helpers/osmFiles.js +237 -23
  33. package/script/methods/loadGeoData.d.ts.map +1 -1
  34. package/script/methods/loadGeoData.js +3 -38
  35. package/script/methods/loadOpenStreetMap.d.ts +24 -0
  36. package/script/methods/loadOpenStreetMap.d.ts.map +1 -0
  37. package/script/methods/loadOpenStreetMap.js +375 -0
  38. package/esm/methods/loadOSM.d.ts +0 -17
  39. package/esm/methods/loadOSM.d.ts.map +0 -1
  40. package/esm/methods/loadOSM.js +0 -194
  41. package/script/methods/loadOSM.d.ts +0 -17
  42. package/script/methods/loadOSM.d.ts.map +0 -1
  43. package/script/methods/loadOSM.js +0 -201
@@ -1,201 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.default = loadOSM;
7
- exports.generateOverpassQuery = generateOverpassQuery;
8
- const node_fs_1 = require("node:fs");
9
- const SDAError_js_1 = __importDefault(require("../class/SDAError.js"));
10
- const loadOsmFile_js_1 = __importDefault(require("../helpers/loadOsmFile.js"));
11
- const osmCache_js_1 = require("../helpers/osmCache.js");
12
- const osmFiles_js_1 = require("../helpers/osmFiles.js");
13
- const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
14
- const DEFAULT_OVERPASS_ENDPOINT = "https://overpass-api.de/api/interpreter";
15
- const QUERY_GENERATOR_VERSION = "overpass-ql-v1";
16
- function loadOSM(table, bbox, options) {
17
- bbox = normalizeBoundingBox(bbox);
18
- options = structuredClone(options);
19
- const endpoint = normalizeEndpoint(options.endpoint ?? DEFAULT_OVERPASS_ENDPOINT);
20
- const filters = normalizeFilters(options.filters);
21
- assertTimeout(options.timeout);
22
- const query = generateOverpassQuery(bbox, filters, options.timeout);
23
- const parameters = { bbox, options };
24
- (0, queueOp_js_1.default)(table, {
25
- kind: "barrier",
26
- method: "loadOSM()",
27
- parameters,
28
- execute: () => executeLoadOSM(table, bbox, options, endpoint, query, parameters),
29
- });
30
- }
31
- async function executeLoadOSM(table, bbox, options, endpoint, query, parameters) {
32
- try {
33
- const cacheEnabled = options.cache ?? true;
34
- const cacheId = (0, osmCache_js_1.createOsmCacheId)({
35
- endpoint,
36
- bbox,
37
- query,
38
- queryGeneratorVersion: QUERY_GENERATOR_VERSION,
39
- });
40
- await (0, osmCache_js_1.useProcessedOsmCache)(table, cacheId, cacheEnabled, parameters, async () => {
41
- const timeoutSignal = options.timeout === undefined
42
- ? undefined
43
- : AbortSignal.timeout(options.timeout * 1000);
44
- const body = new URLSearchParams({ data: query });
45
- const temporaryFile = await (0, osmFiles_js_1.downloadOsmToTemporaryFile)(endpoint, {
46
- suffix: ".osm",
47
- prefix: cacheId,
48
- request: {
49
- method: "POST",
50
- headers: {
51
- "accept-encoding": "gzip",
52
- "content-type": "application/x-www-form-urlencoded;charset=UTF-8",
53
- "user-agent": "simple-data-analysis-core (https://github.com/nshiab/simple-data-analysis-core)",
54
- },
55
- body,
56
- signal: timeoutSignal,
57
- },
58
- });
59
- try {
60
- await assertSuccessfulOverpassResponse(temporaryFile);
61
- await (0, loadOsmFile_js_1.default)(table, temporaryFile, {
62
- method: "loadOSM()",
63
- parameters,
64
- });
65
- }
66
- finally {
67
- (0, node_fs_1.rmSync)(temporaryFile, { force: true });
68
- }
69
- });
70
- }
71
- catch (error) {
72
- if (error instanceof SDAError_js_1.default) {
73
- throw error;
74
- }
75
- throw new SDAError_js_1.default({
76
- method: "loadOSM()",
77
- parameters,
78
- query,
79
- cause: error,
80
- });
81
- }
82
- }
83
- async function assertSuccessfulOverpassResponse(file) {
84
- const stream = (0, node_fs_1.createReadStream)(file, { encoding: "utf-8" });
85
- let buffer = "";
86
- let errorTag;
87
- for await (const chunk of stream) {
88
- buffer += String(chunk);
89
- if (errorTag === undefined) {
90
- const openingTag = /<(remark|error)\b[^>]*>/i.exec(buffer);
91
- if (openingTag === null) {
92
- buffer = buffer.slice(-4096);
93
- continue;
94
- }
95
- errorTag = openingTag[1].toLowerCase() === "remark" ? "remark" : "error";
96
- buffer = buffer.slice(openingTag.index + openingTag[0].length);
97
- }
98
- const closingTag = new RegExp(`</${errorTag}\\s*>`, "i").exec(buffer);
99
- if (closingTag !== null) {
100
- throwOverpassResponseError(buffer.slice(0, closingTag.index));
101
- }
102
- if (buffer.length >= 4096) {
103
- throwOverpassResponseError(buffer.slice(0, 4096));
104
- }
105
- }
106
- if (errorTag !== undefined) {
107
- throwOverpassResponseError(buffer);
108
- }
109
- }
110
- function throwOverpassResponseError(contents) {
111
- const message = contents
112
- .replace(/<[^>]*>/g, " ")
113
- .replace(/\s+/g, " ")
114
- .trim()
115
- .slice(0, 500);
116
- throw new Error(message.length === 0
117
- ? "The Overpass endpoint returned an error response."
118
- : `The Overpass endpoint returned an error response: ${message}`);
119
- }
120
- function generateOverpassQuery(bbox, filters, timeout) {
121
- const box = `${bbox.south},${bbox.west},${bbox.north},${bbox.east}`;
122
- const selections = filters.map((filter) => `nwr${filter}(${box});`);
123
- const selection = selections.length === 1
124
- ? selections[0]
125
- : `(${selections.join("")});`;
126
- return `[out:xml]${timeout === undefined ? "" : `[timeout:${timeout}]`};${selection}(._;>;);out body;`;
127
- }
128
- function normalizeBoundingBox(bbox) {
129
- const normalized = structuredClone(bbox);
130
- for (const [name, value] of Object.entries(normalized)) {
131
- if (!Number.isFinite(value)) {
132
- throw new Error(`loadOSM() bbox.${name} must be a finite number.`);
133
- }
134
- }
135
- if (normalized.west < -180 || normalized.west > 180) {
136
- throw new Error("loadOSM() bbox.west must be between -180 and 180.");
137
- }
138
- if (normalized.east < -180 || normalized.east > 180) {
139
- throw new Error("loadOSM() bbox.east must be between -180 and 180.");
140
- }
141
- if (normalized.south < -90 || normalized.south > 90) {
142
- throw new Error("loadOSM() bbox.south must be between -90 and 90.");
143
- }
144
- if (normalized.north < -90 || normalized.north > 90) {
145
- throw new Error("loadOSM() bbox.north must be between -90 and 90.");
146
- }
147
- if (normalized.west >= normalized.east) {
148
- throw new Error("loadOSM() bbox.west must be less than bbox.east.");
149
- }
150
- if (normalized.south >= normalized.north) {
151
- throw new Error("loadOSM() bbox.south must be less than bbox.north.");
152
- }
153
- normalized.west = Object.is(normalized.west, -0) ? 0 : normalized.west;
154
- normalized.south = Object.is(normalized.south, -0) ? 0 : normalized.south;
155
- normalized.east = Object.is(normalized.east, -0) ? 0 : normalized.east;
156
- normalized.north = Object.is(normalized.north, -0) ? 0 : normalized.north;
157
- return normalized;
158
- }
159
- function normalizeFilters(filters) {
160
- if (typeof filters === "string") {
161
- const filter = filters.trim();
162
- if (filter.length === 0) {
163
- throw new Error("loadOSM() filters must contain at least one non-empty filter fragment.");
164
- }
165
- return [filter];
166
- }
167
- const tuples = isFilterTuple(filters) ? [filters] : filters;
168
- const normalized = tuples.map(([key, value]) => {
169
- if (key.length === 0) {
170
- throw new Error("loadOSM() filter keys must not be empty.");
171
- }
172
- return `[${JSON.stringify(key)}=${JSON.stringify(value)}]`;
173
- });
174
- if (normalized.length === 0) {
175
- throw new Error("loadOSM() filters must contain at least one filter tuple.");
176
- }
177
- return normalized;
178
- }
179
- function isFilterTuple(filters) {
180
- return filters.length === 2 && typeof filters[0] === "string" &&
181
- typeof filters[1] === "string";
182
- }
183
- function normalizeEndpoint(endpoint) {
184
- let url;
185
- try {
186
- url = new URL(endpoint);
187
- }
188
- catch {
189
- throw new Error("loadOSM() endpoint must be a valid HTTP or HTTPS URL.");
190
- }
191
- if (url.protocol !== "http:" && url.protocol !== "https:") {
192
- throw new Error("loadOSM() endpoint must be an HTTP or HTTPS URL.");
193
- }
194
- return url.toString();
195
- }
196
- function assertTimeout(timeout) {
197
- if (timeout !== undefined &&
198
- (!Number.isInteger(timeout) || timeout <= 0)) {
199
- throw new Error("loadOSM() timeout must be a positive integer in seconds.");
200
- }
201
- }