@loaders.gl/geopackage 4.2.0-alpha.4 → 4.2.0-alpha.5

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.
@@ -1,6 +1,30 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
1
4
  import { parseGeoPackage, DEFAULT_SQLJS_CDN } from "./lib/parse-geopackage.js";
5
+ // __VERSION__ is injected by babel-plugin-version-inline
6
+ // @ts-ignore TS2304: Cannot find name '__VERSION__'.
7
+ // const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
2
8
  const VERSION = 'latest';
3
9
  export const GeoPackageLoader = {
10
+ id: 'geopackage',
11
+ name: 'GeoPackage',
12
+ module: 'geopackage',
13
+ version: VERSION,
14
+ extensions: ['gpkg'],
15
+ mimeTypes: ['application/geopackage+sqlite3'],
16
+ category: 'geometry',
17
+ parse: parseGeoPackage,
18
+ options: {
19
+ geopackage: {
20
+ sqlJsCDN: DEFAULT_SQLJS_CDN,
21
+ shape: 'tables'
22
+ },
23
+ gis: {}
24
+ }
25
+ };
26
+ /** Geopackage loader *
27
+ export const GeoPackageTableLoader: LoaderWithParser<Record<string, Feature[]>, never, GeoPackageLoaderOptions> = {
4
28
  id: 'geopackage',
5
29
  name: 'GeoPackage',
6
30
  module: 'geopackage',
@@ -12,9 +36,9 @@ export const GeoPackageLoader = {
12
36
  options: {
13
37
  geopackage: {
14
38
  sqlJsCDN: DEFAULT_SQLJS_CDN,
15
- shape: 'tables'
16
39
  },
17
- gis: {}
40
+ gis: {
41
+ }
18
42
  }
19
43
  };
20
- //# sourceMappingURL=geopackage-loader.js.map
44
+ */
package/dist/index.cjs CHANGED
@@ -27,14 +27,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
- // src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
30
+ // dist/index.js
31
+ var dist_exports = {};
32
+ __export(dist_exports, {
33
33
  GeoPackageLoader: () => GeoPackageLoader
34
34
  });
35
- module.exports = __toCommonJS(src_exports);
35
+ module.exports = __toCommonJS(dist_exports);
36
36
 
37
- // src/lib/parse-geopackage.ts
37
+ // dist/lib/parse-geopackage.js
38
38
  var import_loader_utils = require("@loaders.gl/loader-utils");
39
39
  var import_wkt = require("@loaders.gl/wkt");
40
40
  var import_gis = require("@loaders.gl/gis");
@@ -286,7 +286,7 @@ function getSchema(db, tableName) {
286
286
  return { fields, metadata: {} };
287
287
  }
288
288
 
289
- // src/geopackage-loader.ts
289
+ // dist/geopackage-loader.js
290
290
  var VERSION = "latest";
291
291
  var GeoPackageLoader = {
292
292
  id: "geopackage",
@@ -305,3 +305,4 @@ var GeoPackageLoader = {
305
305
  gis: {}
306
306
  }
307
307
  };
