@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
package/esm/class/SimpleTable.js
CHANGED
|
@@ -62,7 +62,6 @@ import summarize from "../methods/summarize.js";
|
|
|
62
62
|
import correlations from "../methods/correlations.js";
|
|
63
63
|
import linearRegressions from "../methods/linearRegressions.js";
|
|
64
64
|
import joinGeo from "../methods/joinGeo.js";
|
|
65
|
-
import getProjection from "../helpers/getProjection.js";
|
|
66
65
|
import cache from "../methods/cache.js";
|
|
67
66
|
import camelCase from "../helpers/camelCase.js";
|
|
68
67
|
import formatNumber from "../helpers/formatNumber.js";
|
|
@@ -85,7 +84,6 @@ import getIdenticalColumns from "../helpers/getIdenticalColumns.js";
|
|
|
85
84
|
import capitalizeQuery from "../methods/capitalizeQuery.js";
|
|
86
85
|
import truncateQuery from "../methods/truncateQuery.js";
|
|
87
86
|
import padQuery from "../methods/padQuery.js";
|
|
88
|
-
import getProjectionParquet from "../helpers/getProjectionParquet.js";
|
|
89
87
|
import hasGeometryColumn from "../helpers/hasGeometryColumn.js";
|
|
90
88
|
import unifyColumns from "../helpers/unifyColumns.js";
|
|
91
89
|
import accumulateQuery from "../helpers/accumulateQuery.js";
|
|
@@ -147,7 +145,6 @@ export default class SimpleTable extends Simple {
|
|
|
147
145
|
* Creates an instance of SimpleTable.
|
|
148
146
|
*
|
|
149
147
|
* @param name - The name of the table.
|
|
150
|
-
* @param projections - An object mapping column names to their geospatial projections.
|
|
151
148
|
* @param simpleDB - The SimpleDB instance that this table belongs to.
|
|
152
149
|
* @param options - An optional object with configuration options:
|
|
153
150
|
* @param options.debug - A boolean indicating whether to enable debug mode.
|
|
@@ -156,7 +153,7 @@ export default class SimpleTable extends Simple {
|
|
|
156
153
|
* @param options.types - A boolean indicating whether to include data types when logging a table.
|
|
157
154
|
* @category Constructor
|
|
158
155
|
*/
|
|
159
|
-
constructor(name,
|
|
156
|
+
constructor(name, simpleDB, options = {}) {
|
|
160
157
|
super(options);
|
|
161
158
|
/**
|
|
162
159
|
* Name of the table in the database.
|
|
@@ -170,19 +167,7 @@ export default class SimpleTable extends Simple {
|
|
|
170
167
|
value: void 0
|
|
171
168
|
});
|
|
172
169
|
/**
|
|
173
|
-
* The
|
|
174
|
-
*
|
|
175
|
-
* @defaultValue `{}`
|
|
176
|
-
* @category Properties
|
|
177
|
-
*/
|
|
178
|
-
Object.defineProperty(this, "projections", {
|
|
179
|
-
enumerable: true,
|
|
180
|
-
configurable: true,
|
|
181
|
-
writable: true,
|
|
182
|
-
value: void 0
|
|
183
|
-
});
|
|
184
|
-
/**
|
|
185
|
-
* The indexes of the table.
|
|
170
|
+
* The indexes of the table, if any.
|
|
186
171
|
*
|
|
187
172
|
* @defaultValue `[]`
|
|
188
173
|
* @category Properties
|
|
@@ -194,7 +179,6 @@ export default class SimpleTable extends Simple {
|
|
|
194
179
|
value: void 0
|
|
195
180
|
});
|
|
196
181
|
this.name = name;
|
|
197
|
-
this.projections = projections;
|
|
198
182
|
this.sdb = simpleDB;
|
|
199
183
|
this.runQuery = runQuery;
|
|
200
184
|
this.indexes = [];
|
|
@@ -242,8 +226,9 @@ export default class SimpleTable extends Simple {
|
|
|
242
226
|
let spatial = "";
|
|
243
227
|
if (Object.values(types)
|
|
244
228
|
.map((d) => d.toLowerCase())
|
|
245
|
-
.
|
|
246
|
-
spatial =
|
|
229
|
+
.some((d) => d.startsWith("geometry"))) {
|
|
230
|
+
spatial =
|
|
231
|
+
"INSTALL spatial; LOAD spatial; SET geometry_always_xy = true;\n";
|
|
247
232
|
}
|
|
248
233
|
await queryDB(this, `${spatial}CREATE OR REPLACE TABLE "${this.name}" (${Object.keys(types)
|
|
249
234
|
.map((d) => `"${d}" ${parseType(types[d])}`)
|
|
@@ -398,12 +383,10 @@ export default class SimpleTable extends Simple {
|
|
|
398
383
|
}
|
|
399
384
|
/**
|
|
400
385
|
* Loads geospatial data from an external file or URL into the table.
|
|
401
|
-
* The coordinates of files or URLs ending with `.json` or `.geojson` are automatically flipped to `[latitude, longitude]` axis order.
|
|
402
386
|
*
|
|
403
387
|
* @param file - The URL or absolute path to the external file containing the geospatial data.
|
|
404
388
|
* @param options - An optional object with configuration options:
|
|
405
|
-
* @param options.toWGS84 - If `true`, the method will attempt to reproject the data to WGS84
|
|
406
|
-
* @param options.from - An optional string specifying the original projection of the data, if the method is unable to detect it automatically.
|
|
389
|
+
* @param options.toWGS84 - If `true`, the method will attempt to reproject the data to WGS84.
|
|
407
390
|
* @returns A promise that resolves to the SimpleTable instance after the geospatial data has been loaded.
|
|
408
391
|
* @category Geospatial
|
|
409
392
|
*
|
|
@@ -434,7 +417,7 @@ export default class SimpleTable extends Simple {
|
|
|
434
417
|
async loadGeoData(file, options = {}) {
|
|
435
418
|
const fileExtension = getExtension(file);
|
|
436
419
|
if (fileExtension === "geoparquet" || fileExtension === "parquet") {
|
|
437
|
-
await queryDB(this, `INSTALL spatial; LOAD spatial;${file.toLowerCase().includes("http")
|
|
420
|
+
await queryDB(this, `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true;${file.toLowerCase().includes("http")
|
|
438
421
|
? " INSTALL https; LOAD https;"
|
|
439
422
|
: ""}
|
|
440
423
|
CREATE OR REPLACE TABLE "${this.name}" AS SELECT * FROM read_parquet('${cleanPath(file)}');`, mergeOptions(this, {
|
|
@@ -442,32 +425,21 @@ export default class SimpleTable extends Simple {
|
|
|
442
425
|
method: "loadGeoData()",
|
|
443
426
|
parameters: { file, options },
|
|
444
427
|
}));
|
|
445
|
-
this.projections = await getProjectionParquet(this, file);
|
|
446
|
-
if (options.toWGS84) {
|
|
447
|
-
console.log("\nThis file is a parquet. Option toWGS84 has no effect. Use the .reproject() method instead.\n");
|
|
448
|
-
}
|
|
449
428
|
}
|
|
450
429
|
else {
|
|
451
|
-
await queryDB(this, `INSTALL spatial; LOAD spatial;${file.toLowerCase().includes("http")
|
|
430
|
+
await queryDB(this, `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true;${file.toLowerCase().includes("http")
|
|
452
431
|
? " INSTALL https; LOAD https;"
|
|
453
432
|
: ""}
|
|
454
|
-
CREATE OR REPLACE TABLE "${this.name}" AS SELECT * FROM ST_Read('${file}');`, mergeOptions(this, {
|
|
433
|
+
CREATE OR REPLACE TABLE "${this.name}" AS SELECT * EXCLUDE OGC_FID FROM ST_Read('${file}');`, mergeOptions(this, {
|
|
455
434
|
table: this.name,
|
|
456
435
|
method: "loadGeoData()",
|
|
457
436
|
parameters: { file, options },
|
|
458
437
|
}));
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
const
|
|
462
|
-
if (
|
|
463
|
-
await this.
|
|
464
|
-
this.projections["geom"] = "+proj=latlong +datum=WGS84 +no_defs";
|
|
465
|
-
if (options.toWGS84) {
|
|
466
|
-
console.log("This file is a json or geojson. Option toWGS84 has no effect.");
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
else if (options.toWGS84) {
|
|
470
|
-
await this.reproject("WGS84", { ...options, column: "geom" }); // column storing geometries is geom by default
|
|
438
|
+
}
|
|
439
|
+
if (options.toWGS84) {
|
|
440
|
+
const proj = await this.getProjection("geom");
|
|
441
|
+
if (proj !== "EPSG:4326") {
|
|
442
|
+
await this.reproject("EPSG:4326");
|
|
471
443
|
}
|
|
472
444
|
}
|
|
473
445
|
return this;
|
|
@@ -759,9 +731,8 @@ export default class SimpleTable extends Simple {
|
|
|
759
731
|
: [tablesToInsert];
|
|
760
732
|
if (!await this.sdb.hasTable(this.name)) {
|
|
761
733
|
await this.setTypes((await array[0].getTypes()));
|
|
762
|
-
this.projections = structuredClone(array[0].projections);
|
|
763
734
|
}
|
|
764
|
-
// Checking columns, types
|
|
735
|
+
// Checking columns, types
|
|
765
736
|
if (!options.unifyColumns) {
|
|
766
737
|
const thisColumns = (await this.getColumns()).sort().join(",");
|
|
767
738
|
for (const table of array) {
|
|
@@ -773,27 +744,22 @@ export default class SimpleTable extends Simple {
|
|
|
773
744
|
}
|
|
774
745
|
const allTables = [this, ...array];
|
|
775
746
|
const allTypes = {};
|
|
776
|
-
const allProjections = {};
|
|
777
747
|
for (const table of allTables) {
|
|
778
748
|
const types = await table.getTypes();
|
|
779
749
|
for (const key in types) {
|
|
780
750
|
if (!allTypes[key]) {
|
|
781
751
|
allTypes[key] = types[key];
|
|
782
|
-
allProjections[key] = table.projections[key];
|
|
783
752
|
}
|
|
784
753
|
else {
|
|
785
754
|
if (allTypes[key] !== types[key]) {
|
|
786
755
|
throw new Error(`The column ${key} has different types in the tables.`);
|
|
787
756
|
}
|
|
788
|
-
else if (allProjections[key] !== table.projections[key]) {
|
|
789
|
-
throw new Error(`The column ${key} has different projections in the tables.`);
|
|
790
|
-
}
|
|
791
757
|
}
|
|
792
758
|
}
|
|
793
759
|
}
|
|
794
760
|
let columnsAdded = {};
|
|
795
761
|
if (options.unifyColumns) {
|
|
796
|
-
columnsAdded = await unifyColumns(allTables, allTypes
|
|
762
|
+
columnsAdded = await unifyColumns(allTables, allTypes);
|
|
797
763
|
}
|
|
798
764
|
await queryDB(this, array
|
|
799
765
|
.map((tableToInsert) => `INSERT INTO "${this.name}" BY NAME SELECT * FROM "${tableToInsert.name}";`)
|
|
@@ -892,29 +858,16 @@ export default class SimpleTable extends Simple {
|
|
|
892
858
|
const columns = typeof nameOrOptions === "object" && nameOrOptions.columns
|
|
893
859
|
? stringToArray(nameOrOptions.columns)
|
|
894
860
|
: [];
|
|
895
|
-
// Dealing with projections
|
|
896
|
-
const clonedProjections = structuredClone(this.projections);
|
|
897
|
-
let newProjections = {};
|
|
898
|
-
if (columns.length > 0) {
|
|
899
|
-
for (const col of columns) {
|
|
900
|
-
if (clonedProjections[col]) {
|
|
901
|
-
newProjections[col] = clonedProjections[col];
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
else {
|
|
906
|
-
newProjections = clonedProjections;
|
|
907
|
-
}
|
|
908
861
|
// Delegate to sdb.newTable() so subclasses using tableClass work correctly.
|
|
909
862
|
let clonedTable;
|
|
910
863
|
const options = typeof nameOrOptions === "string"
|
|
911
864
|
? { outputTable: nameOrOptions }
|
|
912
865
|
: nameOrOptions;
|
|
913
866
|
if (typeof options.outputTable === "string") {
|
|
914
|
-
clonedTable = this.sdb.newTable(options.outputTable
|
|
867
|
+
clonedTable = this.sdb.newTable(options.outputTable);
|
|
915
868
|
}
|
|
916
869
|
else {
|
|
917
|
-
clonedTable = this.sdb.newTable(undefined
|
|
870
|
+
clonedTable = this.sdb.newTable(undefined);
|
|
918
871
|
}
|
|
919
872
|
await queryDB(this, cloneQuery(this.name, clonedTable.name, columns, options), mergeOptions(this, {
|
|
920
873
|
table: clonedTable.name,
|
|
@@ -945,9 +898,6 @@ export default class SimpleTable extends Simple {
|
|
|
945
898
|
method: "cloneColumn()",
|
|
946
899
|
parameters: { originalColumn, newColumn },
|
|
947
900
|
}));
|
|
948
|
-
if (typeof this.projections[originalColumn] === "string") {
|
|
949
|
-
this.projections[newColumn] = this.projections[originalColumn];
|
|
950
|
-
}
|
|
951
901
|
}
|
|
952
902
|
/**
|
|
953
903
|
* Clones a column in the table and offsets its values by a specified number of rows.
|
|
@@ -1012,9 +962,6 @@ export default class SimpleTable extends Simple {
|
|
|
1012
962
|
method: "cloneColumnWithOffset()",
|
|
1013
963
|
parameters: { originalColumn, newColumn },
|
|
1014
964
|
}));
|
|
1015
|
-
if (typeof this.projections[originalColumn] === "string") {
|
|
1016
|
-
this.projections[newColumn] = this.projections[originalColumn];
|
|
1017
|
-
}
|
|
1018
965
|
}
|
|
1019
966
|
/**
|
|
1020
967
|
* 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`.
|
|
@@ -1260,7 +1207,7 @@ export default class SimpleTable extends Simple {
|
|
|
1260
1207
|
parameters: { count, options },
|
|
1261
1208
|
}));
|
|
1262
1209
|
if (typeof options.outputTable === "string") {
|
|
1263
|
-
return this.sdb.newTable(options.outputTable
|
|
1210
|
+
return this.sdb.newTable(options.outputTable);
|
|
1264
1211
|
}
|
|
1265
1212
|
else {
|
|
1266
1213
|
return this;
|
|
@@ -1533,15 +1480,6 @@ export default class SimpleTable extends Simple {
|
|
|
1533
1480
|
method: "renameColumns()",
|
|
1534
1481
|
parameters: { names },
|
|
1535
1482
|
}));
|
|
1536
|
-
// Taking care of projections
|
|
1537
|
-
const types = await this.getTypes();
|
|
1538
|
-
for (let i = 0; i < newNames.length; i++) {
|
|
1539
|
-
if (types[newNames[i]] === "GEOMETRY") {
|
|
1540
|
-
const projection = this.projections[oldNames[i]];
|
|
1541
|
-
delete this.projections[oldNames[i]];
|
|
1542
|
-
this.projections[newNames[i]] = projection;
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
1483
|
}
|
|
1546
1484
|
/**
|
|
1547
1485
|
* Cleans column names by removing non-alphanumeric characters and formatting them to camel case.
|
|
@@ -1758,12 +1696,6 @@ export default class SimpleTable extends Simple {
|
|
|
1758
1696
|
method: "removeColumns()",
|
|
1759
1697
|
parameters: { columns },
|
|
1760
1698
|
}));
|
|
1761
|
-
// Taking care of projections
|
|
1762
|
-
for (const col of cols) {
|
|
1763
|
-
if (Object.prototype.hasOwnProperty.call(this.projections, col)) {
|
|
1764
|
-
delete this.projections[col];
|
|
1765
|
-
}
|
|
1766
|
-
}
|
|
1767
1699
|
}
|
|
1768
1700
|
/**
|
|
1769
1701
|
* Adds a new column to the table based on a specified data type (JavaScript or SQL types) and a SQL definition.
|
|
@@ -1772,7 +1704,6 @@ export default class SimpleTable extends Simple {
|
|
|
1772
1704
|
* @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"`).
|
|
1773
1705
|
* @param definition - A SQL expression defining how the values for the new column should be computed (e.g., `"column1 + column2"`, `"ST_Centroid(geom_column)"`).
|
|
1774
1706
|
* @param options - An optional object with configuration options:
|
|
1775
|
-
* @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`).
|
|
1776
1707
|
* @returns A promise that resolves when the new column has been added.
|
|
1777
1708
|
* @category Column Operations
|
|
1778
1709
|
*
|
|
@@ -1785,33 +1716,28 @@ export default class SimpleTable extends Simple {
|
|
|
1785
1716
|
* @example
|
|
1786
1717
|
* ```ts
|
|
1787
1718
|
* // Add a new geometry column 'centroid' using the centroid of an existing 'country' geometry column
|
|
1788
|
-
*
|
|
1789
|
-
* await table.addColumn("centroid", "geometry", `ST_Centroid("country")`, {
|
|
1790
|
-
* projection: table.projections.country,
|
|
1791
|
-
* });
|
|
1719
|
+
* await table.addColumn("centroid", "geometry('EPSG:4326')", `ST_Centroid("country")`);
|
|
1792
1720
|
* ```
|
|
1793
1721
|
*/
|
|
1794
|
-
async addColumn(newColumn, type, definition
|
|
1722
|
+
async addColumn(newColumn, type, definition) {
|
|
1795
1723
|
const newType = parseType(type);
|
|
1724
|
+
// let spatial = "";
|
|
1725
|
+
// if (newType.toLowerCase().includes("geometry")) {
|
|
1726
|
+
// spatial = "INSTALL spatial; LOAD spatial; SET geometry_always_xy = true;";
|
|
1727
|
+
// }
|
|
1796
1728
|
await queryDB(this, `ALTER TABLE "${this.name}" ADD "${newColumn}" ${newType};
|
|
1797
1729
|
UPDATE "${this.name}" SET "${newColumn}" = ${definition}`, mergeOptions(this, {
|
|
1798
1730
|
table: this.name,
|
|
1799
1731
|
method: "addColumn()",
|
|
1800
1732
|
parameters: { newColumn, type, definition },
|
|
1801
1733
|
}));
|
|
1802
|
-
if (newType === "GEOMETRY") {
|
|
1803
|
-
if (typeof options.projection === "string") {
|
|
1804
|
-
this.projections[newColumn] = options.projection;
|
|
1805
|
-
}
|
|
1806
|
-
else {
|
|
1807
|
-
throw new Error("You are creating a new column storing geometries. You must specify a projection. See examples in documentation.");
|
|
1808
|
-
}
|
|
1809
|
-
}
|
|
1810
1734
|
}
|
|
1811
1735
|
/**
|
|
1812
|
-
* Adds a new column to the table containing the row number.
|
|
1736
|
+
* Adds a new column to the table containing the row number, starting at 0 (like an index).
|
|
1813
1737
|
*
|
|
1814
1738
|
* @param newColumn - The name of the new column that will store the row number.
|
|
1739
|
+
* @param options - An optional object with configuration options:
|
|
1740
|
+
* @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.
|
|
1815
1741
|
* @returns A promise that resolves when the row number column has been added.
|
|
1816
1742
|
* @category Column Operations
|
|
1817
1743
|
*
|
|
@@ -1820,12 +1746,24 @@ export default class SimpleTable extends Simple {
|
|
|
1820
1746
|
* // Add a new column named 'rowNumber' with the row number for each row
|
|
1821
1747
|
* await table.addRowNumber("rowNumber");
|
|
1822
1748
|
* ```
|
|
1749
|
+
*
|
|
1750
|
+
* @example
|
|
1751
|
+
* ```ts
|
|
1752
|
+
* // Add a new column named 'rowNumber' with the row number for each 'category'
|
|
1753
|
+
* await table.addRowNumber("rowNumber", { categories: "category" });
|
|
1754
|
+
* ```
|
|
1823
1755
|
*/
|
|
1824
|
-
async addRowNumber(newColumn) {
|
|
1825
|
-
|
|
1756
|
+
async addRowNumber(newColumn, options = {}) {
|
|
1757
|
+
const categories = options.categories
|
|
1758
|
+
? stringToArray(options.categories)
|
|
1759
|
+
: [];
|
|
1760
|
+
const partition = categories.length > 0
|
|
1761
|
+
? `PARTITION BY ${categories.map((d) => `"${d}"`).join(", ")}`
|
|
1762
|
+
: "";
|
|
1763
|
+
await queryDB(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`, mergeOptions(this, {
|
|
1826
1764
|
table: this.name,
|
|
1827
1765
|
method: "addRowNumber()",
|
|
1828
|
-
parameters: { newColumn },
|
|
1766
|
+
parameters: { newColumn, options },
|
|
1829
1767
|
}));
|
|
1830
1768
|
}
|
|
1831
1769
|
/**
|
|
@@ -1872,15 +1810,10 @@ export default class SimpleTable extends Simple {
|
|
|
1872
1810
|
method: "crossJoin()",
|
|
1873
1811
|
parameters: { rightTable, options },
|
|
1874
1812
|
}));
|
|
1875
|
-
const allProjections = {
|
|
1876
|
-
...this.projections,
|
|
1877
|
-
...rightTable.projections,
|
|
1878
|
-
};
|
|
1879
1813
|
if (typeof options.outputTable === "string") {
|
|
1880
|
-
return this.sdb.newTable(options.outputTable
|
|
1814
|
+
return this.sdb.newTable(options.outputTable);
|
|
1881
1815
|
}
|
|
1882
1816
|
else {
|
|
1883
|
-
this.projections = allProjections;
|
|
1884
1817
|
return this;
|
|
1885
1818
|
}
|
|
1886
1819
|
}
|
|
@@ -3015,7 +2948,7 @@ export default class SimpleTable extends Simple {
|
|
|
3015
2948
|
}
|
|
3016
2949
|
await summarize(this, options);
|
|
3017
2950
|
if (typeof options.outputTable === "string") {
|
|
3018
|
-
return this.sdb.newTable(options.outputTable
|
|
2951
|
+
return this.sdb.newTable(options.outputTable);
|
|
3019
2952
|
}
|
|
3020
2953
|
else {
|
|
3021
2954
|
return this;
|
|
@@ -3157,7 +3090,7 @@ export default class SimpleTable extends Simple {
|
|
|
3157
3090
|
}
|
|
3158
3091
|
await correlations(this, options);
|
|
3159
3092
|
if (typeof options.outputTable === "string") {
|
|
3160
|
-
return this.sdb.newTable(options.outputTable
|
|
3093
|
+
return this.sdb.newTable(options.outputTable);
|
|
3161
3094
|
}
|
|
3162
3095
|
else {
|
|
3163
3096
|
return this;
|
|
@@ -3214,7 +3147,7 @@ export default class SimpleTable extends Simple {
|
|
|
3214
3147
|
}
|
|
3215
3148
|
await linearRegressions(this, options);
|
|
3216
3149
|
if (typeof options.outputTable === "string") {
|
|
3217
|
-
return this.sdb.newTable(options.outputTable
|
|
3150
|
+
return this.sdb.newTable(options.outputTable);
|
|
3218
3151
|
}
|
|
3219
3152
|
else {
|
|
3220
3153
|
return this;
|
|
@@ -3512,6 +3445,8 @@ export default class SimpleTable extends Simple {
|
|
|
3512
3445
|
/**
|
|
3513
3446
|
* Returns the number of rows in the table.
|
|
3514
3447
|
*
|
|
3448
|
+
* @param options - An optional object with configuration options:
|
|
3449
|
+
* @param options.conditions - The filtering conditions specified as a SQL `WHERE` clause (e.g., `"category = 'Book'"`).
|
|
3515
3450
|
* @returns A promise that resolves to a number representing the total count of rows.
|
|
3516
3451
|
* @category Getting Data
|
|
3517
3452
|
*
|
|
@@ -3521,9 +3456,16 @@ export default class SimpleTable extends Simple {
|
|
|
3521
3456
|
* const nbRows = await table.getNbRows();
|
|
3522
3457
|
* console.log(nbRows); // e.g., 100
|
|
3523
3458
|
* ```
|
|
3459
|
+
*
|
|
3460
|
+
* @example
|
|
3461
|
+
* ```ts
|
|
3462
|
+
* // Get the number of rows where 'category' is 'Book'
|
|
3463
|
+
* const nbBooks = await table.getNbRows({ conditions: "category = 'Book'" });
|
|
3464
|
+
* console.log(nbBooks);
|
|
3465
|
+
* ```
|
|
3524
3466
|
*/
|
|
3525
|
-
async getNbRows() {
|
|
3526
|
-
return await getNbRows(this);
|
|
3467
|
+
async getNbRows(options = {}) {
|
|
3468
|
+
return await getNbRows(this, options);
|
|
3527
3469
|
}
|
|
3528
3470
|
/**
|
|
3529
3471
|
* Returns the total number of values in the table (number of columns multiplied by the number of rows).
|
|
@@ -4060,7 +4002,7 @@ export default class SimpleTable extends Simple {
|
|
|
4060
4002
|
}
|
|
4061
4003
|
// GEOSPATIAL
|
|
4062
4004
|
/**
|
|
4063
|
-
* Creates point geometries from
|
|
4005
|
+
* Creates point geometries from latitude and longitude columns.
|
|
4064
4006
|
*
|
|
4065
4007
|
* @param columnLat - The name of the column storing the latitude values.
|
|
4066
4008
|
* @param columnLon - The name of the column storing the longitude values.
|
|
@@ -4076,13 +4018,12 @@ export default class SimpleTable extends Simple {
|
|
|
4076
4018
|
*/
|
|
4077
4019
|
async points(columnLat, columnLon, newColumn) {
|
|
4078
4020
|
await queryDB(this, (await this.getColumns()).includes(newColumn)
|
|
4079
|
-
? `INSTALL spatial; LOAD spatial; UPDATE "${this.name}" SET "${newColumn}" = ST_Point2D("${
|
|
4080
|
-
: `INSTALL spatial; LOAD spatial; ALTER TABLE "${this.name}" ADD COLUMN "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Point2D("${
|
|
4021
|
+
? `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; UPDATE "${this.name}" SET "${newColumn}" = ST_Point2D("${columnLon}", "${columnLat}")`
|
|
4022
|
+
: `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}")`, mergeOptions(this, {
|
|
4081
4023
|
table: this.name,
|
|
4082
4024
|
method: "points()",
|
|
4083
4025
|
parameters: { columnLat, columnLon, newColumn },
|
|
4084
4026
|
}));
|
|
4085
|
-
this.projections[newColumn] = "+proj=latlong +datum=WGS84 +no_defs";
|
|
4086
4027
|
}
|
|
4087
4028
|
/**
|
|
4088
4029
|
* Adds a column with boolean values indicating the validity of geometries.
|
|
@@ -4239,7 +4180,7 @@ export default class SimpleTable extends Simple {
|
|
|
4239
4180
|
}
|
|
4240
4181
|
/**
|
|
4241
4182
|
* Flips the coordinate order of geometries in a specified column (e.g., from `[lon, lat]` to `[lat, lon]` or vice-versa).
|
|
4242
|
-
* **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.
|
|
4183
|
+
* **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.
|
|
4243
4184
|
*
|
|
4244
4185
|
* @param column - The name of the column storing the geometries. If omitted, the method will automatically attempt to find a geometry column.
|
|
4245
4186
|
* @returns A promise that resolves when the coordinates have been flipped.
|
|
@@ -4298,11 +4239,9 @@ export default class SimpleTable extends Simple {
|
|
|
4298
4239
|
}
|
|
4299
4240
|
/**
|
|
4300
4241
|
* Reprojects the geometries in a specified column to another Spatial Reference System (SRS).
|
|
4301
|
-
* If reprojecting to WGS84 (`"WGS84"` or `"EPSG:4326"`), the resulting geometries will have `[latitude, longitude]` axis order.
|
|
4302
4242
|
*
|
|
4303
4243
|
* @param to - The target SRS (e.g., `"EPSG:3347"`, `"WGS84"`).
|
|
4304
4244
|
* @param options - An optional object with configuration options:
|
|
4305
|
-
* @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.
|
|
4306
4245
|
* @param options.column - The name of the column storing the geometries. If omitted, the method will automatically attempt to find a geometry column.
|
|
4307
4246
|
* @returns A promise that resolves when the geometries have been reprojected.
|
|
4308
4247
|
* @category Geospatial
|
|
@@ -4315,43 +4254,24 @@ export default class SimpleTable extends Simple {
|
|
|
4315
4254
|
*
|
|
4316
4255
|
* @example
|
|
4317
4256
|
* ```ts
|
|
4318
|
-
* // Reproject geometries from EPSG:4326 to EPSG:3347, specifying the original projection
|
|
4319
|
-
* await table.reproject("EPSG:3347", { from: "EPSG:4326" });
|
|
4320
|
-
* ```
|
|
4321
|
-
*
|
|
4322
|
-
* @example
|
|
4323
|
-
* ```ts
|
|
4324
4257
|
* // Reproject geometries in a specific column named 'myGeom' to EPSG:3347
|
|
4325
|
-
* await table.reproject("EPSG:3347", { column: "myGeom"
|
|
4258
|
+
* await table.reproject("EPSG:3347", { column: "myGeom" });
|
|
4326
4259
|
* ```
|
|
4327
4260
|
*/
|
|
4328
4261
|
async reproject(to, options = {}) {
|
|
4262
|
+
const cleanedTo = to.replace("WGS84", "EPSG:4326");
|
|
4329
4263
|
const column = typeof options.column === "string"
|
|
4330
4264
|
? options.column
|
|
4331
4265
|
: await findGeoColumn(this);
|
|
4332
|
-
|
|
4333
|
-
if (typeof from !== "string" || from === "") {
|
|
4334
|
-
throw new Error("Method reproject can't determine the original projection. Use the option 'from' to provide one.");
|
|
4335
|
-
}
|
|
4336
|
-
if (from === "+proj=latlong +datum=WGS84 +no_defs") {
|
|
4337
|
-
await this.flipCoordinates(column);
|
|
4338
|
-
}
|
|
4339
|
-
if (to.toUpperCase() === "WGS84" || to.toUpperCase() === "EPSG:4326") {
|
|
4340
|
-
to = "+proj=latlong +datum=WGS84 +no_defs";
|
|
4341
|
-
}
|
|
4342
|
-
await queryDB(this, `UPDATE "${this.name}" SET "${column}" = ST_Transform("${column}", '${from}', '${to}')`, mergeOptions(this, {
|
|
4266
|
+
await queryDB(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}";`, mergeOptions(this, {
|
|
4343
4267
|
table: this.name,
|
|
4344
4268
|
method: "reproject()",
|
|
4345
4269
|
parameters: { column, to },
|
|
4346
4270
|
}));
|
|
4347
|
-
this.projections[column] = to;
|
|
4348
|
-
if (this.projections[column] === "+proj=latlong +datum=WGS84 +no_defs") {
|
|
4349
|
-
await this.flipCoordinates(column);
|
|
4350
|
-
}
|
|
4351
4271
|
}
|
|
4352
4272
|
/**
|
|
4353
4273
|
* Computes the area of geometries in square meters (`"m2"`) or optionally square kilometers (`"km2"`).
|
|
4354
|
-
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84)
|
|
4274
|
+
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84).
|
|
4355
4275
|
*
|
|
4356
4276
|
* @param newColumn - The name of the new column where the computed areas will be stored.
|
|
4357
4277
|
* @param options - An optional object with configuration options:
|
|
@@ -4390,7 +4310,7 @@ export default class SimpleTable extends Simple {
|
|
|
4390
4310
|
}
|
|
4391
4311
|
/**
|
|
4392
4312
|
* Computes the length of line geometries in meters (`"m"`) or optionally kilometers (`"km"`).
|
|
4393
|
-
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84)
|
|
4313
|
+
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84).
|
|
4394
4314
|
*
|
|
4395
4315
|
* @param newColumn - The name of the new column where the computed lengths will be stored.
|
|
4396
4316
|
* @param options - An optional object with configuration options:
|
|
@@ -4429,7 +4349,7 @@ export default class SimpleTable extends Simple {
|
|
|
4429
4349
|
}
|
|
4430
4350
|
/**
|
|
4431
4351
|
* Computes the perimeter of polygon geometries in meters (`"m"`) or optionally kilometers (`"km"`).
|
|
4432
|
-
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84)
|
|
4352
|
+
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84).
|
|
4433
4353
|
*
|
|
4434
4354
|
* @param newColumn - The name of the new column where the computed perimeters will be stored.
|
|
4435
4355
|
* @param options - An optional object with configuration options:
|
|
@@ -4493,14 +4413,14 @@ export default class SimpleTable extends Simple {
|
|
|
4493
4413
|
const column = typeof options.column === "string"
|
|
4494
4414
|
? options.column
|
|
4495
4415
|
: await findGeoColumn(this);
|
|
4416
|
+
const proj = await this.getProjection(column);
|
|
4496
4417
|
await queryDB(this, (await this.getColumns()).includes(newColumn)
|
|
4497
|
-
? `INSTALL spatial; LOAD spatial; UPDATE "${this.name}" SET "${newColumn}" = ST_Buffer("${column}", ${distance})`
|
|
4498
|
-
: `INSTALL spatial; LOAD spatial; ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Buffer("${column}", ${distance})`, mergeOptions(this, {
|
|
4418
|
+
? `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; UPDATE "${this.name}" SET "${newColumn}" = ST_Buffer("${column}", ${distance})`
|
|
4419
|
+
: `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})`, mergeOptions(this, {
|
|
4499
4420
|
table: this.name,
|
|
4500
4421
|
method: "buffer()",
|
|
4501
4422
|
parameters: { column, newColumn, distance },
|
|
4502
4423
|
}));
|
|
4503
|
-
this.projections[newColumn] = this.projections[column];
|
|
4504
4424
|
}
|
|
4505
4425
|
/**
|
|
4506
4426
|
* Merges the data of this table (considered the left table) with another table (the right table) based on a spatial relationship.
|
|
@@ -4578,17 +4498,13 @@ export default class SimpleTable extends Simple {
|
|
|
4578
4498
|
* ```
|
|
4579
4499
|
*/
|
|
4580
4500
|
async intersection(column1, column2, newColumn) {
|
|
4581
|
-
if (this.projections[column1] !== this.projections[column2]) {
|
|
4582
|
-
throw new Error(`${column1} and ${column2} don't have the same projection.\n${column1}: ${this.projections[column1]}\n${column2}: ${this.projections[column2]}`);
|
|
4583
|
-
}
|
|
4584
4501
|
await queryDB(this, (await this.getColumns()).includes(newColumn)
|
|
4585
|
-
? `INSTALL spatial; LOAD spatial; UPDATE "${this.name}" SET "${newColumn}" = ST_Intersection("${column1}", "${column2}")`
|
|
4586
|
-
: `INSTALL spatial; LOAD spatial; ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Intersection("${column1}", "${column2}")`, mergeOptions(this, {
|
|
4502
|
+
? `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; UPDATE "${this.name}" SET "${newColumn}" = ST_Intersection("${column1}", "${column2}")`
|
|
4503
|
+
: `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}")`, mergeOptions(this, {
|
|
4587
4504
|
table: this.name,
|
|
4588
4505
|
method: "intersection()",
|
|
4589
4506
|
parameters: { column1, column2, newColumn },
|
|
4590
4507
|
}));
|
|
4591
|
-
this.projections[newColumn] = this.projections[column1];
|
|
4592
4508
|
}
|
|
4593
4509
|
/**
|
|
4594
4510
|
* Removes the intersection of two geometries from the first geometry, effectively computing the geometric difference.
|
|
@@ -4606,9 +4522,6 @@ export default class SimpleTable extends Simple {
|
|
|
4606
4522
|
* ```
|
|
4607
4523
|
*/
|
|
4608
4524
|
async removeIntersection(column1, column2, newColumn) {
|
|
4609
|
-
if (this.projections[column1] !== this.projections[column2]) {
|
|
4610
|
-
throw new Error(`${column1} and ${column2} don't have the same projection.\n${column1}: ${this.projections[column1]}\n${column2}: ${this.projections[column2]}`);
|
|
4611
|
-
}
|
|
4612
4525
|
await queryDB(this, (await this.getColumns()).includes(newColumn)
|
|
4613
4526
|
? `UPDATE "${this.name}" SET "${newColumn}" = ST_Difference("${column1}", "${column2}")`
|
|
4614
4527
|
: `ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Difference("${column1}", "${column2}")`, mergeOptions(this, {
|
|
@@ -4616,7 +4529,6 @@ export default class SimpleTable extends Simple {
|
|
|
4616
4529
|
method: "removeIntersection()",
|
|
4617
4530
|
parameters: { column1, column2, newColumn },
|
|
4618
4531
|
}));
|
|
4619
|
-
this.projections[newColumn] = this.projections[column1];
|
|
4620
4532
|
}
|
|
4621
4533
|
/**
|
|
4622
4534
|
* Fills holes in polygon geometries.
|
|
@@ -4705,21 +4617,17 @@ export default class SimpleTable extends Simple {
|
|
|
4705
4617
|
* ```
|
|
4706
4618
|
*/
|
|
4707
4619
|
async union(column1, column2, newColumn) {
|
|
4708
|
-
if (this.projections[column1] !== this.projections[column2]) {
|
|
4709
|
-
throw new Error(`${column1} and ${column2} don't have the same projection.\n${column1}: ${this.projections[column1]}\n${column2}: ${this.projections[column2]}`);
|
|
4710
|
-
}
|
|
4711
4620
|
await queryDB(this, (await this.getColumns()).includes(newColumn)
|
|
4712
|
-
? `INSTALL spatial; LOAD spatial; UPDATE "${this.name}" SET "${newColumn}" = ST_Union("${column1}", "${column2}")`
|
|
4713
|
-
: `INSTALL spatial; LOAD spatial; ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Union("${column1}", "${column2}")`, mergeOptions(this, {
|
|
4621
|
+
? `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; UPDATE "${this.name}" SET "${newColumn}" = ST_Union("${column1}", "${column2}")`
|
|
4622
|
+
: `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}")`, mergeOptions(this, {
|
|
4714
4623
|
table: this.name,
|
|
4715
4624
|
method: "union()",
|
|
4716
4625
|
parameters: { column1, column2, newColumn },
|
|
4717
4626
|
}));
|
|
4718
|
-
this.projections[newColumn] = this.projections[column1];
|
|
4719
4627
|
}
|
|
4720
4628
|
/**
|
|
4721
4629
|
* Extracts the latitude and longitude coordinates from point geometries.
|
|
4722
|
-
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84)
|
|
4630
|
+
* The input geometry is assumed to be in the EPSG:4326 coordinate system (WGS84).
|
|
4723
4631
|
*
|
|
4724
4632
|
* @param column - The name of the column storing the point geometries.
|
|
4725
4633
|
* @param columnLat - The name of the new column where the extracted latitude values will be stored.
|
|
@@ -4734,8 +4642,8 @@ export default class SimpleTable extends Simple {
|
|
|
4734
4642
|
* ```
|
|
4735
4643
|
*/
|
|
4736
4644
|
async latLon(column, columnLat, columnLon) {
|
|
4737
|
-
await queryDB(this, `ALTER TABLE "${this.name}" ADD "${columnLat}" DOUBLE; UPDATE "${this.name}" SET "${columnLat}" =
|
|
4738
|
-
ALTER TABLE "${this.name}" ADD "${columnLon}" DOUBLE; UPDATE "${this.name}" SET "${columnLon}" =
|
|
4645
|
+
await queryDB(this, `ALTER TABLE "${this.name}" ADD "${columnLat}" DOUBLE; UPDATE "${this.name}" SET "${columnLat}" = ST_Y("${column}");
|
|
4646
|
+
ALTER TABLE "${this.name}" ADD "${columnLon}" DOUBLE; UPDATE "${this.name}" SET "${columnLon}" = ST_X("${column}");`, mergeOptions(this, {
|
|
4739
4647
|
table: this.name,
|
|
4740
4648
|
method: "latLon()",
|
|
4741
4649
|
parameters: { column, columnLon, columnLat },
|
|
@@ -4802,13 +4710,12 @@ export default class SimpleTable extends Simple {
|
|
|
4802
4710
|
? options.column
|
|
4803
4711
|
: await findGeoColumn(this);
|
|
4804
4712
|
await queryDB(this, (await this.getColumns()).includes(newColumn)
|
|
4805
|
-
? `INSTALL spatial; LOAD spatial; UPDATE "${this.name}" SET "${newColumn}" = ST_Centroid("${column}")`
|
|
4806
|
-
: `INSTALL spatial; LOAD spatial; ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Centroid("${column}")`, mergeOptions(this, {
|
|
4713
|
+
? `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; UPDATE "${this.name}" SET "${newColumn}" = ST_Centroid("${column}")`
|
|
4714
|
+
: `INSTALL spatial; LOAD spatial; SET geometry_always_xy = true; ALTER TABLE "${this.name}" ADD "${newColumn}" GEOMETRY; UPDATE "${this.name}" SET "${newColumn}" = ST_Centroid("${column}")`, mergeOptions(this, {
|
|
4807
4715
|
table: this.name,
|
|
4808
4716
|
method: "centroid()",
|
|
4809
4717
|
parameters: { column, newColumn },
|
|
4810
4718
|
}));
|
|
4811
|
-
this.projections[newColumn] = this.projections[column];
|
|
4812
4719
|
}
|
|
4813
4720
|
/**
|
|
4814
4721
|
* Generates a random point within the geometries of a specified column.
|
|
@@ -4817,6 +4724,7 @@ export default class SimpleTable extends Simple {
|
|
|
4817
4724
|
* @param nbPointsToTry - The number of points to generate within the bounding box of each geometry to find one that is within the geometry itself.
|
|
4818
4725
|
* @param options - An optional object with configuration options:
|
|
4819
4726
|
* @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.
|
|
4727
|
+
* @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.
|
|
4820
4728
|
*
|
|
4821
4729
|
* @example
|
|
4822
4730
|
* ```ts
|
|
@@ -4829,10 +4737,16 @@ export default class SimpleTable extends Simple {
|
|
|
4829
4737
|
* // Generate a random point for each geometry in a specific column named 'areaGeom', trying 50 points
|
|
4830
4738
|
* await table.randomPoint("pointInArea", 50, { column: "areaGeom" });
|
|
4831
4739
|
* ```
|
|
4740
|
+
*
|
|
4741
|
+
* @example
|
|
4742
|
+
* ```ts
|
|
4743
|
+
* // Generate a random point for each geometry, but don't throw if some points cannot be generated
|
|
4744
|
+
* await table.randomPoint("pointInArea", 1, { try: true });
|
|
4745
|
+
* ```
|
|
4832
4746
|
*/
|
|
4833
4747
|
async randomPoint(newColumn, nbPointsToTry, options = {}) {
|
|
4834
|
-
if (typeof nbPointsToTry !== "number" || nbPointsToTry <
|
|
4835
|
-
throw new Error("nbPointsToTry must be a number greater than 0");
|
|
4748
|
+
if (typeof nbPointsToTry !== "number" || nbPointsToTry < 0) {
|
|
4749
|
+
throw new Error("nbPointsToTry must be a number greater than or equal to 0");
|
|
4836
4750
|
}
|
|
4837
4751
|
const column = typeof options.column === "string"
|
|
4838
4752
|
? options.column
|
|
@@ -4840,15 +4754,20 @@ export default class SimpleTable extends Simple {
|
|
|
4840
4754
|
await queryDB(this, randomPointQuery(this.name, column, newColumn, nbPointsToTry), mergeOptions(this, {
|
|
4841
4755
|
table: this.name,
|
|
4842
4756
|
method: "randomPoint()",
|
|
4843
|
-
parameters: { column, newColumn, nbPointsToTry },
|
|
4757
|
+
parameters: { column, newColumn, nbPointsToTry, options },
|
|
4844
4758
|
}));
|
|
4845
|
-
|
|
4759
|
+
const nbNulls = await this.getNbRows({
|
|
4760
|
+
conditions: `"${newColumn}" IS NULL`,
|
|
4761
|
+
});
|
|
4762
|
+
if (nbNulls > 0 && !options.try) {
|
|
4763
|
+
throw new Error(`${nbNulls} points could not be generated. Consider increasing nbPointsToTry or set options.try to true.`);
|
|
4764
|
+
}
|
|
4846
4765
|
}
|
|
4847
4766
|
/**
|
|
4848
4767
|
* Computes the distance between geometries in two specified columns.
|
|
4849
4768
|
* By default, the distance is calculated in the Spatial Reference System (SRS) unit of the input geometries.
|
|
4850
4769
|
* You can optionally specify `"spheroid"` or `"haversine"` methods to get results in meters or kilometers.
|
|
4851
|
-
* If using `"spheroid"` or `"haversine"`, the input geometries must be in the EPSG:4326 coordinate system (WGS84)
|
|
4770
|
+
* If using `"spheroid"` or `"haversine"`, the input geometries must be in the EPSG:4326 coordinate system (WGS84).
|
|
4852
4771
|
*
|
|
4853
4772
|
* @param column1 - The name of the first column storing geometries.
|
|
4854
4773
|
* @param column2 - The name of the second column storing geometries.
|
|
@@ -4964,7 +4883,7 @@ export default class SimpleTable extends Simple {
|
|
|
4964
4883
|
parameters: { column, method, options },
|
|
4965
4884
|
}));
|
|
4966
4885
|
if (typeof options.outputTable === "string") {
|
|
4967
|
-
return this.sdb.newTable(options.outputTable
|
|
4886
|
+
return this.sdb.newTable(options.outputTable);
|
|
4968
4887
|
}
|
|
4969
4888
|
else {
|
|
4970
4889
|
return this;
|
|
@@ -4999,7 +4918,7 @@ export default class SimpleTable extends Simple {
|
|
|
4999
4918
|
}
|
|
5000
4919
|
/**
|
|
5001
4920
|
* Returns the bounding box of geometries in `[minLat, minLon, maxLat, maxLon]` order.
|
|
5002
|
-
* 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)
|
|
4921
|
+
* 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).
|
|
5003
4922
|
*
|
|
5004
4923
|
* @param column - The name of the column storing geometries. If omitted, the method will automatically attempt to find a geometry column.
|
|
5005
4924
|
* @returns A promise that resolves to an array `[minLat, minLon, maxLat, maxLon]` representing the bounding box.
|
|
@@ -5022,10 +4941,10 @@ export default class SimpleTable extends Simple {
|
|
|
5022
4941
|
async getBoundingBox(column) {
|
|
5023
4942
|
const col = column ?? (await findGeoColumn(this));
|
|
5024
4943
|
const result = (await queryDB(this, `SELECT
|
|
5025
|
-
MIN(
|
|
5026
|
-
MIN(
|
|
5027
|
-
MAX(
|
|
5028
|
-
MAX(
|
|
4944
|
+
MIN(ST_YMin("${col}")) AS minX,
|
|
4945
|
+
MIN(ST_XMin("${col}")) AS minY,
|
|
4946
|
+
MAX(ST_YMax("${col}")) AS maxX,
|
|
4947
|
+
MAX(ST_XMax("${col}")) AS maxY,
|
|
5029
4948
|
from "${this.name}";`, mergeOptions(this, {
|
|
5030
4949
|
table: this.name,
|
|
5031
4950
|
method: "getBoundingBox()",
|
|
@@ -5037,7 +4956,6 @@ export default class SimpleTable extends Simple {
|
|
|
5037
4956
|
/**
|
|
5038
4957
|
* Returns the table's geospatial data as a GeoJSON object.
|
|
5039
4958
|
* If the table has multiple geometry columns, you must specify which one to use.
|
|
5040
|
-
* 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.
|
|
5041
4959
|
*
|
|
5042
4960
|
* @param column - The name of the column storing the geometries. If omitted, the method will automatically attempt to find a geometry column.
|
|
5043
4961
|
* @param options - An optional object with configuration options:
|
|
@@ -5142,8 +5060,6 @@ export default class SimpleTable extends Simple {
|
|
|
5142
5060
|
* Writes the table's geospatial data to a file in GeoJSON, GeoParquet, or Shapefile format.
|
|
5143
5061
|
* If the specified path does not exist, it will be created.
|
|
5144
5062
|
*
|
|
5145
|
-
* 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.
|
|
5146
|
-
*
|
|
5147
5063
|
* @param file - The absolute path to the output file (e.g., `"./output.geojson"`, `"./output.geoparquet"`, `"./shapefile-folder/output.shp"`).
|
|
5148
5064
|
* @param options - An optional object with configuration options:
|
|
5149
5065
|
* @param options.precision - For GeoJSON, the maximum number of figures after the decimal separator to write in coordinates. Defaults to `undefined` (full precision).
|
|
@@ -5397,6 +5313,22 @@ export default class SimpleTable extends Simple {
|
|
|
5397
5313
|
console.table(await getDescription(this));
|
|
5398
5314
|
}
|
|
5399
5315
|
}
|
|
5316
|
+
/**
|
|
5317
|
+
* Retrieves the projection of a specified geospatial column.
|
|
5318
|
+
*
|
|
5319
|
+
* @param column - The name of the geospatial column for which to retrieve the projection.
|
|
5320
|
+
* @returns A promise that resolves to the projection of the specified column.
|
|
5321
|
+
* @category Geospatial
|
|
5322
|
+
*
|
|
5323
|
+
* @example
|
|
5324
|
+
* ```ts
|
|
5325
|
+
* // Get the projection of the 'geom' column
|
|
5326
|
+
* const projection = await table.getProjection("geom");
|
|
5327
|
+
* ```
|
|
5328
|
+
*/
|
|
5329
|
+
async getProjection(column) {
|
|
5330
|
+
return (await this.sdb.customQuery(`SELECT ST_CRS("${column}") AS proj FROM "${this.name}" LIMIT 1;`, { returnDataFrom: "query" }))[0].proj;
|
|
5331
|
+
}
|
|
5400
5332
|
/**
|
|
5401
5333
|
* Logs the projections of the geospatial data (if any) to the console.
|
|
5402
5334
|
*
|
|
@@ -5411,7 +5343,19 @@ export default class SimpleTable extends Simple {
|
|
|
5411
5343
|
*/
|
|
5412
5344
|
async logProjections() {
|
|
5413
5345
|
console.log(`\nTable ${this.name} projections:`);
|
|
5414
|
-
|
|
5346
|
+
const types = await this.getTypes();
|
|
5347
|
+
const geoColumns = Object.entries(types)
|
|
5348
|
+
.filter(([_, type]) => type.toLowerCase().includes("geometry"))
|
|
5349
|
+
.map(([column]) => column);
|
|
5350
|
+
if (geoColumns.length === 0) {
|
|
5351
|
+
console.log("No geometry columns found.");
|
|
5352
|
+
}
|
|
5353
|
+
else {
|
|
5354
|
+
for (const column of geoColumns) {
|
|
5355
|
+
const projection = types[column];
|
|
5356
|
+
console.log(`- Column "${column}": ${projection}`);
|
|
5357
|
+
}
|
|
5358
|
+
}
|
|
5415
5359
|
return await this;
|
|
5416
5360
|
}
|
|
5417
5361
|
/**
|