UNPKG

@trailstash/ultra

Version:

A web based tool for making MapLibre GL maps with data from sources such as Overpass, GeoJSON, GPX, KML, TCX, etc

92 lines (71 loc) 2.41 kB
import { geoJsonLayers as layers } from "./common.js"; export const version = "1.32.0"; // global connection singleton let connInstance = null; async function initDB() { // Return the connection directly if already initialized if (connInstance) return connInstance; const duckdb = await import( `https://cdn.jsdelivr.net/npm/@duckdb/duckdb-wasm@${version}/+esm` ); const JSDELIVR_BUNDLES = duckdb.getJsDelivrBundles(); const bundle = await duckdb.selectBundle(JSDELIVR_BUNDLES); const worker_url = URL.createObjectURL( new Blob([`importScripts("${bundle.mainWorker}");`], { type: "text/javascript", }), ); const worker = new Worker(worker_url); const logger = new duckdb.ConsoleLogger(); const db = new duckdb.AsyncDuckDB(logger, worker); await db.instantiate(bundle.mainModule, bundle.pthreadWorker); URL.revokeObjectURL(worker_url); // Open DB to override query & filesystem defaults await db.open({ // in-memory db, same as default path: ":memory:", // Query options to use standard JS types query: { castBigIntToDouble: true, castTimestampToDate: true, castDecimalToDouble: true, }, // Filesytem options to force Range requests filesystem: { allowFullHTTPReads: false, reliableHeadRequests: true, forceFullHTTPReads: false, }, }); // Establish the connection and store it globally connInstance = await db.connect(); await connInstance.query(`INSTALL spatial; LOAD spatial;`); return connInstance; } const duckdb = { source: async function (query, controller, { geomCol = "geometry" }) { const conn = await initDB(); const jsonQuery = ` WITH _data AS (${query}) SELECT json_object( 'type', 'FeatureCollection', 'features', COALESCE(json_group_array( json_object( 'type', 'Feature', 'geometry', ST_AsGeoJSON(${geomCol})::JSON, 'properties', to_json(struct_pack(*COLUMNS(* EXCLUDE (${geomCol})))) ) ), '[]'::JSON) )::VARCHAR AS geojson_string FROM _data; `; const arrowResult = await conn.query(jsonQuery); const rows = arrowResult.toArray(); const data = JSON.parse( rows[0].toJSON ? rows[0].toJSON().geojson_string : rows[0].geojson_string, ); return { type: "geojson", data }; }, layers, }; export default duckdb;