308
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["index.js", "lib/parse-geopackage.js", "geopackage-loader.js"],
4
+ "sourcesContent": ["// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nexport { GeoPackageLoader } from \"./geopackage-loader.js\";\n", "/* eslint-disable camelcase, @typescript-eslint/no-use-before-define */\nimport { isBrowser } from '@loaders.gl/loader-utils';\nimport { WKBLoader } from '@loaders.gl/wkt';\nimport { binaryToGeometry, transformGeoJsonCoords } from '@loaders.gl/gis';\nimport { Proj4Projection } from '@math.gl/proj4';\nimport initSqlJs from 'sql.js';\nconst SQL_JS_VERSION = '1.8.0';\n/**\n * We pin to the same version as sql.js that we use.\n * As of March 2022, versions 1.6.0, 1.6.1, and 1.6.2 of sql.js appeared not to work.\n */\nexport const DEFAULT_SQLJS_CDN = isBrowser\n ? `https://cdnjs.cloudflare.com/ajax/libs/sql.js/${SQL_JS_VERSION}/`\n : null;\n// https://www.geopackage.org/spec121/#flags_layout\nconst ENVELOPE_BYTE_LENGTHS = {\n 0: 0,\n 1: 32,\n 2: 48,\n 3: 48,\n 4: 64,\n // values 5-7 are invalid and _should_ never show up\n 5: 0,\n 6: 0,\n 7: 0\n};\n// Documentation: https://www.geopackage.org/spec130/index.html#table_column_data_types\nconst SQL_TYPE_MAPPING = {\n BOOLEAN: 'bool',\n TINYINT: 'int8',\n SMALLINT: 'int16',\n MEDIUMINT: 'int32',\n INT: 'int32',\n INTEGER: 'int32',\n FLOAT: 'float32',\n DOUBLE: 'float64',\n REAL: 'float64',\n TEXT: 'utf8',\n BLOB: 'binary',\n DATE: 'utf8',\n DATETIME: 'utf8',\n GEOMETRY: 'binary',\n POINT: 'binary',\n LINESTRING: 'binary',\n POLYGON: 'binary',\n MULTIPOINT: 'binary',\n MULTILINESTRING: 'binary',\n MULTIPOLYGON: 'binary',\n GEOMETRYCOLLECTION: 'binary'\n};\nexport async function parseGeoPackage(arrayBuffer, options) {\n const { sqlJsCDN = DEFAULT_SQLJS_CDN } = options?.geopackage || {};\n const { reproject = false, _targetCrs = 'WGS84' } = options?.gis || {};\n const db = await loadDatabase(arrayBuffer, sqlJsCDN);\n const tables = listVectorTables(db);\n const projections = getProjections(db);\n const selectedTable = tables.find((table) => table.table_name === options?.geopackage?.table);\n const tableName = selectedTable ? selectedTable.table_name : tables[0].table_name;\n const shape = options?.geopackage?.shape;\n switch (shape) {\n case 'geojson-table':\n return getVectorTable(db, tableName, projections, {\n reproject,\n _targetCrs\n });\n case 'tables':\n // Mapping from tableName to geojson feature collection\n const outputTables = {\n shape: 'tables',\n tables: []\n };\n for (const table of tables) {\n const { table_name: tableName } = table;\n outputTables.tables.push({\n name: tableName,\n table: getVectorTable(db, tableName, projections, {\n reproject,\n _targetCrs\n })\n });\n }\n return outputTables;\n default:\n throw new Error(shape);\n }\n}\n/**\n * Initialize SQL.js and create database\n *\n * @param arrayBuffer input bytes\n * @return SQL.js database object\n */\nasync function loadDatabase(arrayBuffer, sqlJsCDN) {\n // In Node, `locateFile` must not be passed\n let SQL;\n if (sqlJsCDN) {\n SQL = await initSqlJs({\n locateFile: (file) => `${sqlJsCDN}${file}`\n });\n }\n else {\n SQL = await initSqlJs();\n }\n return new SQL.Database(new Uint8Array(arrayBuffer));\n}\n/**\n * Find all vector tables in GeoPackage\n * This queries the `gpkg_contents` table to find a list of vector tables\n *\n * @param db GeoPackage to query\n * @return list of table references\n */\nfunction listVectorTables(db) {\n // The gpkg_contents table can have at least three categorical values for\n // data_type.\n // - 'features' refers to a vector geometry table\n // (https://www.geopackage.org/spec121/#_contents_2)\n // - 'tiles' refers to a raster table\n // (https://www.geopackage.org/spec121/#_contents_3)\n // - 'attributes' refers to a data table with no geometry\n // (https://www.geopackage.org/spec121/#_contents_4).\n // We hard code 'features' because for now we don't support raster data or pure attribute data\n // eslint-disable-next-line quotes\n const stmt = db.prepare(\"SELECT * FROM gpkg_contents WHERE data_type='features';\");\n const vectorTablesInfo = [];\n while (stmt.step()) {\n const vectorTableInfo = stmt.getAsObject();\n vectorTablesInfo.push(vectorTableInfo);\n }\n return vectorTablesInfo;\n}\n/**\n * Load geometries from vector table\n *\n * @param db GeoPackage object\n * @param tableName name of vector table to query\n * @param projections keys are srs_id values, values are WKT strings\n * @returns Array of GeoJSON Feature objects\n */\nfunction getVectorTable(db, tableName, projections, { reproject, _targetCrs }) {\n const dataColumns = getDataColumns(db, tableName);\n const geomColumn = getGeometryColumn(db, tableName);\n const featureIdColumn = getFeatureIdName(db, tableName);\n // Get vector features from table\n // Don't think it's possible to parameterize the table name in SQLite?\n const { columns, values } = db.exec(`SELECT * FROM \\`${tableName}\\`;`)[0];\n let projection;\n if (reproject) {\n const geomColumnProjStr = projections[geomColumn.srs_id];\n projection = new Proj4Projection({\n from: geomColumnProjStr,\n to: _targetCrs\n });\n }\n const geojsonFeatures = [];\n for (const row of values) {\n const geojsonFeature = constructGeoJsonFeature(columns, row, geomColumn, \n // @ts-ignore\n dataColumns, featureIdColumn);\n geojsonFeatures.push(geojsonFeature);\n }\n const schema = getSchema(db, tableName);\n if (projection) {\n return {\n shape: 'geojson-table',\n type: 'FeatureCollection',\n // @ts-expect-error TODO - null geometries causing problems...\n features: transformGeoJsonCoords(geojsonFeatures, projection.project),\n schema\n };\n }\n return {\n shape: 'geojson-table',\n schema,\n type: 'FeatureCollection',\n // @ts-expect-error TODO - null features\n features: geojsonFeatures\n };\n}\n/**\n * Find all projections defined in GeoPackage\n * This queries the gpkg_spatial_ref_sys table\n * @param db GeoPackage object\n * @returns mapping from srid to WKT projection string\n */\nfunction getProjections(db) {\n // Query gpkg_spatial_ref_sys to get srid: srtext mappings\n const stmt = db.prepare('SELECT * FROM gpkg_spatial_ref_sys;');\n const projectionMapping = {};\n while (stmt.step()) {\n const srsInfo = stmt.getAsObject();\n const { srs_id, definition } = srsInfo;\n projectionMapping[srs_id] = definition;\n }\n return projectionMapping;\n}\n/**\n * Construct single GeoJSON feature given row's data\n * @param columns array of ordered column identifiers\n * @param row array of ordered values representing row's data\n * @param geomColumn geometry column metadata\n * @param dataColumns mapping from table column names to property name\n * @returns GeoJSON Feature object\n */\nfunction constructGeoJsonFeature(columns, row, geomColumn, dataColumns, featureIdColumn) {\n // Find feature id\n const idIdx = columns.indexOf(featureIdColumn);\n const id = row[idIdx];\n // Parse geometry columns to geojson\n const geomColumnIdx = columns.indexOf(geomColumn.column_name);\n const geometry = parseGeometry(row[geomColumnIdx].buffer);\n const properties = {};\n if (dataColumns) {\n for (const [key, value] of Object.entries(dataColumns)) {\n const idx = columns.indexOf(key);\n // @ts-ignore TODO - Check what happens if null?\n properties[value] = row[idx];\n }\n }\n else {\n // Put all columns except for the feature id and geometry in properties\n for (let i = 0; i < columns.length; i++) {\n if (i === idIdx || i === geomColumnIdx) {\n // eslint-disable-next-line no-continue\n continue;\n }\n const columnName = columns[i];\n properties[columnName] = row[i];\n }\n }\n return {\n id,\n type: 'Feature',\n geometry,\n properties\n };\n}\n/**\n * Get GeoPackage version from database\n * @param db database\n * @returns version string. One of '1.0', '1.1', '1.2'\n */\n// @ts-ignore\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction getGeopackageVersion(db) {\n const textDecoder = new TextDecoder();\n // Read application id from SQLite metadata\n const applicationIdQuery = db.exec('PRAGMA application_id;')[0];\n const applicationId = applicationIdQuery.values[0][0];\n // Convert 4-byte signed int32 application id to text\n const buffer = new ArrayBuffer(4);\n const view = new DataView(buffer);\n view.setInt32(0, Number(applicationId));\n const versionString = textDecoder.decode(buffer);\n if (versionString === 'GP10') {\n return '1.0';\n }\n if (versionString === 'GP11') {\n return '1.1';\n }\n // If versionString is GPKG, then read user_version\n const userVersionQuery = db.exec('PRAGMA user_version;')[0];\n const userVersionInt = userVersionQuery.values[0][0];\n if (userVersionInt && typeof userVersionInt === 'number' && userVersionInt < 10300) {\n return '1.2';\n }\n return null;\n}\n/**\n * Find name of feature id column in table\n * The feature ID is the primary key of the table.\n * http://www.geopackage.org/spec121/#feature_user_tables\n *\n * @param db database\n * @param tableName name of table\n * @return name of feature id column\n */\nfunction getFeatureIdName(db, tableName) {\n // Again, not possible to parameterize table name?\n const stmt = db.prepare(`PRAGMA table_info(\\`${tableName}\\`)`);\n while (stmt.step()) {\n const pragmaTableInfo = stmt.getAsObject();\n const { name, pk } = pragmaTableInfo;\n if (pk) {\n return name;\n }\n }\n // Is it guaranteed for there always to be at least one primary key column in the table?\n return null;\n}\n/**\n * Parse geometry buffer\n * GeoPackage vector geometries are slightly extended past the WKB standard\n * See: https://www.geopackage.org/spec121/#gpb_format\n *\n * @param arrayBuffer geometry buffer\n * @return GeoJSON geometry (in original CRS)\n */\nfunction parseGeometry(arrayBuffer) {\n const view = new DataView(arrayBuffer);\n const { envelopeLength, emptyGeometry } = parseGeometryBitFlags(view.getUint8(3));\n // A Feature object has a member with the name \"geometry\". The value of the\n // geometry member SHALL be either a Geometry object as defined above or, in\n // the case that the Feature is unlocated, a JSON null value.\n /** @see https://tools.ietf.org/html/rfc7946#section-3.2 */\n if (emptyGeometry) {\n return null;\n }\n // Do I need to find the srid here? Is it necessarily the same for every\n // geometry in a table?\n // const srid = view.getInt32(4, littleEndian);\n // 2 byte magic, 1 byte version, 1 byte flags, 4 byte int32 srid\n const wkbOffset = 8 + envelopeLength;\n // Loaders should not depend on `core` and the context passed to the main loader doesn't include a\n // `parseSync` option, so instead we call parseSync directly on WKBLoader\n const binaryGeometry = WKBLoader.parseSync?.(arrayBuffer.slice(wkbOffset));\n // @ts-expect-error\n return binaryToGeometry(binaryGeometry);\n}\n/**\n * Parse geometry header flags\n * https://www.geopackage.org/spec121/#flags_layout\n *\n * @param byte uint8 number representing flags\n * @return object representing information from bit flags\n */\nfunction parseGeometryBitFlags(byte) {\n // Are header values little endian?\n const envelopeValue = (byte & 0b00001110) / 2;\n // TODO: Not sure the best way to handle this. Throw an error if envelopeValue outside 0-7?\n const envelopeLength = ENVELOPE_BYTE_LENGTHS[envelopeValue];\n return {\n littleEndian: Boolean(byte & 0b00000001),\n envelopeLength,\n emptyGeometry: Boolean(byte & 0b00010000),\n extendedGeometryType: Boolean(byte & 0b00100000)\n };\n}\n/**\n * Find geometry column in given vector table\n *\n * @param db GeoPackage object\n * @param tableName Name of vector table\n * @returns Array of geometry column definitions\n */\nfunction getGeometryColumn(db, tableName) {\n const stmt = db.prepare('SELECT * FROM gpkg_geometry_columns WHERE table_name=:tableName;');\n stmt.bind({ ':tableName': tableName });\n // > Requirement 30\n // > A feature table SHALL have only one geometry column.\n // https://www.geopackage.org/spec121/#feature_user_tables\n // So we should need one and only one step, given that we use the WHERE clause in the SQL query\n // above\n stmt.step();\n const geometryColumn = stmt.getAsObject();\n return geometryColumn;\n}\n/**\n * Find property columns in given vector table\n * @param db GeoPackage object\n * @param tableName Name of vector table\n * @returns Mapping from table column names to property name\n */\nfunction getDataColumns(db, tableName) {\n // gpkg_data_columns is not required to exist\n // https://www.geopackage.org/spec121/#extension_schema\n let stmt;\n try {\n stmt = db.prepare('SELECT * FROM gpkg_data_columns WHERE table_name=:tableName;');\n }\n catch (error) {\n if (error.message.includes('no such table')) {\n return null;\n }\n throw error;\n }\n stmt.bind({ ':tableName': tableName });\n // Convert DataColumnsRow object this to a key-value {column_name: name}\n const result = {};\n while (stmt.step()) {\n const column = stmt.getAsObject();\n const { column_name, name } = column;\n result[column_name] = name || null;\n }\n return result;\n}\n/**\n * Get arrow schema\n * @param db GeoPackage object\n * @param tableName table name\n * @returns Arrow-like Schema\n */\nfunction getSchema(db, tableName) {\n const stmt = db.prepare(`PRAGMA table_info(\\`${tableName}\\`)`);\n const fields = [];\n while (stmt.step()) {\n const pragmaTableInfo = stmt.getAsObject();\n const { name, type: sqlType, notnull } = pragmaTableInfo;\n const type = SQL_TYPE_MAPPING[sqlType];\n const field = { name, type, nullable: !notnull };\n fields.push(field);\n }\n return { fields, metadata: {} };\n}\n", "// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\nimport { parseGeoPackage, DEFAULT_SQLJS_CDN } from \"./lib/parse-geopackage.js\";\n// __VERSION__ is injected by babel-plugin-version-inline\n// @ts-ignore TS2304: Cannot find name '__VERSION__'.\n// const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';\nconst VERSION = 'latest';\nexport const GeoPackageLoader = {\n id: 'geopackage',\n name: 'GeoPackage',\n module: 'geopackage',\n version: VERSION,\n extensions: ['gpkg'],\n mimeTypes: ['application/geopackage+sqlite3'],\n category: 'geometry',\n parse: parseGeoPackage,\n options: {\n geopackage: {\n sqlJsCDN: DEFAULT_SQLJS_CDN,\n shape: 'tables'\n },\n gis: {}\n }\n};\n/** Geopackage loader *\nexport const GeoPackageTableLoader: LoaderWithParser<Record<string, Feature[]>, never, GeoPackageLoaderOptions> = {\n id: 'geopackage',\n name: 'GeoPackage',\n module: 'geopackage',\n version: VERSION,\n extensions: ['gpkg'],\n mimeTypes: ['application/geopackage+sqlite3'],\n category: 'geometry',\n parse: parseGeoPackage,\n options: {\n geopackage: {\n sqlJsCDN: DEFAULT_SQLJS_CDN,\n },\n gis: {\n }\n }\n};\n*/\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,0BAA0B;AAC1B,iBAA0B;AAC1B,iBAAyD;AACzD,mBAAgC;AAChC,iBAAsB;AACtB,IAAM,iBAAiB;AAKhB,IAAM,oBAAoB,gCAC3B,iDAAiD,oBACjD;AAEN,IAAM,wBAAwB;AAAA,EAC1B,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA;AAAA,EAEH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACP;AAEA,IAAM,mBAAmB;AAAA,EACrB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,WAAW;AAAA,EACX,KAAK;AAAA,EACL,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,oBAAoB;AACxB;AACA,eAAsB,gBAAgB,aAAa,SAAS;AAlD5D;AAmDI,QAAM,EAAE,WAAW,kBAAkB,KAAI,mCAAS,eAAc,CAAC;AACjE,QAAM,EAAE,YAAY,OAAO,aAAa,QAAQ,KAAI,mCAAS,QAAO,CAAC;AACrE,QAAM,KAAK,MAAM,aAAa,aAAa,QAAQ;AACnD,QAAM,SAAS,iBAAiB,EAAE;AAClC,QAAM,cAAc,eAAe,EAAE;AACrC,QAAM,gBAAgB,OAAO,KAAK,CAAC,UAAO;AAxD9C,QAAAA;AAwDiD,iBAAM,iBAAeA,MAAA,mCAAS,eAAT,gBAAAA,IAAqB;AAAA,GAAK;AAC5F,QAAM,YAAY,gBAAgB,cAAc,aAAa,OAAO,CAAC,EAAE;AACvE,QAAM,SAAQ,wCAAS,eAAT,mBAAqB;AACnC,UAAQ,OAAO;AAAA,IACX,KAAK;AACD,aAAO,eAAe,IAAI,WAAW,aAAa;AAAA,QAC9C;AAAA,QACA;AAAA,MACJ,CAAC;AAAA,IACL,KAAK;AAED,YAAM,eAAe;AAAA,QACjB,OAAO;AAAA,QACP,QAAQ,CAAC;AAAA,MACb;AACA,iBAAW,SAAS,QAAQ;AACxB,cAAM,EAAE,YAAYC,WAAU,IAAI;AAClC,qBAAa,OAAO,KAAK;AAAA,UACrB,MAAMA;AAAA,UACN,OAAO,eAAe,IAAIA,YAAW,aAAa;AAAA,YAC9C;AAAA,YACA;AAAA,UACJ,CAAC;AAAA,QACL,CAAC;AAAA,MACL;AACA,aAAO;AAAA,IACX;AACI,YAAM,IAAI,MAAM,KAAK;AAAA,EAC7B;AACJ;AAOA,eAAe,aAAa,aAAa,UAAU;AAE/C,MAAI;AACJ,MAAI,UAAU;AACV,UAAM,UAAM,WAAAC,SAAU;AAAA,MAClB,YAAY,CAAC,SAAS,GAAG,WAAW;AAAA,IACxC,CAAC;AAAA,EACL,OACK;AACD,UAAM,UAAM,WAAAA,SAAU;AAAA,EAC1B;AACA,SAAO,IAAI,IAAI,SAAS,IAAI,WAAW,WAAW,CAAC;AACvD;AAQA,SAAS,iBAAiB,IAAI;AAW1B,QAAM,OAAO,GAAG,QAAQ,yDAAyD;AACjF,QAAM,mBAAmB,CAAC;AAC1B,SAAO,KAAK,KAAK,GAAG;AAChB,UAAM,kBAAkB,KAAK,YAAY;AACzC,qBAAiB,KAAK,eAAe;AAAA,EACzC;AACA,SAAO;AACX;AASA,SAAS,eAAe,IAAI,WAAW,aAAa,EAAE,WAAW,WAAW,GAAG;AAC3E,QAAM,cAAc,eAAe,IAAI,SAAS;AAChD,QAAM,aAAa,kBAAkB,IAAI,SAAS;AAClD,QAAM,kBAAkB,iBAAiB,IAAI,SAAS;AAGtD,QAAM,EAAE,SAAS,OAAO,IAAI,GAAG,KAAK,mBAAmB,cAAc,EAAE,CAAC;AACxE,MAAI;AACJ,MAAI,WAAW;AACX,UAAM,oBAAoB,YAAY,WAAW,MAAM;AACvD,iBAAa,IAAI,6BAAgB;AAAA,MAC7B,MAAM;AAAA,MACN,IAAI;AAAA,IACR,CAAC;AAAA,EACL;AACA,QAAM,kBAAkB,CAAC;AACzB,aAAW,OAAO,QAAQ;AACtB,UAAM,iBAAiB;AAAA,MAAwB;AAAA,MAAS;AAAA,MAAK;AAAA;AAAA,MAE7D;AAAA,MAAa;AAAA,IAAe;AAC5B,oBAAgB,KAAK,cAAc;AAAA,EACvC;AACA,QAAM,SAAS,UAAU,IAAI,SAAS;AACtC,MAAI,YAAY;AACZ,WAAO;AAAA,MACH,OAAO;AAAA,MACP,MAAM;AAAA;AAAA,MAEN,cAAU,mCAAuB,iBAAiB,WAAW,OAAO;AAAA,MACpE;AAAA,IACJ;AAAA,EACJ;AACA,SAAO;AAAA,IACH,OAAO;AAAA,IACP;AAAA,IACA,MAAM;AAAA;AAAA,IAEN,UAAU;AAAA,EACd;AACJ;AAOA,SAAS,eAAe,IAAI;AAExB,QAAM,OAAO,GAAG,QAAQ,qCAAqC;AAC7D,QAAM,oBAAoB,CAAC;AAC3B,SAAO,KAAK,KAAK,GAAG;AAChB,UAAM,UAAU,KAAK,YAAY;AACjC,UAAM,EAAE,QAAQ,WAAW,IAAI;AAC/B,sBAAkB,MAAM,IAAI;AAAA,EAChC;AACA,SAAO;AACX;AASA,SAAS,wBAAwB,SAAS,KAAK,YAAY,aAAa,iBAAiB;AAErF,QAAM,QAAQ,QAAQ,QAAQ,eAAe;AAC7C,QAAM,KAAK,IAAI,KAAK;AAEpB,QAAM,gBAAgB,QAAQ,QAAQ,WAAW,WAAW;AAC5D,QAAM,WAAW,cAAc,IAAI,aAAa,EAAE,MAAM;AACxD,QAAM,aAAa,CAAC;AACpB,MAAI,aAAa;AACb,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,WAAW,GAAG;AACpD,YAAM,MAAM,QAAQ,QAAQ,GAAG;AAE/B,iBAAW,KAAK,IAAI,IAAI,GAAG;AAAA,IAC/B;AAAA,EACJ,OACK;AAED,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,UAAI,MAAM,SAAS,MAAM,eAAe;AAEpC;AAAA,MACJ;AACA,YAAM,aAAa,QAAQ,CAAC;AAC5B,iBAAW,UAAU,IAAI,IAAI,CAAC;AAAA,IAClC;AAAA,EACJ;AACA,SAAO;AAAA,IACH;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACJ;AACJ;AAyCA,SAAS,iBAAiB,IAAI,WAAW;AAErC,QAAM,OAAO,GAAG,QAAQ,uBAAuB,cAAc;AAC7D,SAAO,KAAK,KAAK,GAAG;AAChB,UAAM,kBAAkB,KAAK,YAAY;AACzC,UAAM,EAAE,MAAM,GAAG,IAAI;AACrB,QAAI,IAAI;AACJ,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,SAAO;AACX;AASA,SAAS,cAAc,aAAa;AA1SpC;AA2SI,QAAM,OAAO,IAAI,SAAS,WAAW;AACrC,QAAM,EAAE,gBAAgB,cAAc,IAAI,sBAAsB,KAAK,SAAS,CAAC,CAAC;AAKhF,MAAI,eAAe;AACf,WAAO;AAAA,EACX;AAKA,QAAM,YAAY,IAAI;AAGtB,QAAM,kBAAiB,iCAAU,cAAV,4BAAsB,YAAY,MAAM,SAAS;AAExE,aAAO,6BAAiB,cAAc;AAC1C;AAQA,SAAS,sBAAsB,MAAM;AAEjC,QAAM,iBAAiB,OAAO,MAAc;AAE5C,QAAM,iBAAiB,sBAAsB,aAAa;AAC1D,SAAO;AAAA,IACH,cAAc,QAAQ,OAAO,CAAU;AAAA,IACvC;AAAA,IACA,eAAe,QAAQ,OAAO,EAAU;AAAA,IACxC,sBAAsB,QAAQ,OAAO,EAAU;AAAA,EACnD;AACJ;AAQA,SAAS,kBAAkB,IAAI,WAAW;AACtC,QAAM,OAAO,GAAG,QAAQ,kEAAkE;AAC1F,OAAK,KAAK,EAAE,cAAc,UAAU,CAAC;AAMrC,OAAK,KAAK;AACV,QAAM,iBAAiB,KAAK,YAAY;AACxC,SAAO;AACX;AAOA,SAAS,eAAe,IAAI,WAAW;AAGnC,MAAI;AACJ,MAAI;AACA,WAAO,GAAG,QAAQ,8DAA8D;AAAA,EACpF,SACO,OAAP;AACI,QAAI,MAAM,QAAQ,SAAS,eAAe,GAAG;AACzC,aAAO;AAAA,IACX;AACA,UAAM;AAAA,EACV;AACA,OAAK,KAAK,EAAE,cAAc,UAAU,CAAC;AAErC,QAAM,SAAS,CAAC;AAChB,SAAO,KAAK,KAAK,GAAG;AAChB,UAAM,SAAS,KAAK,YAAY;AAChC,UAAM,EAAE,aAAa,KAAK,IAAI;AAC9B,WAAO,WAAW,IAAI,QAAQ;AAAA,EAClC;AACA,SAAO;AACX;AAOA,SAAS,UAAU,IAAI,WAAW;AAC9B,QAAM,OAAO,GAAG,QAAQ,uBAAuB,cAAc;AAC7D,QAAM,SAAS,CAAC;AAChB,SAAO,KAAK,KAAK,GAAG;AAChB,UAAM,kBAAkB,KAAK,YAAY;AACzC,UAAM,EAAE,MAAM,MAAM,SAAS,QAAQ,IAAI;AACzC,UAAM,OAAO,iBAAiB,OAAO;AACrC,UAAM,QAAQ,EAAE,MAAM,MAAM,UAAU,CAAC,QAAQ;AAC/C,WAAO,KAAK,KAAK;AAAA,EACrB;AACA,SAAO,EAAE,QAAQ,UAAU,CAAC,EAAE;AAClC;;;AC5YA,IAAM,UAAU;AACT,IAAM,mBAAmB;AAAA,EAC5B,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,YAAY,CAAC,MAAM;AAAA,EACnB,WAAW,CAAC,gCAAgC;AAAA,EAC5C,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,IACL,YAAY;AAAA,MACR,UAAU;AAAA,MACV,OAAO;AAAA,IACX;AAAA,IACA,KAAK,CAAC;AAAA,EACV;AACJ;",
6
+ "names": ["_a", "tableName", "initSqlJs"]
7
+ }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { GeoPackageLoader } from './geopackage-loader';
1
+ export { GeoPackageLoader } from "./geopackage-loader.js";
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,gBAAgB,EAAC,+BAA4B"}
package/dist/index.js CHANGED
@@ -1,2 +1,4 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
1
4
  export { GeoPackageLoader } from "./geopackage-loader.js";
