@loaders.gl/arrow 4.4.0-alpha.2 → 4.4.0-alpha.9
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/dist/arrow-loader.js +1 -0
- package/dist/arrow-loader.js.map +1 -0
- package/dist/arrow-worker.js +29 -3
- package/dist/arrow-writer.js +2 -1
- package/dist/arrow-writer.js.map +1 -0
- package/dist/dist.dev.js +1509 -1458
- package/dist/dist.min.js +5 -5
- package/dist/exports/arrow-format.js +1 -0
- package/dist/exports/arrow-format.js.map +1 -0
- package/dist/exports/arrow-loader.js +2 -1
- package/dist/exports/arrow-loader.js.map +1 -0
- package/dist/exports/geoarrow-loader.js +1 -0
- package/dist/exports/geoarrow-loader.js.map +1 -0
- package/dist/geoarrow-loader.js +1 -0
- package/dist/geoarrow-loader.js.map +1 -0
- package/dist/geoarrow-writer.js +2 -1
- package/dist/geoarrow-writer.js.map +1 -0
- package/dist/index.cjs +7 -5
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/encoders/encode-arrow.d.ts.map +1 -1
- package/dist/lib/encoders/encode-arrow.js +3 -1
- package/dist/lib/encoders/encode-arrow.js.map +1 -0
- package/dist/lib/encoders/encode-geoarrow.d.ts.map +1 -1
- package/dist/lib/encoders/encode-geoarrow.js +3 -1
- package/dist/lib/encoders/encode-geoarrow.js.map +1 -0
- package/dist/lib/parsers/parse-arrow.d.ts +1 -1
- package/dist/lib/parsers/parse-arrow.d.ts.map +1 -1
- package/dist/lib/parsers/parse-arrow.js +3 -1
- package/dist/lib/parsers/parse-arrow.js.map +1 -0
- package/dist/lib/parsers/parse-geoarrow.d.ts +1 -1
- package/dist/lib/parsers/parse-geoarrow.d.ts.map +1 -1
- package/dist/lib/parsers/parse-geoarrow.js +1 -0
- package/dist/lib/parsers/parse-geoarrow.js.map +1 -0
- package/dist/lib/types.js +1 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/triangulate-on-worker.js +2 -1
- package/dist/triangulate-on-worker.js.map +1 -0
- package/dist/workers/arrow-worker.js +1 -0
- package/dist/workers/arrow-worker.js.map +1 -0
- package/dist/workers/hard-clone.js +1 -0
- package/dist/workers/hard-clone.js.map +1 -0
- package/dist/workers/triangulation-worker-node.js +1 -0
- package/dist/workers/triangulation-worker-node.js.map +1 -0
- package/dist/workers/triangulation-worker.js +1 -0
- package/dist/workers/triangulation-worker.js.map +1 -0
- package/package.json +11 -8
- package/src/lib/encoders/encode-arrow.ts +2 -1
- package/src/lib/encoders/encode-geoarrow.ts +2 -1
- package/src/lib/parsers/parse-arrow.ts +5 -2
- package/src/lib/parsers/parse-geoarrow.ts +3 -1
package/dist/dist.dev.js
CHANGED
|
@@ -12842,1647 +12842,1698 @@ return true;`);
|
|
|
12842
12842
|
};
|
|
12843
12843
|
}
|
|
12844
12844
|
|
|
12845
|
-
// src/lib/
|
|
12846
|
-
|
|
12847
|
-
|
|
12848
|
-
|
|
12849
|
-
|
|
12850
|
-
|
|
12851
|
-
|
|
12852
|
-
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
|
|
12859
|
-
|
|
12860
|
-
|
|
12861
|
-
|
|
12862
|
-
|
|
12863
|
-
|
|
12864
|
-
};
|
|
12865
|
-
yield arrowTabledBatch;
|
|
12866
|
-
}
|
|
12867
|
-
break;
|
|
12845
|
+
// ../loader-utils/src/lib/javascript-utils/is-type.ts
|
|
12846
|
+
var isSharedArrayBuffer = (value) => typeof SharedArrayBuffer !== "undefined" && value instanceof SharedArrayBuffer;
|
|
12847
|
+
|
|
12848
|
+
// ../worker-utils/src/lib/npm-tag.ts
|
|
12849
|
+
var NPM_TAG = "beta";
|
|
12850
|
+
|
|
12851
|
+
// ../worker-utils/src/lib/env-utils/version.ts
|
|
12852
|
+
var warningIssued = false;
|
|
12853
|
+
function getVersion() {
|
|
12854
|
+
if (!globalThis._loadersgl_?.version) {
|
|
12855
|
+
globalThis._loadersgl_ = globalThis._loadersgl_ || {};
|
|
12856
|
+
if (typeof __VERSION__ === "undefined" && !warningIssued) {
|
|
12857
|
+
console.warn(
|
|
12858
|
+
"loaders.gl: The __VERSION__ variable is not injected using babel plugin. Latest unstable workers would be fetched from the CDN."
|
|
12859
|
+
);
|
|
12860
|
+
globalThis._loadersgl_.version = NPM_TAG;
|
|
12861
|
+
warningIssued = true;
|
|
12862
|
+
} else {
|
|
12863
|
+
globalThis._loadersgl_.version = __VERSION__;
|
|
12868
12864
|
}
|
|
12869
12865
|
}
|
|
12870
|
-
return
|
|
12866
|
+
return globalThis._loadersgl_.version;
|
|
12871
12867
|
}
|
|
12868
|
+
var VERSION2 = getVersion();
|
|
12872
12869
|
|
|
12873
|
-
// src/
|
|
12874
|
-
|
|
12875
|
-
|
|
12876
|
-
|
|
12877
|
-
|
|
12878
|
-
|
|
12870
|
+
// ../worker-utils/src/lib/env-utils/assert.ts
|
|
12871
|
+
function assert(condition, message) {
|
|
12872
|
+
if (!condition) {
|
|
12873
|
+
throw new Error(message || "loaders.gl assertion failed.");
|
|
12874
|
+
}
|
|
12875
|
+
}
|
|
12876
|
+
|
|
12877
|
+
// ../worker-utils/src/lib/env-utils/globals.ts
|
|
12878
|
+
var globals = {
|
|
12879
|
+
self: typeof self !== "undefined" && self,
|
|
12880
|
+
window: typeof window !== "undefined" && window,
|
|
12881
|
+
global: typeof global !== "undefined" && global,
|
|
12882
|
+
document: typeof document !== "undefined" && document
|
|
12879
12883
|
};
|
|
12884
|
+
var self_ = globals.self || globals.window || globals.global || {};
|
|
12885
|
+
var window_ = globals.window || globals.self || globals.global || {};
|
|
12886
|
+
var global_ = globals.global || globals.self || globals.window || {};
|
|
12887
|
+
var document_ = globals.document || {};
|
|
12888
|
+
var isBrowser = (
|
|
12889
|
+
// @ts-ignore process.browser
|
|
12890
|
+
typeof process !== "object" || String(process) !== "[object process]" || process.browser
|
|
12891
|
+
);
|
|
12892
|
+
var isMobile = typeof window !== "undefined" && typeof window.orientation !== "undefined";
|
|
12893
|
+
var matches = typeof process !== "undefined" && process.version && /v([0-9]*)/.exec(process.version);
|
|
12894
|
+
var nodeVersion = matches && parseFloat(matches[1]) || 0;
|
|
12880
12895
|
|
|
12881
|
-
// src/lib/
|
|
12882
|
-
|
|
12883
|
-
|
|
12884
|
-
|
|
12885
|
-
|
|
12886
|
-
|
|
12896
|
+
// ../worker-utils/src/lib/worker-farm/worker-job.ts
|
|
12897
|
+
var WorkerJob = class {
|
|
12898
|
+
name;
|
|
12899
|
+
workerThread;
|
|
12900
|
+
isRunning = true;
|
|
12901
|
+
/** Promise that resolves when Job is done */
|
|
12902
|
+
result;
|
|
12903
|
+
_resolve = () => {
|
|
12904
|
+
};
|
|
12905
|
+
_reject = () => {
|
|
12906
|
+
};
|
|
12907
|
+
constructor(jobName, workerThread) {
|
|
12908
|
+
this.name = jobName;
|
|
12909
|
+
this.workerThread = workerThread;
|
|
12910
|
+
this.result = new Promise((resolve, reject) => {
|
|
12911
|
+
this._resolve = resolve;
|
|
12912
|
+
this._reject = reject;
|
|
12913
|
+
});
|
|
12887
12914
|
}
|
|
12888
|
-
|
|
12889
|
-
|
|
12890
|
-
|
|
12891
|
-
|
|
12892
|
-
|
|
12893
|
-
|
|
12894
|
-
|
|
12895
|
-
|
|
12896
|
-
|
|
12897
|
-
|
|
12898
|
-
|
|
12915
|
+
/**
|
|
12916
|
+
* Send a message to the job's worker thread
|
|
12917
|
+
* @param data any data structure, ideally consisting mostly of transferrable objects
|
|
12918
|
+
*/
|
|
12919
|
+
postMessage(type, payload) {
|
|
12920
|
+
this.workerThread.postMessage({
|
|
12921
|
+
source: "loaders.gl",
|
|
12922
|
+
// Lets worker ignore unrelated messages
|
|
12923
|
+
type,
|
|
12924
|
+
payload
|
|
12925
|
+
});
|
|
12899
12926
|
}
|
|
12900
|
-
|
|
12901
|
-
|
|
12902
|
-
|
|
12903
|
-
|
|
12904
|
-
|
|
12905
|
-
|
|
12906
|
-
|
|
12907
|
-
|
|
12908
|
-
|
|
12909
|
-
|
|
12910
|
-
|
|
12911
|
-
|
|
12912
|
-
|
|
12913
|
-
|
|
12914
|
-
|
|
12915
|
-
binary: true,
|
|
12916
|
-
options: {},
|
|
12917
|
-
encode: async function encodeArrow(data, options) {
|
|
12918
|
-
return encodeArrowSync(data);
|
|
12919
|
-
},
|
|
12920
|
-
encodeSync(data, options) {
|
|
12921
|
-
return encodeArrowSync(data);
|
|
12927
|
+
/**
|
|
12928
|
+
* Call to resolve the `result` Promise with the supplied value
|
|
12929
|
+
*/
|
|
12930
|
+
done(value) {
|
|
12931
|
+
assert(this.isRunning);
|
|
12932
|
+
this.isRunning = false;
|
|
12933
|
+
this._resolve(value);
|
|
12934
|
+
}
|
|
12935
|
+
/**
|
|
12936
|
+
* Call to reject the `result` Promise with the supplied error
|
|
12937
|
+
*/
|
|
12938
|
+
error(error) {
|
|
12939
|
+
assert(this.isRunning);
|
|
12940
|
+
this.isRunning = false;
|
|
12941
|
+
this._reject(error);
|
|
12922
12942
|
}
|
|
12923
12943
|
};
|
|
12924
12944
|
|
|
12925
|
-
// src/
|
|
12926
|
-
var
|
|
12927
|
-
|
|
12928
|
-
options: {
|
|
12929
|
-
arrow: {
|
|
12930
|
-
shape: "arrow-table"
|
|
12931
|
-
}
|
|
12945
|
+
// ../worker-utils/src/lib/node/worker_threads-browser.ts
|
|
12946
|
+
var NodeWorker = class {
|
|
12947
|
+
terminate() {
|
|
12932
12948
|
}
|
|
12933
12949
|
};
|
|
12934
12950
|
|
|
12935
|
-
// ../
|
|
12936
|
-
|
|
12937
|
-
|
|
12938
|
-
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
|
|
12945
|
-
|
|
12946
|
-
|
|
12947
|
-
|
|
12948
|
-
"geoarrow.wkb",
|
|
12949
|
-
"geoarrow.wkt"
|
|
12950
|
-
];
|
|
12951
|
-
var GEOARROW_ENCODING = "ARROW:extension:name";
|
|
12952
|
-
var GEOARROW_METADATA = "ARROW:extension:metadata";
|
|
12953
|
-
function getGeometryColumnsFromSchema(schema) {
|
|
12954
|
-
const geometryColumns = {};
|
|
12955
|
-
for (const field of schema.fields || []) {
|
|
12956
|
-
const metadata = getGeometryMetadataForField(field?.metadata || {});
|
|
12957
|
-
if (metadata) {
|
|
12958
|
-
geometryColumns[field.name] = metadata;
|
|
12951
|
+
// ../worker-utils/src/lib/worker-utils/get-loadable-worker-url.ts
|
|
12952
|
+
var workerURLCache = /* @__PURE__ */ new Map();
|
|
12953
|
+
function getLoadableWorkerURL(props) {
|
|
12954
|
+
assert(props.source && !props.url || !props.source && props.url);
|
|
12955
|
+
let workerURL = workerURLCache.get(props.source || props.url);
|
|
12956
|
+
if (!workerURL) {
|
|
12957
|
+
if (props.url) {
|
|
12958
|
+
workerURL = getLoadableWorkerURLFromURL(props.url);
|
|
12959
|
+
workerURLCache.set(props.url, workerURL);
|
|
12960
|
+
}
|
|
12961
|
+
if (props.source) {
|
|
12962
|
+
workerURL = getLoadableWorkerURLFromSource(props.source);
|
|
12963
|
+
workerURLCache.set(props.source, workerURL);
|
|
12959
12964
|
}
|
|
12960
12965
|
}
|
|
12961
|
-
|
|
12966
|
+
assert(workerURL);
|
|
12967
|
+
return workerURL;
|
|
12962
12968
|
}
|
|
12963
|
-
function
|
|
12964
|
-
|
|
12965
|
-
|
|
12966
|
-
if (geoEncoding) {
|
|
12967
|
-
geoEncoding = geoEncoding.toLowerCase();
|
|
12968
|
-
if (geoEncoding === "wkb") {
|
|
12969
|
-
geoEncoding = "geoarrow.wkb";
|
|
12970
|
-
}
|
|
12971
|
-
if (geoEncoding === "wkt") {
|
|
12972
|
-
geoEncoding = "geoarrow.wkt";
|
|
12973
|
-
}
|
|
12974
|
-
if (!GEOARROW_ENCODINGS.includes(geoEncoding)) {
|
|
12975
|
-
console.warn(`Invalid GeoArrow encoding: ${geoEncoding}`);
|
|
12976
|
-
} else {
|
|
12977
|
-
metadata ||= {};
|
|
12978
|
-
metadata.encoding = geoEncoding;
|
|
12979
|
-
}
|
|
12969
|
+
function getLoadableWorkerURLFromURL(url) {
|
|
12970
|
+
if (!url.startsWith("http")) {
|
|
12971
|
+
return url;
|
|
12980
12972
|
}
|
|
12981
|
-
const
|
|
12982
|
-
|
|
12983
|
-
|
|
12984
|
-
|
|
12985
|
-
|
|
12986
|
-
|
|
12973
|
+
const workerSource = buildScriptSource(url);
|
|
12974
|
+
return getLoadableWorkerURLFromSource(workerSource);
|
|
12975
|
+
}
|
|
12976
|
+
function getLoadableWorkerURLFromSource(workerSource) {
|
|
12977
|
+
const blob = new Blob([workerSource], { type: "application/javascript" });
|
|
12978
|
+
return URL.createObjectURL(blob);
|
|
12979
|
+
}
|
|
12980
|
+
function buildScriptSource(workerUrl) {
|
|
12981
|
+
return `try {
|
|
12982
|
+
importScripts('${workerUrl}');
|
|
12983
|
+
} catch (error) {
|
|
12984
|
+
console.error(error);
|
|
12985
|
+
throw error;
|
|
12986
|
+
}`;
|
|
12987
|
+
}
|
|
12988
|
+
|
|
12989
|
+
// ../worker-utils/src/lib/worker-utils/get-transfer-list.ts
|
|
12990
|
+
function getTransferList(object, recursive = true, transfers) {
|
|
12991
|
+
const transfersSet = transfers || /* @__PURE__ */ new Set();
|
|
12992
|
+
if (!object) {
|
|
12993
|
+
} else if (isTransferable(object)) {
|
|
12994
|
+
transfersSet.add(object);
|
|
12995
|
+
} else if (isTransferable(object.buffer)) {
|
|
12996
|
+
transfersSet.add(object.buffer);
|
|
12997
|
+
} else if (ArrayBuffer.isView(object)) {
|
|
12998
|
+
} else if (recursive && typeof object === "object") {
|
|
12999
|
+
for (const key in object) {
|
|
13000
|
+
getTransferList(object[key], recursive, transfersSet);
|
|
12987
13001
|
}
|
|
12988
13002
|
}
|
|
12989
|
-
return
|
|
13003
|
+
return transfers === void 0 ? Array.from(transfersSet) : [];
|
|
12990
13004
|
}
|
|
12991
|
-
|
|
12992
|
-
|
|
12993
|
-
|
|
12994
|
-
switch (data.type) {
|
|
12995
|
-
case "Point":
|
|
12996
|
-
return pointToGeoJson(data, startIndex, endIndex);
|
|
12997
|
-
case "LineString":
|
|
12998
|
-
return lineStringToGeoJson(data, startIndex, endIndex);
|
|
12999
|
-
case "Polygon":
|
|
13000
|
-
return polygonToGeoJson(data, startIndex, endIndex);
|
|
13001
|
-
default:
|
|
13002
|
-
const unexpectedInput = data;
|
|
13003
|
-
throw new Error(`Unsupported geometry type: ${unexpectedInput?.type}`);
|
|
13005
|
+
function isTransferable(object) {
|
|
13006
|
+
if (!object) {
|
|
13007
|
+
return false;
|
|
13004
13008
|
}
|
|
13005
|
-
|
|
13006
|
-
|
|
13007
|
-
const { positions } = data;
|
|
13008
|
-
const polygonIndices = data.polygonIndices.value.filter((x) => x >= startIndex && x <= endIndex);
|
|
13009
|
-
const primitivePolygonIndices = data.primitivePolygonIndices.value.filter(
|
|
13010
|
-
(x) => x >= startIndex && x <= endIndex
|
|
13011
|
-
);
|
|
13012
|
-
const multi = polygonIndices.length > 2;
|
|
13013
|
-
if (!multi) {
|
|
13014
|
-
const coordinates2 = [];
|
|
13015
|
-
for (let i = 0; i < primitivePolygonIndices.length - 1; i++) {
|
|
13016
|
-
const startRingIndex = primitivePolygonIndices[i];
|
|
13017
|
-
const endRingIndex = primitivePolygonIndices[i + 1];
|
|
13018
|
-
const ringCoordinates = ringToGeoJson(positions, startRingIndex, endRingIndex);
|
|
13019
|
-
coordinates2.push(ringCoordinates);
|
|
13020
|
-
}
|
|
13021
|
-
return { type: "Polygon", coordinates: coordinates2 };
|
|
13009
|
+
if (object instanceof ArrayBuffer) {
|
|
13010
|
+
return true;
|
|
13022
13011
|
}
|
|
13023
|
-
|
|
13024
|
-
|
|
13025
|
-
const startPolygonIndex = polygonIndices[i];
|
|
13026
|
-
const endPolygonIndex = polygonIndices[i + 1];
|
|
13027
|
-
const polygonCoordinates = polygonToGeoJson(
|
|
13028
|
-
data,
|
|
13029
|
-
startPolygonIndex,
|
|
13030
|
-
endPolygonIndex
|
|
13031
|
-
).coordinates;
|
|
13032
|
-
coordinates.push(polygonCoordinates);
|
|
13012
|
+
if (typeof MessagePort !== "undefined" && object instanceof MessagePort) {
|
|
13013
|
+
return true;
|
|
13033
13014
|
}
|
|
13034
|
-
|
|
13035
|
-
|
|
13036
|
-
function lineStringToGeoJson(data, startIndex = -Infinity, endIndex = Infinity) {
|
|
13037
|
-
const { positions } = data;
|
|
13038
|
-
const pathIndices = data.pathIndices.value.filter((x) => x >= startIndex && x <= endIndex);
|
|
13039
|
-
const multi = pathIndices.length > 2;
|
|
13040
|
-
if (!multi) {
|
|
13041
|
-
const coordinates2 = ringToGeoJson(positions, pathIndices[0], pathIndices[1]);
|
|
13042
|
-
return { type: "LineString", coordinates: coordinates2 };
|
|
13015
|
+
if (typeof ImageBitmap !== "undefined" && object instanceof ImageBitmap) {
|
|
13016
|
+
return true;
|
|
13043
13017
|
}
|
|
13044
|
-
|
|
13045
|
-
|
|
13046
|
-
const ringCoordinates = ringToGeoJson(positions, pathIndices[i], pathIndices[i + 1]);
|
|
13047
|
-
coordinates.push(ringCoordinates);
|
|
13018
|
+
if (typeof OffscreenCanvas !== "undefined" && object instanceof OffscreenCanvas) {
|
|
13019
|
+
return true;
|
|
13048
13020
|
}
|
|
13049
|
-
return
|
|
13021
|
+
return false;
|
|
13050
13022
|
}
|
|
13051
|
-
function
|
|
13052
|
-
|
|
13053
|
-
|
|
13054
|
-
const multi = coordinates.length > 1;
|
|
13055
|
-
if (multi) {
|
|
13056
|
-
return { type: "MultiPoint", coordinates };
|
|
13023
|
+
function getTransferListForWriter(object) {
|
|
13024
|
+
if (object === null) {
|
|
13025
|
+
return {};
|
|
13057
13026
|
}
|
|
13058
|
-
|
|
13059
|
-
|
|
13060
|
-
|
|
13061
|
-
|
|
13062
|
-
|
|
13063
|
-
|
|
13064
|
-
|
|
13065
|
-
|
|
13066
|
-
for (let k = j * positions.size; k < (j + 1) * positions.size; k++) {
|
|
13067
|
-
coord.push(Number(positions.value[k]));
|
|
13027
|
+
const clone = Object.assign({}, object);
|
|
13028
|
+
Object.keys(clone).forEach((key) => {
|
|
13029
|
+
if (typeof object[key] === "object" && !ArrayBuffer.isView(object[key]) && !(object[key] instanceof Array)) {
|
|
13030
|
+
clone[key] = getTransferListForWriter(object[key]);
|
|
13031
|
+
} else if (typeof clone[key] === "function" || clone[key] instanceof RegExp) {
|
|
13032
|
+
clone[key] = {};
|
|
13033
|
+
} else {
|
|
13034
|
+
clone[key] = object[key];
|
|
13068
13035
|
}
|
|
13069
|
-
|
|
13070
|
-
|
|
13071
|
-
return ringCoordinates;
|
|
13036
|
+
});
|
|
13037
|
+
return clone;
|
|
13072
13038
|
}
|
|
13073
13039
|
|
|
13074
|
-
// ../
|
|
13075
|
-
|
|
13076
|
-
|
|
13077
|
-
|
|
13078
|
-
|
|
13040
|
+
// ../worker-utils/src/lib/worker-farm/worker-thread.ts
|
|
13041
|
+
var NOOP = () => {
|
|
13042
|
+
};
|
|
13043
|
+
var WorkerThread = class {
|
|
13044
|
+
name;
|
|
13045
|
+
source;
|
|
13046
|
+
url;
|
|
13047
|
+
terminated = false;
|
|
13048
|
+
worker;
|
|
13049
|
+
onMessage;
|
|
13050
|
+
onError;
|
|
13051
|
+
_loadableURL = "";
|
|
13052
|
+
/** Checks if workers are supported on this platform */
|
|
13053
|
+
static isSupported() {
|
|
13054
|
+
return typeof Worker !== "undefined" && isBrowser || typeof NodeWorker !== "undefined" && !isBrowser;
|
|
13079
13055
|
}
|
|
13080
|
-
|
|
13081
|
-
|
|
13082
|
-
|
|
13083
|
-
|
|
13084
|
-
|
|
13085
|
-
|
|
13086
|
-
|
|
13087
|
-
|
|
13056
|
+
constructor(props) {
|
|
13057
|
+
const { name, source, url } = props;
|
|
13058
|
+
assert(source || url);
|
|
13059
|
+
this.name = name;
|
|
13060
|
+
this.source = source;
|
|
13061
|
+
this.url = url;
|
|
13062
|
+
this.onMessage = NOOP;
|
|
13063
|
+
this.onError = (error) => console.log(error);
|
|
13064
|
+
this.worker = isBrowser ? this._createBrowserWorker() : this._createNodeWorker();
|
|
13088
13065
|
}
|
|
13089
|
-
|
|
13090
|
-
|
|
13091
|
-
|
|
13092
|
-
|
|
13093
|
-
|
|
13094
|
-
|
|
13095
|
-
|
|
13096
|
-
|
|
13097
|
-
|
|
13098
|
-
positions: { value: concatenatedPositions, size: dimension }
|
|
13099
|
-
};
|
|
13100
|
-
}
|
|
13101
|
-
function concatenateBinaryLineGeometries(binaryLineGeometries, dimension) {
|
|
13102
|
-
const lines = binaryLineGeometries.map((geometry) => geometry.positions.value);
|
|
13103
|
-
const concatenatedPositions = new Float64Array(concatTypedArrays(lines).buffer);
|
|
13104
|
-
const pathIndices = lines.map((line) => line.length / dimension).map(cumulativeSum(0));
|
|
13105
|
-
pathIndices.unshift(0);
|
|
13106
|
-
return {
|
|
13107
|
-
type: "LineString",
|
|
13108
|
-
positions: { value: concatenatedPositions, size: dimension },
|
|
13109
|
-
pathIndices: { value: new Uint32Array(pathIndices), size: 1 }
|
|
13110
|
-
};
|
|
13111
|
-
}
|
|
13112
|
-
function concatenateBinaryPolygonGeometries(binaryPolygonGeometries, dimension) {
|
|
13113
|
-
const polygons = [];
|
|
13114
|
-
const primitivePolygons = [];
|
|
13115
|
-
for (const binaryPolygon of binaryPolygonGeometries) {
|
|
13116
|
-
const { positions, primitivePolygonIndices: primitivePolygonIndices2 } = binaryPolygon;
|
|
13117
|
-
polygons.push(positions.value);
|
|
13118
|
-
primitivePolygons.push(primitivePolygonIndices2.value);
|
|
13066
|
+
/**
|
|
13067
|
+
* Terminate this worker thread
|
|
13068
|
+
* @note Can free up significant memory
|
|
13069
|
+
*/
|
|
13070
|
+
destroy() {
|
|
13071
|
+
this.onMessage = NOOP;
|
|
13072
|
+
this.onError = NOOP;
|
|
13073
|
+
this.worker.terminate();
|
|
13074
|
+
this.terminated = true;
|
|
13119
13075
|
}
|
|
13120
|
-
|
|
13121
|
-
|
|
13122
|
-
polygonIndices.unshift(0);
|
|
13123
|
-
const primitivePolygonIndices = [0];
|
|
13124
|
-
for (const primitivePolygon of primitivePolygons) {
|
|
13125
|
-
primitivePolygonIndices.push(
|
|
13126
|
-
...primitivePolygon.filter((x) => x > 0).map((x) => x + primitivePolygonIndices[primitivePolygonIndices.length - 1])
|
|
13127
|
-
);
|
|
13076
|
+
get isRunning() {
|
|
13077
|
+
return Boolean(this.onMessage);
|
|
13128
13078
|
}
|
|
13129
|
-
|
|
13130
|
-
|
|
13131
|
-
|
|
13132
|
-
|
|
13133
|
-
|
|
13134
|
-
|
|
13135
|
-
|
|
13136
|
-
|
|
13137
|
-
|
|
13138
|
-
// ../gis/src/lib/geometry-converters/wkb/helpers/wkb-types.ts
|
|
13139
|
-
var EWKB_FLAG_Z = 2147483648;
|
|
13140
|
-
var EWKB_FLAG_M = 1073741824;
|
|
13141
|
-
var EWKB_FLAG_SRID = 536870912;
|
|
13142
|
-
var WKT_MAGIC_STRINGS = [
|
|
13143
|
-
"POINT(",
|
|
13144
|
-
"LINESTRING(",
|
|
13145
|
-
"POLYGON(",
|
|
13146
|
-
"MULTIPOINT(",
|
|
13147
|
-
"MULTILINESTRING(",
|
|
13148
|
-
"MULTIPOLYGON(",
|
|
13149
|
-
"GEOMETRYCOLLECTION("
|
|
13150
|
-
];
|
|
13151
|
-
var textEncoder = new TextEncoder();
|
|
13152
|
-
var WKT_MAGIC_BYTES = WKT_MAGIC_STRINGS.map((string) => textEncoder.encode(string));
|
|
13153
|
-
|
|
13154
|
-
// ../gis/src/lib/geometry-converters/wkb/helpers/parse-wkb-header.ts
|
|
13155
|
-
function isWKT(input) {
|
|
13156
|
-
return getWKTGeometryType(input) !== null;
|
|
13157
|
-
}
|
|
13158
|
-
function getWKTGeometryType(input) {
|
|
13159
|
-
if (typeof input === "string") {
|
|
13160
|
-
const index2 = WKT_MAGIC_STRINGS.findIndex((magicString) => input.startsWith(magicString));
|
|
13161
|
-
return index2 >= 0 ? index2 + 1 : null;
|
|
13079
|
+
/**
|
|
13080
|
+
* Send a message to this worker thread
|
|
13081
|
+
* @param data any data structure, ideally consisting mostly of transferrable objects
|
|
13082
|
+
* @param transferList If not supplied, calculated automatically by traversing data
|
|
13083
|
+
*/
|
|
13084
|
+
postMessage(data, transferList) {
|
|
13085
|
+
transferList = transferList || getTransferList(data);
|
|
13086
|
+
this.worker.postMessage(data, transferList);
|
|
13162
13087
|
}
|
|
13163
|
-
|
|
13164
|
-
|
|
13165
|
-
|
|
13166
|
-
|
|
13167
|
-
|
|
13168
|
-
|
|
13169
|
-
|
|
13170
|
-
|
|
13171
|
-
|
|
13172
|
-
|
|
13173
|
-
|
|
13174
|
-
|
|
13175
|
-
|
|
13176
|
-
|
|
13177
|
-
|
|
13178
|
-
});
|
|
13179
|
-
if (isWKT(dataView.buffer)) {
|
|
13180
|
-
throw new Error("WKB: Cannot parse WKT data");
|
|
13088
|
+
// PRIVATE
|
|
13089
|
+
/**
|
|
13090
|
+
* Generate a standard Error from an ErrorEvent
|
|
13091
|
+
* @param event
|
|
13092
|
+
*/
|
|
13093
|
+
_getErrorFromErrorEvent(event) {
|
|
13094
|
+
let message = "Failed to load ";
|
|
13095
|
+
message += `worker ${this.name} from ${this.url}. `;
|
|
13096
|
+
if (event.message) {
|
|
13097
|
+
message += `${event.message} in `;
|
|
13098
|
+
}
|
|
13099
|
+
if (event.lineno) {
|
|
13100
|
+
message += `:${event.lineno}:${event.colno}`;
|
|
13101
|
+
}
|
|
13102
|
+
return new Error(message);
|
|
13181
13103
|
}
|
|
13182
|
-
|
|
13183
|
-
|
|
13184
|
-
|
|
13185
|
-
|
|
13186
|
-
|
|
13187
|
-
|
|
13188
|
-
|
|
13189
|
-
|
|
13190
|
-
|
|
13191
|
-
|
|
13192
|
-
|
|
13193
|
-
|
|
13194
|
-
|
|
13195
|
-
|
|
13196
|
-
|
|
13197
|
-
|
|
13198
|
-
|
|
13199
|
-
|
|
13200
|
-
|
|
13201
|
-
case 3:
|
|
13202
|
-
wkbHeader.variant = "iso-wkb";
|
|
13203
|
-
wkbHeader.dimensions = 4;
|
|
13204
|
-
wkbHeader.coordinates = "xyzm";
|
|
13205
|
-
break;
|
|
13206
|
-
default:
|
|
13207
|
-
throw new Error(`WKB: Unsupported iso-wkb type: ${isoType}`);
|
|
13208
|
-
}
|
|
13209
|
-
const ewkbZ = geometryCode & EWKB_FLAG_Z;
|
|
13210
|
-
const ewkbM = geometryCode & EWKB_FLAG_M;
|
|
13211
|
-
const ewkbSRID = geometryCode & EWKB_FLAG_SRID;
|
|
13212
|
-
if (ewkbZ && ewkbM) {
|
|
13213
|
-
wkbHeader.variant = "ewkb";
|
|
13214
|
-
wkbHeader.dimensions = 4;
|
|
13215
|
-
wkbHeader.coordinates = "xyzm";
|
|
13216
|
-
} else if (ewkbZ) {
|
|
13217
|
-
wkbHeader.variant = "ewkb";
|
|
13218
|
-
wkbHeader.dimensions = 3;
|
|
13219
|
-
wkbHeader.coordinates = "xyz";
|
|
13220
|
-
} else if (ewkbM) {
|
|
13221
|
-
wkbHeader.variant = "ewkb";
|
|
13222
|
-
wkbHeader.dimensions = 3;
|
|
13223
|
-
wkbHeader.coordinates = "xym";
|
|
13104
|
+
/**
|
|
13105
|
+
* Creates a worker thread on the browser
|
|
13106
|
+
*/
|
|
13107
|
+
_createBrowserWorker() {
|
|
13108
|
+
this._loadableURL = getLoadableWorkerURL({ source: this.source, url: this.url });
|
|
13109
|
+
const worker = new Worker(this._loadableURL, { name: this.name });
|
|
13110
|
+
worker.onmessage = (event) => {
|
|
13111
|
+
if (!event.data) {
|
|
13112
|
+
this.onError(new Error("No data received"));
|
|
13113
|
+
} else {
|
|
13114
|
+
this.onMessage(event.data);
|
|
13115
|
+
}
|
|
13116
|
+
};
|
|
13117
|
+
worker.onerror = (error) => {
|
|
13118
|
+
this.onError(this._getErrorFromErrorEvent(error));
|
|
13119
|
+
this.terminated = true;
|
|
13120
|
+
};
|
|
13121
|
+
worker.onmessageerror = (event) => console.error(event);
|
|
13122
|
+
return worker;
|
|
13224
13123
|
}
|
|
13225
|
-
|
|
13226
|
-
|
|
13227
|
-
|
|
13228
|
-
|
|
13124
|
+
/**
|
|
13125
|
+
* Creates a worker thread in node.js
|
|
13126
|
+
* @todo https://nodejs.org/api/async_hooks.html#async-resource-worker-pool
|
|
13127
|
+
*/
|
|
13128
|
+
_createNodeWorker() {
|
|
13129
|
+
let worker;
|
|
13130
|
+
if (this.url) {
|
|
13131
|
+
const absolute = this.url.includes(":/") || this.url.startsWith("/");
|
|
13132
|
+
const url = absolute ? this.url : `./${this.url}`;
|
|
13133
|
+
const type = this.url.endsWith(".ts") || this.url.endsWith(".mjs") ? "module" : "commonjs";
|
|
13134
|
+
worker = new NodeWorker(url, { eval: false, type });
|
|
13135
|
+
} else if (this.source) {
|
|
13136
|
+
worker = new NodeWorker(this.source, { eval: true });
|
|
13137
|
+
} else {
|
|
13138
|
+
throw new Error("no worker");
|
|
13139
|
+
}
|
|
13140
|
+
worker.on("message", (data) => {
|
|
13141
|
+
this.onMessage(data);
|
|
13142
|
+
});
|
|
13143
|
+
worker.on("error", (error) => {
|
|
13144
|
+
this.onError(error);
|
|
13145
|
+
});
|
|
13146
|
+
worker.on("exit", (code) => {
|
|
13147
|
+
});
|
|
13148
|
+
return worker;
|
|
13229
13149
|
}
|
|
13230
|
-
|
|
13231
|
-
}
|
|
13150
|
+
};
|
|
13232
13151
|
|
|
13233
|
-
// ../
|
|
13234
|
-
|
|
13235
|
-
|
|
13236
|
-
|
|
13237
|
-
|
|
13238
|
-
|
|
13239
|
-
|
|
13240
|
-
|
|
13241
|
-
|
|
13242
|
-
return point.geometry;
|
|
13243
|
-
case 2 /* LineString */:
|
|
13244
|
-
const line = parseLineString(dataView, offset, dimensions, littleEndian);
|
|
13245
|
-
return line.geometry;
|
|
13246
|
-
case 3 /* Polygon */:
|
|
13247
|
-
const polygon = parsePolygon(dataView, offset, dimensions, littleEndian);
|
|
13248
|
-
return polygon.geometry;
|
|
13249
|
-
case 4 /* MultiPoint */:
|
|
13250
|
-
const multiPoint = parseMultiPoint(dataView, offset, dimensions, littleEndian);
|
|
13251
|
-
multiPoint.type = "Point";
|
|
13252
|
-
return multiPoint;
|
|
13253
|
-
case 5 /* MultiLineString */:
|
|
13254
|
-
const multiLine = parseMultiLineString(dataView, offset, dimensions, littleEndian);
|
|
13255
|
-
multiLine.type = "LineString";
|
|
13256
|
-
return multiLine;
|
|
13257
|
-
case 6 /* MultiPolygon */:
|
|
13258
|
-
const multiPolygon = parseMultiPolygon(dataView, offset, dimensions, littleEndian);
|
|
13259
|
-
multiPolygon.type = "Polygon";
|
|
13260
|
-
return multiPolygon;
|
|
13261
|
-
default:
|
|
13262
|
-
throw new Error(`WKB: Unsupported geometry type: ${geometryType}`);
|
|
13263
|
-
}
|
|
13264
|
-
}
|
|
13265
|
-
function parsePoint(dataView, offset, dimension, littleEndian) {
|
|
13266
|
-
const positions = new Float64Array(dimension);
|
|
13267
|
-
for (let i = 0; i < dimension; i++) {
|
|
13268
|
-
positions[i] = dataView.getFloat64(offset, littleEndian);
|
|
13269
|
-
offset += 8;
|
|
13270
|
-
}
|
|
13271
|
-
return {
|
|
13272
|
-
geometry: { type: "Point", positions: { value: positions, size: dimension } },
|
|
13273
|
-
offset
|
|
13152
|
+
// ../worker-utils/src/lib/worker-farm/worker-pool.ts
|
|
13153
|
+
var WorkerPool = class {
|
|
13154
|
+
name = "unnamed";
|
|
13155
|
+
source;
|
|
13156
|
+
// | Function;
|
|
13157
|
+
url;
|
|
13158
|
+
maxConcurrency = 1;
|
|
13159
|
+
maxMobileConcurrency = 1;
|
|
13160
|
+
onDebug = () => {
|
|
13274
13161
|
};
|
|
13275
|
-
|
|
13276
|
-
|
|
13277
|
-
|
|
13278
|
-
|
|
13279
|
-
|
|
13280
|
-
|
|
13281
|
-
|
|
13282
|
-
|
|
13283
|
-
|
|
13284
|
-
const pathIndices = [0];
|
|
13285
|
-
if (nPoints > 0) {
|
|
13286
|
-
pathIndices.push(nPoints);
|
|
13162
|
+
reuseWorkers = true;
|
|
13163
|
+
props = {};
|
|
13164
|
+
jobQueue = [];
|
|
13165
|
+
idleQueue = [];
|
|
13166
|
+
count = 0;
|
|
13167
|
+
isDestroyed = false;
|
|
13168
|
+
/** Checks if workers are supported on this platform */
|
|
13169
|
+
static isSupported() {
|
|
13170
|
+
return WorkerThread.isSupported();
|
|
13287
13171
|
}
|
|
13288
|
-
|
|
13289
|
-
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
|
|
13293
|
-
|
|
13294
|
-
|
|
13295
|
-
|
|
13296
|
-
}
|
|
13297
|
-
var cumulativeSum2 = (sum) => (value) => sum += value;
|
|
13298
|
-
function parsePolygon(dataView, offset, dimension, littleEndian) {
|
|
13299
|
-
const nRings = dataView.getUint32(offset, littleEndian);
|
|
13300
|
-
offset += 4;
|
|
13301
|
-
const rings = [];
|
|
13302
|
-
for (let i = 0; i < nRings; i++) {
|
|
13303
|
-
const parsed = parseLineString(dataView, offset, dimension, littleEndian);
|
|
13304
|
-
const { positions } = parsed.geometry;
|
|
13305
|
-
offset = parsed.offset;
|
|
13306
|
-
rings.push(positions.value);
|
|
13172
|
+
/**
|
|
13173
|
+
* @param processor - worker function
|
|
13174
|
+
* @param maxConcurrency - max count of workers
|
|
13175
|
+
*/
|
|
13176
|
+
constructor(props) {
|
|
13177
|
+
this.source = props.source;
|
|
13178
|
+
this.url = props.url;
|
|
13179
|
+
this.setProps(props);
|
|
13307
13180
|
}
|
|
13308
|
-
|
|
13309
|
-
|
|
13310
|
-
|
|
13311
|
-
|
|
13181
|
+
/**
|
|
13182
|
+
* Terminates all workers in the pool
|
|
13183
|
+
* @note Can free up significant memory
|
|
13184
|
+
*/
|
|
13185
|
+
destroy() {
|
|
13186
|
+
this.idleQueue.forEach((worker) => worker.destroy());
|
|
13187
|
+
this.isDestroyed = true;
|
|
13312
13188
|
}
|
|
13313
|
-
|
|
13314
|
-
|
|
13315
|
-
|
|
13316
|
-
|
|
13317
|
-
type: "Polygon",
|
|
13318
|
-
positions: { value: concatenatedPositions, size: dimension },
|
|
13319
|
-
polygonIndices: {
|
|
13320
|
-
value: new Uint32Array(polygonIndices),
|
|
13321
|
-
size: 1
|
|
13322
|
-
},
|
|
13323
|
-
primitivePolygonIndices: { value: new Uint32Array(primitivePolygonIndices), size: 1 }
|
|
13324
|
-
},
|
|
13325
|
-
offset
|
|
13326
|
-
};
|
|
13327
|
-
}
|
|
13328
|
-
function parseMultiPoint(dataView, offset, dimension, littleEndian) {
|
|
13329
|
-
const nPoints = dataView.getUint32(offset, littleEndian);
|
|
13330
|
-
offset += 4;
|
|
13331
|
-
const binaryPointGeometries = [];
|
|
13332
|
-
for (let i = 0; i < nPoints; i++) {
|
|
13333
|
-
const littleEndianPoint = dataView.getUint8(offset) === 1;
|
|
13334
|
-
offset++;
|
|
13335
|
-
if (dataView.getUint32(offset, littleEndianPoint) % 1e3 !== 1) {
|
|
13336
|
-
throw new Error("WKB: Inner geometries of MultiPoint not of type Point");
|
|
13189
|
+
setProps(props) {
|
|
13190
|
+
this.props = { ...this.props, ...props };
|
|
13191
|
+
if (props.name !== void 0) {
|
|
13192
|
+
this.name = props.name;
|
|
13337
13193
|
}
|
|
13338
|
-
|
|
13339
|
-
|
|
13340
|
-
offset = parsed.offset;
|
|
13341
|
-
binaryPointGeometries.push(parsed.geometry);
|
|
13342
|
-
}
|
|
13343
|
-
return concatenateBinaryPointGeometries(binaryPointGeometries, dimension);
|
|
13344
|
-
}
|
|
13345
|
-
function parseMultiLineString(dataView, offset, dimension, littleEndian) {
|
|
13346
|
-
const nLines = dataView.getUint32(offset, littleEndian);
|
|
13347
|
-
offset += 4;
|
|
13348
|
-
const binaryLineGeometries = [];
|
|
13349
|
-
for (let i = 0; i < nLines; i++) {
|
|
13350
|
-
const littleEndianLine = dataView.getUint8(offset) === 1;
|
|
13351
|
-
offset++;
|
|
13352
|
-
if (dataView.getUint32(offset, littleEndianLine) % 1e3 !== 2) {
|
|
13353
|
-
throw new Error("WKB: Inner geometries of MultiLineString not of type LineString");
|
|
13194
|
+
if (props.maxConcurrency !== void 0) {
|
|
13195
|
+
this.maxConcurrency = props.maxConcurrency;
|
|
13354
13196
|
}
|
|
13355
|
-
|
|
13356
|
-
|
|
13357
|
-
|
|
13358
|
-
|
|
13359
|
-
|
|
13360
|
-
|
|
13361
|
-
|
|
13362
|
-
|
|
13363
|
-
const nPolygons = dataView.getUint32(offset, littleEndian);
|
|
13364
|
-
offset += 4;
|
|
13365
|
-
const binaryPolygonGeometries = [];
|
|
13366
|
-
for (let i = 0; i < nPolygons; i++) {
|
|
13367
|
-
const littleEndianPolygon = dataView.getUint8(offset) === 1;
|
|
13368
|
-
offset++;
|
|
13369
|
-
if (dataView.getUint32(offset, littleEndianPolygon) % 1e3 !== 3) {
|
|
13370
|
-
throw new Error("WKB: Inner geometries of MultiPolygon not of type Polygon");
|
|
13197
|
+
if (props.maxMobileConcurrency !== void 0) {
|
|
13198
|
+
this.maxMobileConcurrency = props.maxMobileConcurrency;
|
|
13199
|
+
}
|
|
13200
|
+
if (props.reuseWorkers !== void 0) {
|
|
13201
|
+
this.reuseWorkers = props.reuseWorkers;
|
|
13202
|
+
}
|
|
13203
|
+
if (props.onDebug !== void 0) {
|
|
13204
|
+
this.onDebug = props.onDebug;
|
|
13371
13205
|
}
|
|
13372
|
-
offset += 4;
|
|
13373
|
-
const parsed = parsePolygon(dataView, offset, dimension, littleEndianPolygon);
|
|
13374
|
-
offset = parsed.offset;
|
|
13375
|
-
binaryPolygonGeometries.push(parsed.geometry);
|
|
13376
13206
|
}
|
|
13377
|
-
|
|
13378
|
-
|
|
13379
|
-
|
|
13380
|
-
|
|
13381
|
-
|
|
13382
|
-
|
|
13383
|
-
|
|
13384
|
-
|
|
13385
|
-
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
13389
|
-
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
|
|
13396
|
-
|
|
13397
|
-
|
|
13398
|
-
|
|
13399
|
-
|
|
13400
|
-
|
|
13401
|
-
|
|
13402
|
-
|
|
13403
|
-
|
|
13404
|
-
|
|
13405
|
-
|
|
13207
|
+
async startJob(name, onMessage2 = (job, type, data) => job.done(data), onError = (job, error) => job.error(error)) {
|
|
13208
|
+
const startPromise = new Promise((onStart) => {
|
|
13209
|
+
this.jobQueue.push({ name, onMessage: onMessage2, onError, onStart });
|
|
13210
|
+
return this;
|
|
13211
|
+
});
|
|
13212
|
+
this._startQueuedJob();
|
|
13213
|
+
return await startPromise;
|
|
13214
|
+
}
|
|
13215
|
+
// PRIVATE
|
|
13216
|
+
/**
|
|
13217
|
+
* Starts first queued job if worker is available or can be created
|
|
13218
|
+
* Called when job is started and whenever a worker returns to the idleQueue
|
|
13219
|
+
*/
|
|
13220
|
+
async _startQueuedJob() {
|
|
13221
|
+
if (!this.jobQueue.length) {
|
|
13222
|
+
return;
|
|
13223
|
+
}
|
|
13224
|
+
const workerThread = this._getAvailableWorker();
|
|
13225
|
+
if (!workerThread) {
|
|
13226
|
+
return;
|
|
13227
|
+
}
|
|
13228
|
+
const queuedJob = this.jobQueue.shift();
|
|
13229
|
+
if (queuedJob) {
|
|
13230
|
+
this.onDebug({
|
|
13231
|
+
message: "Starting job",
|
|
13232
|
+
name: queuedJob.name,
|
|
13233
|
+
workerThread,
|
|
13234
|
+
backlog: this.jobQueue.length
|
|
13235
|
+
});
|
|
13236
|
+
const job = new WorkerJob(queuedJob.name, workerThread);
|
|
13237
|
+
workerThread.onMessage = (data) => queuedJob.onMessage(job, data.type, data.payload);
|
|
13238
|
+
workerThread.onError = (error) => queuedJob.onError(job, error);
|
|
13239
|
+
queuedJob.onStart(job);
|
|
13240
|
+
try {
|
|
13241
|
+
await job.result;
|
|
13242
|
+
} catch (error) {
|
|
13243
|
+
console.error(`Worker exception: ${error}`);
|
|
13244
|
+
} finally {
|
|
13245
|
+
this.returnWorkerToQueue(workerThread);
|
|
13406
13246
|
}
|
|
13407
|
-
}
|
|
13408
|
-
|
|
13247
|
+
}
|
|
13248
|
+
}
|
|
13249
|
+
/**
|
|
13250
|
+
* Returns a worker to the idle queue
|
|
13251
|
+
* Destroys the worker if
|
|
13252
|
+
* - pool is destroyed
|
|
13253
|
+
* - if this pool doesn't reuse workers
|
|
13254
|
+
* - if maxConcurrency has been lowered
|
|
13255
|
+
* @param worker
|
|
13256
|
+
*/
|
|
13257
|
+
returnWorkerToQueue(worker) {
|
|
13258
|
+
const shouldDestroyWorker = (
|
|
13259
|
+
// Workers on Node.js prevent the process from exiting.
|
|
13260
|
+
// Until we figure out how to close them before exit, we always destroy them
|
|
13261
|
+
!isBrowser || // If the pool is destroyed, there is no reason to keep the worker around
|
|
13262
|
+
this.isDestroyed || // If the app has disabled worker reuse, any completed workers should be destroyed
|
|
13263
|
+
!this.reuseWorkers || // If concurrency has been lowered, this worker might be surplus to requirements
|
|
13264
|
+
this.count > this._getMaxConcurrency()
|
|
13265
|
+
);
|
|
13266
|
+
if (shouldDestroyWorker) {
|
|
13267
|
+
worker.destroy();
|
|
13268
|
+
this.count--;
|
|
13269
|
+
} else {
|
|
13270
|
+
this.idleQueue.push(worker);
|
|
13271
|
+
}
|
|
13272
|
+
if (!this.isDestroyed) {
|
|
13273
|
+
this._startQueuedJob();
|
|
13274
|
+
}
|
|
13409
13275
|
}
|
|
13410
|
-
|
|
13411
|
-
|
|
13412
|
-
|
|
13413
|
-
|
|
13276
|
+
/**
|
|
13277
|
+
* Returns idle worker or creates new worker if maxConcurrency has not been reached
|
|
13278
|
+
*/
|
|
13279
|
+
_getAvailableWorker() {
|
|
13280
|
+
if (this.idleQueue.length > 0) {
|
|
13281
|
+
return this.idleQueue.shift() || null;
|
|
13282
|
+
}
|
|
13283
|
+
if (this.count < this._getMaxConcurrency()) {
|
|
13284
|
+
this.count++;
|
|
13285
|
+
const name = `${this.name.toLowerCase()} (#${this.count} of ${this.maxConcurrency})`;
|
|
13286
|
+
return new WorkerThread({ name, source: this.source, url: this.url });
|
|
13287
|
+
}
|
|
13414
13288
|
return null;
|
|
13415
13289
|
}
|
|
13416
|
-
|
|
13417
|
-
|
|
13418
|
-
return null;
|
|
13290
|
+
_getMaxConcurrency() {
|
|
13291
|
+
return isMobile ? this.maxMobileConcurrency : this.maxConcurrency;
|
|
13419
13292
|
}
|
|
13420
|
-
|
|
13421
|
-
|
|
13422
|
-
|
|
13293
|
+
};
|
|
13294
|
+
|
|
13295
|
+
// ../worker-utils/src/lib/worker-farm/worker-farm.ts
|
|
13296
|
+
var DEFAULT_PROPS = {
|
|
13297
|
+
maxConcurrency: 3,
|
|
13298
|
+
maxMobileConcurrency: 1,
|
|
13299
|
+
reuseWorkers: true,
|
|
13300
|
+
onDebug: () => {
|
|
13423
13301
|
}
|
|
13424
|
-
|
|
13425
|
-
|
|
13426
|
-
|
|
13302
|
+
};
|
|
13303
|
+
var _WorkerFarm = class {
|
|
13304
|
+
props;
|
|
13305
|
+
workerPools = /* @__PURE__ */ new Map();
|
|
13306
|
+
/** Checks if workers are supported on this platform */
|
|
13307
|
+
static isSupported() {
|
|
13308
|
+
return WorkerThread.isSupported();
|
|
13427
13309
|
}
|
|
13428
|
-
|
|
13429
|
-
|
|
13430
|
-
|
|
13431
|
-
|
|
13432
|
-
|
|
13433
|
-
function parseMultiPoint2(state) {
|
|
13434
|
-
if (!$(/^(MULTIPOINT)/i, state)) {
|
|
13435
|
-
return null;
|
|
13310
|
+
/** Get the singleton instance of the global worker farm */
|
|
13311
|
+
static getWorkerFarm(props = {}) {
|
|
13312
|
+
_WorkerFarm._workerFarm = _WorkerFarm._workerFarm || new _WorkerFarm({});
|
|
13313
|
+
_WorkerFarm._workerFarm.setProps(props);
|
|
13314
|
+
return _WorkerFarm._workerFarm;
|
|
13436
13315
|
}
|
|
13437
|
-
|
|
13438
|
-
|
|
13439
|
-
|
|
13440
|
-
|
|
13441
|
-
|
|
13442
|
-
return null;
|
|
13316
|
+
/** get global instance with WorkerFarm.getWorkerFarm() */
|
|
13317
|
+
constructor(props) {
|
|
13318
|
+
this.props = { ...DEFAULT_PROPS };
|
|
13319
|
+
this.setProps(props);
|
|
13320
|
+
this.workerPools = /* @__PURE__ */ new Map();
|
|
13443
13321
|
}
|
|
13444
|
-
|
|
13445
|
-
|
|
13446
|
-
|
|
13447
|
-
|
|
13448
|
-
|
|
13449
|
-
|
|
13450
|
-
|
|
13451
|
-
|
|
13452
|
-
|
|
13322
|
+
/**
|
|
13323
|
+
* Terminate all workers in the farm
|
|
13324
|
+
* @note Can free up significant memory
|
|
13325
|
+
*/
|
|
13326
|
+
destroy() {
|
|
13327
|
+
for (const workerPool of this.workerPools.values()) {
|
|
13328
|
+
workerPool.destroy();
|
|
13329
|
+
}
|
|
13330
|
+
this.workerPools = /* @__PURE__ */ new Map();
|
|
13453
13331
|
}
|
|
13454
|
-
|
|
13455
|
-
|
|
13456
|
-
|
|
13332
|
+
/**
|
|
13333
|
+
* Set props used when initializing worker pools
|
|
13334
|
+
* @param props
|
|
13335
|
+
*/
|
|
13336
|
+
setProps(props) {
|
|
13337
|
+
this.props = { ...this.props, ...props };
|
|
13338
|
+
for (const workerPool of this.workerPools.values()) {
|
|
13339
|
+
workerPool.setProps(this._getWorkerPoolProps());
|
|
13340
|
+
}
|
|
13457
13341
|
}
|
|
13458
|
-
|
|
13459
|
-
|
|
13460
|
-
|
|
13342
|
+
/**
|
|
13343
|
+
* Returns a worker pool for the specified worker
|
|
13344
|
+
* @param options - only used first time for a specific worker name
|
|
13345
|
+
* @param options.name - the name of the worker - used to identify worker pool
|
|
13346
|
+
* @param options.url -
|
|
13347
|
+
* @param options.source -
|
|
13348
|
+
* @example
|
|
13349
|
+
* const job = WorkerFarm.getWorkerFarm().getWorkerPool({name, url}).startJob(...);
|
|
13350
|
+
*/
|
|
13351
|
+
getWorkerPool(options) {
|
|
13352
|
+
const { name, source, url } = options;
|
|
13353
|
+
let workerPool = this.workerPools.get(name);
|
|
13354
|
+
if (!workerPool) {
|
|
13355
|
+
workerPool = new WorkerPool({
|
|
13356
|
+
name,
|
|
13357
|
+
source,
|
|
13358
|
+
url
|
|
13359
|
+
});
|
|
13360
|
+
workerPool.setProps(this._getWorkerPoolProps());
|
|
13361
|
+
this.workerPools.set(name, workerPool);
|
|
13362
|
+
}
|
|
13363
|
+
return workerPool;
|
|
13461
13364
|
}
|
|
13462
|
-
|
|
13463
|
-
return
|
|
13365
|
+
_getWorkerPoolProps() {
|
|
13366
|
+
return {
|
|
13367
|
+
maxConcurrency: this.props.maxConcurrency,
|
|
13368
|
+
maxMobileConcurrency: this.props.maxMobileConcurrency,
|
|
13369
|
+
reuseWorkers: this.props.reuseWorkers,
|
|
13370
|
+
onDebug: this.props.onDebug
|
|
13371
|
+
};
|
|
13464
13372
|
}
|
|
13465
|
-
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13373
|
+
};
|
|
13374
|
+
var WorkerFarm = _WorkerFarm;
|
|
13375
|
+
// singleton
|
|
13376
|
+
__publicField(WorkerFarm, "_workerFarm");
|
|
13377
|
+
|
|
13378
|
+
// ../worker-utils/src/lib/worker-api/get-worker-url.ts
|
|
13379
|
+
function getWorkerName(worker) {
|
|
13380
|
+
const warning = worker.version !== VERSION2 ? ` (worker-utils@${VERSION2})` : "";
|
|
13381
|
+
return `${worker.name}@${worker.version}${warning}`;
|
|
13469
13382
|
}
|
|
13470
|
-
function
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
return null;
|
|
13383
|
+
function getWorkerURL(worker, options = {}) {
|
|
13384
|
+
const workerOptions = options[worker.id] || {};
|
|
13385
|
+
const workerFile = isBrowser ? `${worker.id}-worker.js` : `${worker.id}-worker-node.js`;
|
|
13386
|
+
let url = workerOptions.workerUrl;
|
|
13387
|
+
if (!url && worker.id === "compression") {
|
|
13388
|
+
url = options.workerUrl;
|
|
13477
13389
|
}
|
|
13478
|
-
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
|
|
13483
|
-
|
|
13484
|
-
|
|
13485
|
-
}
|
|
13486
|
-
function parsePolygon2(state) {
|
|
13487
|
-
if (!$(/^(POLYGON(\sz)?)/i, state)) {
|
|
13488
|
-
return null;
|
|
13390
|
+
const workerType = options._workerType || options?.core?._workerType;
|
|
13391
|
+
if (workerType === "test") {
|
|
13392
|
+
if (isBrowser) {
|
|
13393
|
+
url = `modules/${worker.module}/dist/${workerFile}`;
|
|
13394
|
+
} else {
|
|
13395
|
+
url = `modules/${worker.module}/src/workers/${worker.id}-worker-node.ts`;
|
|
13396
|
+
}
|
|
13489
13397
|
}
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
|
|
13398
|
+
if (!url) {
|
|
13399
|
+
let version = worker.version;
|
|
13400
|
+
if (version === "latest") {
|
|
13401
|
+
version = NPM_TAG;
|
|
13402
|
+
}
|
|
13403
|
+
const versionTag = version ? `@${version}` : "";
|
|
13404
|
+
url = `https://unpkg.com/@loaders.gl/${worker.module}${versionTag}/dist/${workerFile}`;
|
|
13494
13405
|
}
|
|
13495
|
-
|
|
13496
|
-
|
|
13497
|
-
type: "Polygon",
|
|
13498
|
-
// @ts-expect-error
|
|
13499
|
-
coordinates: c
|
|
13500
|
-
};
|
|
13406
|
+
assert(url);
|
|
13407
|
+
return url;
|
|
13501
13408
|
}
|
|
13502
|
-
|
|
13503
|
-
|
|
13504
|
-
|
|
13409
|
+
|
|
13410
|
+
// ../worker-utils/src/lib/worker-api/process-on-worker.ts
|
|
13411
|
+
async function processOnWorker(worker, data, options = {}, context = {}) {
|
|
13412
|
+
const name = getWorkerName(worker);
|
|
13413
|
+
const workerFarm = WorkerFarm.getWorkerFarm(options);
|
|
13414
|
+
const { source } = options;
|
|
13415
|
+
const workerPoolProps = { name, source };
|
|
13416
|
+
if (!source) {
|
|
13417
|
+
workerPoolProps.url = getWorkerURL(worker, options);
|
|
13505
13418
|
}
|
|
13506
|
-
|
|
13507
|
-
const
|
|
13508
|
-
|
|
13509
|
-
|
|
13419
|
+
const workerPool = workerFarm.getWorkerPool(workerPoolProps);
|
|
13420
|
+
const jobName = options.jobName || worker.name;
|
|
13421
|
+
const job = await workerPool.startJob(
|
|
13422
|
+
jobName,
|
|
13423
|
+
// eslint-disable-next-line
|
|
13424
|
+
onMessage.bind(null, context)
|
|
13425
|
+
);
|
|
13426
|
+
const transferableOptions = getTransferListForWriter(options);
|
|
13427
|
+
job.postMessage("process", { input: data, options: transferableOptions });
|
|
13428
|
+
const result = await job.result;
|
|
13429
|
+
return result.result;
|
|
13430
|
+
}
|
|
13431
|
+
async function onMessage(context, job, type, payload) {
|
|
13432
|
+
switch (type) {
|
|
13433
|
+
case "done":
|
|
13434
|
+
job.done(payload);
|
|
13435
|
+
break;
|
|
13436
|
+
case "error":
|
|
13437
|
+
job.error(new Error(payload.error));
|
|
13438
|
+
break;
|
|
13439
|
+
case "process":
|
|
13440
|
+
const { id, input, options } = payload;
|
|
13441
|
+
try {
|
|
13442
|
+
if (!context.process) {
|
|
13443
|
+
job.postMessage("error", { id, error: "Worker not set up to process on main thread" });
|
|
13444
|
+
return;
|
|
13445
|
+
}
|
|
13446
|
+
const result = await context.process(input, options);
|
|
13447
|
+
job.postMessage("done", { id, result });
|
|
13448
|
+
} catch (error) {
|
|
13449
|
+
const message = error instanceof Error ? error.message : "unknown error";
|
|
13450
|
+
job.postMessage("error", { id, error: message });
|
|
13451
|
+
}
|
|
13452
|
+
break;
|
|
13453
|
+
default:
|
|
13454
|
+
console.warn(`process-on-worker: unknown message ${type}`);
|
|
13510
13455
|
}
|
|
13511
|
-
return {
|
|
13512
|
-
type: "MultiPolygon",
|
|
13513
|
-
// @ts-expect-error
|
|
13514
|
-
coordinates: c
|
|
13515
|
-
};
|
|
13516
13456
|
}
|
|
13517
|
-
|
|
13518
|
-
|
|
13519
|
-
|
|
13520
|
-
|
|
13521
|
-
|
|
13522
|
-
}
|
|
13523
|
-
white(state);
|
|
13524
|
-
if (!$(/^(\()/, state)) {
|
|
13525
|
-
return null;
|
|
13457
|
+
|
|
13458
|
+
// ../loader-utils/src/lib/iterators/async-iteration.ts
|
|
13459
|
+
async function* toArrayBufferIterator(asyncIterator) {
|
|
13460
|
+
for await (const chunk of asyncIterator) {
|
|
13461
|
+
yield copyToArrayBuffer(chunk);
|
|
13526
13462
|
}
|
|
13527
|
-
|
|
13528
|
-
|
|
13529
|
-
|
|
13530
|
-
|
|
13531
|
-
white(state);
|
|
13463
|
+
}
|
|
13464
|
+
function copyToArrayBuffer(chunk) {
|
|
13465
|
+
if (chunk instanceof ArrayBuffer) {
|
|
13466
|
+
return chunk;
|
|
13532
13467
|
}
|
|
13533
|
-
if (
|
|
13534
|
-
|
|
13468
|
+
if (ArrayBuffer.isView(chunk)) {
|
|
13469
|
+
const { buffer, byteOffset, byteLength } = chunk;
|
|
13470
|
+
return copyFromBuffer(buffer, byteOffset, byteLength);
|
|
13535
13471
|
}
|
|
13536
|
-
return
|
|
13537
|
-
type: "GeometryCollection",
|
|
13538
|
-
geometries
|
|
13539
|
-
};
|
|
13472
|
+
return copyFromBuffer(chunk);
|
|
13540
13473
|
}
|
|
13541
|
-
function
|
|
13542
|
-
|
|
13543
|
-
|
|
13544
|
-
|
|
13545
|
-
|
|
13546
|
-
let pointer = rings;
|
|
13547
|
-
let elem;
|
|
13548
|
-
while (elem = $(/^(\()/, state) || $(/^(\))/, state) || $(/^(,)/, state) || $(tuples, state)) {
|
|
13549
|
-
if (elem === "(") {
|
|
13550
|
-
stack.push(pointer);
|
|
13551
|
-
pointer = [];
|
|
13552
|
-
stack[stack.length - 1].push(pointer);
|
|
13553
|
-
depth++;
|
|
13554
|
-
} else if (elem === ")") {
|
|
13555
|
-
if (pointer.length === 0)
|
|
13556
|
-
return null;
|
|
13557
|
-
pointer = stack.pop();
|
|
13558
|
-
if (!pointer)
|
|
13559
|
-
return null;
|
|
13560
|
-
depth--;
|
|
13561
|
-
if (depth === 0)
|
|
13562
|
-
break;
|
|
13563
|
-
} else if (elem === ",") {
|
|
13564
|
-
pointer = [];
|
|
13565
|
-
stack[stack.length - 1].push(pointer);
|
|
13566
|
-
} else if (!elem.split(/\s/g).some(isNaN)) {
|
|
13567
|
-
Array.prototype.push.apply(pointer, elem.split(/\s/g).map(parseFloat));
|
|
13568
|
-
} else {
|
|
13569
|
-
return null;
|
|
13570
|
-
}
|
|
13571
|
-
white(state);
|
|
13572
|
-
}
|
|
13573
|
-
if (depth !== 0)
|
|
13574
|
-
return null;
|
|
13575
|
-
return rings;
|
|
13474
|
+
function copyFromBuffer(buffer, byteOffset = 0, byteLength = buffer.byteLength - byteOffset) {
|
|
13475
|
+
const view = new Uint8Array(buffer, byteOffset, byteLength);
|
|
13476
|
+
const copy = new Uint8Array(view.length);
|
|
13477
|
+
copy.set(view);
|
|
13478
|
+
return copy.buffer;
|
|
13576
13479
|
}
|
|
13577
|
-
|
|
13578
|
-
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
if (pt === ",") {
|
|
13583
|
-
list.push(item);
|
|
13584
|
-
item = [];
|
|
13585
|
-
} else if (!pt.split(/\s/g).some(isNaN)) {
|
|
13586
|
-
if (!item)
|
|
13587
|
-
item = [];
|
|
13588
|
-
Array.prototype.push.apply(item, pt.split(/\s/g).map(parseFloat));
|
|
13589
|
-
}
|
|
13590
|
-
white(state);
|
|
13480
|
+
|
|
13481
|
+
// ../loader-utils/src/lib/binary-utils/memory-conversion-utils.ts
|
|
13482
|
+
function ensureArrayBuffer(bufferSource) {
|
|
13483
|
+
if (bufferSource instanceof ArrayBuffer) {
|
|
13484
|
+
return bufferSource;
|
|
13591
13485
|
}
|
|
13592
|
-
if (
|
|
13593
|
-
|
|
13594
|
-
|
|
13595
|
-
|
|
13596
|
-
|
|
13597
|
-
|
|
13598
|
-
function $(regexp, state) {
|
|
13599
|
-
const match = state._?.substring(state.i).match(regexp);
|
|
13600
|
-
if (!match)
|
|
13601
|
-
return null;
|
|
13602
|
-
else {
|
|
13603
|
-
state.i += match[0].length;
|
|
13604
|
-
return match[0];
|
|
13486
|
+
if (isSharedArrayBuffer(bufferSource)) {
|
|
13487
|
+
return copyToArrayBuffer2(bufferSource);
|
|
13488
|
+
}
|
|
13489
|
+
const { buffer, byteOffset, byteLength } = bufferSource;
|
|
13490
|
+
if (buffer instanceof ArrayBuffer && byteOffset === 0 && byteLength === buffer.byteLength) {
|
|
13491
|
+
return buffer;
|
|
13605
13492
|
}
|
|
13493
|
+
return copyToArrayBuffer2(buffer, byteOffset, byteLength);
|
|
13606
13494
|
}
|
|
13607
|
-
function
|
|
13608
|
-
|
|
13495
|
+
function copyToArrayBuffer2(buffer, byteOffset = 0, byteLength = buffer.byteLength - byteOffset) {
|
|
13496
|
+
const view = new Uint8Array(buffer, byteOffset, byteLength);
|
|
13497
|
+
const copy = new Uint8Array(view.length);
|
|
13498
|
+
copy.set(view);
|
|
13499
|
+
return copy.buffer;
|
|
13609
13500
|
}
|
|
13610
13501
|
|
|
13611
|
-
//
|
|
13612
|
-
function
|
|
13613
|
-
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13625
|
-
|
|
13626
|
-
|
|
13627
|
-
|
|
13628
|
-
|
|
13629
|
-
|
|
13630
|
-
|
|
13631
|
-
|
|
13632
|
-
|
|
13633
|
-
|
|
13634
|
-
default: {
|
|
13635
|
-
throw Error(`GeoArrow encoding not supported ${encoding}`);
|
|
13502
|
+
// src/lib/parsers/parse-arrow.ts
|
|
13503
|
+
function parseArrowSync(arrayBuffer, options) {
|
|
13504
|
+
const shape = options?.shape || "arrow-table";
|
|
13505
|
+
const arrowTable = tableFromIPC([new Uint8Array(arrayBuffer)]);
|
|
13506
|
+
return convertArrowToTable(arrowTable, shape);
|
|
13507
|
+
}
|
|
13508
|
+
function parseArrowInBatches(asyncIterator, options) {
|
|
13509
|
+
async function* makeArrowAsyncIterator() {
|
|
13510
|
+
const readers = RecordBatchReader.readAll(toArrayBufferIterator(asyncIterator));
|
|
13511
|
+
for await (const reader of readers) {
|
|
13512
|
+
for await (const recordBatch of reader) {
|
|
13513
|
+
if (options?.arrow?.batchDebounceMs !== void 0 && options?.arrow?.batchDebounceMs > 0) {
|
|
13514
|
+
await new Promise((resolve) => setTimeout(resolve, options.arrow?.batchDebounceMs || 0));
|
|
13515
|
+
}
|
|
13516
|
+
const arrowTabledBatch = {
|
|
13517
|
+
shape: "arrow-table",
|
|
13518
|
+
batchType: "data",
|
|
13519
|
+
data: new Table([recordBatch]),
|
|
13520
|
+
length: recordBatch.data.length
|
|
13521
|
+
};
|
|
13522
|
+
yield arrowTabledBatch;
|
|
13523
|
+
}
|
|
13524
|
+
break;
|
|
13636
13525
|
}
|
|
13637
13526
|
}
|
|
13527
|
+
return makeArrowAsyncIterator();
|
|
13638
13528
|
}
|
|
13639
|
-
|
|
13640
|
-
|
|
13641
|
-
|
|
13642
|
-
|
|
13643
|
-
)
|
|
13644
|
-
|
|
13529
|
+
|
|
13530
|
+
// src/arrow-loader.ts
|
|
13531
|
+
var ArrowLoader = {
|
|
13532
|
+
...ArrowWorkerLoader,
|
|
13533
|
+
parse: async (arraybuffer, options) => parseArrowSync(arraybuffer, options?.arrow),
|
|
13534
|
+
parseSync: (arraybuffer, options) => parseArrowSync(arraybuffer, options?.arrow),
|
|
13535
|
+
parseInBatches: parseArrowInBatches
|
|
13536
|
+
};
|
|
13537
|
+
|
|
13538
|
+
// src/lib/encoders/encode-arrow.ts
|
|
13539
|
+
function encodeArrowSync(data) {
|
|
13540
|
+
const vectors = {};
|
|
13541
|
+
for (const arrayData of data) {
|
|
13542
|
+
const arrayVector = createVector(arrayData.array, arrayData.type);
|
|
13543
|
+
vectors[arrayData.name] = arrayVector;
|
|
13544
|
+
}
|
|
13545
|
+
const table = new Table(vectors);
|
|
13546
|
+
const arrowBuffer = tableToIPC(table);
|
|
13547
|
+
return ensureArrayBuffer(arrowBuffer);
|
|
13645
13548
|
}
|
|
13646
|
-
function
|
|
13647
|
-
|
|
13648
|
-
|
|
13549
|
+
function createVector(array, type) {
|
|
13550
|
+
switch (type) {
|
|
13551
|
+
case 1 /* DATE */:
|
|
13552
|
+
return vectorFromArray(array);
|
|
13553
|
+
case 0 /* FLOAT */:
|
|
13554
|
+
default:
|
|
13555
|
+
return vectorFromArray(array);
|
|
13556
|
+
}
|
|
13649
13557
|
}
|
|
13650
|
-
|
|
13651
|
-
|
|
13652
|
-
|
|
13653
|
-
|
|
13654
|
-
|
|
13655
|
-
|
|
13656
|
-
|
|
13657
|
-
|
|
13658
|
-
|
|
13659
|
-
|
|
13660
|
-
|
|
13661
|
-
|
|
13662
|
-
|
|
13663
|
-
|
|
13558
|
+
|
|
13559
|
+
// src/arrow-writer.ts
|
|
13560
|
+
var VERSION3 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
|
|
13561
|
+
var ArrowWriter = {
|
|
13562
|
+
name: "Apache Arrow",
|
|
13563
|
+
id: "arrow",
|
|
13564
|
+
module: "arrow",
|
|
13565
|
+
version: VERSION3,
|
|
13566
|
+
extensions: ["arrow", "feather"],
|
|
13567
|
+
mimeTypes: [
|
|
13568
|
+
"application/vnd.apache.arrow.file",
|
|
13569
|
+
"application/vnd.apache.arrow.stream",
|
|
13570
|
+
"application/octet-stream"
|
|
13571
|
+
],
|
|
13572
|
+
binary: true,
|
|
13573
|
+
options: {},
|
|
13574
|
+
encode: async function encodeArrow(data, options) {
|
|
13575
|
+
return encodeArrowSync(data);
|
|
13576
|
+
},
|
|
13577
|
+
encodeSync(data, options) {
|
|
13578
|
+
return encodeArrowSync(data);
|
|
13579
|
+
}
|
|
13580
|
+
};
|
|
13581
|
+
|
|
13582
|
+
// src/exports/geoarrow-loader.ts
|
|
13583
|
+
var GeoArrowWorkerLoader = {
|
|
13584
|
+
...ArrowWorkerLoader,
|
|
13585
|
+
options: {
|
|
13586
|
+
arrow: {
|
|
13587
|
+
shape: "arrow-table"
|
|
13664
13588
|
}
|
|
13665
|
-
multiPolygon.push(polygon);
|
|
13666
13589
|
}
|
|
13667
|
-
|
|
13668
|
-
|
|
13669
|
-
|
|
13670
|
-
|
|
13671
|
-
return
|
|
13590
|
+
};
|
|
13591
|
+
|
|
13592
|
+
// ../geoarrow/src/metadata/metadata-utils.ts
|
|
13593
|
+
function getMetadataValue(metadata, key) {
|
|
13594
|
+
return metadata instanceof Map ? metadata.get(key) || null : metadata[key] || null;
|
|
13672
13595
|
}
|
|
13673
|
-
|
|
13674
|
-
|
|
13675
|
-
|
|
13676
|
-
|
|
13677
|
-
|
|
13678
|
-
|
|
13679
|
-
|
|
13680
|
-
|
|
13681
|
-
|
|
13596
|
+
|
|
13597
|
+
// ../geoarrow/src/metadata/geoarrow-metadata.ts
|
|
13598
|
+
var GEOARROW_ENCODINGS = [
|
|
13599
|
+
"geoarrow.multipolygon",
|
|
13600
|
+
"geoarrow.polygon",
|
|
13601
|
+
"geoarrow.multilinestring",
|
|
13602
|
+
"geoarrow.linestring",
|
|
13603
|
+
"geoarrow.multipoint",
|
|
13604
|
+
"geoarrow.point",
|
|
13605
|
+
"geoarrow.wkb",
|
|
13606
|
+
"geoarrow.wkt"
|
|
13607
|
+
];
|
|
13608
|
+
var GEOARROW_ENCODING = "ARROW:extension:name";
|
|
13609
|
+
var GEOARROW_METADATA = "ARROW:extension:metadata";
|
|
13610
|
+
function getGeometryColumnsFromSchema(schema) {
|
|
13611
|
+
const geometryColumns = {};
|
|
13612
|
+
for (const field of schema.fields || []) {
|
|
13613
|
+
const metadata = getGeometryMetadataForField(field?.metadata || {});
|
|
13614
|
+
if (metadata) {
|
|
13615
|
+
geometryColumns[field.name] = metadata;
|
|
13682
13616
|
}
|
|
13683
|
-
polygon.push(ring);
|
|
13684
13617
|
}
|
|
13685
|
-
|
|
13686
|
-
type: "Polygon",
|
|
13687
|
-
coordinates: polygon
|
|
13688
|
-
};
|
|
13689
|
-
return geometry;
|
|
13618
|
+
return geometryColumns;
|
|
13690
13619
|
}
|
|
13691
|
-
function
|
|
13692
|
-
|
|
13693
|
-
|
|
13694
|
-
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
|
|
13620
|
+
function getGeometryMetadataForField(fieldMetadata) {
|
|
13621
|
+
let metadata = null;
|
|
13622
|
+
let geoEncoding = getMetadataValue(fieldMetadata, GEOARROW_ENCODING);
|
|
13623
|
+
if (geoEncoding) {
|
|
13624
|
+
geoEncoding = geoEncoding.toLowerCase();
|
|
13625
|
+
if (geoEncoding === "wkb") {
|
|
13626
|
+
geoEncoding = "geoarrow.wkb";
|
|
13698
13627
|
}
|
|
13699
|
-
|
|
13700
|
-
|
|
13701
|
-
|
|
13702
|
-
|
|
13703
|
-
|
|
13704
|
-
|
|
13705
|
-
|
|
13706
|
-
|
|
13707
|
-
return {
|
|
13708
|
-
type: "Point",
|
|
13709
|
-
coordinates: point
|
|
13710
|
-
};
|
|
13711
|
-
}
|
|
13712
|
-
function arrowMultiLineStringToGeometry(arrowMultiLineString) {
|
|
13713
|
-
const multiLineString = [];
|
|
13714
|
-
for (let i = 0; arrowMultiLineString && i < arrowMultiLineString.length; i++) {
|
|
13715
|
-
const arrowLineString = arrowMultiLineString.get(i);
|
|
13716
|
-
const lineString = [];
|
|
13717
|
-
for (let j = 0; arrowLineString && j < arrowLineString.length; j++) {
|
|
13718
|
-
const arrowCoord = arrowLineString.get(j);
|
|
13719
|
-
if (arrowCoord) {
|
|
13720
|
-
const coords2 = Array.from(arrowCoord);
|
|
13721
|
-
lineString.push(coords2);
|
|
13722
|
-
}
|
|
13628
|
+
if (geoEncoding === "wkt") {
|
|
13629
|
+
geoEncoding = "geoarrow.wkt";
|
|
13630
|
+
}
|
|
13631
|
+
if (!GEOARROW_ENCODINGS.includes(geoEncoding)) {
|
|
13632
|
+
console.warn(`Invalid GeoArrow encoding: ${geoEncoding}`);
|
|
13633
|
+
} else {
|
|
13634
|
+
metadata ||= {};
|
|
13635
|
+
metadata.encoding = geoEncoding;
|
|
13723
13636
|
}
|
|
13724
|
-
multiLineString.push(lineString);
|
|
13725
13637
|
}
|
|
13726
|
-
|
|
13727
|
-
|
|
13728
|
-
|
|
13729
|
-
|
|
13730
|
-
|
|
13731
|
-
|
|
13732
|
-
const lineString = [];
|
|
13733
|
-
for (let i = 0; arrowLineString && i < arrowLineString.length; i++) {
|
|
13734
|
-
const arrowCoord = arrowLineString.get(i);
|
|
13735
|
-
if (arrowCoord) {
|
|
13736
|
-
const coords2 = Array.from(arrowCoord);
|
|
13737
|
-
lineString.push(coords2);
|
|
13638
|
+
const columnMetadata = getMetadataValue(fieldMetadata, GEOARROW_METADATA);
|
|
13639
|
+
if (columnMetadata) {
|
|
13640
|
+
try {
|
|
13641
|
+
metadata = JSON.parse(columnMetadata);
|
|
13642
|
+
} catch (error) {
|
|
13643
|
+
console.warn("Failed to parse GeoArrow metadata", error);
|
|
13738
13644
|
}
|
|
13739
13645
|
}
|
|
13740
|
-
return
|
|
13741
|
-
type: "LineString",
|
|
13742
|
-
coordinates: lineString
|
|
13743
|
-
};
|
|
13646
|
+
return metadata || null;
|
|
13744
13647
|
}
|
|
13745
13648
|
|
|
13746
|
-
// ../gis/src/lib/
|
|
13747
|
-
function
|
|
13748
|
-
switch (
|
|
13749
|
-
case "
|
|
13750
|
-
return
|
|
13751
|
-
case "
|
|
13752
|
-
return
|
|
13753
|
-
case "
|
|
13754
|
-
return
|
|
13755
|
-
case "columnar-table":
|
|
13756
|
-
return convertArrowToColumnarTable2(arrowTable);
|
|
13757
|
-
case "geojson-table":
|
|
13758
|
-
return convertArrowToGeoJSONTable2(arrowTable);
|
|
13649
|
+
// ../gis/src/lib/geometry-converters/convert-binary-geometry-to-geojson.ts
|
|
13650
|
+
function convertBinaryGeometryToGeometry(data, startIndex, endIndex) {
|
|
13651
|
+
switch (data.type) {
|
|
13652
|
+
case "Point":
|
|
13653
|
+
return pointToGeoJson(data, startIndex, endIndex);
|
|
13654
|
+
case "LineString":
|
|
13655
|
+
return lineStringToGeoJson(data, startIndex, endIndex);
|
|
13656
|
+
case "Polygon":
|
|
13657
|
+
return polygonToGeoJson(data, startIndex, endIndex);
|
|
13759
13658
|
default:
|
|
13760
|
-
|
|
13761
|
-
|
|
13762
|
-
}
|
|
13763
|
-
function convertArrowToArrowTable2(arrowTable) {
|
|
13764
|
-
return {
|
|
13765
|
-
shape: "arrow-table",
|
|
13766
|
-
schema: convertArrowToSchema(arrowTable.schema),
|
|
13767
|
-
data: arrowTable
|
|
13768
|
-
};
|
|
13769
|
-
}
|
|
13770
|
-
function convertArrowToArrayRowTable2(arrowTable) {
|
|
13771
|
-
const columnarTable = convertArrowToColumnarTable2(arrowTable);
|
|
13772
|
-
return convertTable(columnarTable, "array-row-table");
|
|
13773
|
-
}
|
|
13774
|
-
function convertArrowToObjectRowTable2(arrowTable) {
|
|
13775
|
-
const columnarTable = convertArrowToColumnarTable2(arrowTable);
|
|
13776
|
-
return convertTable(columnarTable, "object-row-table");
|
|
13777
|
-
}
|
|
13778
|
-
function convertArrowToColumnarTable2(arrowTable) {
|
|
13779
|
-
const columns = {};
|
|
13780
|
-
for (const field of arrowTable.schema.fields) {
|
|
13781
|
-
const arrowColumn = arrowTable.getChild(field.name);
|
|
13782
|
-
const values = arrowColumn?.toArray();
|
|
13783
|
-
columns[field.name] = values;
|
|
13659
|
+
const unexpectedInput = data;
|
|
13660
|
+
throw new Error(`Unsupported geometry type: ${unexpectedInput?.type}`);
|
|
13784
13661
|
}
|
|
13785
|
-
const schema = convertArrowToSchema(arrowTable.schema);
|
|
13786
|
-
return {
|
|
13787
|
-
shape: "columnar-table",
|
|
13788
|
-
schema,
|
|
13789
|
-
data: columns
|
|
13790
|
-
};
|
|
13791
13662
|
}
|
|
13792
|
-
function
|
|
13793
|
-
const
|
|
13794
|
-
const
|
|
13795
|
-
const
|
|
13796
|
-
|
|
13797
|
-
|
|
13798
|
-
const
|
|
13799
|
-
|
|
13800
|
-
|
|
13801
|
-
|
|
13802
|
-
|
|
13803
|
-
|
|
13804
|
-
const
|
|
13805
|
-
|
|
13663
|
+
function polygonToGeoJson(data, startIndex = -Infinity, endIndex = Infinity) {
|
|
13664
|
+
const { positions } = data;
|
|
13665
|
+
const polygonIndices = data.polygonIndices.value.filter((x) => x >= startIndex && x <= endIndex);
|
|
13666
|
+
const primitivePolygonIndices = data.primitivePolygonIndices.value.filter(
|
|
13667
|
+
(x) => x >= startIndex && x <= endIndex
|
|
13668
|
+
);
|
|
13669
|
+
const multi = polygonIndices.length > 2;
|
|
13670
|
+
if (!multi) {
|
|
13671
|
+
const coordinates2 = [];
|
|
13672
|
+
for (let i = 0; i < primitivePolygonIndices.length - 1; i++) {
|
|
13673
|
+
const startRingIndex = primitivePolygonIndices[i];
|
|
13674
|
+
const endRingIndex = primitivePolygonIndices[i + 1];
|
|
13675
|
+
const ringCoordinates = ringToGeoJson(positions, startRingIndex, endRingIndex);
|
|
13676
|
+
coordinates2.push(ringCoordinates);
|
|
13806
13677
|
}
|
|
13678
|
+
return { type: "Polygon", coordinates: coordinates2 };
|
|
13807
13679
|
}
|
|
13808
|
-
|
|
13809
|
-
|
|
13810
|
-
|
|
13811
|
-
|
|
13812
|
-
|
|
13813
|
-
|
|
13814
|
-
|
|
13815
|
-
|
|
13816
|
-
|
|
13817
|
-
|
|
13818
|
-
const table = parseArrowSync(arrayBuffer, { shape: "arrow-table" });
|
|
13819
|
-
switch (options?.shape) {
|
|
13820
|
-
case "geojson-table":
|
|
13821
|
-
return convertGeoArrowToTable(table.data, "geojson-table");
|
|
13822
|
-
default:
|
|
13823
|
-
return table;
|
|
13680
|
+
const coordinates = [];
|
|
13681
|
+
for (let i = 0; i < polygonIndices.length - 1; i++) {
|
|
13682
|
+
const startPolygonIndex = polygonIndices[i];
|
|
13683
|
+
const endPolygonIndex = polygonIndices[i + 1];
|
|
13684
|
+
const polygonCoordinates = polygonToGeoJson(
|
|
13685
|
+
data,
|
|
13686
|
+
startPolygonIndex,
|
|
13687
|
+
endPolygonIndex
|
|
13688
|
+
).coordinates;
|
|
13689
|
+
coordinates.push(polygonCoordinates);
|
|
13824
13690
|
}
|
|
13691
|
+
return { type: "MultiPolygon", coordinates };
|
|
13825
13692
|
}
|
|
13826
|
-
function
|
|
13827
|
-
|
|
13828
|
-
|
|
13829
|
-
|
|
13830
|
-
|
|
13831
|
-
|
|
13832
|
-
|
|
13833
|
-
parse: async (arraybuffer, options) => parseGeoArrowSync(arraybuffer, options?.arrow),
|
|
13834
|
-
parseSync: (arraybuffer, options) => parseGeoArrowSync(arraybuffer, options?.arrow),
|
|
13835
|
-
parseInBatches: parseGeoArrowInBatches
|
|
13836
|
-
};
|
|
13837
|
-
|
|
13838
|
-
// src/workers/hard-clone.ts
|
|
13839
|
-
function hardClone(data, force = false) {
|
|
13840
|
-
if ("data" in data) {
|
|
13841
|
-
return new Vector(data.data.map((data2) => hardClone(data2, force)));
|
|
13842
|
-
}
|
|
13843
|
-
const clonedChildren = [];
|
|
13844
|
-
for (const childData of data.children) {
|
|
13845
|
-
clonedChildren.push(hardClone(childData, force));
|
|
13693
|
+
function lineStringToGeoJson(data, startIndex = -Infinity, endIndex = Infinity) {
|
|
13694
|
+
const { positions } = data;
|
|
13695
|
+
const pathIndices = data.pathIndices.value.filter((x) => x >= startIndex && x <= endIndex);
|
|
13696
|
+
const multi = pathIndices.length > 2;
|
|
13697
|
+
if (!multi) {
|
|
13698
|
+
const coordinates2 = ringToGeoJson(positions, pathIndices[0], pathIndices[1]);
|
|
13699
|
+
return { type: "LineString", coordinates: coordinates2 };
|
|
13846
13700
|
}
|
|
13847
|
-
|
|
13848
|
-
|
|
13849
|
-
|
|
13701
|
+
const coordinates = [];
|
|
13702
|
+
for (let i = 0; i < pathIndices.length - 1; i++) {
|
|
13703
|
+
const ringCoordinates = ringToGeoJson(positions, pathIndices[i], pathIndices[i + 1]);
|
|
13704
|
+
coordinates.push(ringCoordinates);
|
|
13850
13705
|
}
|
|
13851
|
-
|
|
13852
|
-
[BufferType.OFFSET]: cloneBuffer(data.buffers[BufferType.OFFSET], force),
|
|
13853
|
-
[BufferType.DATA]: cloneBuffer(data.buffers[BufferType.DATA], force),
|
|
13854
|
-
[BufferType.VALIDITY]: cloneBuffer(data.buffers[BufferType.VALIDITY], force),
|
|
13855
|
-
[BufferType.TYPE]: cloneBuffer(data.buffers[BufferType.TYPE], force)
|
|
13856
|
-
};
|
|
13857
|
-
return new Data(
|
|
13858
|
-
data.type,
|
|
13859
|
-
data.offset,
|
|
13860
|
-
data.length,
|
|
13861
|
-
// @ts-expect-error _nullCount is protected. We're using it here to mimic
|
|
13862
|
-
// `Data.clone`
|
|
13863
|
-
data._nullCount,
|
|
13864
|
-
clonedBuffers,
|
|
13865
|
-
clonedChildren,
|
|
13866
|
-
clonedDictionary
|
|
13867
|
-
);
|
|
13868
|
-
}
|
|
13869
|
-
function isTypedArraySliced(arr) {
|
|
13870
|
-
return !(arr.byteOffset === 0 && arr.byteLength === arr.buffer.byteLength);
|
|
13706
|
+
return { type: "MultiLineString", coordinates };
|
|
13871
13707
|
}
|
|
13872
|
-
function
|
|
13873
|
-
|
|
13874
|
-
|
|
13875
|
-
|
|
13876
|
-
if (
|
|
13877
|
-
return
|
|
13708
|
+
function pointToGeoJson(data, startIndex, endIndex) {
|
|
13709
|
+
const { positions } = data;
|
|
13710
|
+
const coordinates = ringToGeoJson(positions, startIndex, endIndex);
|
|
13711
|
+
const multi = coordinates.length > 1;
|
|
13712
|
+
if (multi) {
|
|
13713
|
+
return { type: "MultiPoint", coordinates };
|
|
13878
13714
|
}
|
|
13879
|
-
return
|
|
13715
|
+
return { type: "Point", coordinates: coordinates[0] };
|
|
13880
13716
|
}
|
|
13881
|
-
|
|
13882
|
-
|
|
13883
|
-
|
|
13884
|
-
|
|
13885
|
-
|
|
13886
|
-
|
|
13887
|
-
|
|
13888
|
-
|
|
13889
|
-
if (typeof __VERSION__ === "undefined") {
|
|
13890
|
-
console.warn(
|
|
13891
|
-
"loaders.gl: The __VERSION__ variable is not injected using babel plugin. Latest unstable workers would be fetched from the CDN."
|
|
13892
|
-
);
|
|
13893
|
-
globalThis._loadersgl_.version = NPM_TAG;
|
|
13894
|
-
} else {
|
|
13895
|
-
globalThis._loadersgl_.version = __VERSION__;
|
|
13717
|
+
function ringToGeoJson(positions, startIndex, endIndex) {
|
|
13718
|
+
startIndex = startIndex || 0;
|
|
13719
|
+
endIndex = endIndex || positions.value.length / positions.size;
|
|
13720
|
+
const ringCoordinates = [];
|
|
13721
|
+
for (let j = startIndex; j < endIndex; j++) {
|
|
13722
|
+
const coord = Array();
|
|
13723
|
+
for (let k = j * positions.size; k < (j + 1) * positions.size; k++) {
|
|
13724
|
+
coord.push(Number(positions.value[k]));
|
|
13896
13725
|
}
|
|
13726
|
+
ringCoordinates.push(coord);
|
|
13897
13727
|
}
|
|
13898
|
-
return
|
|
13728
|
+
return ringCoordinates;
|
|
13899
13729
|
}
|
|
13900
|
-
var VERSION3 = getVersion();
|
|
13901
13730
|
|
|
13902
|
-
// ../
|
|
13903
|
-
function
|
|
13904
|
-
|
|
13905
|
-
|
|
13731
|
+
// ../gis/src/lib/utils/concat-typed-arrays.ts
|
|
13732
|
+
function concatTypedArrays(arrays) {
|
|
13733
|
+
let byteLength = 0;
|
|
13734
|
+
for (let i = 0; i < arrays.length; ++i) {
|
|
13735
|
+
byteLength += arrays[i].byteLength;
|
|
13736
|
+
}
|
|
13737
|
+
const buffer = new Uint8Array(byteLength);
|
|
13738
|
+
let byteOffset = 0;
|
|
13739
|
+
for (let i = 0; i < arrays.length; ++i) {
|
|
13740
|
+
const data = new Uint8Array(arrays[i].buffer);
|
|
13741
|
+
byteLength = data.length;
|
|
13742
|
+
for (let j = 0; j < byteLength; ++j) {
|
|
13743
|
+
buffer[byteOffset++] = data[j];
|
|
13744
|
+
}
|
|
13906
13745
|
}
|
|
13746
|
+
return buffer;
|
|
13907
13747
|
}
|
|
13908
13748
|
|
|
13909
|
-
// ../
|
|
13910
|
-
|
|
13911
|
-
|
|
13912
|
-
|
|
13913
|
-
|
|
13914
|
-
|
|
13915
|
-
|
|
13916
|
-
var self_ = globals.self || globals.window || globals.global || {};
|
|
13917
|
-
var window_ = globals.window || globals.self || globals.global || {};
|
|
13918
|
-
var global_ = globals.global || globals.self || globals.window || {};
|
|
13919
|
-
var document_ = globals.document || {};
|
|
13920
|
-
var isBrowser = (
|
|
13921
|
-
// @ts-ignore process.browser
|
|
13922
|
-
typeof process !== "object" || String(process) !== "[object process]" || process.browser
|
|
13923
|
-
);
|
|
13924
|
-
var isMobile = typeof window !== "undefined" && typeof window.orientation !== "undefined";
|
|
13925
|
-
var matches = typeof process !== "undefined" && process.version && /v([0-9]*)/.exec(process.version);
|
|
13926
|
-
var nodeVersion = matches && parseFloat(matches[1]) || 0;
|
|
13927
|
-
|
|
13928
|
-
// ../worker-utils/src/lib/worker-farm/worker-job.ts
|
|
13929
|
-
var WorkerJob = class {
|
|
13930
|
-
name;
|
|
13931
|
-
workerThread;
|
|
13932
|
-
isRunning = true;
|
|
13933
|
-
/** Promise that resolves when Job is done */
|
|
13934
|
-
result;
|
|
13935
|
-
_resolve = () => {
|
|
13749
|
+
// ../gis/src/lib/binary-geometry-api/concat-binary-geometry.ts
|
|
13750
|
+
function concatenateBinaryPointGeometries(binaryPointGeometries, dimension) {
|
|
13751
|
+
const positions = binaryPointGeometries.map((geometry) => geometry.positions.value);
|
|
13752
|
+
const concatenatedPositions = new Float64Array(concatTypedArrays(positions).buffer);
|
|
13753
|
+
return {
|
|
13754
|
+
type: "Point",
|
|
13755
|
+
positions: { value: concatenatedPositions, size: dimension }
|
|
13936
13756
|
};
|
|
13937
|
-
|
|
13757
|
+
}
|
|
13758
|
+
function concatenateBinaryLineGeometries(binaryLineGeometries, dimension) {
|
|
13759
|
+
const lines = binaryLineGeometries.map((geometry) => geometry.positions.value);
|
|
13760
|
+
const concatenatedPositions = new Float64Array(concatTypedArrays(lines).buffer);
|
|
13761
|
+
const pathIndices = lines.map((line) => line.length / dimension).map(cumulativeSum(0));
|
|
13762
|
+
pathIndices.unshift(0);
|
|
13763
|
+
return {
|
|
13764
|
+
type: "LineString",
|
|
13765
|
+
positions: { value: concatenatedPositions, size: dimension },
|
|
13766
|
+
pathIndices: { value: new Uint32Array(pathIndices), size: 1 }
|
|
13938
13767
|
};
|
|
13939
|
-
|
|
13940
|
-
|
|
13941
|
-
|
|
13942
|
-
|
|
13943
|
-
|
|
13944
|
-
|
|
13945
|
-
|
|
13768
|
+
}
|
|
13769
|
+
function concatenateBinaryPolygonGeometries(binaryPolygonGeometries, dimension) {
|
|
13770
|
+
const polygons = [];
|
|
13771
|
+
const primitivePolygons = [];
|
|
13772
|
+
for (const binaryPolygon of binaryPolygonGeometries) {
|
|
13773
|
+
const { positions, primitivePolygonIndices: primitivePolygonIndices2 } = binaryPolygon;
|
|
13774
|
+
polygons.push(positions.value);
|
|
13775
|
+
primitivePolygons.push(primitivePolygonIndices2.value);
|
|
13946
13776
|
}
|
|
13947
|
-
|
|
13948
|
-
|
|
13949
|
-
|
|
13950
|
-
|
|
13951
|
-
|
|
13952
|
-
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
type,
|
|
13956
|
-
payload
|
|
13957
|
-
});
|
|
13777
|
+
const concatenatedPositions = new Float64Array(concatTypedArrays(polygons).buffer);
|
|
13778
|
+
const polygonIndices = polygons.map((p) => p.length / dimension).map(cumulativeSum(0));
|
|
13779
|
+
polygonIndices.unshift(0);
|
|
13780
|
+
const primitivePolygonIndices = [0];
|
|
13781
|
+
for (const primitivePolygon of primitivePolygons) {
|
|
13782
|
+
primitivePolygonIndices.push(
|
|
13783
|
+
...primitivePolygon.filter((x) => x > 0).map((x) => x + primitivePolygonIndices[primitivePolygonIndices.length - 1])
|
|
13784
|
+
);
|
|
13958
13785
|
}
|
|
13959
|
-
|
|
13960
|
-
|
|
13961
|
-
|
|
13962
|
-
|
|
13963
|
-
|
|
13964
|
-
|
|
13965
|
-
|
|
13786
|
+
return {
|
|
13787
|
+
type: "Polygon",
|
|
13788
|
+
positions: { value: concatenatedPositions, size: dimension },
|
|
13789
|
+
polygonIndices: { value: new Uint32Array(polygonIndices), size: 1 },
|
|
13790
|
+
primitivePolygonIndices: { value: new Uint32Array(primitivePolygonIndices), size: 1 }
|
|
13791
|
+
};
|
|
13792
|
+
}
|
|
13793
|
+
var cumulativeSum = (sum) => (value) => sum += value;
|
|
13794
|
+
|
|
13795
|
+
// ../gis/src/lib/geometry-converters/wkb/helpers/wkb-types.ts
|
|
13796
|
+
var EWKB_FLAG_Z = 2147483648;
|
|
13797
|
+
var EWKB_FLAG_M = 1073741824;
|
|
13798
|
+
var EWKB_FLAG_SRID = 536870912;
|
|
13799
|
+
var WKT_MAGIC_STRINGS = [
|
|
13800
|
+
"POINT(",
|
|
13801
|
+
"LINESTRING(",
|
|
13802
|
+
"POLYGON(",
|
|
13803
|
+
"MULTIPOINT(",
|
|
13804
|
+
"MULTILINESTRING(",
|
|
13805
|
+
"MULTIPOLYGON(",
|
|
13806
|
+
"GEOMETRYCOLLECTION("
|
|
13807
|
+
];
|
|
13808
|
+
var textEncoder = new TextEncoder();
|
|
13809
|
+
var WKT_MAGIC_BYTES = WKT_MAGIC_STRINGS.map((string) => textEncoder.encode(string));
|
|
13810
|
+
|
|
13811
|
+
// ../gis/src/lib/geometry-converters/wkb/helpers/parse-wkb-header.ts
|
|
13812
|
+
function isWKT(input) {
|
|
13813
|
+
return getWKTGeometryType(input) !== null;
|
|
13814
|
+
}
|
|
13815
|
+
function getWKTGeometryType(input) {
|
|
13816
|
+
if (typeof input === "string") {
|
|
13817
|
+
const index2 = WKT_MAGIC_STRINGS.findIndex((magicString) => input.startsWith(magicString));
|
|
13818
|
+
return index2 >= 0 ? index2 + 1 : null;
|
|
13966
13819
|
}
|
|
13967
|
-
|
|
13968
|
-
|
|
13969
|
-
|
|
13970
|
-
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
|
|
13820
|
+
const inputArray = new Uint8Array(input);
|
|
13821
|
+
const index = WKT_MAGIC_BYTES.findIndex(
|
|
13822
|
+
(magicBytes) => magicBytes.every((value, index2) => value === inputArray[index2])
|
|
13823
|
+
);
|
|
13824
|
+
return index >= 0 ? index + 1 : null;
|
|
13825
|
+
}
|
|
13826
|
+
function parseWKBHeader(dataView, target) {
|
|
13827
|
+
const wkbHeader = Object.assign(target || {}, {
|
|
13828
|
+
type: "wkb",
|
|
13829
|
+
variant: "wkb",
|
|
13830
|
+
geometryType: 1,
|
|
13831
|
+
dimensions: 2,
|
|
13832
|
+
coordinates: "xy",
|
|
13833
|
+
littleEndian: true,
|
|
13834
|
+
byteOffset: 0
|
|
13835
|
+
});
|
|
13836
|
+
if (isWKT(dataView.buffer)) {
|
|
13837
|
+
throw new Error("WKB: Cannot parse WKT data");
|
|
13974
13838
|
}
|
|
13975
|
-
|
|
13976
|
-
|
|
13977
|
-
|
|
13978
|
-
|
|
13979
|
-
|
|
13839
|
+
wkbHeader.littleEndian = dataView.getUint8(wkbHeader.byteOffset) === 1;
|
|
13840
|
+
wkbHeader.byteOffset++;
|
|
13841
|
+
const geometryCode = dataView.getUint32(wkbHeader.byteOffset, wkbHeader.littleEndian);
|
|
13842
|
+
wkbHeader.byteOffset += 4;
|
|
13843
|
+
wkbHeader.geometryType = geometryCode & 7;
|
|
13844
|
+
const isoType = (geometryCode - wkbHeader.geometryType) / 1e3;
|
|
13845
|
+
switch (isoType) {
|
|
13846
|
+
case 0:
|
|
13847
|
+
break;
|
|
13848
|
+
case 1:
|
|
13849
|
+
wkbHeader.variant = "iso-wkb";
|
|
13850
|
+
wkbHeader.dimensions = 3;
|
|
13851
|
+
wkbHeader.coordinates = "xyz";
|
|
13852
|
+
break;
|
|
13853
|
+
case 2:
|
|
13854
|
+
wkbHeader.variant = "iso-wkb";
|
|
13855
|
+
wkbHeader.dimensions = 3;
|
|
13856
|
+
wkbHeader.coordinates = "xym";
|
|
13857
|
+
break;
|
|
13858
|
+
case 3:
|
|
13859
|
+
wkbHeader.variant = "iso-wkb";
|
|
13860
|
+
wkbHeader.dimensions = 4;
|
|
13861
|
+
wkbHeader.coordinates = "xyzm";
|
|
13862
|
+
break;
|
|
13863
|
+
default:
|
|
13864
|
+
throw new Error(`WKB: Unsupported iso-wkb type: ${isoType}`);
|
|
13980
13865
|
}
|
|
13981
|
-
|
|
13982
|
-
|
|
13983
|
-
|
|
13984
|
-
|
|
13985
|
-
|
|
13986
|
-
|
|
13987
|
-
|
|
13988
|
-
if (
|
|
13989
|
-
|
|
13990
|
-
|
|
13991
|
-
|
|
13992
|
-
|
|
13993
|
-
|
|
13994
|
-
|
|
13995
|
-
|
|
13996
|
-
}
|
|
13866
|
+
const ewkbZ = geometryCode & EWKB_FLAG_Z;
|
|
13867
|
+
const ewkbM = geometryCode & EWKB_FLAG_M;
|
|
13868
|
+
const ewkbSRID = geometryCode & EWKB_FLAG_SRID;
|
|
13869
|
+
if (ewkbZ && ewkbM) {
|
|
13870
|
+
wkbHeader.variant = "ewkb";
|
|
13871
|
+
wkbHeader.dimensions = 4;
|
|
13872
|
+
wkbHeader.coordinates = "xyzm";
|
|
13873
|
+
} else if (ewkbZ) {
|
|
13874
|
+
wkbHeader.variant = "ewkb";
|
|
13875
|
+
wkbHeader.dimensions = 3;
|
|
13876
|
+
wkbHeader.coordinates = "xyz";
|
|
13877
|
+
} else if (ewkbM) {
|
|
13878
|
+
wkbHeader.variant = "ewkb";
|
|
13879
|
+
wkbHeader.dimensions = 3;
|
|
13880
|
+
wkbHeader.coordinates = "xym";
|
|
13997
13881
|
}
|
|
13998
|
-
|
|
13999
|
-
|
|
14000
|
-
|
|
14001
|
-
|
|
14002
|
-
if (!url.startsWith("http")) {
|
|
14003
|
-
return url;
|
|
13882
|
+
if (ewkbSRID) {
|
|
13883
|
+
wkbHeader.variant = "ewkb";
|
|
13884
|
+
wkbHeader.srid = dataView.getUint32(wkbHeader.byteOffset, wkbHeader.littleEndian);
|
|
13885
|
+
wkbHeader.byteOffset += 4;
|
|
14004
13886
|
}
|
|
14005
|
-
|
|
14006
|
-
return getLoadableWorkerURLFromSource(workerSource);
|
|
14007
|
-
}
|
|
14008
|
-
function getLoadableWorkerURLFromSource(workerSource) {
|
|
14009
|
-
const blob = new Blob([workerSource], { type: "application/javascript" });
|
|
14010
|
-
return URL.createObjectURL(blob);
|
|
14011
|
-
}
|
|
14012
|
-
function buildScriptSource(workerUrl) {
|
|
14013
|
-
return `try {
|
|
14014
|
-
importScripts('${workerUrl}');
|
|
14015
|
-
} catch (error) {
|
|
14016
|
-
console.error(error);
|
|
14017
|
-
throw error;
|
|
14018
|
-
}`;
|
|
13887
|
+
return wkbHeader;
|
|
14019
13888
|
}
|
|
14020
13889
|
|
|
14021
|
-
// ../
|
|
14022
|
-
function
|
|
14023
|
-
const
|
|
14024
|
-
|
|
14025
|
-
|
|
14026
|
-
|
|
14027
|
-
|
|
14028
|
-
|
|
14029
|
-
|
|
14030
|
-
|
|
14031
|
-
|
|
14032
|
-
|
|
14033
|
-
|
|
13890
|
+
// ../gis/src/lib/geometry-converters/wkb/convert-wkb-to-binary-geometry.ts
|
|
13891
|
+
function convertWKBToBinaryGeometry(arrayBuffer) {
|
|
13892
|
+
const dataView = new DataView(arrayBuffer);
|
|
13893
|
+
const wkbHeader = parseWKBHeader(dataView);
|
|
13894
|
+
const { geometryType, dimensions, littleEndian } = wkbHeader;
|
|
13895
|
+
const offset = wkbHeader.byteOffset;
|
|
13896
|
+
switch (geometryType) {
|
|
13897
|
+
case 1 /* Point */:
|
|
13898
|
+
const point = parsePoint(dataView, offset, dimensions, littleEndian);
|
|
13899
|
+
return point.geometry;
|
|
13900
|
+
case 2 /* LineString */:
|
|
13901
|
+
const line = parseLineString(dataView, offset, dimensions, littleEndian);
|
|
13902
|
+
return line.geometry;
|
|
13903
|
+
case 3 /* Polygon */:
|
|
13904
|
+
const polygon = parsePolygon(dataView, offset, dimensions, littleEndian);
|
|
13905
|
+
return polygon.geometry;
|
|
13906
|
+
case 4 /* MultiPoint */:
|
|
13907
|
+
const multiPoint = parseMultiPoint(dataView, offset, dimensions, littleEndian);
|
|
13908
|
+
multiPoint.type = "Point";
|
|
13909
|
+
return multiPoint;
|
|
13910
|
+
case 5 /* MultiLineString */:
|
|
13911
|
+
const multiLine = parseMultiLineString(dataView, offset, dimensions, littleEndian);
|
|
13912
|
+
multiLine.type = "LineString";
|
|
13913
|
+
return multiLine;
|
|
13914
|
+
case 6 /* MultiPolygon */:
|
|
13915
|
+
const multiPolygon = parseMultiPolygon(dataView, offset, dimensions, littleEndian);
|
|
13916
|
+
multiPolygon.type = "Polygon";
|
|
13917
|
+
return multiPolygon;
|
|
13918
|
+
default:
|
|
13919
|
+
throw new Error(`WKB: Unsupported geometry type: ${geometryType}`);
|
|
14034
13920
|
}
|
|
14035
|
-
return transfers === void 0 ? Array.from(transfersSet) : [];
|
|
14036
13921
|
}
|
|
14037
|
-
function
|
|
14038
|
-
|
|
14039
|
-
|
|
13922
|
+
function parsePoint(dataView, offset, dimension, littleEndian) {
|
|
13923
|
+
const positions = new Float64Array(dimension);
|
|
13924
|
+
for (let i = 0; i < dimension; i++) {
|
|
13925
|
+
positions[i] = dataView.getFloat64(offset, littleEndian);
|
|
13926
|
+
offset += 8;
|
|
14040
13927
|
}
|
|
14041
|
-
|
|
14042
|
-
|
|
13928
|
+
return {
|
|
13929
|
+
geometry: { type: "Point", positions: { value: positions, size: dimension } },
|
|
13930
|
+
offset
|
|
13931
|
+
};
|
|
13932
|
+
}
|
|
13933
|
+
function parseLineString(dataView, offset, dimension, littleEndian) {
|
|
13934
|
+
const nPoints = dataView.getUint32(offset, littleEndian);
|
|
13935
|
+
offset += 4;
|
|
13936
|
+
const positions = new Float64Array(nPoints * dimension);
|
|
13937
|
+
for (let i = 0; i < nPoints * dimension; i++) {
|
|
13938
|
+
positions[i] = dataView.getFloat64(offset, littleEndian);
|
|
13939
|
+
offset += 8;
|
|
14043
13940
|
}
|
|
14044
|
-
|
|
14045
|
-
|
|
13941
|
+
const pathIndices = [0];
|
|
13942
|
+
if (nPoints > 0) {
|
|
13943
|
+
pathIndices.push(nPoints);
|
|
14046
13944
|
}
|
|
14047
|
-
|
|
14048
|
-
|
|
13945
|
+
return {
|
|
13946
|
+
geometry: {
|
|
13947
|
+
type: "LineString",
|
|
13948
|
+
positions: { value: positions, size: dimension },
|
|
13949
|
+
pathIndices: { value: new Uint32Array(pathIndices), size: 1 }
|
|
13950
|
+
},
|
|
13951
|
+
offset
|
|
13952
|
+
};
|
|
13953
|
+
}
|
|
13954
|
+
var cumulativeSum2 = (sum) => (value) => sum += value;
|
|
13955
|
+
function parsePolygon(dataView, offset, dimension, littleEndian) {
|
|
13956
|
+
const nRings = dataView.getUint32(offset, littleEndian);
|
|
13957
|
+
offset += 4;
|
|
13958
|
+
const rings = [];
|
|
13959
|
+
for (let i = 0; i < nRings; i++) {
|
|
13960
|
+
const parsed = parseLineString(dataView, offset, dimension, littleEndian);
|
|
13961
|
+
const { positions } = parsed.geometry;
|
|
13962
|
+
offset = parsed.offset;
|
|
13963
|
+
rings.push(positions.value);
|
|
14049
13964
|
}
|
|
14050
|
-
|
|
14051
|
-
|
|
13965
|
+
const concatenatedPositions = new Float64Array(concatTypedArrays(rings).buffer);
|
|
13966
|
+
const polygonIndices = [0];
|
|
13967
|
+
if (concatenatedPositions.length > 0) {
|
|
13968
|
+
polygonIndices.push(concatenatedPositions.length / dimension);
|
|
14052
13969
|
}
|
|
14053
|
-
|
|
13970
|
+
const primitivePolygonIndices = rings.map((l) => l.length / dimension).map(cumulativeSum2(0));
|
|
13971
|
+
primitivePolygonIndices.unshift(0);
|
|
13972
|
+
return {
|
|
13973
|
+
geometry: {
|
|
13974
|
+
type: "Polygon",
|
|
13975
|
+
positions: { value: concatenatedPositions, size: dimension },
|
|
13976
|
+
polygonIndices: {
|
|
13977
|
+
value: new Uint32Array(polygonIndices),
|
|
13978
|
+
size: 1
|
|
13979
|
+
},
|
|
13980
|
+
primitivePolygonIndices: { value: new Uint32Array(primitivePolygonIndices), size: 1 }
|
|
13981
|
+
},
|
|
13982
|
+
offset
|
|
13983
|
+
};
|
|
14054
13984
|
}
|
|
14055
|
-
function
|
|
14056
|
-
|
|
14057
|
-
|
|
13985
|
+
function parseMultiPoint(dataView, offset, dimension, littleEndian) {
|
|
13986
|
+
const nPoints = dataView.getUint32(offset, littleEndian);
|
|
13987
|
+
offset += 4;
|
|
13988
|
+
const binaryPointGeometries = [];
|
|
13989
|
+
for (let i = 0; i < nPoints; i++) {
|
|
13990
|
+
const littleEndianPoint = dataView.getUint8(offset) === 1;
|
|
13991
|
+
offset++;
|
|
13992
|
+
if (dataView.getUint32(offset, littleEndianPoint) % 1e3 !== 1) {
|
|
13993
|
+
throw new Error("WKB: Inner geometries of MultiPoint not of type Point");
|
|
13994
|
+
}
|
|
13995
|
+
offset += 4;
|
|
13996
|
+
const parsed = parsePoint(dataView, offset, dimension, littleEndianPoint);
|
|
13997
|
+
offset = parsed.offset;
|
|
13998
|
+
binaryPointGeometries.push(parsed.geometry);
|
|
14058
13999
|
}
|
|
14059
|
-
|
|
14060
|
-
|
|
14061
|
-
|
|
14062
|
-
|
|
14063
|
-
|
|
14064
|
-
|
|
14065
|
-
|
|
14066
|
-
|
|
14000
|
+
return concatenateBinaryPointGeometries(binaryPointGeometries, dimension);
|
|
14001
|
+
}
|
|
14002
|
+
function parseMultiLineString(dataView, offset, dimension, littleEndian) {
|
|
14003
|
+
const nLines = dataView.getUint32(offset, littleEndian);
|
|
14004
|
+
offset += 4;
|
|
14005
|
+
const binaryLineGeometries = [];
|
|
14006
|
+
for (let i = 0; i < nLines; i++) {
|
|
14007
|
+
const littleEndianLine = dataView.getUint8(offset) === 1;
|
|
14008
|
+
offset++;
|
|
14009
|
+
if (dataView.getUint32(offset, littleEndianLine) % 1e3 !== 2) {
|
|
14010
|
+
throw new Error("WKB: Inner geometries of MultiLineString not of type LineString");
|
|
14067
14011
|
}
|
|
14068
|
-
|
|
14069
|
-
|
|
14012
|
+
offset += 4;
|
|
14013
|
+
const parsed = parseLineString(dataView, offset, dimension, littleEndianLine);
|
|
14014
|
+
offset = parsed.offset;
|
|
14015
|
+
binaryLineGeometries.push(parsed.geometry);
|
|
14016
|
+
}
|
|
14017
|
+
return concatenateBinaryLineGeometries(binaryLineGeometries, dimension);
|
|
14018
|
+
}
|
|
14019
|
+
function parseMultiPolygon(dataView, offset, dimension, littleEndian) {
|
|
14020
|
+
const nPolygons = dataView.getUint32(offset, littleEndian);
|
|
14021
|
+
offset += 4;
|
|
14022
|
+
const binaryPolygonGeometries = [];
|
|
14023
|
+
for (let i = 0; i < nPolygons; i++) {
|
|
14024
|
+
const littleEndianPolygon = dataView.getUint8(offset) === 1;
|
|
14025
|
+
offset++;
|
|
14026
|
+
if (dataView.getUint32(offset, littleEndianPolygon) % 1e3 !== 3) {
|
|
14027
|
+
throw new Error("WKB: Inner geometries of MultiPolygon not of type Polygon");
|
|
14028
|
+
}
|
|
14029
|
+
offset += 4;
|
|
14030
|
+
const parsed = parsePolygon(dataView, offset, dimension, littleEndianPolygon);
|
|
14031
|
+
offset = parsed.offset;
|
|
14032
|
+
binaryPolygonGeometries.push(parsed.geometry);
|
|
14033
|
+
}
|
|
14034
|
+
return concatenateBinaryPolygonGeometries(binaryPolygonGeometries, dimension);
|
|
14070
14035
|
}
|
|
14071
14036
|
|
|
14072
|
-
// ../
|
|
14073
|
-
|
|
14074
|
-
|
|
14075
|
-
|
|
14076
|
-
|
|
14077
|
-
|
|
14078
|
-
|
|
14079
|
-
|
|
14080
|
-
|
|
14081
|
-
|
|
14082
|
-
|
|
14083
|
-
|
|
14084
|
-
|
|
14085
|
-
|
|
14086
|
-
|
|
14037
|
+
// ../gis/src/lib/geometry-converters/wkb/convert-wkb-to-geometry.ts
|
|
14038
|
+
function convertWKBToGeometry(arrayBuffer) {
|
|
14039
|
+
const binaryGeometry = convertWKBToBinaryGeometry(arrayBuffer);
|
|
14040
|
+
return convertBinaryGeometryToGeometry(binaryGeometry);
|
|
14041
|
+
}
|
|
14042
|
+
|
|
14043
|
+
// ../gis/src/lib/geometry-converters/wkb/convert-wkt-to-geometry.ts
|
|
14044
|
+
var numberRegexp = /[-+]?([0-9]*\.[0-9]+|[0-9]+)([eE][-+]?[0-9]+)?/;
|
|
14045
|
+
var tuples = new RegExp("^" + numberRegexp.source + "(\\s" + numberRegexp.source + "){1,}");
|
|
14046
|
+
function convertWKTToGeometry(input, options) {
|
|
14047
|
+
const parts = input.split(";");
|
|
14048
|
+
let _ = parts.pop();
|
|
14049
|
+
const srid = (parts.shift() || "").split("=").pop();
|
|
14050
|
+
const state = { parts, _, i: 0 };
|
|
14051
|
+
const geometry = parseGeometry(state);
|
|
14052
|
+
return options?.wkt?.crs ? addCRS(geometry, srid) : geometry;
|
|
14053
|
+
}
|
|
14054
|
+
function parseGeometry(state) {
|
|
14055
|
+
return parsePoint2(state) || parseLineString2(state) || parsePolygon2(state) || parseMultiPoint2(state) || parseMultiLineString2(state) || parseMultiPolygon2(state) || parseGeometryCollection(state);
|
|
14056
|
+
}
|
|
14057
|
+
function addCRS(obj, srid) {
|
|
14058
|
+
if (obj && srid?.match(/\d+/)) {
|
|
14059
|
+
const crs = {
|
|
14060
|
+
type: "name",
|
|
14061
|
+
properties: {
|
|
14062
|
+
name: "urn:ogc:def:crs:EPSG::" + srid
|
|
14063
|
+
}
|
|
14064
|
+
};
|
|
14065
|
+
obj.crs = crs;
|
|
14066
|
+
}
|
|
14067
|
+
return obj;
|
|
14068
|
+
}
|
|
14069
|
+
function parsePoint2(state) {
|
|
14070
|
+
if (!$(/^(POINT(\sz)?)/i, state)) {
|
|
14071
|
+
return null;
|
|
14072
|
+
}
|
|
14073
|
+
white(state);
|
|
14074
|
+
if (!$(/^(\()/, state)) {
|
|
14075
|
+
return null;
|
|
14076
|
+
}
|
|
14077
|
+
const c = coords(state);
|
|
14078
|
+
if (!c) {
|
|
14079
|
+
return null;
|
|
14087
14080
|
}
|
|
14088
|
-
|
|
14089
|
-
|
|
14090
|
-
|
|
14091
|
-
this.name = name;
|
|
14092
|
-
this.source = source;
|
|
14093
|
-
this.url = url;
|
|
14094
|
-
this.onMessage = NOOP;
|
|
14095
|
-
this.onError = (error) => console.log(error);
|
|
14096
|
-
this.worker = isBrowser ? this._createBrowserWorker() : this._createNodeWorker();
|
|
14081
|
+
white(state);
|
|
14082
|
+
if (!$(/^(\))/, state)) {
|
|
14083
|
+
return null;
|
|
14097
14084
|
}
|
|
14098
|
-
|
|
14099
|
-
|
|
14100
|
-
|
|
14101
|
-
|
|
14102
|
-
|
|
14103
|
-
|
|
14104
|
-
|
|
14105
|
-
|
|
14106
|
-
this.terminated = true;
|
|
14085
|
+
return {
|
|
14086
|
+
type: "Point",
|
|
14087
|
+
coordinates: c[0]
|
|
14088
|
+
};
|
|
14089
|
+
}
|
|
14090
|
+
function parseMultiPoint2(state) {
|
|
14091
|
+
if (!$(/^(MULTIPOINT)/i, state)) {
|
|
14092
|
+
return null;
|
|
14107
14093
|
}
|
|
14108
|
-
|
|
14109
|
-
|
|
14094
|
+
white(state);
|
|
14095
|
+
const newCoordsFormat = state._?.substring(state._?.indexOf("(") + 1, state._.length - 1).replace(/\(/g, "").replace(/\)/g, "");
|
|
14096
|
+
state._ = "MULTIPOINT (" + newCoordsFormat + ")";
|
|
14097
|
+
const c = multicoords(state);
|
|
14098
|
+
if (!c) {
|
|
14099
|
+
return null;
|
|
14110
14100
|
}
|
|
14111
|
-
|
|
14112
|
-
|
|
14113
|
-
|
|
14114
|
-
|
|
14115
|
-
|
|
14116
|
-
|
|
14117
|
-
|
|
14118
|
-
|
|
14101
|
+
white(state);
|
|
14102
|
+
return {
|
|
14103
|
+
type: "MultiPoint",
|
|
14104
|
+
coordinates: c
|
|
14105
|
+
};
|
|
14106
|
+
}
|
|
14107
|
+
function parseLineString2(state) {
|
|
14108
|
+
if (!$(/^(LINESTRING(\sz)?)/i, state)) {
|
|
14109
|
+
return null;
|
|
14119
14110
|
}
|
|
14120
|
-
|
|
14121
|
-
|
|
14122
|
-
|
|
14123
|
-
* @param event
|
|
14124
|
-
*/
|
|
14125
|
-
_getErrorFromErrorEvent(event) {
|
|
14126
|
-
let message = "Failed to load ";
|
|
14127
|
-
message += `worker ${this.name} from ${this.url}. `;
|
|
14128
|
-
if (event.message) {
|
|
14129
|
-
message += `${event.message} in `;
|
|
14130
|
-
}
|
|
14131
|
-
if (event.lineno) {
|
|
14132
|
-
message += `:${event.lineno}:${event.colno}`;
|
|
14133
|
-
}
|
|
14134
|
-
return new Error(message);
|
|
14111
|
+
white(state);
|
|
14112
|
+
if (!$(/^(\()/, state)) {
|
|
14113
|
+
return null;
|
|
14135
14114
|
}
|
|
14136
|
-
|
|
14137
|
-
|
|
14138
|
-
|
|
14139
|
-
_createBrowserWorker() {
|
|
14140
|
-
this._loadableURL = getLoadableWorkerURL({ source: this.source, url: this.url });
|
|
14141
|
-
const worker = new Worker(this._loadableURL, { name: this.name });
|
|
14142
|
-
worker.onmessage = (event) => {
|
|
14143
|
-
if (!event.data) {
|
|
14144
|
-
this.onError(new Error("No data received"));
|
|
14145
|
-
} else {
|
|
14146
|
-
this.onMessage(event.data);
|
|
14147
|
-
}
|
|
14148
|
-
};
|
|
14149
|
-
worker.onerror = (error) => {
|
|
14150
|
-
this.onError(this._getErrorFromErrorEvent(error));
|
|
14151
|
-
this.terminated = true;
|
|
14152
|
-
};
|
|
14153
|
-
worker.onmessageerror = (event) => console.error(event);
|
|
14154
|
-
return worker;
|
|
14115
|
+
const c = coords(state);
|
|
14116
|
+
if (!c) {
|
|
14117
|
+
return null;
|
|
14155
14118
|
}
|
|
14156
|
-
|
|
14157
|
-
|
|
14158
|
-
* @todo https://nodejs.org/api/async_hooks.html#async-resource-worker-pool
|
|
14159
|
-
*/
|
|
14160
|
-
_createNodeWorker() {
|
|
14161
|
-
let worker;
|
|
14162
|
-
if (this.url) {
|
|
14163
|
-
const absolute = this.url.includes(":/") || this.url.startsWith("/");
|
|
14164
|
-
const url = absolute ? this.url : `./${this.url}`;
|
|
14165
|
-
worker = new NodeWorker(url, { eval: false });
|
|
14166
|
-
} else if (this.source) {
|
|
14167
|
-
worker = new NodeWorker(this.source, { eval: true });
|
|
14168
|
-
} else {
|
|
14169
|
-
throw new Error("no worker");
|
|
14170
|
-
}
|
|
14171
|
-
worker.on("message", (data) => {
|
|
14172
|
-
this.onMessage(data);
|
|
14173
|
-
});
|
|
14174
|
-
worker.on("error", (error) => {
|
|
14175
|
-
this.onError(error);
|
|
14176
|
-
});
|
|
14177
|
-
worker.on("exit", (code) => {
|
|
14178
|
-
});
|
|
14179
|
-
return worker;
|
|
14119
|
+
if (!$(/^(\))/, state)) {
|
|
14120
|
+
return null;
|
|
14180
14121
|
}
|
|
14181
|
-
|
|
14182
|
-
|
|
14183
|
-
|
|
14184
|
-
var WorkerPool = class {
|
|
14185
|
-
name = "unnamed";
|
|
14186
|
-
source;
|
|
14187
|
-
// | Function;
|
|
14188
|
-
url;
|
|
14189
|
-
maxConcurrency = 1;
|
|
14190
|
-
maxMobileConcurrency = 1;
|
|
14191
|
-
onDebug = () => {
|
|
14122
|
+
return {
|
|
14123
|
+
type: "LineString",
|
|
14124
|
+
coordinates: c
|
|
14192
14125
|
};
|
|
14193
|
-
|
|
14194
|
-
|
|
14195
|
-
|
|
14196
|
-
|
|
14197
|
-
|
|
14198
|
-
|
|
14199
|
-
|
|
14200
|
-
|
|
14201
|
-
return WorkerThread.isSupported();
|
|
14126
|
+
}
|
|
14127
|
+
function parseMultiLineString2(state) {
|
|
14128
|
+
if (!$(/^(MULTILINESTRING)/i, state))
|
|
14129
|
+
return null;
|
|
14130
|
+
white(state);
|
|
14131
|
+
const c = multicoords(state);
|
|
14132
|
+
if (!c) {
|
|
14133
|
+
return null;
|
|
14202
14134
|
}
|
|
14203
|
-
|
|
14204
|
-
|
|
14205
|
-
|
|
14206
|
-
|
|
14207
|
-
|
|
14208
|
-
|
|
14209
|
-
|
|
14210
|
-
|
|
14135
|
+
white(state);
|
|
14136
|
+
return {
|
|
14137
|
+
// @ts-ignore
|
|
14138
|
+
type: "MultiLineString",
|
|
14139
|
+
// @ts-expect-error
|
|
14140
|
+
coordinates: c
|
|
14141
|
+
};
|
|
14142
|
+
}
|
|
14143
|
+
function parsePolygon2(state) {
|
|
14144
|
+
if (!$(/^(POLYGON(\sz)?)/i, state)) {
|
|
14145
|
+
return null;
|
|
14211
14146
|
}
|
|
14212
|
-
|
|
14213
|
-
|
|
14214
|
-
|
|
14215
|
-
|
|
14216
|
-
destroy() {
|
|
14217
|
-
this.idleQueue.forEach((worker) => worker.destroy());
|
|
14218
|
-
this.isDestroyed = true;
|
|
14147
|
+
white(state);
|
|
14148
|
+
const c = multicoords(state);
|
|
14149
|
+
if (!c) {
|
|
14150
|
+
return null;
|
|
14219
14151
|
}
|
|
14220
|
-
|
|
14221
|
-
|
|
14222
|
-
|
|
14223
|
-
|
|
14224
|
-
|
|
14225
|
-
|
|
14226
|
-
|
|
14227
|
-
|
|
14228
|
-
|
|
14229
|
-
|
|
14230
|
-
}
|
|
14231
|
-
if (props.reuseWorkers !== void 0) {
|
|
14232
|
-
this.reuseWorkers = props.reuseWorkers;
|
|
14233
|
-
}
|
|
14234
|
-
if (props.onDebug !== void 0) {
|
|
14235
|
-
this.onDebug = props.onDebug;
|
|
14236
|
-
}
|
|
14152
|
+
return {
|
|
14153
|
+
// @ts-ignore
|
|
14154
|
+
type: "Polygon",
|
|
14155
|
+
// @ts-expect-error
|
|
14156
|
+
coordinates: c
|
|
14157
|
+
};
|
|
14158
|
+
}
|
|
14159
|
+
function parseMultiPolygon2(state) {
|
|
14160
|
+
if (!$(/^(MULTIPOLYGON)/i, state)) {
|
|
14161
|
+
return null;
|
|
14237
14162
|
}
|
|
14238
|
-
|
|
14239
|
-
|
|
14240
|
-
|
|
14241
|
-
|
|
14242
|
-
});
|
|
14243
|
-
this._startQueuedJob();
|
|
14244
|
-
return await startPromise;
|
|
14163
|
+
white(state);
|
|
14164
|
+
const c = multicoords(state);
|
|
14165
|
+
if (!c) {
|
|
14166
|
+
return null;
|
|
14245
14167
|
}
|
|
14246
|
-
|
|
14247
|
-
|
|
14248
|
-
|
|
14249
|
-
|
|
14250
|
-
|
|
14251
|
-
|
|
14252
|
-
|
|
14253
|
-
|
|
14254
|
-
|
|
14255
|
-
|
|
14256
|
-
|
|
14257
|
-
return;
|
|
14258
|
-
}
|
|
14259
|
-
const queuedJob = this.jobQueue.shift();
|
|
14260
|
-
if (queuedJob) {
|
|
14261
|
-
this.onDebug({
|
|
14262
|
-
message: "Starting job",
|
|
14263
|
-
name: queuedJob.name,
|
|
14264
|
-
workerThread,
|
|
14265
|
-
backlog: this.jobQueue.length
|
|
14266
|
-
});
|
|
14267
|
-
const job = new WorkerJob(queuedJob.name, workerThread);
|
|
14268
|
-
workerThread.onMessage = (data) => queuedJob.onMessage(job, data.type, data.payload);
|
|
14269
|
-
workerThread.onError = (error) => queuedJob.onError(job, error);
|
|
14270
|
-
queuedJob.onStart(job);
|
|
14271
|
-
try {
|
|
14272
|
-
await job.result;
|
|
14273
|
-
} catch (error) {
|
|
14274
|
-
console.error(`Worker exception: ${error}`);
|
|
14275
|
-
} finally {
|
|
14276
|
-
this.returnWorkerToQueue(workerThread);
|
|
14277
|
-
}
|
|
14278
|
-
}
|
|
14168
|
+
return {
|
|
14169
|
+
type: "MultiPolygon",
|
|
14170
|
+
// @ts-expect-error
|
|
14171
|
+
coordinates: c
|
|
14172
|
+
};
|
|
14173
|
+
}
|
|
14174
|
+
function parseGeometryCollection(state) {
|
|
14175
|
+
const geometries = [];
|
|
14176
|
+
let geometry;
|
|
14177
|
+
if (!$(/^(GEOMETRYCOLLECTION)/i, state)) {
|
|
14178
|
+
return null;
|
|
14279
14179
|
}
|
|
14280
|
-
|
|
14281
|
-
|
|
14282
|
-
|
|
14283
|
-
|
|
14284
|
-
|
|
14285
|
-
|
|
14286
|
-
|
|
14287
|
-
|
|
14288
|
-
|
|
14289
|
-
|
|
14290
|
-
|
|
14291
|
-
|
|
14292
|
-
|
|
14293
|
-
|
|
14294
|
-
|
|
14295
|
-
|
|
14296
|
-
|
|
14297
|
-
|
|
14298
|
-
|
|
14299
|
-
|
|
14180
|
+
white(state);
|
|
14181
|
+
if (!$(/^(\()/, state)) {
|
|
14182
|
+
return null;
|
|
14183
|
+
}
|
|
14184
|
+
while (geometry = parseGeometry(state)) {
|
|
14185
|
+
geometries.push(geometry);
|
|
14186
|
+
white(state);
|
|
14187
|
+
$(/^(,)/, state);
|
|
14188
|
+
white(state);
|
|
14189
|
+
}
|
|
14190
|
+
if (!$(/^(\))/, state)) {
|
|
14191
|
+
return null;
|
|
14192
|
+
}
|
|
14193
|
+
return {
|
|
14194
|
+
type: "GeometryCollection",
|
|
14195
|
+
geometries
|
|
14196
|
+
};
|
|
14197
|
+
}
|
|
14198
|
+
function multicoords(state) {
|
|
14199
|
+
white(state);
|
|
14200
|
+
let depth = 0;
|
|
14201
|
+
const rings = [];
|
|
14202
|
+
const stack = [rings];
|
|
14203
|
+
let pointer = rings;
|
|
14204
|
+
let elem;
|
|
14205
|
+
while (elem = $(/^(\()/, state) || $(/^(\))/, state) || $(/^(,)/, state) || $(tuples, state)) {
|
|
14206
|
+
if (elem === "(") {
|
|
14207
|
+
stack.push(pointer);
|
|
14208
|
+
pointer = [];
|
|
14209
|
+
stack[stack.length - 1].push(pointer);
|
|
14210
|
+
depth++;
|
|
14211
|
+
} else if (elem === ")") {
|
|
14212
|
+
if (pointer.length === 0)
|
|
14213
|
+
return null;
|
|
14214
|
+
pointer = stack.pop();
|
|
14215
|
+
if (!pointer)
|
|
14216
|
+
return null;
|
|
14217
|
+
depth--;
|
|
14218
|
+
if (depth === 0)
|
|
14219
|
+
break;
|
|
14220
|
+
} else if (elem === ",") {
|
|
14221
|
+
pointer = [];
|
|
14222
|
+
stack[stack.length - 1].push(pointer);
|
|
14223
|
+
} else if (!elem.split(/\s/g).some(isNaN)) {
|
|
14224
|
+
Array.prototype.push.apply(pointer, elem.split(/\s/g).map(parseFloat));
|
|
14300
14225
|
} else {
|
|
14301
|
-
|
|
14302
|
-
}
|
|
14303
|
-
if (!this.isDestroyed) {
|
|
14304
|
-
this._startQueuedJob();
|
|
14226
|
+
return null;
|
|
14305
14227
|
}
|
|
14228
|
+
white(state);
|
|
14306
14229
|
}
|
|
14307
|
-
|
|
14308
|
-
* Returns idle worker or creates new worker if maxConcurrency has not been reached
|
|
14309
|
-
*/
|
|
14310
|
-
_getAvailableWorker() {
|
|
14311
|
-
if (this.idleQueue.length > 0) {
|
|
14312
|
-
return this.idleQueue.shift() || null;
|
|
14313
|
-
}
|
|
14314
|
-
if (this.count < this._getMaxConcurrency()) {
|
|
14315
|
-
this.count++;
|
|
14316
|
-
const name = `${this.name.toLowerCase()} (#${this.count} of ${this.maxConcurrency})`;
|
|
14317
|
-
return new WorkerThread({ name, source: this.source, url: this.url });
|
|
14318
|
-
}
|
|
14230
|
+
if (depth !== 0)
|
|
14319
14231
|
return null;
|
|
14232
|
+
return rings;
|
|
14233
|
+
}
|
|
14234
|
+
function coords(state) {
|
|
14235
|
+
const list = [];
|
|
14236
|
+
let item;
|
|
14237
|
+
let pt;
|
|
14238
|
+
while (pt = $(tuples, state) || $(/^(,)/, state)) {
|
|
14239
|
+
if (pt === ",") {
|
|
14240
|
+
list.push(item);
|
|
14241
|
+
item = [];
|
|
14242
|
+
} else if (!pt.split(/\s/g).some(isNaN)) {
|
|
14243
|
+
if (!item)
|
|
14244
|
+
item = [];
|
|
14245
|
+
Array.prototype.push.apply(item, pt.split(/\s/g).map(parseFloat));
|
|
14246
|
+
}
|
|
14247
|
+
white(state);
|
|
14320
14248
|
}
|
|
14321
|
-
|
|
14322
|
-
|
|
14249
|
+
if (item)
|
|
14250
|
+
list.push(item);
|
|
14251
|
+
else
|
|
14252
|
+
return null;
|
|
14253
|
+
return list.length ? list : null;
|
|
14254
|
+
}
|
|
14255
|
+
function $(regexp, state) {
|
|
14256
|
+
const match = state._?.substring(state.i).match(regexp);
|
|
14257
|
+
if (!match)
|
|
14258
|
+
return null;
|
|
14259
|
+
else {
|
|
14260
|
+
state.i += match[0].length;
|
|
14261
|
+
return match[0];
|
|
14323
14262
|
}
|
|
14324
|
-
}
|
|
14263
|
+
}
|
|
14264
|
+
function white(state) {
|
|
14265
|
+
$(/^\s*/, state);
|
|
14266
|
+
}
|
|
14325
14267
|
|
|
14326
|
-
// ../
|
|
14327
|
-
|
|
14328
|
-
|
|
14329
|
-
|
|
14330
|
-
|
|
14331
|
-
onDebug: () => {
|
|
14268
|
+
// ../gis/src/lib/geometry-converters/convert-geoarrow-to-geojson.ts
|
|
14269
|
+
function convertGeoArrowGeometryToGeoJSON(arrowCellValue, encoding) {
|
|
14270
|
+
encoding = encoding?.toLowerCase();
|
|
14271
|
+
if (!encoding || !arrowCellValue) {
|
|
14272
|
+
return null;
|
|
14332
14273
|
}
|
|
14333
|
-
|
|
14334
|
-
|
|
14335
|
-
|
|
14336
|
-
|
|
14337
|
-
|
|
14338
|
-
|
|
14339
|
-
|
|
14274
|
+
switch (encoding) {
|
|
14275
|
+
case "geoarrow.multipolygon":
|
|
14276
|
+
return arrowMultiPolygonToGeometry(arrowCellValue);
|
|
14277
|
+
case "geoarrow.polygon":
|
|
14278
|
+
return arrowPolygonToGeometry(arrowCellValue);
|
|
14279
|
+
case "geoarrow.multipoint":
|
|
14280
|
+
return arrowMultiPointToGeometry(arrowCellValue);
|
|
14281
|
+
case "geoarrow.point":
|
|
14282
|
+
return arrowPointToGeometry(arrowCellValue);
|
|
14283
|
+
case "geoarrow.multilinestring":
|
|
14284
|
+
return arrowMultiLineStringToGeometry(arrowCellValue);
|
|
14285
|
+
case "geoarrow.linestring":
|
|
14286
|
+
return arrowLineStringToGeometry(arrowCellValue);
|
|
14287
|
+
case "geoarrow.wkb":
|
|
14288
|
+
return arrowWKBToGeometry(arrowCellValue);
|
|
14289
|
+
case "geoarrow.wkt":
|
|
14290
|
+
return arrowWKTToGeometry(arrowCellValue);
|
|
14291
|
+
default: {
|
|
14292
|
+
throw Error(`GeoArrow encoding not supported ${encoding}`);
|
|
14293
|
+
}
|
|
14340
14294
|
}
|
|
14341
|
-
|
|
14342
|
-
|
|
14343
|
-
|
|
14344
|
-
|
|
14345
|
-
|
|
14295
|
+
}
|
|
14296
|
+
function arrowWKBToGeometry(arrowCellValue) {
|
|
14297
|
+
const arrayBuffer = arrowCellValue.buffer.slice(
|
|
14298
|
+
arrowCellValue.byteOffset,
|
|
14299
|
+
arrowCellValue.byteOffset + arrowCellValue.byteLength
|
|
14300
|
+
);
|
|
14301
|
+
return convertWKBToGeometry(arrayBuffer);
|
|
14302
|
+
}
|
|
14303
|
+
function arrowWKTToGeometry(arrowCellValue) {
|
|
14304
|
+
const string = arrowCellValue;
|
|
14305
|
+
return convertWKTToGeometry(string);
|
|
14306
|
+
}
|
|
14307
|
+
function arrowMultiPolygonToGeometry(arrowMultiPolygon) {
|
|
14308
|
+
const multiPolygon = [];
|
|
14309
|
+
for (let m = 0; m < arrowMultiPolygon.length; m++) {
|
|
14310
|
+
const arrowPolygon = arrowMultiPolygon.get(m);
|
|
14311
|
+
const polygon = [];
|
|
14312
|
+
for (let i = 0; arrowPolygon && i < arrowPolygon?.length; i++) {
|
|
14313
|
+
const arrowRing = arrowPolygon?.get(i);
|
|
14314
|
+
const ring = [];
|
|
14315
|
+
for (let j = 0; arrowRing && j < arrowRing.length; j++) {
|
|
14316
|
+
const arrowCoord = arrowRing.get(j);
|
|
14317
|
+
const coord = Array.from(arrowCoord);
|
|
14318
|
+
ring.push(coord);
|
|
14319
|
+
}
|
|
14320
|
+
polygon.push(ring);
|
|
14321
|
+
}
|
|
14322
|
+
multiPolygon.push(polygon);
|
|
14346
14323
|
}
|
|
14347
|
-
|
|
14348
|
-
|
|
14349
|
-
|
|
14350
|
-
|
|
14351
|
-
|
|
14324
|
+
const geometry = {
|
|
14325
|
+
type: "MultiPolygon",
|
|
14326
|
+
coordinates: multiPolygon
|
|
14327
|
+
};
|
|
14328
|
+
return geometry;
|
|
14329
|
+
}
|
|
14330
|
+
function arrowPolygonToGeometry(arrowPolygon) {
|
|
14331
|
+
const polygon = [];
|
|
14332
|
+
for (let i = 0; arrowPolygon && i < arrowPolygon.length; i++) {
|
|
14333
|
+
const arrowRing = arrowPolygon.get(i);
|
|
14334
|
+
const ring = [];
|
|
14335
|
+
for (let j = 0; arrowRing && j < arrowRing.length; j++) {
|
|
14336
|
+
const arrowCoord = arrowRing.get(j);
|
|
14337
|
+
const coords2 = Array.from(arrowCoord);
|
|
14338
|
+
ring.push(coords2);
|
|
14339
|
+
}
|
|
14340
|
+
polygon.push(ring);
|
|
14352
14341
|
}
|
|
14353
|
-
|
|
14354
|
-
|
|
14355
|
-
|
|
14356
|
-
|
|
14357
|
-
|
|
14358
|
-
|
|
14359
|
-
|
|
14342
|
+
const geometry = {
|
|
14343
|
+
type: "Polygon",
|
|
14344
|
+
coordinates: polygon
|
|
14345
|
+
};
|
|
14346
|
+
return geometry;
|
|
14347
|
+
}
|
|
14348
|
+
function arrowMultiPointToGeometry(arrowMultiPoint) {
|
|
14349
|
+
const multiPoint = [];
|
|
14350
|
+
for (let i = 0; arrowMultiPoint && i < arrowMultiPoint.length; i++) {
|
|
14351
|
+
const arrowPoint = arrowMultiPoint.get(i);
|
|
14352
|
+
if (arrowPoint) {
|
|
14353
|
+
const coord = Array.from(arrowPoint);
|
|
14354
|
+
multiPoint.push(coord);
|
|
14360
14355
|
}
|
|
14361
|
-
this.workerPools = /* @__PURE__ */ new Map();
|
|
14362
14356
|
}
|
|
14363
|
-
|
|
14364
|
-
|
|
14365
|
-
|
|
14366
|
-
|
|
14367
|
-
|
|
14368
|
-
|
|
14369
|
-
|
|
14370
|
-
|
|
14357
|
+
return {
|
|
14358
|
+
type: "MultiPoint",
|
|
14359
|
+
coordinates: multiPoint
|
|
14360
|
+
};
|
|
14361
|
+
}
|
|
14362
|
+
function arrowPointToGeometry(arrowPoint) {
|
|
14363
|
+
const point = Array.from(arrowPoint);
|
|
14364
|
+
return {
|
|
14365
|
+
type: "Point",
|
|
14366
|
+
coordinates: point
|
|
14367
|
+
};
|
|
14368
|
+
}
|
|
14369
|
+
function arrowMultiLineStringToGeometry(arrowMultiLineString) {
|
|
14370
|
+
const multiLineString = [];
|
|
14371
|
+
for (let i = 0; arrowMultiLineString && i < arrowMultiLineString.length; i++) {
|
|
14372
|
+
const arrowLineString = arrowMultiLineString.get(i);
|
|
14373
|
+
const lineString = [];
|
|
14374
|
+
for (let j = 0; arrowLineString && j < arrowLineString.length; j++) {
|
|
14375
|
+
const arrowCoord = arrowLineString.get(j);
|
|
14376
|
+
if (arrowCoord) {
|
|
14377
|
+
const coords2 = Array.from(arrowCoord);
|
|
14378
|
+
lineString.push(coords2);
|
|
14379
|
+
}
|
|
14371
14380
|
}
|
|
14381
|
+
multiLineString.push(lineString);
|
|
14372
14382
|
}
|
|
14373
|
-
|
|
14374
|
-
|
|
14375
|
-
|
|
14376
|
-
|
|
14377
|
-
|
|
14378
|
-
|
|
14379
|
-
|
|
14380
|
-
|
|
14381
|
-
|
|
14382
|
-
|
|
14383
|
-
|
|
14384
|
-
|
|
14385
|
-
if (!workerPool) {
|
|
14386
|
-
workerPool = new WorkerPool({
|
|
14387
|
-
name,
|
|
14388
|
-
source,
|
|
14389
|
-
url
|
|
14390
|
-
});
|
|
14391
|
-
workerPool.setProps(this._getWorkerPoolProps());
|
|
14392
|
-
this.workerPools.set(name, workerPool);
|
|
14383
|
+
return {
|
|
14384
|
+
type: "MultiLineString",
|
|
14385
|
+
coordinates: multiLineString
|
|
14386
|
+
};
|
|
14387
|
+
}
|
|
14388
|
+
function arrowLineStringToGeometry(arrowLineString) {
|
|
14389
|
+
const lineString = [];
|
|
14390
|
+
for (let i = 0; arrowLineString && i < arrowLineString.length; i++) {
|
|
14391
|
+
const arrowCoord = arrowLineString.get(i);
|
|
14392
|
+
if (arrowCoord) {
|
|
14393
|
+
const coords2 = Array.from(arrowCoord);
|
|
14394
|
+
lineString.push(coords2);
|
|
14393
14395
|
}
|
|
14394
|
-
return workerPool;
|
|
14395
|
-
}
|
|
14396
|
-
_getWorkerPoolProps() {
|
|
14397
|
-
return {
|
|
14398
|
-
maxConcurrency: this.props.maxConcurrency,
|
|
14399
|
-
maxMobileConcurrency: this.props.maxMobileConcurrency,
|
|
14400
|
-
reuseWorkers: this.props.reuseWorkers,
|
|
14401
|
-
onDebug: this.props.onDebug
|
|
14402
|
-
};
|
|
14403
14396
|
}
|
|
14404
|
-
|
|
14405
|
-
|
|
14406
|
-
|
|
14407
|
-
|
|
14397
|
+
return {
|
|
14398
|
+
type: "LineString",
|
|
14399
|
+
coordinates: lineString
|
|
14400
|
+
};
|
|
14401
|
+
}
|
|
14408
14402
|
|
|
14409
|
-
// ../
|
|
14410
|
-
function
|
|
14411
|
-
|
|
14412
|
-
|
|
14403
|
+
// ../gis/src/lib/table-converters/convert-geoarrow-table.ts
|
|
14404
|
+
function convertGeoArrowToTable(arrowTable, shape) {
|
|
14405
|
+
switch (shape) {
|
|
14406
|
+
case "arrow-table":
|
|
14407
|
+
return convertArrowToArrowTable2(arrowTable);
|
|
14408
|
+
case "array-row-table":
|
|
14409
|
+
return convertArrowToArrayRowTable2(arrowTable);
|
|
14410
|
+
case "object-row-table":
|
|
14411
|
+
return convertArrowToObjectRowTable2(arrowTable);
|
|
14412
|
+
case "columnar-table":
|
|
14413
|
+
return convertArrowToColumnarTable2(arrowTable);
|
|
14414
|
+
case "geojson-table":
|
|
14415
|
+
return convertArrowToGeoJSONTable2(arrowTable);
|
|
14416
|
+
default:
|
|
14417
|
+
throw new Error(shape);
|
|
14418
|
+
}
|
|
14413
14419
|
}
|
|
14414
|
-
function
|
|
14415
|
-
|
|
14416
|
-
|
|
14417
|
-
|
|
14418
|
-
|
|
14419
|
-
|
|
14420
|
+
function convertArrowToArrowTable2(arrowTable) {
|
|
14421
|
+
return {
|
|
14422
|
+
shape: "arrow-table",
|
|
14423
|
+
schema: convertArrowToSchema(arrowTable.schema),
|
|
14424
|
+
data: arrowTable
|
|
14425
|
+
};
|
|
14426
|
+
}
|
|
14427
|
+
function convertArrowToArrayRowTable2(arrowTable) {
|
|
14428
|
+
const columnarTable = convertArrowToColumnarTable2(arrowTable);
|
|
14429
|
+
return convertTable(columnarTable, "array-row-table");
|
|
14430
|
+
}
|
|
14431
|
+
function convertArrowToObjectRowTable2(arrowTable) {
|
|
14432
|
+
const columnarTable = convertArrowToColumnarTable2(arrowTable);
|
|
14433
|
+
return convertTable(columnarTable, "object-row-table");
|
|
14434
|
+
}
|
|
14435
|
+
function convertArrowToColumnarTable2(arrowTable) {
|
|
14436
|
+
const columns = {};
|
|
14437
|
+
for (const field of arrowTable.schema.fields) {
|
|
14438
|
+
const arrowColumn = arrowTable.getChild(field.name);
|
|
14439
|
+
const values = arrowColumn?.toArray();
|
|
14440
|
+
columns[field.name] = values;
|
|
14420
14441
|
}
|
|
14421
|
-
|
|
14422
|
-
|
|
14423
|
-
|
|
14424
|
-
|
|
14425
|
-
|
|
14442
|
+
const schema = convertArrowToSchema(arrowTable.schema);
|
|
14443
|
+
return {
|
|
14444
|
+
shape: "columnar-table",
|
|
14445
|
+
schema,
|
|
14446
|
+
data: columns
|
|
14447
|
+
};
|
|
14448
|
+
}
|
|
14449
|
+
function convertArrowToGeoJSONTable2(arrowTable) {
|
|
14450
|
+
const schema = convertArrowToSchema(arrowTable.schema);
|
|
14451
|
+
const geometryColumns = getGeometryColumnsFromSchema(schema);
|
|
14452
|
+
const encoding = geometryColumns.geometry.encoding;
|
|
14453
|
+
const features = [];
|
|
14454
|
+
const propertyColumnNames = arrowTable.schema.fields.map((field) => field.name).filter((name) => !(name in geometryColumns));
|
|
14455
|
+
const propertiesTable = arrowTable.select(propertyColumnNames);
|
|
14456
|
+
const arrowGeometryColumn = arrowTable.getChild("geometry");
|
|
14457
|
+
for (let row = 0; row < arrowTable.numRows; row++) {
|
|
14458
|
+
const arrowGeometry = arrowGeometryColumn?.get(row);
|
|
14459
|
+
const feature = convertGeoArrowGeometryToGeoJSON(arrowGeometry, encoding);
|
|
14460
|
+
if (feature) {
|
|
14461
|
+
const properties = propertiesTable.get(row)?.toJSON() || {};
|
|
14462
|
+
features.push({ type: "Feature", geometry: feature, properties });
|
|
14426
14463
|
}
|
|
14427
14464
|
}
|
|
14428
|
-
|
|
14429
|
-
|
|
14430
|
-
|
|
14431
|
-
|
|
14432
|
-
|
|
14433
|
-
|
|
14434
|
-
|
|
14465
|
+
return {
|
|
14466
|
+
shape: "geojson-table",
|
|
14467
|
+
type: "FeatureCollection",
|
|
14468
|
+
schema,
|
|
14469
|
+
features
|
|
14470
|
+
};
|
|
14471
|
+
}
|
|
14472
|
+
|
|
14473
|
+
// src/lib/parsers/parse-geoarrow.ts
|
|
14474
|
+
function parseGeoArrowSync(arrayBuffer, options) {
|
|
14475
|
+
const table = parseArrowSync(arrayBuffer, { shape: "arrow-table" });
|
|
14476
|
+
switch (options?.shape) {
|
|
14477
|
+
case "geojson-table":
|
|
14478
|
+
return convertGeoArrowToTable(table.data, "geojson-table");
|
|
14479
|
+
default:
|
|
14480
|
+
return table;
|
|
14435
14481
|
}
|
|
14436
|
-
|
|
14437
|
-
|
|
14482
|
+
}
|
|
14483
|
+
function parseGeoArrowInBatches(asyncIterator) {
|
|
14484
|
+
return parseArrowInBatches(asyncIterator);
|
|
14438
14485
|
}
|
|
14439
14486
|
|
|
14440
|
-
//
|
|
14441
|
-
|
|
14442
|
-
|
|
14443
|
-
|
|
14444
|
-
|
|
14445
|
-
|
|
14446
|
-
|
|
14447
|
-
|
|
14487
|
+
// src/geoarrow-loader.ts
|
|
14488
|
+
var GeoArrowLoader = {
|
|
14489
|
+
...GeoArrowWorkerLoader,
|
|
14490
|
+
parse: async (arraybuffer, options) => parseGeoArrowSync(arraybuffer, options?.arrow),
|
|
14491
|
+
parseSync: (arraybuffer, options) => parseGeoArrowSync(arraybuffer, options?.arrow),
|
|
14492
|
+
parseInBatches: parseGeoArrowInBatches
|
|
14493
|
+
};
|
|
14494
|
+
|
|
14495
|
+
// src/workers/hard-clone.ts
|
|
14496
|
+
function hardClone(data, force = false) {
|
|
14497
|
+
if ("data" in data) {
|
|
14498
|
+
return new Vector(data.data.map((data2) => hardClone(data2, force)));
|
|
14448
14499
|
}
|
|
14449
|
-
const
|
|
14450
|
-
const
|
|
14451
|
-
|
|
14452
|
-
|
|
14453
|
-
|
|
14454
|
-
|
|
14500
|
+
const clonedChildren = [];
|
|
14501
|
+
for (const childData of data.children) {
|
|
14502
|
+
clonedChildren.push(hardClone(childData, force));
|
|
14503
|
+
}
|
|
14504
|
+
let clonedDictionary;
|
|
14505
|
+
if (data.dictionary !== void 0) {
|
|
14506
|
+
clonedDictionary = hardClone(data.dictionary, force);
|
|
14507
|
+
}
|
|
14508
|
+
const clonedBuffers = {
|
|
14509
|
+
[BufferType.OFFSET]: cloneBuffer(data.buffers[BufferType.OFFSET], force),
|
|
14510
|
+
[BufferType.DATA]: cloneBuffer(data.buffers[BufferType.DATA], force),
|
|
14511
|
+
[BufferType.VALIDITY]: cloneBuffer(data.buffers[BufferType.VALIDITY], force),
|
|
14512
|
+
[BufferType.TYPE]: cloneBuffer(data.buffers[BufferType.TYPE], force)
|
|
14513
|
+
};
|
|
14514
|
+
return new Data(
|
|
14515
|
+
data.type,
|
|
14516
|
+
data.offset,
|
|
14517
|
+
data.length,
|
|
14518
|
+
// @ts-expect-error _nullCount is protected. We're using it here to mimic
|
|
14519
|
+
// `Data.clone`
|
|
14520
|
+
data._nullCount,
|
|
14521
|
+
clonedBuffers,
|
|
14522
|
+
clonedChildren,
|
|
14523
|
+
clonedDictionary
|
|
14455
14524
|
);
|
|
14456
|
-
const transferableOptions = getTransferListForWriter(options);
|
|
14457
|
-
job.postMessage("process", { input: data, options: transferableOptions });
|
|
14458
|
-
const result = await job.result;
|
|
14459
|
-
return result.result;
|
|
14460
14525
|
}
|
|
14461
|
-
|
|
14462
|
-
|
|
14463
|
-
|
|
14464
|
-
|
|
14465
|
-
|
|
14466
|
-
|
|
14467
|
-
job.error(new Error(payload.error));
|
|
14468
|
-
break;
|
|
14469
|
-
case "process":
|
|
14470
|
-
const { id, input, options } = payload;
|
|
14471
|
-
try {
|
|
14472
|
-
if (!context.process) {
|
|
14473
|
-
job.postMessage("error", { id, error: "Worker not set up to process on main thread" });
|
|
14474
|
-
return;
|
|
14475
|
-
}
|
|
14476
|
-
const result = await context.process(input, options);
|
|
14477
|
-
job.postMessage("done", { id, result });
|
|
14478
|
-
} catch (error) {
|
|
14479
|
-
const message = error instanceof Error ? error.message : "unknown error";
|
|
14480
|
-
job.postMessage("error", { id, error: message });
|
|
14481
|
-
}
|
|
14482
|
-
break;
|
|
14483
|
-
default:
|
|
14484
|
-
console.warn(`process-on-worker: unknown message ${type}`);
|
|
14526
|
+
function isTypedArraySliced(arr) {
|
|
14527
|
+
return !(arr.byteOffset === 0 && arr.byteLength === arr.buffer.byteLength);
|
|
14528
|
+
}
|
|
14529
|
+
function cloneBuffer(arr, force) {
|
|
14530
|
+
if (arr === void 0) {
|
|
14531
|
+
return arr;
|
|
14485
14532
|
}
|
|
14533
|
+
if (!force && !isTypedArraySliced(arr)) {
|
|
14534
|
+
return arr;
|
|
14535
|
+
}
|
|
14536
|
+
return arr.slice();
|
|
14486
14537
|
}
|
|
14487
14538
|
|
|
14488
14539
|
// src/triangulate-on-worker.ts
|