@nshiab/simple-data-analysis-core 0.0.26 → 0.1.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/esm/class/SimpleDB.d.ts +3 -8
- package/esm/class/SimpleDB.d.ts.map +1 -1
- package/esm/class/SimpleDB.js +8 -10
- package/esm/class/SimpleTable.d.ts +61 -51
- package/esm/class/SimpleTable.d.ts.map +1 -1
- package/esm/class/SimpleTable.js +132 -188
- package/esm/helpers/convertForJS.js +1 -1
- package/esm/helpers/findGeoColumn.js +2 -2
- package/esm/helpers/hasGeometryColumn.js +1 -1
- package/esm/helpers/logData.d.ts.map +1 -1
- package/esm/helpers/logData.js +7 -2
- package/esm/helpers/parseTypes.d.ts +1 -1
- package/esm/helpers/parseTypes.d.ts.map +1 -1
- package/esm/helpers/parseTypes.js +3 -1
- package/esm/helpers/setDbProps.d.ts +1 -1
- package/esm/helpers/setDbProps.d.ts.map +1 -1
- package/esm/helpers/setDbProps.js +5 -9
- package/esm/helpers/unifyColumns.d.ts +0 -2
- package/esm/helpers/unifyColumns.d.ts.map +1 -1
- package/esm/helpers/unifyColumns.js +2 -6
- package/esm/helpers/writeGeoData.d.ts.map +1 -1
- package/esm/helpers/writeGeoData.js +11 -41
- package/esm/helpers/writeIndexes.d.ts +3 -0
- package/esm/helpers/writeIndexes.d.ts.map +1 -0
- package/esm/helpers/writeIndexes.js +16 -0
- package/esm/methods/bm25.d.ts.map +1 -1
- package/esm/methods/bm25.js +1 -1
- package/esm/methods/cache.js +1 -1
- package/esm/methods/distanceQuery.d.ts.map +1 -1
- package/esm/methods/distanceQuery.js +4 -2
- package/esm/methods/fuzzyJoin.d.ts.map +1 -1
- package/esm/methods/fuzzyJoin.js +1 -6
- package/esm/methods/getGeoData.d.ts.map +1 -1
- package/esm/methods/getGeoData.js +1 -10
- package/esm/methods/getNbRows.d.ts +3 -1
- package/esm/methods/getNbRows.d.ts.map +1 -1
- package/esm/methods/getNbRows.js +5 -5
- package/esm/methods/join.d.ts.map +1 -1
- package/esm/methods/join.js +1 -7
- package/esm/methods/joinGeo.d.ts.map +1 -1
- package/esm/methods/joinGeo.js +1 -14
- package/esm/methods/joinGeoQuery.js +1 -1
- package/esm/methods/randomPointQuery.d.ts.map +1 -1
- package/esm/methods/randomPointQuery.js +60 -22
- package/esm/methods/summarizeQuery.js +1 -1
- package/esm/methods/writeGeoDataQuery.js +2 -2
- package/package.json +2 -2
- package/script/class/SimpleDB.d.ts +3 -8
- package/script/class/SimpleDB.d.ts.map +1 -1
- package/script/class/SimpleDB.js +8 -10
- package/script/class/SimpleTable.d.ts +61 -51
- package/script/class/SimpleTable.d.ts.map +1 -1
- package/script/class/SimpleTable.js +132 -188
- package/script/helpers/convertForJS.js +1 -1
- package/script/helpers/findGeoColumn.js +2 -2
- package/script/helpers/hasGeometryColumn.js +1 -1
- package/script/helpers/logData.d.ts.map +1 -1
- package/script/helpers/logData.js +7 -2
- package/script/helpers/parseTypes.d.ts +1 -1
- package/script/helpers/parseTypes.d.ts.map +1 -1
- package/script/helpers/parseTypes.js +3 -1
- package/script/helpers/setDbProps.d.ts +1 -1
- package/script/helpers/setDbProps.d.ts.map +1 -1
- package/script/helpers/setDbProps.js +5 -9
- package/script/helpers/unifyColumns.d.ts +0 -2
- package/script/helpers/unifyColumns.d.ts.map +1 -1
- package/script/helpers/unifyColumns.js +2 -6
- package/script/helpers/writeGeoData.d.ts.map +1 -1
- package/script/helpers/writeGeoData.js +11 -41
- package/script/helpers/writeIndexes.d.ts +3 -0
- package/script/helpers/writeIndexes.d.ts.map +1 -0
- package/script/helpers/writeIndexes.js +19 -0
- package/script/methods/bm25.d.ts.map +1 -1
- package/script/methods/bm25.js +1 -1
- package/script/methods/cache.js +1 -1
- package/script/methods/distanceQuery.d.ts.map +1 -1
- package/script/methods/distanceQuery.js +4 -2
- package/script/methods/fuzzyJoin.d.ts.map +1 -1
- package/script/methods/fuzzyJoin.js +1 -6
- package/script/methods/getGeoData.d.ts.map +1 -1
- package/script/methods/getGeoData.js +1 -10
- package/script/methods/getNbRows.d.ts +3 -1
- package/script/methods/getNbRows.d.ts.map +1 -1
- package/script/methods/getNbRows.js +5 -5
- package/script/methods/join.d.ts.map +1 -1
- package/script/methods/join.js +1 -7
- package/script/methods/joinGeo.d.ts.map +1 -1
- package/script/methods/joinGeo.js +1 -14
- package/script/methods/joinGeoQuery.js +1 -1
- package/script/methods/randomPointQuery.d.ts.map +1 -1
- package/script/methods/randomPointQuery.js +60 -22
- package/script/methods/summarizeQuery.js +1 -1
- package/script/methods/writeGeoDataQuery.js +2 -2
- package/esm/helpers/getProjection.d.ts +0 -3
- package/esm/helpers/getProjection.d.ts.map +0 -1
- package/esm/helpers/getProjection.js +0 -25
- package/esm/helpers/getProjectionParquet.d.ts +0 -3
- package/esm/helpers/getProjectionParquet.d.ts.map +0 -1
- package/esm/helpers/getProjectionParquet.js +0 -24
- package/esm/helpers/shouldFlipBeforeExport.d.ts +0 -2
- package/esm/helpers/shouldFlipBeforeExport.d.ts.map +0 -1
- package/esm/helpers/shouldFlipBeforeExport.js +0 -3
- package/esm/helpers/writeProjectionsAndIndexes.d.ts +0 -3
- package/esm/helpers/writeProjectionsAndIndexes.d.ts.map +0 -1
- package/esm/helpers/writeProjectionsAndIndexes.js +0 -29
- package/script/helpers/getProjection.d.ts +0 -3
- package/script/helpers/getProjection.d.ts.map +0 -1
- package/script/helpers/getProjection.js +0 -31
- package/script/helpers/getProjectionParquet.d.ts +0 -3
- package/script/helpers/getProjectionParquet.d.ts.map +0 -1
- package/script/helpers/getProjectionParquet.js +0 -30
- package/script/helpers/shouldFlipBeforeExport.d.ts +0 -2
- package/script/helpers/shouldFlipBeforeExport.d.ts.map +0 -1
- package/script/helpers/shouldFlipBeforeExport.js +0 -6
- package/script/helpers/writeProjectionsAndIndexes.d.ts +0 -3
- package/script/helpers/writeProjectionsAndIndexes.d.ts.map +0 -1
- package/script/helpers/writeProjectionsAndIndexes.js +0 -32
|
@@ -67,7 +67,6 @@ const summarize_js_1 = __importDefault(require("../methods/summarize.js"));
|
|
|
67
67
|
const correlations_js_1 = __importDefault(require("../methods/correlations.js"));
|
|
68
68
|
const linearRegressions_js_1 = __importDefault(require("../methods/linearRegressions.js"));
|
|
69
69
|
const joinGeo_js_1 = __importDefault(require("../methods/joinGeo.js"));
|
|
70
|
-
const getProjection_js_1 = __importDefault(require("../helpers/getProjection.js"));
|
|
71
70
|
const cache_js_1 = __importDefault(require("../methods/cache.js"));
|
|
72
71
|
const camelCase_js_1 = __importDefault(require("../helpers/camelCase.js"));
|
|
73
72
|
const formatNumber_js_1 = __importDefault(require("../helpers/formatNumber.js"));
|
|
@@ -90,7 +89,6 @@ const getIdenticalColumns_js_1 = __importDefault(require("../helpers/getIdentica
|
|
|
90
89
|
const capitalizeQuery_js_1 = __importDefault(require("../methods/capitalizeQuery.js"));
|
|
91
90
|
const truncateQuery_js_1 = __importDefault(require("../methods/truncateQuery.js"));
|
|
92
91
|
const padQuery_js_1 = __importDefault(require("../methods/padQuery.js"));
|
|
93
|
-
const getProjectionParquet_js_1 = __importDefault(require("../helpers/getProjectionParquet.js"));
|
|
94
92
|
const hasGeometryColumn_js_1 = __importDefault(require("../helpers/hasGeometryColumn.js"));
|
|
95
93
|
const unifyColumns_js_1 = __importDefault(require("../helpers/unifyColumns.js"));
|
|
96
94
|
const accumulateQuery_js_1 = __importDefault(require("../helpers/accumulateQuery.js"));
|
|
@@ -152,7 +150,6 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
152
150
|
* Creates an instance of SimpleTable.
|
|
153
151
|
*
|
|
154
152
|
* @param name - The name of the table.
|
|
155
|
-
* @param projections - An object mapping column names to their geospatial projections.
|
|
156
153
|
* @param simpleDB - The SimpleDB instance that this table belongs to.
|
|
157
154
|
* @param options - An optional object with configuration options:
|
|
158
155
|
* @param options.debug - A boolean indicating whether to enable debug mode.
|
|
@@ -161,7 +158,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
161
158
|
* @param options.types - A boolean indicating whether to include data types when logging a table.
|
|
162
159
|
* @category Constructor
|
|
163
160
|
*/
|
|
164
|
-
constructor(name,
|
|
161
|
+
constructor(name, simpleDB, options = {}) {
|
|
165
162
|
super(options);
|
|
166
163
|
/**
|
|
167
164
|
* Name of the table in the database.
|
|
@@ -175,19 +172,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
175
172
|
value: void 0
|
|
176
173
|
});
|
|
177
174
|
/**
|
|
178
|
-
* The
|
|
179
|
-
*
|
|
180
|
-
* @defaultValue `{}`
|
|
181
|
-
* @category Properties
|
|
182
|
-
*/
|
|
183
|
-
Object.defineProperty(this, "projections", {
|
|
184
|
-
enumerable: true,
|
|
185
|
-
configurable: true,
|
|
186
|
-
writable: true,
|
|
187
|
-
value: void 0
|
|
188
|
-
});
|
|
189
|
-
/**
|
|
190
|
-
* The indexes of the table.
|
|
175
|
+
* The indexes of the table, if any.
|
|
191
176
|
*
|
|
192
177
|
* @defaultValue `[]`
|
|
193
178
|
* @category Properties
|
|
@@ -199,7 +184,6 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
199
184
|
value: void 0
|
|
200
185
|
});
|
|
201
186
|
this.name = name;
|
|
202
|
-
this.projections = projections;
|
|
203
187
|
this.sdb = simpleDB;
|
|
204
188
|
this.runQuery = runQuery_js_1.default;
|
|
205
189
|
this.indexes = [];
|
|
@@ -247,8 +231,9 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
247
231
|
let spatial = "";
|
|
248
232
|
if (Object.values(types)
|
|
249
233
|
.map((d) => d.toLowerCase())
|
|
250
|
-
.
|
|
251
|
-
spatial =
|
|
234
|
+
.some((d) => d.startsWith("geometry"))) {
|
|
235
|
+
spatial =
|
|
236
|
+
"INSTALL spatial; LOAD spatial; SET geometry_always_xy = true;\n";
|
|
252
237
|
}
|
|
253
238
|
await (0, queryDB_js_1.default)(this, `${spatial}CREATE OR REPLACE TABLE "${this.name}" (${Object.keys(types)
|
|
254
239
|
.map((d) => `"${d}" ${(0, parseTypes_js_1.default)(types[d])}`)
|
|
@@ -403,12 +388,10 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
403
388
|
}
|
|
404
389
|
/**
|
|
405
390
|
* Loads geospatial data from an external file or URL into the table.
|
|
406
|
-
* The coordinates of files or URLs ending with `.json` or `.geojson` are automatically flipped to `[latitude, longitude]` axis order.
|
|
407
391
|
*
|
|
408
392
|
* @param file - The URL or absolute path to the external file containing the geospatial data.
|
|
409
393
|
* @param options - An optional object with configuration options:
|
|
410
|
-
* @param options.toWGS84 - If `true`, the method will attempt to reproject the data to WGS84
|
|
411
|
-
* @param options.from - An optional string specifying the original projection of the data, if the method is unable to detect it automatically.
|
|
394
|
+
* @param options.toWGS84 - If `true`, the method will attempt to reproject the data to WGS84.
|
|
412
395
|
* @returns A promise that resolves to the SimpleTable instance after the geospatial data has been loaded.
|
|
413
396
|
* @category Geospatial
|
|
414
397
|
*
|
|
@@ -439,7 +422,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
439
422
|
async loadGeoData(file, options = {}) {
|
|
440
423
|
const fileExtension = (0, getExtension_js_1.default)(file);
|
|
441
424
|
if (fileExtension === "geoparquet" || fileExtension === "parquet") {
|
|
442
|
-
await (0, queryDB_js_1.default)(this, `INSTALL spatial; LOAD spatial;${file.toLowerCase().includes("http")
|
|
425
|
+
await (0, queryDB_js_1.default)(this, `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true;${file.toLowerCase().includes("http")
|
|
443
426
|
? " INSTALL https; LOAD https;"
|
|
444
427
|
: ""}
|
|
445
428
|
CREATE OR REPLACE TABLE "${this.name}" AS SELECT * FROM read_parquet('${(0, cleanPath_js_1.default)(file)}');`, (0, mergeOptions_js_1.default)(this, {
|
|
@@ -447,32 +430,21 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
447
430
|
method: "loadGeoData()",
|
|
448
431
|
parameters: { file, options },
|
|
449
432
|
}));
|
|
450
|
-
this.projections = await (0, getProjectionParquet_js_1.default)(this, file);
|
|
451
|
-
if (options.toWGS84) {
|
|
452
|
-
console.log("\nThis file is a parquet. Option toWGS84 has no effect. Use the .reproject() method instead.\n");
|
|
453
|
-
}
|
|
454
433
|
}
|
|
455
434
|
else {
|
|
456
|
-
await (0, queryDB_js_1.default)(this, `INSTALL spatial; LOAD spatial;${file.toLowerCase().includes("http")
|
|
435
|
+
await (0, queryDB_js_1.default)(this, `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true;${file.toLowerCase().includes("http")
|
|
457
436
|
? " INSTALL https; LOAD https;"
|
|
458
437
|
: ""}
|
|
459
|
-
CREATE OR REPLACE TABLE "${this.name}" AS SELECT * FROM ST_Read('${file}');`, (0, mergeOptions_js_1.default)(this, {
|
|
438
|
+
CREATE OR REPLACE TABLE "${this.name}" AS SELECT * EXCLUDE OGC_FID FROM ST_Read('${file}');`, (0, mergeOptions_js_1.default)(this, {
|
|
460
439
|
table: this.name,
|
|
461
440
|
method: "loadGeoData()",
|
|
462
441
|
parameters: { file, options },
|
|
463
442
|
}));
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
const
|
|
467
|
-
if (
|
|
468
|
-
await this.
|
|
469
|
-
this.projections["geom"] = "+proj=latlong +datum=WGS84 +no_defs";
|
|
470
|
-
if (options.toWGS84) {
|
|
471
|
-
console.log("This file is a json or geojson. Option toWGS84 has no effect.");
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
else if (options.toWGS84) {
|
|
475
|
-
await this.reproject("WGS84", { ...options, column: "geom" }); // column storing geometries is geom by default
|
|
443
|
+
}
|
|
444
|
+
if (options.toWGS84) {
|
|
445
|
+
const proj = await this.getProjection("geom");
|
|
446
|
+
if (proj !== "EPSG:4326") {
|
|
447
|
+
await this.reproject("EPSG:4326");
|
|
476
448
|
}
|
|
477
449
|
}
|
|
478
450
|
return this;
|
|
@@ -764,9 +736,8 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
764
736
|
: [tablesToInsert];
|
|
765
737
|
if (!await this.sdb.hasTable(this.name)) {
|
|
766
738
|
await this.setTypes((await array[0].getTypes()));
|
|
767
|
-
this.projections = structuredClone(array[0].projections);
|
|
768
739
|
}
|
|
769
|
-
// Checking columns, types
|
|
740
|
+
// Checking columns, types
|
|
770
741
|
if (!options.unifyColumns) {
|
|
771
742
|
const thisColumns = (await this.getColumns()).sort().join(",");
|
|
772
743
|
for (const table of array) {
|
|
@@ -778,27 +749,22 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
778
749
|
}
|
|
779
750
|
const allTables = [this, ...array];
|
|
780
751
|
const allTypes = {};
|
|
781
|
-
const allProjections = {};
|
|
782
752
|
for (const table of allTables) {
|
|
783
753
|
const types = await table.getTypes();
|
|
784
754
|
for (const key in types) {
|
|
785
755
|
if (!allTypes[key]) {
|
|
786
756
|
allTypes[key] = types[key];
|
|
787
|
-
allProjections[key] = table.projections[key];
|
|
788
757
|
}
|
|
789
758
|
else {
|
|
790
759
|
if (allTypes[key] !== types[key]) {
|
|
791
760
|
throw new Error(`The column ${key} has different types in the tables.`);
|
|
792
761
|
}
|
|
793
|
-
else if (allProjections[key] !== table.projections[key]) {
|
|
794
|
-
throw new Error(`The column ${key} has different projections in the tables.`);
|
|
795
|
-
}
|
|
796
762
|
}
|
|
797
763
|
}
|
|
798
764
|
}
|
|
799
765
|
let columnsAdded = {};
|
|
800
766
|
if (options.unifyColumns) {
|
|
801
|
-
columnsAdded = await (0, unifyColumns_js_1.default)(allTables, allTypes
|
|
767
|
+
columnsAdded = await (0, unifyColumns_js_1.default)(allTables, allTypes);
|
|
802
768
|
}
|
|
803
769
|
await (0, queryDB_js_1.default)(this, array
|
|
804
770
|
.map((tableToInsert) => `INSERT INTO "${this.name}" BY NAME SELECT * FROM "${tableToInsert.name}";`)
|
|
@@ -897,29 +863,16 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
897
863
|
const columns = typeof nameOrOptions === "object" && nameOrOptions.columns
|
|
898
864
|
? (0, stringToArray_js_1.default)(nameOrOptions.columns)
|
|
899
865
|
: [];
|
|
900
|
-
// Dealing with projections
|
|
901
|
-
const clonedProjections = structuredClone(this.projections);
|
|
902
|
-
let newProjections = {};
|
|
903
|
-
if (columns.length > 0) {
|
|
904
|
-
for (const col of columns) {
|
|
905
|
-
if (clonedProjections[col]) {
|
|
906
|
-
newProjections[col] = clonedProjections[col];
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
else {
|
|
911
|
-
newProjections = clonedProjections;
|
|
912
|
-
}
|
|
913
866
|
// Delegate to sdb.newTable() so subclasses using tableClass work correctly.
|
|
914
867
|
let clonedTable;
|
|
915
868
|
const options = typeof nameOrOptions === "string"
|
|
916
869
|
? { outputTable: nameOrOptions }
|
|
917
870
|
: nameOrOptions;
|
|
918
871
|
if (typeof options.outputTable === "string") {
|
|
919
|
-
clonedTable = this.sdb.newTable(options.outputTable
|
|
872
|
+
clonedTable = this.sdb.newTable(options.outputTable);
|
|
920
873
|
}
|
|
921
874
|
else {
|
|
922
|
-
clonedTable = this.sdb.newTable(undefined
|
|
875
|
+
clonedTable = this.sdb.newTable(undefined);
|
|
923
876
|
}
|
|
924
877
|
await (0, queryDB_js_1.default)(this, (0, cloneQuery_js_1.default)(this.name, clonedTable.name, columns, options), (0, mergeOptions_js_1.default)(this, {
|
|
925
878
|
table: clonedTable.name,
|
|
@@ -950,9 +903,6 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
950
903
|
method: "cloneColumn()",
|
|
951
904
|
parameters: { originalColumn, newColumn },
|
|
952
905
|
}));
|
|
953
|
-
if (typeof this.projections[originalColumn] === "string") {
|
|
954
|
-
this.projections[newColumn] = this.projections[originalColumn];
|
|
955
|
-
}
|
|
956
906
|
}
|
|
957
907
|
/**
|
|
958
908
|
* Clones a column in the table and offsets its values by a specified number of rows.
|
|
@@ -1017,9 +967,6 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
1017
967
|
method: "cloneColumnWithOffset()",
|
|
1018
968
|
parameters: { originalColumn, newColumn },
|
|
1019
969
|
}));
|
|
1020
|
-
if (typeof this.projections[originalColumn] === "string") {
|
|
1021
|
-
this.projections[newColumn] = this.projections[originalColumn];
|
|
1022
|
-
}
|
|
1023
970
|
}
|
|
1024
971
|
/**
|
|
1025
972
|
* Fills `NULL` values in specified columns. By default, each `NULL` is replaced with the last non-`NULL` value from the preceding row. When `interpolate` is `true`, `NULL` values are replaced using linear interpolation (or extrapolation at the ends). Pass `interpolateBy` with a real numeric or date column name to use it as the X-axis, so that interpolated values are proportional to the actual distances between X-axis values rather than treating every row as equidistant. When `interpolateBy` is set, `interpolate` is automatically assumed `true`.
|
|
@@ -1265,7 +1212,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
1265
1212
|
parameters: { count, options },
|
|
1266
1213
|
}));
|
|
1267
1214
|
if (typeof options.outputTable === "string") {
|
|
1268
|
-
return this.sdb.newTable(options.outputTable
|
|
1215
|
+
return this.sdb.newTable(options.outputTable);
|
|
1269
1216
|
}
|
|
1270
1217
|
else {
|
|
1271
1218
|
return this;
|
|
@@ -1538,15 +1485,6 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
1538
1485
|
method: "renameColumns()",
|
|
1539
1486
|
parameters: { names },
|
|
1540
1487
|
}));
|
|
1541
|
-
// Taking care of projections
|
|
1542
|
-
const types = await this.getTypes();
|
|
1543
|
-
for (let i = 0; i < newNames.length; i++) {
|
|
1544
|
-
if (types[newNames[i]] === "GEOMETRY") {
|
|
1545
|
-
const projection = this.projections[oldNames[i]];
|
|
1546
|
-
delete this.projections[oldNames[i]];
|
|
1547
|
-
this.projections[newNames[i]] = projection;
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1550
1488
|
}
|
|
1551
1489
|
/**
|
|
1552
1490
|
* Cleans column names by removing non-alphanumeric characters and formatting them to camel case.
|
|
@@ -1763,12 +1701,6 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
1763
1701
|
method: "removeColumns()",
|
|
1764
1702
|
parameters: { columns },
|
|
1765
1703
|
}));
|
|
1766
|
-
// Taking care of projections
|
|
1767
|
-
for (const col of cols) {
|
|
1768
|
-
if (Object.prototype.hasOwnProperty.call(this.projections, col)) {
|
|
1769
|
-
delete this.projections[col];
|
|
1770
|
-
}
|
|
1771
|
-
}
|
|
1772
1704
|
}
|
|
1773
1705
|
/**
|
|
1774
1706
|
* Adds a new column to the table based on a specified data type (JavaScript or SQL types) and a SQL definition.
|
|
@@ -1777,7 +1709,6 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
1777
1709
|
* @param type - The data type for the new column. Can be a JavaScript type (e.g., `"number"`, `"string"`) or a SQL type (e.g., `"integer"`, `"varchar"`).
|
|
1778
1710
|
* @param definition - A SQL expression defining how the values for the new column should be computed (e.g., `"column1 + column2"`, `"ST_Centroid(geom_column)"`).
|
|
1779
1711
|
* @param options - An optional object with configuration options:
|
|
1780
|
-
* @param options.projection - Required if the new column stores geometries. Specifies the geospatial projection of the new geometry column. You can reuse the projection of an existing geometry column (available in `table.projections`).
|
|
1781
1712
|
* @returns A promise that resolves when the new column has been added.
|
|
1782
1713
|
* @category Column Operations
|
|
1783
1714
|
*
|
|
@@ -1790,33 +1721,28 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
1790
1721
|
* @example
|
|
1791
1722
|
* ```ts
|
|
1792
1723
|
* // Add a new geometry column 'centroid' using the centroid of an existing 'country' geometry column
|
|
1793
|
-
*
|
|
1794
|
-
* await table.addColumn("centroid", "geometry", `ST_Centroid("country")`, {
|
|
1795
|
-
* projection: table.projections.country,
|
|
1796
|
-
* });
|
|
1724
|
+
* await table.addColumn("centroid", "geometry('EPSG:4326')", `ST_Centroid("country")`);
|
|
1797
1725
|
* ```
|
|
1798
1726
|
*/
|
|
1799
|
-
async addColumn(newColumn, type, definition
|
|
1727
|
+
async addColumn(newColumn, type, definition) {
|
|
1800
1728
|
const newType = (0, parseTypes_js_1.default)(type);
|
|
1729
|
+
// let spatial = "";
|
|
1730
|
+
// if (newType.toLowerCase().includes("geometry")) {
|
|
1731
|
+
// spatial = "INSTALL spatial; LOAD spatial; SET geometry_always_xy = true;";
|
|
1732
|
+
// }
|
|
1801
1733
|
await (0, queryDB_js_1.default)(this, `ALTER TABLE "${this.name}" ADD "${newColumn}" ${newType};
|
|
1802
1734
|
UPDATE "${this.name}" SET "${newColumn}" = ${definition}`, (0, mergeOptions_js_1.default)(this, {
|
|
1803
1735
|
table: this.name,
|
|
1804
1736
|
method: "addColumn()",
|
|
1805
1737
|
parameters: { newColumn, type, definition },
|
|
1806
1738
|
}));
|
|
1807
|
-
if (newType === "GEOMETRY") {
|
|
1808
|
-
if (typeof options.projection === "string") {
|
|
1809
|
-
this.projections[newColumn] = options.projection;
|
|
1810
|
-
}
|
|
1811
|
-
else {
|
|
1812
|
-
throw new Error("You are creating a new column storing geometries. You must specify a projection. See examples in documentation.");
|
|
1813
|
-
}
|
|
1814
|
-
}
|
|
1815
1739
|
}
|
|
1816
1740
|
/**
|
|
1817
|
-
* Adds a new column to the table containing the row number.
|
|
1741
|
+
* Adds a new column to the table containing the row number, starting at 0 (like an index).
|
|
1818
1742
|
*
|
|
1819
1743
|
* @param newColumn - The name of the new column that will store the row number.
|
|
1744
|
+
* @param options - An optional object with configuration options:
|
|
1745
|
+
* @param options.categories - A string or an array of strings representing columns to partition the data by. The row number will restart at 0 for each unique combination of values in these columns.
|
|
1820
1746
|
* @returns A promise that resolves when the row number column has been added.
|
|
1821
1747
|
* @category Column Operations
|
|
1822
1748
|
*
|
|
@@ -1825,12 +1751,24 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
1825
1751
|
* // Add a new column named 'rowNumber' with the row number for each row
|
|
1826
1752
|
* await table.addRowNumber("rowNumber");
|
|
1827
1753
|
* ```
|
|
1754
|
+
*
|
|
1755
|
+
* @example
|
|
1756
|
+
* ```ts
|
|
1757
|
+
* // Add a new column named 'rowNumber' with the row number for each 'category'
|
|
1758
|
+
* await table.addRowNumber("rowNumber", { categories: "category" });
|
|
1759
|
+
* ```
|
|
1828
1760
|
*/
|
|
1829
|
-
async addRowNumber(newColumn) {
|
|
1830
|
-
|
|
1761
|
+
async addRowNumber(newColumn, options = {}) {
|
|
1762
|
+
const categories = options.categories
|
|
1763
|
+
? (0, stringToArray_js_1.default)(options.categories)
|
|
1764
|
+
: [];
|
|
1765
|
+
const partition = categories.length > 0
|
|
1766
|
+
? `PARTITION BY ${categories.map((d) => `"${d}"`).join(", ")}`
|
|
1767
|
+
: "";
|
|
1768
|
+
await (0, queryDB_js_1.default)(this, `CREATE OR REPLACE TABLE "${this.name}" AS SELECT *, (ROW_NUMBER() OVER(${partition} ORDER BY rowid) - 1) AS "${newColumn}" FROM "${this.name}" ORDER BY rowid`, (0, mergeOptions_js_1.default)(this, {
|
|
1831
1769
|
table: this.name,
|
|
1832
1770
|
method: "addRowNumber()",
|
|
1833
|
-
parameters: { newColumn },
|
|
1771
|
+
parameters: { newColumn, options },
|
|
1834
1772
|
}));
|
|
1835
1773
|
}
|
|
1836
1774
|
/**
|
|
@@ -1877,15 +1815,10 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
1877
1815
|
method: "crossJoin()",
|
|
1878
1816
|
parameters: { rightTable, options },
|
|
1879
1817
|
}));
|
|
1880
|
-
const allProjections = {
|
|
1881
|
-
...this.projections,
|
|
1882
|
-
...rightTable.projections,
|
|
1883
|
-
};
|
|
1884
1818
|
if (typeof options.outputTable === "string") {
|
|
1885
|
-
return this.sdb.newTable(options.outputTable
|
|
1819
|
+
return this.sdb.newTable(options.outputTable);
|
|
1886
1820
|
}
|
|
1887
1821
|
else {
|
|
1888
|
-
this.projections = allProjections;
|
|
1889
1822
|
return this;
|
|
1890
1823
|
}
|
|
1891
1824
|
}
|
|
@@ -3020,7 +2953,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
3020
2953
|
}
|
|
3021
2954
|
await (0, summarize_js_1.default)(this, options);
|
|
3022
2955
|
if (typeof options.outputTable === "string") {
|
|
3023
|
-
return this.sdb.newTable(options.outputTable
|
|
2956
|
+
return this.sdb.newTable(options.outputTable);
|
|
3024
2957
|
}
|
|
3025
2958
|
else {
|
|
3026
2959
|
return this;
|
|
@@ -3162,7 +3095,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
3162
3095
|
}
|
|
3163
3096
|
await (0, correlations_js_1.default)(this, options);
|
|
3164
3097
|
if (typeof options.outputTable === "string") {
|
|
3165
|
-
return this.sdb.newTable(options.outputTable
|
|
3098
|
+
return this.sdb.newTable(options.outputTable);
|
|
3166
3099
|
}
|
|
3167
3100
|
else {
|
|
3168
3101
|
return this;
|
|
@@ -3219,7 +3152,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
3219
3152
|
}
|
|
3220
3153
|
await (0, linearRegressions_js_1.default)(this, options);
|
|
3221
3154
|
if (typeof options.outputTable === "string") {
|
|
3222
|
-
return this.sdb.newTable(options.outputTable
|
|
3155
|
+
return this.sdb.newTable(options.outputTable);
|
|
3223
3156
|
}
|
|
3224
3157
|
else {
|
|
3225
3158
|
return this;
|
|
@@ -3517,6 +3450,8 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
3517
3450
|
/**
|
|
3518
3451
|
* Returns the number of rows in the table.
|
|
3519
3452
|
*
|
|
3453
|
+
* @param options - An optional object with configuration options:
|
|
3454
|
+
* @param options.conditions - The filtering conditions specified as a SQL `WHERE` clause (e.g., `"category = 'Book'"`).
|
|
3520
3455
|
* @returns A promise that resolves to a number representing the total count of rows.
|
|
3521
3456
|
* @category Getting Data
|
|
3522
3457
|
*
|
|
@@ -3526,9 +3461,16 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
3526
3461
|
* const nbRows = await table.getNbRows();
|
|
3527
3462
|
* console.log(nbRows); // e.g., 100
|
|
3528
3463
|
* ```
|
|
3464
|
+
*
|
|
3465
|
+
* @example
|
|
3466
|
+
* ```ts
|
|
3467
|
+
* // Get the number of rows where 'category' is 'Book'
|
|
3468
|
+
* const nbBooks = await table.getNbRows({ conditions: "category = 'Book'" });
|
|
3469
|
+
* console.log(nbBooks);
|
|
3470
|
+
* ```
|
|
3529
3471
|
*/
|
|
3530
|
-
async getNbRows() {
|
|
3531
|
-
return await (0, getNbRows_js_1.default)(this);
|
|
3472
|
+
async getNbRows(options = {}) {
|
|
3473
|
+
return await (0, getNbRows_js_1.default)(this, options);
|
|
3532
3474
|
}
|
|
3533
3475
|
/**
|
|
3534
3476
|
* Returns the total number of values in the table (number of columns multiplied by the number of rows).
|
|
@@ -4065,7 +4007,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4065
4007
|
}
|
|
4066
4008
|
// GEOSPATIAL
|
|
4067
4009
|
/**
|
|
4068
|
-
* Creates point geometries from
|
|
4010
|
+
* Creates point geometries from latitude and longitude columns.
|
|
4069
4011
|
*
|
|
4070
4012
|
* @param columnLat - The name of the column storing the latitude values.
|
|
4071
4013
|
* @param columnLon - The name of the column storing the longitude values.
|
|
@@ -4081,13 +4023,12 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4081
4023
|
*/
|
|
4082
4024
|
async points(columnLat, columnLon, newColumn) {
|
|
4083
4025
|
await (0, queryDB_js_1.default)(this, (await this.getColumns()).includes(newColumn)
|
|
4084
|
-
? `INSTALL spatial; LOAD spatial; UPDATE "${this.name}" SET "${newColumn}" = ST_Point2D("${
|
|
4085
|
-
: `INSTALL spatial; LOAD spatial; ALTER TABLE "${this.name}" ADD COLUMN "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Point2D("${
|
|
4026
|
+
? `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; UPDATE "${this.name}" SET "${newColumn}" = ST_Point2D("${columnLon}", "${columnLat}")`
|
|
4027
|
+
: `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; ALTER TABLE "${this.name}" ADD COLUMN "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Point2D("${columnLon}", "${columnLat}")`, (0, mergeOptions_js_1.default)(this, {
|
|
4086
4028
|
table: this.name,
|
|
4087
4029
|
method: "points()",
|
|
4088
4030
|
parameters: { columnLat, columnLon, newColumn },
|
|
4089
4031
|
}));
|
|
4090
|
-
this.projections[newColumn] = "+proj=latlong +datum=WGS84 +no_defs";
|
|
4091
4032
|
}
|
|
4092
4033
|
/**
|
|
4093
4034
|
* Adds a column with boolean values indicating the validity of geometries.
|
|
@@ -4244,7 +4185,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4244
4185
|
}
|
|
4245
4186
|
/**
|
|
4246
4187
|
* Flips the coordinate order of geometries in a specified column (e.g., from `[lon, lat]` to `[lat, lon]` or vice-versa).
|
|
4247
|
-
* **Warning:** This method should be used with caution as it directly manipulates coordinate order and can affect the accuracy of geospatial operations if not used correctly.
|
|
4188
|
+
* **Warning:** This method should be used with caution as it directly manipulates coordinate order and can affect the accuracy of geospatial operations if not used correctly.
|
|
4248
4189
|
*
|
|
4249
4190
|
* @param column - The name of the column storing the geometries. If omitted, the method will automatically attempt to find a geometry column.
|
|
4250
4191
|
* @returns A promise that resolves when the coordinates have been flipped.
|
|
@@ -4303,11 +4244,9 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4303
4244
|
}
|
|
4304
4245
|
/**
|
|
4305
4246
|
* Reprojects the geometries in a specified column to another Spatial Reference System (SRS).
|
|
4306
|
-
* If reprojecting to WGS84 (`"WGS84"` or `"EPSG:4326"`), the resulting geometries will have `[latitude, longitude]` axis order.
|
|
4307
4247
|
*
|
|
4308
4248
|
* @param to - The target SRS (e.g., `"EPSG:3347"`, `"WGS84"`).
|
|
4309
4249
|
* @param options - An optional object with configuration options:
|
|
4310
|
-
* @param options.from - The original projection of the geometries. If omitted, the method attempts to automatically detect it. Provide this option if auto-detection fails.
|
|
4311
4250
|
* @param options.column - The name of the column storing the geometries. If omitted, the method will automatically attempt to find a geometry column.
|
|
4312
4251
|
* @returns A promise that resolves when the geometries have been reprojected.
|
|
4313
4252
|
* @category Geospatial
|
|
@@ -4320,43 +4259,24 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4320
4259
|
*
|
|
4321
4260
|
* @example
|
|
4322
4261
|
* ```ts
|
|
4323
|
-
* // Reproject geometries from EPSG:4326 to EPSG:3347, specifying the original projection
|
|
4324
|
-
* await table.reproject("EPSG:3347", { from: "EPSG:4326" });
|
|
4325
|
-
* ```
|
|
4326
|
-
*
|
|
4327
|
-
* @example
|
|
4328
|
-
* ```ts
|
|
4329
4262
|
* // Reproject geometries in a specific column named 'myGeom' to EPSG:3347
|
|
4330
|
-
* await table.reproject("EPSG:3347", { column: "myGeom"
|
|
4263
|
+
* await table.reproject("EPSG:3347", { column: "myGeom" });
|
|
4331
4264
|
* ```
|
|
4332
4265
|
*/
|
|
4333
4266
|
async reproject(to, options = {}) {
|
|
4267
|
+
const cleanedTo = to.replace("WGS84", "EPSG:4326");
|
|
4334
4268
|
const column = typeof options.column === "string"
|
|
4335
4269
|
? options.column
|
|
4336
4270
|
: await (0, findGeoColumn_js_1.default)(this);
|
|
4337
|
-
|
|
4338
|
-
if (typeof from !== "string" || from === "") {
|
|
4339
|
-
throw new Error("Method reproject can't determine the original projection. Use the option 'from' to provide one.");
|
|
4340
|
-
}
|
|
4341
|
-
if (from === "+proj=latlong +datum=WGS84 +no_defs") {
|
|
4342
|
-
await this.flipCoordinates(column);
|
|
4343
|
-
}
|
|
4344
|
-
if (to.toUpperCase() === "WGS84" || to.toUpperCase() === "EPSG:4326") {
|
|
4345
|
-
to = "+proj=latlong +datum=WGS84 +no_defs";
|
|
4346
|
-
}
|
|
4347
|
-
await (0, queryDB_js_1.default)(this, `UPDATE "${this.name}" SET "${column}" = ST_Transform("${column}", '${from}', '${to}')`, (0, mergeOptions_js_1.default)(this, {
|
|
4271
|
+
await (0, queryDB_js_1.default)(this, `ALTER TABLE "${this.name}" ADD COLUMN "${column}_reprojected" GEOMETRY('${cleanedTo}'); UPDATE "${this.name}" SET "${column}_reprojected" = ST_Transform("${column}", '${cleanedTo}'); ALTER TABLE "${this.name}" DROP COLUMN "${column}"; ALTER TABLE "${this.name}" RENAME COLUMN "${column}_reprojected" TO "${column}";`, (0, mergeOptions_js_1.default)(this, {
|
|
4348
4272
|
table: this.name,
|
|
4349
4273
|
method: "reproject()",
|
|
4350
4274
|
parameters: { column, to },
|
|
4351
4275
|
}));
|
|
4352
|
-
this.projections[column] = to;
|
|
4353
|
-
if (this.projections[column] === "+proj=latlong +datum=WGS84 +no_defs") {
|
|
4354
|
-
await this.flipCoordinates(column);
|
|
4355
|
-
}
|
|
4356
4276
|
}
|
|
4357
4277
|
/**
|
|
4358
4278
|
* Computes the area of geometries in square meters (`"m2"`) or optionally square kilometers (`"km2"`).
|
|
4359
|
-
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84)
|
|
4279
|
+
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84).
|
|
4360
4280
|
*
|
|
4361
4281
|
* @param newColumn - The name of the new column where the computed areas will be stored.
|
|
4362
4282
|
* @param options - An optional object with configuration options:
|
|
@@ -4395,7 +4315,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4395
4315
|
}
|
|
4396
4316
|
/**
|
|
4397
4317
|
* Computes the length of line geometries in meters (`"m"`) or optionally kilometers (`"km"`).
|
|
4398
|
-
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84)
|
|
4318
|
+
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84).
|
|
4399
4319
|
*
|
|
4400
4320
|
* @param newColumn - The name of the new column where the computed lengths will be stored.
|
|
4401
4321
|
* @param options - An optional object with configuration options:
|
|
@@ -4434,7 +4354,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4434
4354
|
}
|
|
4435
4355
|
/**
|
|
4436
4356
|
* Computes the perimeter of polygon geometries in meters (`"m"`) or optionally kilometers (`"km"`).
|
|
4437
|
-
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84)
|
|
4357
|
+
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84).
|
|
4438
4358
|
*
|
|
4439
4359
|
* @param newColumn - The name of the new column where the computed perimeters will be stored.
|
|
4440
4360
|
* @param options - An optional object with configuration options:
|
|
@@ -4498,14 +4418,14 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4498
4418
|
const column = typeof options.column === "string"
|
|
4499
4419
|
? options.column
|
|
4500
4420
|
: await (0, findGeoColumn_js_1.default)(this);
|
|
4421
|
+
const proj = await this.getProjection(column);
|
|
4501
4422
|
await (0, queryDB_js_1.default)(this, (await this.getColumns()).includes(newColumn)
|
|
4502
|
-
? `INSTALL spatial; LOAD spatial; UPDATE "${this.name}" SET "${newColumn}" = ST_Buffer("${column}", ${distance})`
|
|
4503
|
-
: `INSTALL spatial; LOAD spatial; ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Buffer("${column}", ${distance})`, (0, mergeOptions_js_1.default)(this, {
|
|
4423
|
+
? `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; UPDATE "${this.name}" SET "${newColumn}" = ST_Buffer("${column}", ${distance})`
|
|
4424
|
+
: `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY('${proj}'); UPDATE "${this.name}" SET "${newColumn}" = ST_Buffer("${column}", ${distance})`, (0, mergeOptions_js_1.default)(this, {
|
|
4504
4425
|
table: this.name,
|
|
4505
4426
|
method: "buffer()",
|
|
4506
4427
|
parameters: { column, newColumn, distance },
|
|
4507
4428
|
}));
|
|
4508
|
-
this.projections[newColumn] = this.projections[column];
|
|
4509
4429
|
}
|
|
4510
4430
|
/**
|
|
4511
4431
|
* Merges the data of this table (considered the left table) with another table (the right table) based on a spatial relationship.
|
|
@@ -4583,17 +4503,13 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4583
4503
|
* ```
|
|
4584
4504
|
*/
|
|
4585
4505
|
async intersection(column1, column2, newColumn) {
|
|
4586
|
-
if (this.projections[column1] !== this.projections[column2]) {
|
|
4587
|
-
throw new Error(`${column1} and ${column2} don't have the same projection.\n${column1}: ${this.projections[column1]}\n${column2}: ${this.projections[column2]}`);
|
|
4588
|
-
}
|
|
4589
4506
|
await (0, queryDB_js_1.default)(this, (await this.getColumns()).includes(newColumn)
|
|
4590
|
-
? `INSTALL spatial; LOAD spatial; UPDATE "${this.name}" SET "${newColumn}" = ST_Intersection("${column1}", "${column2}")`
|
|
4591
|
-
: `INSTALL spatial; LOAD spatial; ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Intersection("${column1}", "${column2}")`, (0, mergeOptions_js_1.default)(this, {
|
|
4507
|
+
? `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; UPDATE "${this.name}" SET "${newColumn}" = ST_Intersection("${column1}", "${column2}")`
|
|
4508
|
+
: `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Intersection("${column1}", "${column2}")`, (0, mergeOptions_js_1.default)(this, {
|
|
4592
4509
|
table: this.name,
|
|
4593
4510
|
method: "intersection()",
|
|
4594
4511
|
parameters: { column1, column2, newColumn },
|
|
4595
4512
|
}));
|
|
4596
|
-
this.projections[newColumn] = this.projections[column1];
|
|
4597
4513
|
}
|
|
4598
4514
|
/**
|
|
4599
4515
|
* Removes the intersection of two geometries from the first geometry, effectively computing the geometric difference.
|
|
@@ -4611,9 +4527,6 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4611
4527
|
* ```
|
|
4612
4528
|
*/
|
|
4613
4529
|
async removeIntersection(column1, column2, newColumn) {
|
|
4614
|
-
if (this.projections[column1] !== this.projections[column2]) {
|
|
4615
|
-
throw new Error(`${column1} and ${column2} don't have the same projection.\n${column1}: ${this.projections[column1]}\n${column2}: ${this.projections[column2]}`);
|
|
4616
|
-
}
|
|
4617
4530
|
await (0, queryDB_js_1.default)(this, (await this.getColumns()).includes(newColumn)
|
|
4618
4531
|
? `UPDATE "${this.name}" SET "${newColumn}" = ST_Difference("${column1}", "${column2}")`
|
|
4619
4532
|
: `ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Difference("${column1}", "${column2}")`, (0, mergeOptions_js_1.default)(this, {
|
|
@@ -4621,7 +4534,6 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4621
4534
|
method: "removeIntersection()",
|
|
4622
4535
|
parameters: { column1, column2, newColumn },
|
|
4623
4536
|
}));
|
|
4624
|
-
this.projections[newColumn] = this.projections[column1];
|
|
4625
4537
|
}
|
|
4626
4538
|
/**
|
|
4627
4539
|
* Fills holes in polygon geometries.
|
|
@@ -4710,21 +4622,17 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4710
4622
|
* ```
|
|
4711
4623
|
*/
|
|
4712
4624
|
async union(column1, column2, newColumn) {
|
|
4713
|
-
if (this.projections[column1] !== this.projections[column2]) {
|
|
4714
|
-
throw new Error(`${column1} and ${column2} don't have the same projection.\n${column1}: ${this.projections[column1]}\n${column2}: ${this.projections[column2]}`);
|
|
4715
|
-
}
|
|
4716
4625
|
await (0, queryDB_js_1.default)(this, (await this.getColumns()).includes(newColumn)
|
|
4717
|
-
? `INSTALL spatial; LOAD spatial; UPDATE "${this.name}" SET "${newColumn}" = ST_Union("${column1}", "${column2}")`
|
|
4718
|
-
: `INSTALL spatial; LOAD spatial; ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Union("${column1}", "${column2}")`, (0, mergeOptions_js_1.default)(this, {
|
|
4626
|
+
? `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; UPDATE "${this.name}" SET "${newColumn}" = ST_Union("${column1}", "${column2}")`
|
|
4627
|
+
: `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Union("${column1}", "${column2}")`, (0, mergeOptions_js_1.default)(this, {
|
|
4719
4628
|
table: this.name,
|
|
4720
4629
|
method: "union()",
|
|
4721
4630
|
parameters: { column1, column2, newColumn },
|
|
4722
4631
|
}));
|
|
4723
|
-
this.projections[newColumn] = this.projections[column1];
|
|
4724
4632
|
}
|
|
4725
4633
|
/**
|
|
4726
4634
|
* Extracts the latitude and longitude coordinates from point geometries.
|
|
4727
|
-
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84)
|
|
4635
|
+
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84).
|
|
4728
4636
|
*
|
|
4729
4637
|
* @param column - The name of the column storing the point geometries.
|
|
4730
4638
|
* @param columnLat - The name of the new column where the extracted latitude values will be stored.
|
|
@@ -4739,8 +4647,8 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4739
4647
|
* ```
|
|
4740
4648
|
*/
|
|
4741
4649
|
async latLon(column, columnLat, columnLon) {
|
|
4742
|
-
await (0, queryDB_js_1.default)(this, `ALTER TABLE "${this.name}" ADD "${columnLat}" DOUBLE; UPDATE "${this.name}" SET "${columnLat}" =
|
|
4743
|
-
ALTER TABLE "${this.name}" ADD "${columnLon}" DOUBLE; UPDATE "${this.name}" SET "${columnLon}" =
|
|
4650
|
+
await (0, queryDB_js_1.default)(this, `ALTER TABLE "${this.name}" ADD "${columnLat}" DOUBLE; UPDATE "${this.name}" SET "${columnLat}" = ST_Y("${column}");
|
|
4651
|
+
ALTER TABLE "${this.name}" ADD "${columnLon}" DOUBLE; UPDATE "${this.name}" SET "${columnLon}" = ST_X("${column}");`, (0, mergeOptions_js_1.default)(this, {
|
|
4744
4652
|
table: this.name,
|
|
4745
4653
|
method: "latLon()",
|
|
4746
4654
|
parameters: { column, columnLon, columnLat },
|
|
@@ -4807,13 +4715,12 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4807
4715
|
? options.column
|
|
4808
4716
|
: await (0, findGeoColumn_js_1.default)(this);
|
|
4809
4717
|
await (0, queryDB_js_1.default)(this, (await this.getColumns()).includes(newColumn)
|
|
4810
|
-
? `INSTALL spatial; LOAD spatial; UPDATE "${this.name}" SET "${newColumn}" = ST_Centroid("${column}")`
|
|
4811
|
-
: `INSTALL spatial; LOAD spatial; ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Centroid("${column}")`, (0, mergeOptions_js_1.default)(this, {
|
|
4718
|
+
? `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; UPDATE "${this.name}" SET "${newColumn}" = ST_Centroid("${column}")`
|
|
4719
|
+
: `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Centroid("${column}")`, (0, mergeOptions_js_1.default)(this, {
|
|
4812
4720
|
table: this.name,
|
|
4813
4721
|
method: "centroid()",
|
|
4814
4722
|
parameters: { column, newColumn },
|
|
4815
4723
|
}));
|
|
4816
|
-
this.projections[newColumn] = this.projections[column];
|
|
4817
4724
|
}
|
|
4818
4725
|
/**
|
|
4819
4726
|
* Generates a random point within the geometries of a specified column.
|
|
@@ -4822,6 +4729,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4822
4729
|
* @param nbPointsToTry - The number of points to generate within the bounding box of each geometry to find one that is within the geometry itself.
|
|
4823
4730
|
* @param options - An optional object with configuration options:
|
|
4824
4731
|
* @param options.column - The name of the column storing the geometries within which the random points will be generated. If omitted, the method will automatically attempt to find a geometry column.
|
|
4732
|
+
* @param options.try - If `true`, the method will not throw an error if some points cannot be generated. Corresponding rows will have `NULL` in the new column.
|
|
4825
4733
|
*
|
|
4826
4734
|
* @example
|
|
4827
4735
|
* ```ts
|
|
@@ -4834,10 +4742,16 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4834
4742
|
* // Generate a random point for each geometry in a specific column named 'areaGeom', trying 50 points
|
|
4835
4743
|
* await table.randomPoint("pointInArea", 50, { column: "areaGeom" });
|
|
4836
4744
|
* ```
|
|
4745
|
+
*
|
|
4746
|
+
* @example
|
|
4747
|
+
* ```ts
|
|
4748
|
+
* // Generate a random point for each geometry, but don't throw if some points cannot be generated
|
|
4749
|
+
* await table.randomPoint("pointInArea", 1, { try: true });
|
|
4750
|
+
* ```
|
|
4837
4751
|
*/
|
|
4838
4752
|
async randomPoint(newColumn, nbPointsToTry, options = {}) {
|
|
4839
|
-
if (typeof nbPointsToTry !== "number" || nbPointsToTry <
|
|
4840
|
-
throw new Error("nbPointsToTry must be a number greater than 0");
|
|
4753
|
+
if (typeof nbPointsToTry !== "number" || nbPointsToTry < 0) {
|
|
4754
|
+
throw new Error("nbPointsToTry must be a number greater than or equal to 0");
|
|
4841
4755
|
}
|
|
4842
4756
|
const column = typeof options.column === "string"
|
|
4843
4757
|
? options.column
|
|
@@ -4845,15 +4759,20 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4845
4759
|
await (0, queryDB_js_1.default)(this, (0, randomPointQuery_js_1.default)(this.name, column, newColumn, nbPointsToTry), (0, mergeOptions_js_1.default)(this, {
|
|
4846
4760
|
table: this.name,
|
|
4847
4761
|
method: "randomPoint()",
|
|
4848
|
-
parameters: { column, newColumn, nbPointsToTry },
|
|
4762
|
+
parameters: { column, newColumn, nbPointsToTry, options },
|
|
4849
4763
|
}));
|
|
4850
|
-
|
|
4764
|
+
const nbNulls = await this.getNbRows({
|
|
4765
|
+
conditions: `"${newColumn}" IS NULL`,
|
|
4766
|
+
});
|
|
4767
|
+
if (nbNulls > 0 && !options.try) {
|
|
4768
|
+
throw new Error(`${nbNulls} points could not be generated. Consider increasing nbPointsToTry or set options.try to true.`);
|
|
4769
|
+
}
|
|
4851
4770
|
}
|
|
4852
4771
|
/**
|
|
4853
4772
|
* Computes the distance between geometries in two specified columns.
|
|
4854
4773
|
* By default, the distance is calculated in the Spatial Reference System (SRS) unit of the input geometries.
|
|
4855
4774
|
* You can optionally specify `"spheroid"` or `"haversine"` methods to get results in meters or kilometers.
|
|
4856
|
-
* If using `"spheroid"` or `"haversine"`, the input geometries must be in the EPSG:4326 coordinate system (WGS84)
|
|
4775
|
+
* If using `"spheroid"` or `"haversine"`, the input geometries must be in the EPSG:4326 coordinate system (WGS84).
|
|
4857
4776
|
*
|
|
4858
4777
|
* @param column1 - The name of the first column storing geometries.
|
|
4859
4778
|
* @param column2 - The name of the second column storing geometries.
|
|
@@ -4969,7 +4888,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4969
4888
|
parameters: { column, method, options },
|
|
4970
4889
|
}));
|
|
4971
4890
|
if (typeof options.outputTable === "string") {
|
|
4972
|
-
return this.sdb.newTable(options.outputTable
|
|
4891
|
+
return this.sdb.newTable(options.outputTable);
|
|
4973
4892
|
}
|
|
4974
4893
|
else {
|
|
4975
4894
|
return this;
|
|
@@ -5004,7 +4923,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
5004
4923
|
}
|
|
5005
4924
|
/**
|
|
5006
4925
|
* Returns the bounding box of geometries in `[minLat, minLon, maxLat, maxLon]` order.
|
|
5007
|
-
* By default, the method will try to find the column with the geometries. The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84)
|
|
4926
|
+
* By default, the method will try to find the column with the geometries. The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84).
|
|
5008
4927
|
*
|
|
5009
4928
|
* @param column - The name of the column storing geometries. If omitted, the method will automatically attempt to find a geometry column.
|
|
5010
4929
|
* @returns A promise that resolves to an array `[minLat, minLon, maxLat, maxLon]` representing the bounding box.
|
|
@@ -5027,10 +4946,10 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
5027
4946
|
async getBoundingBox(column) {
|
|
5028
4947
|
const col = column ?? (await (0, findGeoColumn_js_1.default)(this));
|
|
5029
4948
|
const result = (await (0, queryDB_js_1.default)(this, `SELECT
|
|
5030
|
-
MIN(
|
|
5031
|
-
MIN(
|
|
5032
|
-
MAX(
|
|
5033
|
-
MAX(
|
|
4949
|
+
MIN(ST_YMin("${col}")) AS minX,
|
|
4950
|
+
MIN(ST_XMin("${col}")) AS minY,
|
|
4951
|
+
MAX(ST_YMax("${col}")) AS maxX,
|
|
4952
|
+
MAX(ST_XMax("${col}")) AS maxY,
|
|
5034
4953
|
from "${this.name}";`, (0, mergeOptions_js_1.default)(this, {
|
|
5035
4954
|
table: this.name,
|
|
5036
4955
|
method: "getBoundingBox()",
|
|
@@ -5042,7 +4961,6 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
5042
4961
|
/**
|
|
5043
4962
|
* Returns the table's geospatial data as a GeoJSON object.
|
|
5044
4963
|
* If the table has multiple geometry columns, you must specify which one to use.
|
|
5045
|
-
* If the geometry column's projection is WGS84 or EPSG:4326 (`[latitude, longitude]` axis order), the coordinates will be flipped to follow the RFC7946 standard (`[longitude, latitude]` axis order) in the output GeoJSON.
|
|
5046
4964
|
*
|
|
5047
4965
|
* @param column - The name of the column storing the geometries. If omitted, the method will automatically attempt to find a geometry column.
|
|
5048
4966
|
* @param options - An optional object with configuration options:
|
|
@@ -5147,8 +5065,6 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
5147
5065
|
* Writes the table's geospatial data to a file in GeoJSON, GeoParquet, or Shapefile format.
|
|
5148
5066
|
* If the specified path does not exist, it will be created.
|
|
5149
5067
|
*
|
|
5150
|
-
* For GeoJSON files (`.geojson` or `.json`), if the projection is WGS84 or EPSG:4326 (`[latitude, longitude]` axis order), the coordinates will be flipped to follow the RFC7946 standard (`[longitude, latitude]` axis order) in the output.
|
|
5151
|
-
*
|
|
5152
5068
|
* @param file - The absolute path to the output file (e.g., `"./output.geojson"`, `"./output.geoparquet"`, `"./shapefile-folder/output.shp"`).
|
|
5153
5069
|
* @param options - An optional object with configuration options:
|
|
5154
5070
|
* @param options.precision - For GeoJSON, the maximum number of figures after the decimal separator to write in coordinates. Defaults to `undefined` (full precision).
|
|
@@ -5402,6 +5318,22 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
5402
5318
|
console.table(await (0, getDescription_js_1.default)(this));
|
|
5403
5319
|
}
|
|
5404
5320
|
}
|
|
5321
|
+
/**
|
|
5322
|
+
* Retrieves the projection of a specified geospatial column.
|
|
5323
|
+
*
|
|
5324
|
+
* @param column - The name of the geospatial column for which to retrieve the projection.
|
|
5325
|
+
* @returns A promise that resolves to the projection of the specified column.
|
|
5326
|
+
* @category Geospatial
|
|
5327
|
+
*
|
|
5328
|
+
* @example
|
|
5329
|
+
* ```ts
|
|
5330
|
+
* // Get the projection of the 'geom' column
|
|
5331
|
+
* const projection = await table.getProjection("geom");
|
|
5332
|
+
* ```
|
|
5333
|
+
*/
|
|
5334
|
+
async getProjection(column) {
|
|
5335
|
+
return (await this.sdb.customQuery(`SELECT ST_CRS("${column}") AS proj FROM "${this.name}" LIMIT 1;`, { returnDataFrom: "query" }))[0].proj;
|
|
5336
|
+
}
|
|
5405
5337
|
/**
|
|
5406
5338
|
* Logs the projections of the geospatial data (if any) to the console.
|
|
5407
5339
|
*
|
|
@@ -5416,7 +5348,19 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
5416
5348
|
*/
|
|
5417
5349
|
async logProjections() {
|
|
5418
5350
|
console.log(`\nTable ${this.name} projections:`);
|
|
5419
|
-
|
|
5351
|
+
const types = await this.getTypes();
|
|
5352
|
+
const geoColumns = Object.entries(types)
|
|
5353
|
+
.filter(([_, type]) => type.toLowerCase().includes("geometry"))
|
|
5354
|
+
.map(([column]) => column);
|
|
5355
|
+
if (geoColumns.length === 0) {
|
|
5356
|
+
console.log("No geometry columns found.");
|
|
5357
|
+
}
|
|
5358
|
+
else {
|
|
5359
|
+
for (const column of geoColumns) {
|
|
5360
|
+
const projection = types[column];
|
|
5361
|
+
console.log(`- Column "${column}": ${projection}`);
|
|
5362
|
+
}
|
|
5363
|
+
}
|
|
5420
5364
|
return await this;
|
|
5421
5365
|
}
|
|
5422
5366
|
/**
|