2
- //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
1
  import { Tables, GeoJSONTable } from '@loaders.gl/schema';
2
- import type { GeoPackageLoaderOptions } from '../geopackage-loader';
2
+ import type { GeoPackageLoaderOptions } from "../geopackage-loader.js";
3
3
  /**
4
4
  * We pin to the same version as sql.js that we use.
5
5
  * As of March 2022, versions 1.6.0, 1.6.1, and 1.6.2 of sql.js appeared not to work.
@@ -1 +1 @@
1
- {"version":3,"file":"parse-geopackage.d.ts","sourceRoot":"","sources":["../../src/lib/parse-geopackage.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoC,MAAM,EAAE,YAAY,EAAU,MAAM,oBAAoB,CAAC;AAKpG,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,sBAAsB,CAAC;AAgBlE;;;GAGG;AACH,eAAO,MAAM,iBAAiB,eAEtB,CAAC;AAwCT,wBAAsB,eAAe,CACnC,WAAW,EAAE,WAAW,EACxB,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CA0C9C"}
1
+ {"version":3,"file":"parse-geopackage.d.ts","sourceRoot":"","sources":["../../src/lib/parse-geopackage.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoC,MAAM,EAAE,YAAY,EAAU,MAAM,oBAAoB,CAAC;AAKpG,OAAO,KAAK,EAAC,uBAAuB,EAAC,gCAA6B;AAgBlE;;;GAGG;AACH,eAAO,MAAM,iBAAiB,eAEtB,CAAC;AAwCT,wBAAsB,eAAe,CACnC,WAAW,EAAE,WAAW,EACxB,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CA0C9C"}
@@ -1,303 +1,404 @@
1
+ /* eslint-disable camelcase, @typescript-eslint/no-use-before-define */
1
2
  import { isBrowser } from '@loaders.gl/loader-utils';
2
3
  import { WKBLoader } from '@loaders.gl/wkt';
3
4
  import { binaryToGeometry, transformGeoJsonCoords } from '@loaders.gl/gis';
4
5
  import { Proj4Projection } from '@math.gl/proj4';
5
6
  import initSqlJs from 'sql.js';
6
7
  const SQL_JS_VERSION = '1.8.0';
7
- export const DEFAULT_SQLJS_CDN = isBrowser ? `https://cdnjs.cloudflare.com/ajax/libs/sql.js/${SQL_JS_VERSION}/` : null;
8
+ /**
9
+ * We pin to the same version as sql.js that we use.
10
+ * As of March 2022, versions 1.6.0, 1.6.1, and 1.6.2 of sql.js appeared not to work.
11
+ */
12
+ export const DEFAULT_SQLJS_CDN = isBrowser
13
+ ? `https://cdnjs.cloudflare.com/ajax/libs/sql.js/${SQL_JS_VERSION}/`
14
+ : null;
15
+ // https://www.geopackage.org/spec121/#flags_layout
8
16
  const ENVELOPE_BYTE_LENGTHS = {
9
- 0: 0,
10
- 1: 32,
11
- 2: 48,
12
- 3: 48,
13
- 4: 64,
14
- 5: 0,
15
- 6: 0,
16
- 7: 0
17
+ 0: 0,
18
+ 1: 32,
19
+ 2: 48,
20
+ 3: 48,
21
+ 4: 64,
22
+ // values 5-7 are invalid and _should_ never show up
23
+ 5: 0,
24
+ 6: 0,
25
+ 7: 0
17
26
  };
27
+ // Documentation: https://www.geopackage.org/spec130/index.html#table_column_data_types
18
28
  const SQL_TYPE_MAPPING = {
19
- BOOLEAN: 'bool',
20
- TINYINT: 'int8',
21
- SMALLINT: 'int16',
22
- MEDIUMINT: 'int32',
23
- INT: 'int32',
24
- INTEGER: 'int32',
25
- FLOAT: 'float32',
26
- DOUBLE: 'float64',
27
- REAL: 'float64',
28
- TEXT: 'utf8',
29
- BLOB: 'binary',
30
- DATE: 'utf8',
31
- DATETIME: 'utf8',
32
- GEOMETRY: 'binary',
33
- POINT: 'binary',
34
- LINESTRING: 'binary',
35
- POLYGON: 'binary',
36
- MULTIPOINT: 'binary',
37
- MULTILINESTRING: 'binary',
38
- MULTIPOLYGON: 'binary',
39
- GEOMETRYCOLLECTION: 'binary'
29
+ BOOLEAN: 'bool',
30
+ TINYINT: 'int8',
31
+ SMALLINT: 'int16',
32
+ MEDIUMINT: 'int32',
33
+ INT: 'int32',
34
+ INTEGER: 'int32',
35
+ FLOAT: 'float32',
36
+ DOUBLE: 'float64',
37
+ REAL: 'float64',
38
+ TEXT: 'utf8',
39
+ BLOB: 'binary',
40
+ DATE: 'utf8',
41
+ DATETIME: 'utf8',
42
+ GEOMETRY: 'binary',
43
+ POINT: 'binary',
44
+ LINESTRING: 'binary',
45
+ POLYGON: 'binary',
46
+ MULTIPOINT: 'binary',
47
+ MULTILINESTRING: 'binary',
48
+ MULTIPOLYGON: 'binary',
49
+ GEOMETRYCOLLECTION: 'binary'
40
50
  };
41
51
  export async function parseGeoPackage(arrayBuffer, options) {
42
- var _options$geopackage2;
43
- const {
44
- sqlJsCDN = DEFAULT_SQLJS_CDN
45
- } = (options === null || options === void 0 ? void 0 : options.geopackage) || {};
46
- const {
47
- reproject = false,
48
- _targetCrs = 'WGS84'
49
- } = (options === null || options === void 0 ? void 0 : options.gis) || {};
50
- const db = await loadDatabase(arrayBuffer, sqlJsCDN);
51
- const tables = listVectorTables(db);
52
- const projections = getProjections(db);
53
- const selectedTable = tables.find(table => {
54
- var _options$geopackage;
55
- return table.table_name === (options === null || options === void 0 ? void 0 : (_options$geopackage = options.geopackage) === null || _options$geopackage === void 0 ? void 0 : _options$geopackage.table);
56
- });
57
- const tableName = selectedTable ? selectedTable.table_name : tables[0].table_name;
58
- const shape = options === null || options === void 0 ? void 0 : (_options$geopackage2 = options.geopackage) === null || _options$geopackage2 === void 0 ? void 0 : _options$geopackage2.shape;
59
- switch (shape) {
60
- case 'geojson-table':
61
- return getVectorTable(db, tableName, projections, {
62
- reproject,
63
- _targetCrs
64
- });
65
- case 'tables':
66
- const outputTables = {
67
- shape: 'tables',
68
- tables: []
69
- };
70
- for (const table of tables) {
71
- const {
72
- table_name: tableName
73
- } = table;
74
- outputTables.tables.push({
75
- name: tableName,
76
- table: getVectorTable(db, tableName, projections, {
77
- reproject,
78
- _targetCrs
79
- })
80
- });
81
- }
82
- return outputTables;
83
- default:
84
- throw new Error(shape);
85
- }
52
+ const { sqlJsCDN = DEFAULT_SQLJS_CDN } = options?.geopackage || {};
53
+ const { reproject = false, _targetCrs = 'WGS84' } = options?.gis || {};
54
+ const db = await loadDatabase(arrayBuffer, sqlJsCDN);
55
+ const tables = listVectorTables(db);
56
+ const projections = getProjections(db);
57
+ const selectedTable = tables.find((table) => table.table_name === options?.geopackage?.table);
58
+ const tableName = selectedTable ? selectedTable.table_name : tables[0].table_name;
59
+ const shape = options?.geopackage?.shape;
60
+ switch (shape) {
61
+ case 'geojson-table':
62
+ return getVectorTable(db, tableName, projections, {
63
+ reproject,
64
+ _targetCrs
65
+ });
66
+ case 'tables':
67
+ // Mapping from tableName to geojson feature collection
68
+ const outputTables = {
69
+ shape: 'tables',
70
+ tables: []
71
+ };
72
+ for (const table of tables) {
73
+ const { table_name: tableName } = table;
74
+ outputTables.tables.push({
75
+ name: tableName,
76
+ table: getVectorTable(db, tableName, projections, {
77
+ reproject,
78
+ _targetCrs
79
+ })
80
+ });
81
+ }
82
+ return outputTables;
83
+ default:
84
+ throw new Error(shape);
85
+ }
86
86
  }
87
+ /**
88
+ * Initialize SQL.js and create database
89
+ *
90
+ * @param arrayBuffer input bytes
91
+ * @return SQL.js database object
92
+ */
87
93
  async function loadDatabase(arrayBuffer, sqlJsCDN) {
88
- let SQL;
89
- if (sqlJsCDN) {
90
- SQL = await initSqlJs({
91
- locateFile: file => `${sqlJsCDN}${file}`
92
- });
93
- } else {
94
- SQL = await initSqlJs();
95
- }
96
- return new SQL.Database(new Uint8Array(arrayBuffer));
94
+ // In Node, `locateFile` must not be passed
95
+ let SQL;
96
+ if (sqlJsCDN) {
97
+ SQL = await initSqlJs({
98
+ locateFile: (file) => `${sqlJsCDN}${file}`
99
+ });
100
+ }
101
+ else {
102
+ SQL = await initSqlJs();
103
+ }
104
+ return new SQL.Database(new Uint8Array(arrayBuffer));
97
105
  }
106
+ /**
107
+ * Find all vector tables in GeoPackage
108
+ * This queries the `gpkg_contents` table to find a list of vector tables
109
+ *
110
+ * @param db GeoPackage to query
111
+ * @return list of table references
112
+ */
98
113
  function listVectorTables(db) {
99
- const stmt = db.prepare("SELECT * FROM gpkg_contents WHERE data_type='features';");
100
- const vectorTablesInfo = [];
101
- while (stmt.step()) {
102
- const vectorTableInfo = stmt.getAsObject();
103
- vectorTablesInfo.push(vectorTableInfo);
104
- }
105
- return vectorTablesInfo;
114
+ // The gpkg_contents table can have at least three categorical values for
115
+ // data_type.
116
+ // - 'features' refers to a vector geometry table
117
+ // (https://www.geopackage.org/spec121/#_contents_2)
118
+ // - 'tiles' refers to a raster table
119
+ // (https://www.geopackage.org/spec121/#_contents_3)
120
+ // - 'attributes' refers to a data table with no geometry
121
+ // (https://www.geopackage.org/spec121/#_contents_4).
122
+ // We hard code 'features' because for now we don't support raster data or pure attribute data
123
+ // eslint-disable-next-line quotes
124
+ const stmt = db.prepare("SELECT * FROM gpkg_contents WHERE data_type='features';");
125
+ const vectorTablesInfo = [];
126
+ while (stmt.step()) {
127
+ const vectorTableInfo = stmt.getAsObject();
128
+ vectorTablesInfo.push(vectorTableInfo);
129
+ }
130
+ return vectorTablesInfo;
106
131
  }
107
- function getVectorTable(db, tableName, projections, _ref) {
108
- let {
109
- reproject,
110
- _targetCrs
111
- } = _ref;
112
- const dataColumns = getDataColumns(db, tableName);
113
- const geomColumn = getGeometryColumn(db, tableName);
114
- const featureIdColumn = getFeatureIdName(db, tableName);
115
- const {
116
- columns,
117
- values
118
- } = db.exec(`SELECT * FROM \`${tableName}\`;`)[0];
119
- let projection;
120
- if (reproject) {
121
- const geomColumnProjStr = projections[geomColumn.srs_id];
122
- projection = new Proj4Projection({
123
- from: geomColumnProjStr,
124
- to: _targetCrs
125
- });
126
- }
127
- const geojsonFeatures = [];
128
- for (const row of values) {
129
- const geojsonFeature = constructGeoJsonFeature(columns, row, geomColumn, dataColumns, featureIdColumn);
130
- geojsonFeatures.push(geojsonFeature);
131
- }
132
- const schema = getSchema(db, tableName);
133
- if (projection) {
132
+ /**
133
+ * Load geometries from vector table
134
+ *
135
+ * @param db GeoPackage object
136
+ * @param tableName name of vector table to query
137
+ * @param projections keys are srs_id values, values are WKT strings
138
+ * @returns Array of GeoJSON Feature objects
139
+ */
140
+ function getVectorTable(db, tableName, projections, { reproject, _targetCrs }) {
141
+ const dataColumns = getDataColumns(db, tableName);
142
+ const geomColumn = getGeometryColumn(db, tableName);
143
+ const featureIdColumn = getFeatureIdName(db, tableName);
144
+ // Get vector features from table
145
+ // Don't think it's possible to parameterize the table name in SQLite?
146
+ const { columns, values } = db.exec(`SELECT * FROM \`${tableName}\`;`)[0];
147
+ let projection;
148
+ if (reproject) {
149
+ const geomColumnProjStr = projections[geomColumn.srs_id];
150
+ projection = new Proj4Projection({
151
+ from: geomColumnProjStr,
152
+ to: _targetCrs
153
+ });
154
+ }
155
+ const geojsonFeatures = [];
156
+ for (const row of values) {
157
+ const geojsonFeature = constructGeoJsonFeature(columns, row, geomColumn,
158
+ // @ts-ignore
159
+ dataColumns, featureIdColumn);
160
+ geojsonFeatures.push(geojsonFeature);
161
+ }
162
+ const schema = getSchema(db, tableName);
163
+ if (projection) {
164
+ return {
165
+ shape: 'geojson-table',
166
+ type: 'FeatureCollection',
167
+ // @ts-expect-error TODO - null geometries causing problems...
168
+ features: transformGeoJsonCoords(geojsonFeatures, projection.project),
169
+ schema
170
+ };
171
+ }
134
172
  return {
135
- shape: 'geojson-table',
136
- type: 'FeatureCollection',
137
- features: transformGeoJsonCoords(geojsonFeatures, projection.project),
138
- schema
173
+ shape: 'geojson-table',
174
+ schema,
175
+ type: 'FeatureCollection',
176
+ // @ts-expect-error TODO - null features
177
+ features: geojsonFeatures
139
178
  };
140
- }
141
- return {
142
- shape: 'geojson-table',
143
- schema,
144
- type: 'FeatureCollection',
145
- features: geojsonFeatures
146
- };
147
179
  }
180
+ /**
181
+ * Find all projections defined in GeoPackage
182
+ * This queries the gpkg_spatial_ref_sys table
183
+ * @param db GeoPackage object
184
+ * @returns mapping from srid to WKT projection string
185
+ */
148
186
  function getProjections(db) {
149
- const stmt = db.prepare('SELECT * FROM gpkg_spatial_ref_sys;');
150
- const projectionMapping = {};
151
- while (stmt.step()) {
152
- const srsInfo = stmt.getAsObject();
153
- const {
154
- srs_id,
155
- definition
156
- } = srsInfo;
157
- projectionMapping[srs_id] = definition;
158
- }
159
- return projectionMapping;
187
+ // Query gpkg_spatial_ref_sys to get srid: srtext mappings
188
+ const stmt = db.prepare('SELECT * FROM gpkg_spatial_ref_sys;');
189
+ const projectionMapping = {};
190
+ while (stmt.step()) {
191
+ const srsInfo = stmt.getAsObject();
192
+ const { srs_id, definition } = srsInfo;
193
+ projectionMapping[srs_id] = definition;
194
+ }
195
+ return projectionMapping;
160
196
  }
197
+ /**
198
+ * Construct single GeoJSON feature given row's data
199
+ * @param columns array of ordered column identifiers
200
+ * @param row array of ordered values representing row's data
201
+ * @param geomColumn geometry column metadata
202
+ * @param dataColumns mapping from table column names to property name
203
+ * @returns GeoJSON Feature object
204
+ */
161
205
  function constructGeoJsonFeature(columns, row, geomColumn, dataColumns, featureIdColumn) {
162
- const idIdx = columns.indexOf(featureIdColumn);
163
- const id = row[idIdx];
164
- const geomColumnIdx = columns.indexOf(geomColumn.column_name);
165
- const geometry = parseGeometry(row[geomColumnIdx].buffer);
166
- const properties = {};
167
- if (dataColumns) {
168
- for (const [key, value] of Object.entries(dataColumns)) {
169
- const idx = columns.indexOf(key);
170
- properties[value] = row[idx];
206
+ // Find feature id
207
+ const idIdx = columns.indexOf(featureIdColumn);
208
+ const id = row[idIdx];
209
+ // Parse geometry columns to geojson
210
+ const geomColumnIdx = columns.indexOf(geomColumn.column_name);
211
+ const geometry = parseGeometry(row[geomColumnIdx].buffer);
212
+ const properties = {};
213
+ if (dataColumns) {
214
+ for (const [key, value] of Object.entries(dataColumns)) {
215
+ const idx = columns.indexOf(key);
216
+ // @ts-ignore TODO - Check what happens if null?
217
+ properties[value] = row[idx];
218
+ }
171
219
  }
172
- } else {
173
- for (let i = 0; i < columns.length; i++) {
174
- if (i === idIdx || i === geomColumnIdx) {
175
- continue;
176
- }
177
- const columnName = columns[i];
178
- properties[columnName] = row[i];
220
+ else {
221
+ // Put all columns except for the feature id and geometry in properties
222
+ for (let i = 0; i < columns.length; i++) {
223
+ if (i === idIdx || i === geomColumnIdx) {
224
+ // eslint-disable-next-line no-continue
225
+ continue;
226
+ }
227
+ const columnName = columns[i];
228
+ properties[columnName] = row[i];
229
+ }
179
230
  }
180
- }
181
- return {
182
- id,
183
- type: 'Feature',
184
- geometry,
185
- properties
186
- };
231
+ return {
232
+ id,
233
+ type: 'Feature',
234
+ geometry,
235
+ properties
236
+ };
187
237
  }
238
+ /**
239
+ * Get GeoPackage version from database
240
+ * @param db database
241
+ * @returns version string. One of '1.0', '1.1', '1.2'
242
+ */
243
+ // @ts-ignore
244
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
188
245
  function getGeopackageVersion(db) {
189
- const textDecoder = new TextDecoder();
190
- const applicationIdQuery = db.exec('PRAGMA application_id;')[0];
191
- const applicationId = applicationIdQuery.values[0][0];
192
- const buffer = new ArrayBuffer(4);
193
- const view = new DataView(buffer);
194
- view.setInt32(0, Number(applicationId));
195
- const versionString = textDecoder.decode(buffer);
196
- if (versionString === 'GP10') {
197
- return '1.0';
198
- }
199
- if (versionString === 'GP11') {
200
- return '1.1';
201
- }
202
- const userVersionQuery = db.exec('PRAGMA user_version;')[0];
203
- const userVersionInt = userVersionQuery.values[0][0];
204
- if (userVersionInt && typeof userVersionInt === 'number' && userVersionInt < 10300) {
205
- return '1.2';
206
- }
207
- return null;
246
+ const textDecoder = new TextDecoder();
247
+ // Read application id from SQLite metadata
248
+ const applicationIdQuery = db.exec('PRAGMA application_id;')[0];
249
+ const applicationId = applicationIdQuery.values[0][0];
250
+ // Convert 4-byte signed int32 application id to text
251
+ const buffer = new ArrayBuffer(4);
252
+ const view = new DataView(buffer);
253
+ view.setInt32(0, Number(applicationId));
254
+ const versionString = textDecoder.decode(buffer);
255
+ if (versionString === 'GP10') {
256
+ return '1.0';
257
+ }
258
+ if (versionString === 'GP11') {
259
+ return '1.1';
260
+ }
261
+ // If versionString is GPKG, then read user_version
262
+ const userVersionQuery = db.exec('PRAGMA user_version;')[0];
263
+ const userVersionInt = userVersionQuery.values[0][0];
264
+ if (userVersionInt && typeof userVersionInt === 'number' && userVersionInt < 10300) {
265
+ return '1.2';
266
+ }
267
+ return null;
208
268
  }
269
+ /**
270
+ * Find name of feature id column in table
271
+ * The feature ID is the primary key of the table.
272
+ * http://www.geopackage.org/spec121/#feature_user_tables
273
+ *
274
+ * @param db database
275
+ * @param tableName name of table
276
+ * @return name of feature id column
277
+ */
209
278
  function getFeatureIdName(db, tableName) {
210
- const stmt = db.prepare(`PRAGMA table_info(\`${tableName}\`)`);
211
- while (stmt.step()) {
212
- const pragmaTableInfo = stmt.getAsObject();
213
- const {
214
- name,
215
- pk
216
- } = pragmaTableInfo;
217
- if (pk) {
218
- return name;
279
+ // Again, not possible to parameterize table name?
280
+ const stmt = db.prepare(`PRAGMA table_info(\`${tableName}\`)`);
281
+ while (stmt.step()) {
282
+ const pragmaTableInfo = stmt.getAsObject();
283
+ const { name, pk } = pragmaTableInfo;
284
+ if (pk) {
285
+ return name;
286
+ }
219
287
  }
220
- }
221
- return null;
288
+ // Is it guaranteed for there always to be at least one primary key column in the table?
289
+ return null;
222
290
  }
291
+ /**
292
+ * Parse geometry buffer
293
+ * GeoPackage vector geometries are slightly extended past the WKB standard
294
+ * See: https://www.geopackage.org/spec121/#gpb_format
295
+ *
296
+ * @param arrayBuffer geometry buffer
297
+ * @return GeoJSON geometry (in original CRS)
298
+ */
223
299
  function parseGeometry(arrayBuffer) {
224
- var _WKBLoader$parseSync;
225
- const view = new DataView(arrayBuffer);
226
- const {
227
- envelopeLength,
228
- emptyGeometry
229
- } = parseGeometryBitFlags(view.getUint8(3));
230
- if (emptyGeometry) {
231
- return null;
232
- }
233
- const wkbOffset = 8 + envelopeLength;
234
- const binaryGeometry = (_WKBLoader$parseSync = WKBLoader.parseSync) === null || _WKBLoader$parseSync === void 0 ? void 0 : _WKBLoader$parseSync.call(WKBLoader, arrayBuffer.slice(wkbOffset));
235
- return binaryToGeometry(binaryGeometry);
300
+ const view = new DataView(arrayBuffer);
301
+ const { envelopeLength, emptyGeometry } = parseGeometryBitFlags(view.getUint8(3));
302
+ // A Feature object has a member with the name "geometry". The value of the
303
+ // geometry member SHALL be either a Geometry object as defined above or, in
304
+ // the case that the Feature is unlocated, a JSON null value.
305
+ /** @see https://tools.ietf.org/html/rfc7946#section-3.2 */
306
+ if (emptyGeometry) {
307
+ return null;
308
+ }
309
+ // Do I need to find the srid here? Is it necessarily the same for every
310
+ // geometry in a table?
311
+ // const srid = view.getInt32(4, littleEndian);
312
+ // 2 byte magic, 1 byte version, 1 byte flags, 4 byte int32 srid
313
+ const wkbOffset = 8 + envelopeLength;
314
+ // Loaders should not depend on `core` and the context passed to the main loader doesn't include a
315
+ // `parseSync` option, so instead we call parseSync directly on WKBLoader
316
+ const binaryGeometry = WKBLoader.parseSync?.(arrayBuffer.slice(wkbOffset));
317
+ // @ts-expect-error
318
+ return binaryToGeometry(binaryGeometry);
236
319
  }
320
+ /**
321
+ * Parse geometry header flags
322
+ * https://www.geopackage.org/spec121/#flags_layout
323
+ *
324
+ * @param byte uint8 number representing flags
325
+ * @return object representing information from bit flags
326
+ */
237
327
  function parseGeometryBitFlags(byte) {
238
- const envelopeValue = (byte & 0b00001110) / 2;
239
- const envelopeLength = ENVELOPE_BYTE_LENGTHS[envelopeValue];
240
- return {
241
- littleEndian: Boolean(byte & 0b00000001),
242
- envelopeLength,
243
- emptyGeometry: Boolean(byte & 0b00010000),
244
- extendedGeometryType: Boolean(byte & 0b00100000)
245
- };
328
+ // Are header values little endian?
329
+ const envelopeValue = (byte & 0b00001110) / 2;
330
+ // TODO: Not sure the best way to handle this. Throw an error if envelopeValue outside 0-7?
331
+ const envelopeLength = ENVELOPE_BYTE_LENGTHS[envelopeValue];
332
+ return {
333
+ littleEndian: Boolean(byte & 0b00000001),
334
+ envelopeLength,
335
+ emptyGeometry: Boolean(byte & 0b00010000),
336
+ extendedGeometryType: Boolean(byte & 0b00100000)
337
+ };
246
338
  }
339
+ /**
340
+ * Find geometry column in given vector table
341
+ *
342
+ * @param db GeoPackage object
343
+ * @param tableName Name of vector table
344
+ * @returns Array of geometry column definitions
345
+ */
247
346
  function getGeometryColumn(db, tableName) {
248
- const stmt = db.prepare('SELECT * FROM gpkg_geometry_columns WHERE table_name=:tableName;');
249
- stmt.bind({
250
- ':tableName': tableName
251
- });
252
- stmt.step();
253
- const geometryColumn = stmt.getAsObject();
254
- return geometryColumn;
347
+ const stmt = db.prepare('SELECT * FROM gpkg_geometry_columns WHERE table_name=:tableName;');
348
+ stmt.bind({ ':tableName': tableName });
349
+ // > Requirement 30
350
+ // > A feature table SHALL have only one geometry column.
351
+ // https://www.geopackage.org/spec121/#feature_user_tables
352
+ // So we should need one and only one step, given that we use the WHERE clause in the SQL query
353
+ // above
354
+ stmt.step();
355
+ const geometryColumn = stmt.getAsObject();
356
+ return geometryColumn;
255
357
  }
358
+ /**
359
+ * Find property columns in given vector table
360
+ * @param db GeoPackage object
361
+ * @param tableName Name of vector table
362
+ * @returns Mapping from table column names to property name
363
+ */
256
364
  function getDataColumns(db, tableName) {
257
- let stmt;
258
- try {
259
- stmt = db.prepare('SELECT * FROM gpkg_data_columns WHERE table_name=:tableName;');
260
- } catch (error) {
261
- if (error.message.includes('no such table')) {
262
- return null;
365
+ // gpkg_data_columns is not required to exist
366
+ // https://www.geopackage.org/spec121/#extension_schema
367
+ let stmt;
368
+ try {
369
+ stmt = db.prepare('SELECT * FROM gpkg_data_columns WHERE table_name=:tableName;');
370
+ }
371
+ catch (error) {
372
+ if (error.message.includes('no such table')) {
373
+ return null;
374
+ }
375
+ throw error;
263
376
  }
264
- throw error;
265
- }
266
- stmt.bind({
267
- ':tableName': tableName
268
- });
269
- const result = {};
270
- while (stmt.step()) {
271
- const column = stmt.getAsObject();
272
- const {
273
- column_name,
274
- name
275
- } = column;
276
- result[column_name] = name || null;
277
- }
278
- return result;
377
+ stmt.bind({ ':tableName': tableName });
378
+ // Convert DataColumnsRow object this to a key-value {column_name: name}
379
+ const result = {};
380
+ while (stmt.step()) {
381
+ const column = stmt.getAsObject();
382
+ const { column_name, name } = column;
383
+ result[column_name] = name || null;
384
+ }
385
+ return result;
279
386
  }
387
+ /**
388
+ * Get arrow schema
389
+ * @param db GeoPackage object
390
+ * @param tableName table name
391
+ * @returns Arrow-like Schema
392
+ */
280
393
  function getSchema(db, tableName) {
281
- const stmt = db.prepare(`PRAGMA table_info(\`${tableName}\`)`);
282
- const fields = [];
283
- while (stmt.step()) {
284
- const pragmaTableInfo = stmt.getAsObject();
285
- const {
286
- name,
287
- type: sqlType,
288
- notnull
289
- } = pragmaTableInfo;
290
- const type = SQL_TYPE_MAPPING[sqlType];
291
- const field = {
292
- name,
293
- type,
294
- nullable: !notnull
295
- };
296
- fields.push(field);
297
- }
298
- return {
299
- fields,
300
- metadata: {}
301
- };
394
+ const stmt = db.prepare(`PRAGMA table_info(\`${tableName}\`)`);
395
+ const fields = [];
396
+ while (stmt.step()) {
397
+ const pragmaTableInfo = stmt.getAsObject();
398
+ const { name, type: sqlType, notnull } = pragmaTableInfo;
399
+ const type = SQL_TYPE_MAPPING[sqlType];
400
+ const field = { name, type, nullable: !notnull };
401
+ fields.push(field);
402
+ }
403
+ return { fields, metadata: {} };
302
404
  }
303
- //# sourceMappingURL=parse-geopackage.js.map
package/dist/lib/types.js CHANGED
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=types.js.map
@@ -1,4 +1,6 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
1
4
  import { createLoaderWorker } from '@loaders.gl/loader-utils';
2
5
  import { GeoPackageLoader } from "../geopackage-loader.js";
3
6
  createLoaderWorker(GeoPackageLoader);
4
- //# sourceMappingURL=geopackage-worker.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@loaders.gl/geopackage",
3
3
  "description": "GeoPackage data loaders",
4
- "version": "4.2.0-alpha.4",
4
+ "version": "4.2.0-alpha.5",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "publishConfig": {
@@ -35,23 +35,25 @@
35
35
  "fs": false
36
36
  },
37
37
  "scripts_comments": [
38
- "build-bundle: ocular-bundle does not seem to respect --external and --define options"
38
+ "build-bundle: ocular-bundle does not seem to respect --external"
39
39
  ],
40
40
  "scripts": {
41
41
  "pre-build": "npm run build-worker && npm run build-worker --env.dev && npm run build-bundle && npm run build-bundle -- --env=dev",
42
- "build-bundle": "# ocular-bundle ./src/index.ts --external:{util,fs,path} --define:__VERSION__=\\\"$npm_package_version\\\"",
42
+ "build-bundle": "# ocular-bundle ./bundle.ts --output=dist/dist.min.js --external=util,fs,path",
43
43
  "build-worker": "# esbuild src/workers/geopackage-worker.ts --bundle --outfile=dist/geopackage-worker.js --external:{util,fs,path} --define:__VERSION__=\\\"$npm_package_version\\\""
44
44
  },
45
45
  "dependencies": {
46
- "@babel/runtime": "^7.3.1",
47
- "@loaders.gl/gis": "4.2.0-alpha.4",
48
- "@loaders.gl/schema": "4.2.0-alpha.4",
49
- "@loaders.gl/wkt": "4.2.0-alpha.4",
46
+ "@loaders.gl/gis": "4.2.0-alpha.5",
47
+ "@loaders.gl/schema": "4.2.0-alpha.5",
48
+ "@loaders.gl/wkt": "4.2.0-alpha.5",
50
49
  "@math.gl/proj4": "^4.0.0",
51
50
  "@types/sql.js": "^1.4.5",
52
51
  "fs": "^0.0.1-security",
53
52
  "path": "^0.12.7",
54
53
  "sql.js": "1.8.0"
55
54
  },
56
- "gitHead": "6c52dee5c3f005648a394cc4aee7fc37005c8e83"
55
+ "peerDependencies": {
56
+ "@loaders.gl/core": "^4.0.0"
57
+ },
58
+ "gitHead": "32d95a81971f104e4dfeb88ab57065f05321a76a"
57
59
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"geopackage-loader.js","names":["parseGeoPackage","DEFAULT_SQLJS_CDN","VERSION","GeoPackageLoader","id","name","module","version","extensions","mimeTypes","category","parse","options","geopackage","sqlJsCDN","shape","gis"],"sources":["../src/geopackage-loader.ts"],"sourcesContent":["// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {LoaderWithParser, LoaderOptions} from '@loaders.gl/loader-utils';\nimport {Tables, GeoJSONTable} from '@loaders.gl/schema';\nimport {parseGeoPackage, DEFAULT_SQLJS_CDN} from './lib/parse-geopackage';\n\n// __VERSION__ is injected by babel-plugin-version-inline\n// @ts-ignore TS2304: Cannot find name '__VERSION__'.\n// const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';\nconst VERSION = 'latest';\n\nexport type GeoPackageLoaderOptions = LoaderOptions & {\n /** Options for the geopackage loader */\n geopackage?: {\n /** Shape of returned data */\n shape?: 'geojson-table' | 'tables';\n /** Name of table to load (defaults to first table), unless shape==='tables' */\n table?: string;\n /** Use null in Node */\n sqlJsCDN?: string | null;\n };\n gis?: {\n reproject?: boolean;\n _targetCrs?: string;\n };\n};\n\nexport const GeoPackageLoader: LoaderWithParser<\n GeoJSONTable | Tables<GeoJSONTable>,\n never,\n GeoPackageLoaderOptions\n> = {\n id: 'geopackage',\n name: 'GeoPackage',\n module: 'geopackage',\n version: VERSION,\n extensions: ['gpkg'],\n mimeTypes: ['application/geopackage+sqlite3'],\n category: 'geometry',\n parse: parseGeoPackage,\n options: {\n geopackage: {\n sqlJsCDN: DEFAULT_SQLJS_CDN,\n shape: 'tables'\n },\n gis: {}\n }\n};\n\n/** Geopackage loader *\nexport const GeoPackageTableLoader: LoaderWithParser<Record<string, Feature[]>, never, GeoPackageLoaderOptions> = {\n id: 'geopackage',\n name: 'GeoPackage',\n module: 'geopackage',\n version: VERSION,\n extensions: ['gpkg'],\n mimeTypes: ['application/geopackage+sqlite3'],\n category: 'geometry',\n parse: parseGeoPackage,\n options: {\n geopackage: {\n sqlJsCDN: DEFAULT_SQLJS_CDN,\n },\n gis: {\n }\n }\n};\n*/\n"],"mappings":"SAMQA,eAAe,EAAEC,iBAAiB;AAK1C,MAAMC,OAAO,GAAG,QAAQ;AAkBxB,OAAO,MAAMC,gBAIZ,GAAG;EACFC,EAAE,EAAE,YAAY;EAChBC,IAAI,EAAE,YAAY;EAClBC,MAAM,EAAE,YAAY;EACpBC,OAAO,EAAEL,OAAO;EAChBM,UAAU,EAAE,CAAC,MAAM,CAAC;EACpBC,SAAS,EAAE,CAAC,gCAAgC,CAAC;EAC7CC,QAAQ,EAAE,UAAU;EACpBC,KAAK,EAAEX,eAAe;EACtBY,OAAO,EAAE;IACPC,UAAU,EAAE;MACVC,QAAQ,EAAEb,iBAAiB;MAC3Bc,KAAK,EAAE;IACT,CAAC;IACDC,GAAG,EAAE,CAAC;EACR;AACF,CAAC"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":["GeoPackageLoader"],"sources":["../src/index.ts"],"sourcesContent":["// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport {GeoPackageLoader} from './geopackage-loader';\n"],"mappings":"SAIQA,gBAAgB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"parse-geopackage.js","names":["isBrowser","WKBLoader","binaryToGeometry","transformGeoJsonCoords","Proj4Projection","initSqlJs","SQL_JS_VERSION","DEFAULT_SQLJS_CDN","ENVELOPE_BYTE_LENGTHS","SQL_TYPE_MAPPING","BOOLEAN","TINYINT","SMALLINT","MEDIUMINT","INT","INTEGER","FLOAT","DOUBLE","REAL","TEXT","BLOB","DATE","DATETIME","GEOMETRY","POINT","LINESTRING","POLYGON","MULTIPOINT","MULTILINESTRING","MULTIPOLYGON","GEOMETRYCOLLECTION","parseGeoPackage","arrayBuffer","options","_options$geopackage2","sqlJsCDN","geopackage","reproject","_targetCrs","gis","db","loadDatabase","tables","listVectorTables","projections","getProjections","selectedTable","find","table","_options$geopackage","table_name","tableName","shape","getVectorTable","outputTables","push","name","Error","SQL","locateFile","file","Database","Uint8Array","stmt","prepare","vectorTablesInfo","step","vectorTableInfo","getAsObject","_ref","dataColumns","getDataColumns","geomColumn","getGeometryColumn","featureIdColumn","getFeatureIdName","columns","values","exec","projection","geomColumnProjStr","srs_id","from","to","geojsonFeatures","row","geojsonFeature","constructGeoJsonFeature","schema","getSchema","type","features","project","projectionMapping","srsInfo","definition","idIdx","indexOf","id","geomColumnIdx","column_name","geometry","parseGeometry","buffer","properties","key","value","Object","entries","idx","i","length","columnName","getGeopackageVersion","textDecoder","TextDecoder","applicationIdQuery","applicationId","ArrayBuffer","view","DataView","setInt32","Number","versionString","decode","userVersionQuery","userVersionInt","pragmaTableInfo","pk","_WKBLoader$parseSync","envelopeLength","emptyGeometry","parseGeometryBitFlags","getUint8","wkbOffset","binaryGeometry","parseSync","call","slice","byte","envelopeValue","littleEndian","Boolean","extendedGeometryType","bind","geometryColumn","error","message","includes","result","column","fields","sqlType","notnull","field","nullable","metadata"],"sources":["../../src/lib/parse-geopackage.ts"],"sourcesContent":["/* eslint-disable camelcase, @typescript-eslint/no-use-before-define */\nimport {isBrowser} from '@loaders.gl/loader-utils';\nimport {WKBLoader} from '@loaders.gl/wkt';\nimport {Schema, Field, Geometry, DataType, Tables, GeoJSONTable, Feature} from '@loaders.gl/schema';\nimport {binaryToGeometry, transformGeoJsonCoords} from '@loaders.gl/gis';\nimport {Proj4Projection} from '@math.gl/proj4';\nimport initSqlJs, {SqlJsStatic, Database, Statement} from 'sql.js';\n\nimport type {GeoPackageLoaderOptions} from '../geopackage-loader';\nimport {\n GeometryColumnsRow,\n ContentsRow,\n SpatialRefSysRow,\n ProjectionMapping,\n GeometryBitFlags,\n DataColumnsRow,\n DataColumnsMapping,\n PragmaTableInfoRow,\n SQLiteTypes,\n GeoPackageGeometryTypes\n} from './types';\n\nconst SQL_JS_VERSION = '1.8.0';\n\n/**\n * We pin to the same version as sql.js that we use.\n * As of March 2022, versions 1.6.0, 1.6.1, and 1.6.2 of sql.js appeared not to work.\n */\nexport const DEFAULT_SQLJS_CDN = isBrowser\n ? `https://cdnjs.cloudflare.com/ajax/libs/sql.js/${SQL_JS_VERSION}/`\n : null;\n\n// https://www.geopackage.org/spec121/#flags_layout\nconst ENVELOPE_BYTE_LENGTHS = {\n 0: 0,\n 1: 32,\n 2: 48,\n 3: 48,\n 4: 64,\n // values 5-7 are invalid and _should_ never show up\n 5: 0,\n 6: 0,\n 7: 0\n};\n\n// Documentation: https://www.geopackage.org/spec130/index.html#table_column_data_types\nconst SQL_TYPE_MAPPING: Record<SQLiteTypes | GeoPackageGeometryTypes, DataType> = {\n BOOLEAN: 'bool',\n TINYINT: 'int8',\n SMALLINT: 'int16',\n MEDIUMINT: 'int32',\n INT: 'int32',\n INTEGER: 'int32',\n FLOAT: 'float32',\n DOUBLE: 'float64',\n REAL: 'float64',\n TEXT: 'utf8',\n BLOB: 'binary',\n DATE: 'utf8',\n DATETIME: 'utf8',\n GEOMETRY: 'binary',\n POINT: 'binary',\n LINESTRING: 'binary',\n POLYGON: 'binary',\n MULTIPOINT: 'binary',\n MULTILINESTRING: 'binary',\n MULTIPOLYGON: 'binary',\n GEOMETRYCOLLECTION: 'binary'\n};\n\nexport async function parseGeoPackage(\n arrayBuffer: ArrayBuffer,\n options?: GeoPackageLoaderOptions\n): Promise<GeoJSONTable | Tables<GeoJSONTable>> {\n const {sqlJsCDN = DEFAULT_SQLJS_CDN} = options?.geopackage || {};\n const {reproject = false, _targetCrs = 'WGS84'} = options?.gis || {};\n\n const db = await loadDatabase(arrayBuffer, sqlJsCDN);\n const tables = listVectorTables(db);\n const projections = getProjections(db);\n\n const selectedTable = tables.find((table) => table.table_name === options?.geopackage?.table);\n const tableName = selectedTable ? selectedTable.table_name : tables[0].table_name;\n\n const shape = options?.geopackage?.shape;\n switch (shape) {\n case 'geojson-table':\n return getVectorTable(db, tableName, projections, {\n reproject,\n _targetCrs\n });\n\n case 'tables':\n // Mapping from tableName to geojson feature collection\n const outputTables: Tables<GeoJSONTable> = {\n shape: 'tables',\n tables: []\n };\n\n for (const table of tables) {\n const {table_name: tableName} = table;\n outputTables.tables.push({\n name: tableName,\n table: getVectorTable(db, tableName, projections, {\n reproject,\n _targetCrs\n })\n });\n }\n\n return outputTables;\n\n default:\n throw new Error(shape);\n }\n}\n\n/**\n * Initialize SQL.js and create database\n *\n * @param arrayBuffer input bytes\n * @return SQL.js database object\n */\nasync function loadDatabase(arrayBuffer: ArrayBuffer, sqlJsCDN: string | null): Promise<Database> {\n // In Node, `locateFile` must not be passed\n let SQL: SqlJsStatic;\n if (sqlJsCDN) {\n SQL = await initSqlJs({\n locateFile: (file) => `${sqlJsCDN}${file}`\n });\n } else {\n SQL = await initSqlJs();\n }\n return new SQL.Database(new Uint8Array(arrayBuffer));\n}\n\n/**\n * Find all vector tables in GeoPackage\n * This queries the `gpkg_contents` table to find a list of vector tables\n *\n * @param db GeoPackage to query\n * @return list of table references\n */\nfunction listVectorTables(db: Database): ContentsRow[] {\n // The gpkg_contents table can have at least three categorical values for\n // data_type.\n // - 'features' refers to a vector geometry table\n // (https://www.geopackage.org/spec121/#_contents_2)\n // - 'tiles' refers to a raster table\n // (https://www.geopackage.org/spec121/#_contents_3)\n // - 'attributes' refers to a data table with no geometry\n // (https://www.geopackage.org/spec121/#_contents_4).\n\n // We hard code 'features' because for now we don't support raster data or pure attribute data\n // eslint-disable-next-line quotes\n const stmt = db.prepare(\"SELECT * FROM gpkg_contents WHERE data_type='features';\");\n\n const vectorTablesInfo: ContentsRow[] = [];\n while (stmt.step()) {\n const vectorTableInfo = stmt.getAsObject() as unknown as ContentsRow;\n vectorTablesInfo.push(vectorTableInfo);\n }\n\n return vectorTablesInfo;\n}\n\n/**\n * Load geometries from vector table\n *\n * @param db GeoPackage object\n * @param tableName name of vector table to query\n * @param projections keys are srs_id values, values are WKT strings\n * @returns Array of GeoJSON Feature objects\n */\nfunction getVectorTable(\n db: Database,\n tableName: string,\n projections: ProjectionMapping,\n {reproject, _targetCrs}: {reproject: boolean; _targetCrs: string}\n): GeoJSONTable {\n const dataColumns = getDataColumns(db, tableName);\n const geomColumn = getGeometryColumn(db, tableName);\n const featureIdColumn = getFeatureIdName(db, tableName);\n\n // Get vector features from table\n // Don't think it's possible to parameterize the table name in SQLite?\n const {columns, values} = db.exec(`SELECT * FROM \\`${tableName}\\`;`)[0];\n\n let projection;\n if (reproject) {\n const geomColumnProjStr = projections[geomColumn.srs_id];\n projection = new Proj4Projection({\n from: geomColumnProjStr,\n to: _targetCrs\n });\n }\n\n const geojsonFeatures: Feature<Geometry | null>[] = [];\n for (const row of values) {\n const geojsonFeature = constructGeoJsonFeature(\n columns,\n row,\n geomColumn,\n // @ts-ignore\n dataColumns,\n featureIdColumn\n );\n geojsonFeatures.push(geojsonFeature);\n }\n\n const schema = getSchema(db, tableName);\n if (projection) {\n return {\n shape: 'geojson-table',\n type: 'FeatureCollection',\n // @ts-expect-error TODO - null geometries causing problems...\n features: transformGeoJsonCoords(geojsonFeatures, projection.project),\n schema\n };\n }\n\n return {\n shape: 'geojson-table',\n schema,\n type: 'FeatureCollection',\n // @ts-expect-error TODO - null features\n features: geojsonFeatures\n };\n}\n\n/**\n * Find all projections defined in GeoPackage\n * This queries the gpkg_spatial_ref_sys table\n * @param db GeoPackage object\n * @returns mapping from srid to WKT projection string\n */\nfunction getProjections(db: Database): ProjectionMapping {\n // Query gpkg_spatial_ref_sys to get srid: srtext mappings\n const stmt = db.prepare('SELECT * FROM gpkg_spatial_ref_sys;');\n\n const projectionMapping: ProjectionMapping = {};\n while (stmt.step()) {\n const srsInfo = stmt.getAsObject() as unknown as SpatialRefSysRow;\n const {srs_id, definition} = srsInfo;\n projectionMapping[srs_id] = definition;\n }\n\n return projectionMapping;\n}\n\n/**\n * Construct single GeoJSON feature given row's data\n * @param columns array of ordered column identifiers\n * @param row array of ordered values representing row's data\n * @param geomColumn geometry column metadata\n * @param dataColumns mapping from table column names to property name\n * @returns GeoJSON Feature object\n */\nfunction constructGeoJsonFeature(\n columns: string[],\n row: any[],\n geomColumn: GeometryColumnsRow,\n dataColumns: DataColumnsMapping,\n featureIdColumn: string\n): Feature<Geometry | null> {\n // Find feature id\n const idIdx = columns.indexOf(featureIdColumn);\n const id = row[idIdx];\n\n // Parse geometry columns to geojson\n const geomColumnIdx = columns.indexOf(geomColumn.column_name);\n const geometry = parseGeometry(row[geomColumnIdx].buffer);\n\n const properties = {};\n if (dataColumns) {\n for (const [key, value] of Object.entries(dataColumns)) {\n const idx = columns.indexOf(key);\n // @ts-ignore TODO - Check what happens if null?\n properties[value] = row[idx];\n }\n } else {\n // Put all columns except for the feature id and geometry in properties\n for (let i = 0; i < columns.length; i++) {\n if (i === idIdx || i === geomColumnIdx) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const columnName = columns[i];\n properties[columnName] = row[i];\n }\n }\n\n return {\n id,\n type: 'Feature',\n geometry,\n properties\n };\n}\n\n/**\n * Get GeoPackage version from database\n * @param db database\n * @returns version string. One of '1.0', '1.1', '1.2'\n */\n\n// @ts-ignore\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction getGeopackageVersion(db: Database): string | null {\n const textDecoder = new TextDecoder();\n\n // Read application id from SQLite metadata\n const applicationIdQuery = db.exec('PRAGMA application_id;')[0];\n const applicationId = applicationIdQuery.values[0][0];\n\n // Convert 4-byte signed int32 application id to text\n const buffer = new ArrayBuffer(4);\n const view = new DataView(buffer);\n view.setInt32(0, Number(applicationId));\n const versionString = textDecoder.decode(buffer);\n\n if (versionString === 'GP10') {\n return '1.0';\n }\n\n if (versionString === 'GP11') {\n return '1.1';\n }\n\n // If versionString is GPKG, then read user_version\n const userVersionQuery = db.exec('PRAGMA user_version;')[0];\n const userVersionInt = userVersionQuery.values[0][0];\n\n if (userVersionInt && typeof userVersionInt === 'number' && userVersionInt < 10300) {\n return '1.2';\n }\n\n return null;\n}\n\n/**\n * Find name of feature id column in table\n * The feature ID is the primary key of the table.\n * http://www.geopackage.org/spec121/#feature_user_tables\n *\n * @param db database\n * @param tableName name of table\n * @return name of feature id column\n */\nfunction getFeatureIdName(db: Database, tableName: string): string | null {\n // Again, not possible to parameterize table name?\n const stmt = db.prepare(`PRAGMA table_info(\\`${tableName}\\`)`);\n\n while (stmt.step()) {\n const pragmaTableInfo = stmt.getAsObject() as unknown as PragmaTableInfoRow;\n const {name, pk} = pragmaTableInfo;\n if (pk) {\n return name;\n }\n }\n\n // Is it guaranteed for there always to be at least one primary key column in the table?\n return null;\n}\n\n/**\n * Parse geometry buffer\n * GeoPackage vector geometries are slightly extended past the WKB standard\n * See: https://www.geopackage.org/spec121/#gpb_format\n *\n * @param arrayBuffer geometry buffer\n * @return GeoJSON geometry (in original CRS)\n */\nfunction parseGeometry(arrayBuffer: ArrayBuffer): Geometry | null {\n const view = new DataView(arrayBuffer);\n const {envelopeLength, emptyGeometry} = parseGeometryBitFlags(view.getUint8(3));\n\n // A Feature object has a member with the name \"geometry\". The value of the\n // geometry member SHALL be either a Geometry object as defined above or, in\n // the case that the Feature is unlocated, a JSON null value.\n /** @see https://tools.ietf.org/html/rfc7946#section-3.2 */\n if (emptyGeometry) {\n return null;\n }\n\n // Do I need to find the srid here? Is it necessarily the same for every\n // geometry in a table?\n // const srid = view.getInt32(4, littleEndian);\n\n // 2 byte magic, 1 byte version, 1 byte flags, 4 byte int32 srid\n const wkbOffset = 8 + envelopeLength;\n\n // Loaders should not depend on `core` and the context passed to the main loader doesn't include a\n // `parseSync` option, so instead we call parseSync directly on WKBLoader\n const binaryGeometry = WKBLoader.parseSync?.(arrayBuffer.slice(wkbOffset));\n\n // @ts-expect-error\n return binaryToGeometry(binaryGeometry);\n}\n\n/**\n * Parse geometry header flags\n * https://www.geopackage.org/spec121/#flags_layout\n *\n * @param byte uint8 number representing flags\n * @return object representing information from bit flags\n */\nfunction parseGeometryBitFlags(byte: number): GeometryBitFlags {\n // Are header values little endian?\n const envelopeValue = (byte & 0b00001110) / 2;\n\n // TODO: Not sure the best way to handle this. Throw an error if envelopeValue outside 0-7?\n const envelopeLength = ENVELOPE_BYTE_LENGTHS[envelopeValue] as number;\n\n return {\n littleEndian: Boolean(byte & 0b00000001),\n envelopeLength,\n emptyGeometry: Boolean(byte & 0b00010000),\n extendedGeometryType: Boolean(byte & 0b00100000)\n };\n}\n\n/**\n * Find geometry column in given vector table\n *\n * @param db GeoPackage object\n * @param tableName Name of vector table\n * @returns Array of geometry column definitions\n */\nfunction getGeometryColumn(db: Database, tableName: string): GeometryColumnsRow {\n const stmt = db.prepare('SELECT * FROM gpkg_geometry_columns WHERE table_name=:tableName;');\n stmt.bind({':tableName': tableName});\n\n // > Requirement 30\n // > A feature table SHALL have only one geometry column.\n // https://www.geopackage.org/spec121/#feature_user_tables\n // So we should need one and only one step, given that we use the WHERE clause in the SQL query\n // above\n stmt.step();\n const geometryColumn = stmt.getAsObject() as unknown as GeometryColumnsRow;\n return geometryColumn;\n}\n\n/**\n * Find property columns in given vector table\n * @param db GeoPackage object\n * @param tableName Name of vector table\n * @returns Mapping from table column names to property name\n */\nfunction getDataColumns(db: Database, tableName: string): DataColumnsMapping | null {\n // gpkg_data_columns is not required to exist\n // https://www.geopackage.org/spec121/#extension_schema\n let stmt: Statement;\n try {\n stmt = db.prepare('SELECT * FROM gpkg_data_columns WHERE table_name=:tableName;');\n } catch (error) {\n if ((error as Error).message.includes('no such table')) {\n return null;\n }\n\n throw error;\n }\n\n stmt.bind({':tableName': tableName});\n\n // Convert DataColumnsRow object this to a key-value {column_name: name}\n const result: DataColumnsMapping = {};\n while (stmt.step()) {\n const column = stmt.getAsObject() as unknown as DataColumnsRow;\n const {column_name, name} = column;\n result[column_name] = name || null;\n }\n\n return result;\n}\n\n/**\n * Get arrow schema\n * @param db GeoPackage object\n * @param tableName table name\n * @returns Arrow-like Schema\n */\nfunction getSchema(db: Database, tableName: string): Schema {\n const stmt = db.prepare(`PRAGMA table_info(\\`${tableName}\\`)`);\n\n const fields: Field[] = [];\n while (stmt.step()) {\n const pragmaTableInfo = stmt.getAsObject() as unknown as PragmaTableInfoRow;\n const {name, type: sqlType, notnull} = pragmaTableInfo;\n const type = SQL_TYPE_MAPPING[sqlType];\n const field = {name, type, nullable: !notnull};\n fields.push(field);\n }\n\n return {fields, metadata: {}};\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../src/lib/types.ts"],"sourcesContent":["/* eslint-disable camelcase */\nexport interface GeometryBitFlags {\n littleEndian: boolean;\n envelopeLength: number;\n emptyGeometry: boolean;\n extendedGeometryType: boolean;\n}\n\nexport type ProjectionMapping = {[srsId: number]: string};\nexport type DataColumnsMapping = {[columnName: string]: string | null};\nexport type SQLiteTypes =\n | 'BOOLEAN'\n | 'TINYINT'\n | 'SMALLINT'\n | 'MEDIUMINT'\n | 'INT'\n | 'INTEGER'\n | 'FLOAT'\n | 'DOUBLE'\n | 'REAL'\n | 'TEXT'\n | 'BLOB'\n | 'DATE'\n | 'DATETIME';\n\n/** Type names for geopackage geometries\n *\n * As defined in https://www.geopackage.org/spec130/index.html#table_column_data_types, geometries\n * can be stored with any geometry name listed here:\n * https://www.geopackage.org/spec130/index.html#geometry_types\n */\nexport type GeoPackageGeometryTypes =\n | 'GEOMETRY'\n | 'POINT'\n | 'LINESTRING'\n | 'POLYGON'\n | 'MULTIPOINT'\n | 'MULTILINESTRING'\n | 'MULTIPOLYGON'\n | 'GEOMETRYCOLLECTION';\n\n/**\n * https://www.geopackage.org/spec121/#spatial_ref_sys\n */\nexport interface SpatialRefSysRow {\n /**\n * Human readable name of this SRS\n */\n srs_name: string;\n\n /**\n * Unique identifier for each Spatial Reference System within a GeoPackage\n */\n srs_id: number;\n\n /**\n * Case-insensitive name of the defining organization e.g. EPSG or epsg\n */\n organization: string;\n\n /**\n * Numeric ID of the Spatial Reference System assigned by the organization\n */\n organization_coordsys_id: number;\n\n /**\n * Well-known Text [A32] Representation of the Spatial Reference System\n */\n definition: string;\n\n /**\n * Human readable description of this SRS\n */\n description?: string;\n}\n\n/**\n * https://www.geopackage.org/spec121/#_contents\n */\nexport interface ContentsRow {\n /**\n * The name of the actual content (e.g., tiles, features, or attributes) table\n */\n table_name: string;\n\n /**\n * Type of data stored in the table\n */\n data_type: 'features' | 'attributes' | 'tiles';\n\n /**\n * A human-readable identifier (e.g. short name) for the table_name content\n */\n identifier?: string;\n\n /**\n * A human-readable description for the table_name content\n */\n description?: string;\n\n /**\n * timestamp of last change to content, in ISO 8601 format\n */\n last_change: string;\n\n /**\n * Bounding box minimum easting or longitude for all content in table_name. If tiles, this is informational and the tile matrix set should be used for calculating tile coordinates.\n */\n min_x?: number;\n\n /**\n * Bounding box minimum northing or latitude for all content in table_name. If tiles, this is informational and the tile matrix set should be used for calculating tile coordinates.\n */\n min_y?: number;\n /**\n * Bounding box maximum easting or longitude for all content in table_name. If tiles, this is informational and the tile matrix set should be used for calculating tile coordinates.\n */\n max_x?: number;\n\n /**\n * Bounding box maximum northing or latitude for all content in table_name. If tiles, this is informational and the tile matrix set should be used for calculating tile coordinates.\n */\n max_y?: number;\n\n /**\n * Spatial Reference System ID: gpkg_spatial_ref_sys.srs_id; when data_type is features, SHALL also match gpkg_geometry_columns.srs_id; When data_type is tiles, SHALL also match gpkg_tile_matrix_set.srs_id\n */\n srs_id?: number;\n}\n\n// https://www.geopackage.org/spec121/#geometry_types_extension\ntype GeometryType =\n | 'GEOMETRY'\n | 'POINT'\n | 'LINESTRING'\n | 'POLYGON'\n | 'MULTIPOINT'\n | 'MULTILINESTRING'\n | 'MULTIPOLYGON'\n | 'GEOMETRYCOLLECTION'\n | 'CIRCULARSTRING'\n | 'COMPOUNDCURVE'\n | 'CURVEPOLYGON'\n | 'MULTICURVE'\n | 'MULTISURFACE'\n | 'CURVE'\n | 'SURFACE';\n\n/**\n * https://www.geopackage.org/spec121/#_geometry_columns\n */\nexport interface GeometryColumnsRow {\n /**\n * Name of the table containing the geometry column\n */\n table_name: string;\n\n /**\n * Name of a column in the feature table that is a Geometry Column\n */\n column_name: string;\n\n /**\n * Name from Geometry Type Codes (Core) or Geometry Type Codes (Extension) in Geometry Types (Normative)\n */\n geometry_type_name: GeometryType;\n\n /**\n * Spatial Reference System ID: gpkg_spatial_ref_sys.srs_id\n */\n srs_id: number;\n\n /**\n * 0: z values prohibited; 1: z values mandatory; 2: z values optional\n */\n z: 0 | 1 | 2;\n\n /**\n * 0: m values prohibited; 1: m values mandatory; 2: m values optional\n */\n m: 0 | 1 | 2;\n}\n\n/**\n * https://www.geopackage.org/spec121/#extensions_table_definition\n */\nexport interface ExtensionsRow {\n /**\n * Name of the table that requires the extension. When NULL, the extension is required for the entire GeoPackage. SHALL NOT be NULL when the column_name is not NULL.\n */\n table_name?: string;\n\n /**\n * Name of the column that requires the extension. When NULL, the extension is required for the entire table.\n */\n column_name?: string;\n\n /**\n * The case sensitive name of the extension that is required, in the form <author>_<extension_name>.\n */\n extension_name: string;\n\n /**\n * Permalink, URI, or reference to a document that defines the extension\n */\n definition: string;\n\n /**\n * Indicates scope of extension effects on readers / writers: 'read-write' or 'write-only' in lowercase.\n */\n scope: string;\n}\n\n/**\n * https://www.geopackage.org/spec121/#gpkg_data_columns_cols\n */\nexport interface DataColumnsRow {\n /**\n * Name of the tiles or feature table\n */\n table_name: string;\n\n /**\n * Name of the table column\n */\n column_name: string;\n\n /**\n * A human-readable identifier (e.g. short name) for the column_name content\n */\n name?: string;\n\n /**\n * A human-readable formal title for the column_name content\n */\n title?: string;\n\n /**\n * A human-readable description for the column_name content\n */\n description?: string;\n\n /**\n * MIME [A21] type of column_name if BLOB type, or NULL for other types\n */\n mime_type?: string;\n\n /**\n * Column value constraint name (lowercase) specified by reference to gpkg_data_column_constraints.constraint name\n */\n constraint_name?: string;\n}\n\n/**\n * Type for PRAGMA table_info(tableName);\n */\nexport interface PragmaTableInfoRow {\n cid: number;\n name: string;\n type: SQLiteTypes;\n notnull: 0 | 1;\n dflt_value: any;\n pk: 0 | 1;\n}\n"],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"geopackage-worker.js","names":["createLoaderWorker","GeoPackageLoader"],"sources":["../../src/workers/geopackage-worker.ts"],"sourcesContent":["// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {createLoaderWorker} from '@loaders.gl/loader-utils';\nimport {GeoPackageLoader} from '../geopackage-loader';\n\ncreateLoaderWorker(GeoPackageLoader);\n"],"mappings":"AAIA,SAAQA,kBAAkB,QAAO,0BAA0B;AAAC,SACpDC,gBAAgB;AAExBD,kBAAkB,CAACC,gBAAgB,CAAC"}