@ngageoint/geopackage
Version:
GeoPackage JavaScript Library
2,270 lines • 112 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GeoPackage = void 0;
var wkx_1 = __importDefault(require("wkx"));
// @ts-ignore
var reproject_1 = __importDefault(require("reproject"));
var point_to_line_distance_1 = __importDefault(require("@turf/point-to-line-distance"));
var polygon_to_line_1 = __importDefault(require("@turf/polygon-to-line"));
var boolean_point_in_polygon_1 = __importDefault(require("@turf/boolean-point-in-polygon"));
// @ts-ignore
var distance_1 = __importDefault(require("@turf/distance"));
var helpers = __importStar(require("@turf/helpers"));
var proj4_1 = __importDefault(require("proj4"));
var geometryData_1 = require("./geom/geometryData");
var crsWkt_1 = require("./extension/crsWkt");
var relatedTables_1 = require("./extension/relatedTables");
var style_1 = require("./extension/style");
var contents_1 = require("./extension/contents");
var scale_1 = require("./extension/scale");
var spatialReferenceSystemDao_1 = require("./core/srs/spatialReferenceSystemDao");
var geometryColumnsDao_1 = require("./features/columns/geometryColumnsDao");
var featureDao_1 = require("./features/user/featureDao");
var featureTableReader_1 = require("./features/user/featureTableReader");
var contentsDao_1 = require("./core/contents/contentsDao");
var tileMatrixSetDao_1 = require("./tiles/matrixset/tileMatrixSetDao");
var tileMatrixDao_1 = require("./tiles/matrix/tileMatrixDao");
var dataColumnsDao_1 = require("./dataColumns/dataColumnsDao");
var dataColumnConstraintsDao_1 = require("./dataColumnConstraints/dataColumnConstraintsDao");
var metadataDao_1 = require("./metadata/metadataDao");
var metadataReferenceDao_1 = require("./metadata/reference/metadataReferenceDao");
var extensionDao_1 = require("./extension/extensionDao");
var tableIndexDao_1 = require("./extension/index/tableIndexDao");
var geometryIndexDao_1 = require("./extension/index/geometryIndexDao");
var extendedRelationDao_1 = require("./extension/relatedTables/extendedRelationDao");
var attributesDao_1 = require("./attributes/attributesDao");
var tileDao_1 = require("./tiles/user/tileDao");
var contentsIdDao_1 = require("./extension/contents/contentsIdDao");
var tileScalingDao_1 = require("./extension/scale/tileScalingDao");
var attributesTable_1 = require("./attributes/attributesTable");
var tileTableReader_1 = require("./tiles/user/tileTableReader");
var attributesTableReader_1 = require("./attributes/attributesTableReader");
var featureTable_1 = require("./features/user/featureTable");
var styleMappingTable_1 = require("./extension/style/styleMappingTable");
var tileTable_1 = require("./tiles/user/tileTable");
var contents_2 = require("./core/contents/contents");
var geoPackageDataType_1 = require("./db/geoPackageDataType");
var schema_1 = require("./extension/schema");
var geometryColumns_1 = require("./features/columns/geometryColumns");
var tableCreator_1 = require("./db/tableCreator");
var tileMatrix_1 = require("./tiles/matrix/tileMatrix");
var tileBoundingBoxUtils_1 = require("./tiles/tileBoundingBoxUtils");
var boundingBox_1 = require("./boundingBox");
var tileMatrixSet_1 = require("./tiles/matrixset/tileMatrixSet");
var userColumn_1 = require("./user/userColumn");
var dataColumns_1 = require("./dataColumns/dataColumns");
var geoPackageValidate_1 = require("./validate/geoPackageValidate");
var featureColumn_1 = require("./features/user/featureColumn");
var mediaTable_1 = require("./extension/relatedTables/mediaTable");
var relationType_1 = require("./extension/relatedTables/relationType");
var simpleAttributesTable_1 = require("./extension/relatedTables/simpleAttributesTable");
var features_1 = require("./tiles/features");
var retriever_1 = require("./tiles/retriever");
var tileScaling_1 = require("./extension/scale/tileScaling");
var tileScalingType_1 = require("./extension/scale/tileScalingType");
var attributesColumn_1 = require("./attributes/attributesColumn");
var alterTable_1 = require("./db/alterTable");
var geoPackageExtensions_1 = require("./extension/geoPackageExtensions");
var contentsDataType_1 = require("./core/contents/contentsDataType");
var geometryType_1 = require("./features/user/geometryType");
var constraints_1 = require("./db/table/constraints");
var projection_1 = require("./projection/projection");
var projectionConstants_1 = require("./projection/projectionConstants");
var sqliteQueryBuilder_1 = require("./db/sqliteQueryBuilder");
/**
* A `GeoPackage` instance is the interface to a physical GeoPackage SQLite
* database.
*/
var GeoPackage = /** @class */ (function () {
/**
* Construct a new GeoPackage object
* @param name name to give to this GeoPackage
* @param path path to the GeoPackage
* @param connection database connection to the GeoPackage
*/
function GeoPackage(name, path, connection) {
this.name = name;
this.path = path;
this.connection = connection;
this.tableCreator = new tableCreator_1.TableCreator(this);
this.loadSpatialReferenceSystemsIntoProj4();
}
GeoPackage.prototype.close = function () {
this.connection.close();
};
Object.defineProperty(GeoPackage.prototype, "database", {
get: function () {
return this.connection;
},
enumerable: false,
configurable: true
});
GeoPackage.prototype.export = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, this.connection.export()];
});
});
};
GeoPackage.prototype.loadSpatialReferenceSystemsIntoProj4 = function () {
this.spatialReferenceSystemDao.getAllSpatialReferenceSystems().forEach(function (spatialReferenceSystem) {
try {
if (spatialReferenceSystem.srs_id > 0 && (spatialReferenceSystem.organization !== projectionConstants_1.ProjectionConstants.EPSG ||
(spatialReferenceSystem.organization_coordsys_id !== projectionConstants_1.ProjectionConstants.EPSG_CODE_4326 &&
spatialReferenceSystem.organization_coordsys_id !== projectionConstants_1.ProjectionConstants.EPSG_CODE_3857)))
projection_1.Projection.loadProjection([spatialReferenceSystem.organization, spatialReferenceSystem.organization_coordsys_id].join(':'), spatialReferenceSystem.definition);
}
catch (e) { }
});
};
GeoPackage.prototype.validate = function () {
var errors = [];
errors = errors.concat(geoPackageValidate_1.GeoPackageValidate.validateMinimumTables(this));
return errors;
};
Object.defineProperty(GeoPackage.prototype, "spatialReferenceSystemDao", {
/**
* @returns {module:core/srs~SpatialReferenceSystemDao} the DAO to access the [SRS table]{@link module:core/srs~SpatialReferenceSystem} in this `GeoPackage`
*/
get: function () {
return this._spatialReferenceSystemDao || (this._spatialReferenceSystemDao = new spatialReferenceSystemDao_1.SpatialReferenceSystemDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "contentsDao", {
/**
* @returns {module:core/contents~ContentsDao} the DAO to access the [contents table]{@link module:core/contents~Contents} in this `GeoPackage`
*/
get: function () {
return this._contentsDao || (this._contentsDao = new contentsDao_1.ContentsDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "tileMatrixSetDao", {
/**
* @returns {module:tiles/matrixset~TileMatrixSetDao} the DAO to access the [tile matrix set]{@link module:tiles/matrixset~TileMatrixSet} in this `GeoPackage`
*/
get: function () {
return this._tileMatrixSetDao || (this._tileMatrixSetDao = new tileMatrixSetDao_1.TileMatrixSetDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "tileMatrixDao", {
/**
* @returns {module:tiles/matrixset~TileMatrixDao} the DAO to access the [tile matrix]{@link module:tiles/matrixset~TileMatrix} in this `GeoPackage`
*/
get: function () {
return this._tileMatrixDao || (this._tileMatrixDao = new tileMatrixDao_1.TileMatrixDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "dataColumnsDao", {
get: function () {
return this._dataColumnsDao || (this._dataColumnsDao = new dataColumnsDao_1.DataColumnsDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "extensionDao", {
get: function () {
return this._extensionDao || (this._extensionDao = new extensionDao_1.ExtensionDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "tableIndexDao", {
get: function () {
return this._tableIndexDao || (this._tableIndexDao = new tableIndexDao_1.TableIndexDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "geometryColumnsDao", {
get: function () {
return this._geometryColumnsDao || (this._geometryColumnsDao = new geometryColumnsDao_1.GeometryColumnsDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "dataColumnConstraintsDao", {
get: function () {
return this._dataColumnConstraintsDao || (this._dataColumnConstraintsDao = new dataColumnConstraintsDao_1.DataColumnConstraintsDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "metadataReferenceDao", {
get: function () {
return this._metadataReferenceDao || (this._metadataReferenceDao = new metadataReferenceDao_1.MetadataReferenceDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "metadataDao", {
get: function () {
return this._metadataDao || (this._metadataDao = new metadataDao_1.MetadataDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "extendedRelationDao", {
get: function () {
return this._extendedRelationDao || (this._extendedRelationDao = new extendedRelationDao_1.ExtendedRelationDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "contentsIdDao", {
get: function () {
return this._contentsIdDao || (this._contentsIdDao = new contentsIdDao_1.ContentsIdDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "tileScalingDao", {
get: function () {
return this._tileScalingDao || (this._tileScalingDao = new tileScalingDao_1.TileScalingDao(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "contentsIdExtension", {
get: function () {
return this._contentsIdExtension || (this._contentsIdExtension = new contents_1.ContentsIdExtension(this));
},
enumerable: false,
configurable: true
});
Object.defineProperty(GeoPackage.prototype, "featureStyleExtension", {
get: function () {
return this._featureStyleExtension || (this._featureStyleExtension = new style_1.FeatureStyleExtension(this));
},
enumerable: false,
configurable: true
});
GeoPackage.prototype.getTileScalingExtension = function (tableName) {
return new scale_1.TileScalingExtension(this, tableName);
};
GeoPackage.prototype.getGeometryIndexDao = function (featureDao) {
return new geometryIndexDao_1.GeometryIndexDao(this, featureDao);
};
Object.defineProperty(GeoPackage.prototype, "relatedTablesExtension", {
get: function () {
return this._relatedTablesExtension || (this._relatedTablesExtension = new relatedTables_1.RelatedTablesExtension(this));
},
enumerable: false,
configurable: true
});
GeoPackage.prototype.getSrs = function (srsId) {
var dao = this.spatialReferenceSystemDao;
return dao.queryForId(srsId);
};
GeoPackage.prototype.createRequiredTables = function () {
this.tableCreator.createRequired();
return this;
};
GeoPackage.prototype.createSupportedExtensions = function () {
var crs = new crsWkt_1.CrsWktExtension(this);
crs.getOrCreateExtension();
var schema = new schema_1.SchemaExtension(this);
schema.getOrCreateExtension();
return this;
};
/**
* Get a Tile DAO
* @param table
* @returns {TileDao}
*/
GeoPackage.prototype.getTileDao = function (table) {
if (table instanceof contents_2.Contents) {
table = this.contentsDao.getTileMatrixSet(table);
}
else if (!(table instanceof tileMatrixSet_1.TileMatrixSet)) {
var tms = this.tileMatrixSetDao;
var results_1 = tms.queryForAllEq(tileMatrixSetDao_1.TileMatrixSetDao.COLUMN_TABLE_NAME, table);
if (results_1.length > 1) {
throw new Error('Unexpected state. More than one Tile Matrix Set matched for table name: ' +
table +
', count: ' +
results_1.length);
}
else if (results_1.length === 0) {
throw new Error('No Tile Matrix found for table name: ' + table);
}
table = tms.createObject(results_1[0]);
}
if (!table) {
throw new Error('Non null TileMatrixSet is required to create Tile DAO');
}
var tileMatrices = [];
var tileMatrixDao = this.tileMatrixDao;
var results = tileMatrixDao.queryForAllEq(tileMatrixDao_1.TileMatrixDao.COLUMN_TABLE_NAME, table.table_name, null, null, tileMatrixDao_1.TileMatrixDao.COLUMN_ZOOM_LEVEL +
' ASC, ' +
tileMatrixDao_1.TileMatrixDao.COLUMN_PIXEL_X_SIZE +
' DESC, ' +
tileMatrixDao_1.TileMatrixDao.COLUMN_PIXEL_Y_SIZE +
' DESC');
results.forEach(function (result) {
var tm = tileMatrixDao.createObject(result);
// verify first that there are actual tiles at this zoom level due to QGIS doing weird things and
// creating tile matrix entries for zoom levels that have no tiles
if (tileMatrixDao.hasTiles(tm)) {
tileMatrices.push(tm);
}
});
var tableReader = new tileTableReader_1.TileTableReader(table);
var tileTable = tableReader.readTileTable(this);
return new tileDao_1.TileDao(this, tileTable, table, tileMatrices);
};
GeoPackage.prototype.getTables = function (fullInformation) {
if (fullInformation === void 0) { fullInformation = false; }
if (!fullInformation) {
var tables = {
features: this.getFeatureTables(),
tiles: this.getTileTables(),
attributes: this.getAttributesTables(),
};
return tables;
}
else {
var tables = {
features: this.contentsDao.getContentsForTableType(contentsDataType_1.ContentsDataType.FEATURES),
tiles: this.contentsDao.getContentsForTableType(contentsDataType_1.ContentsDataType.TILES),
attributes: this.contentsDao.getContentsForTableType(contentsDataType_1.ContentsDataType.ATTRIBUTES),
};
return tables;
}
};
GeoPackage.prototype.getAttributesTables = function () {
return this.contentsDao.getTables(contentsDataType_1.ContentsDataType.ATTRIBUTES);
};
GeoPackage.prototype.hasAttributeTable = function (attributeTableName) {
var tables = this.getAttributesTables();
return tables && tables.indexOf(attributeTableName) != -1;
};
/**
* Get the tile tables
* @returns {String[]} tile table names
*/
GeoPackage.prototype.getTileTables = function () {
var cd = this.contentsDao;
if (!cd.isTableExists()) {
return [];
}
return cd.getTables(contentsDataType_1.ContentsDataType.TILES);
};
/**
* Checks if the tile table exists in the GeoPackage
* @param {String} tileTableName name of the table to query for
* @returns {Boolean} indicates the existence of the tile table
*/
GeoPackage.prototype.hasTileTable = function (tileTableName) {
var tables = this.getTileTables();
return tables && tables.indexOf(tileTableName) !== -1;
};
/**
* Checks if the feature table exists in the GeoPackage
* @param {String} featureTableName name of the table to query for
* @returns {Boolean} indicates the existence of the feature table
*/
GeoPackage.prototype.hasFeatureTable = function (featureTableName) {
var tables = this.getFeatureTables();
return tables && tables.indexOf(featureTableName) != -1;
};
/**
* Get the feature tables
* @returns {String[]} feature table names
*/
GeoPackage.prototype.getFeatureTables = function () {
var cd = this.contentsDao;
if (!cd.isTableExists()) {
return [];
}
return cd.getTables(contentsDataType_1.ContentsDataType.FEATURES);
};
GeoPackage.prototype.isTable = function (tableName) {
return !!this.connection.tableExists(tableName);
};
GeoPackage.prototype.isTableType = function (type, tableName) {
return type === this.getTableType(tableName);
};
GeoPackage.prototype.getTableType = function (tableName) {
var contents = this.getTableContents(tableName);
if (contents) {
return contents.data_type;
}
};
GeoPackage.prototype.getTableContents = function (tableName) {
return this.contentsDao.queryForId(tableName);
};
GeoPackage.prototype.dropTable = function (tableName) {
return this.connection.dropTable(tableName);
};
/**
* {@inheritDoc}
*/
GeoPackage.prototype.deleteTable = function (table) {
geoPackageExtensions_1.GeoPackageExtensions.deleteTableExtensions(this, table);
this.contentsDao.deleteTable(table);
};
/**
* {@inheritDoc}
*/
GeoPackage.prototype.deleteTableQuietly = function (tableName) {
try {
this.deleteTable(tableName);
}
catch (e) {
// eat
}
};
GeoPackage.prototype.getTableCreator = function () {
return this.tableCreator;
};
GeoPackage.prototype.index = function () {
return __awaiter(this, void 0, void 0, function () {
var tables, i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
tables = this.getFeatureTables();
i = 0;
_a.label = 1;
case 1:
if (!(i < tables.length)) return [3 /*break*/, 4];
return [4 /*yield*/, this.indexFeatureTable(tables[i])];
case 2:
if (!(_a.sent())) {
throw new Error('Unable to index table ' + tables[i]);
}
_a.label = 3;
case 3:
i++;
return [3 /*break*/, 1];
case 4: return [2 /*return*/, true];
}
});
});
};
GeoPackage.prototype.indexFeatureTable = function (table, progress) {
return __awaiter(this, void 0, void 0, function () {
var featureDao, fti;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
featureDao = this.getFeatureDao(table);
fti = featureDao.featureTableIndex;
if (fti.isIndexed()) {
return [2 /*return*/, true];
}
return [4 /*yield*/, fti.index(progress)];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
};
/**
* Get a Feature DAO from Contents
* @returns {FeatureDao}
* @param table
*/
GeoPackage.prototype.getFeatureDao = function (table) {
if (table instanceof contents_2.Contents) {
table = this.contentsDao.getGeometryColumns(table);
}
else if (!(table instanceof geometryColumns_1.GeometryColumns)) {
table = this.geometryColumnsDao.queryForTableName(table);
}
if (!table) {
throw new Error('Non null Geometry Columns is required to create Feature DAO');
}
var tableReader = new featureTableReader_1.FeatureTableReader(table);
var featureTable = tableReader.readFeatureTable(this);
return new featureDao_1.FeatureDao(this, featureTable, table, this.metadataDao);
};
/**
* Queries for GeoJSON features in a feature table
* @param {String} tableName Table name to query
* @param {BoundingBox} boundingBox BoundingBox to query
* @returns {Object[]} array of GeoJSON features
*/
GeoPackage.prototype.queryForGeoJSONFeaturesInTable = function (tableName, boundingBox) {
var e_1, _a;
var featureDao = this.getFeatureDao(tableName);
var features = [];
var iterator = featureDao.queryForGeoJSONIndexedFeaturesWithBoundingBox(boundingBox);
try {
for (var iterator_1 = __values(iterator), iterator_1_1 = iterator_1.next(); !iterator_1_1.done; iterator_1_1 = iterator_1.next()) {
var feature = iterator_1_1.value;
features.push(feature);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (iterator_1_1 && !iterator_1_1.done && (_a = iterator_1.return)) _a.call(iterator_1);
}
finally { if (e_1) throw e_1.error; }
}
return features;
};
/**
* Create the Geometry Columns table if it does not already exist
* @returns {Promise}
*/
GeoPackage.prototype.createGeometryColumnsTable = function () {
if (this.geometryColumnsDao.isTableExists()) {
return true;
}
return this.tableCreator.createGeometryColumns();
};
/**
* Get a Attribute DAO
* @param {Contents} contents Contents
* @returns {AttributesDao}
*/
GeoPackage.prototype.getAttributeDao = function (table) {
if (!(table instanceof contents_2.Contents)) {
table = this.contentsDao.queryForId(table);
}
if (!table) {
throw new Error('Non null Contents is required to create an Attributes DAO');
}
var reader = new attributesTableReader_1.AttributesTableReader(table.table_name);
var attributeTable = reader.readTable(this.connection);
attributeTable.setContents(table);
return new attributesDao_1.AttributesDao(this, attributeTable);
};
/**
* Create AttributesTable from properties
* @param tableName
* @param properties
*/
GeoPackage.prototype.createAttributesTableFromProperties = function (tableName, properties) {
var attributeColumns = [];
var columnNumber = 0;
var dataColumns = [];
attributeColumns.push(userColumn_1.UserColumn.createPrimaryKeyColumn(columnNumber++, 'id'));
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
attributeColumns.push(userColumn_1.UserColumn.createColumn(columnNumber++, property.name, geoPackageDataType_1.GeoPackageDataType.fromName(property.dataType)));
if (property.dataColumn) {
var dc = new dataColumns_1.DataColumns();
dc.table_name = property.dataColumn.table_name;
dc.column_name = property.dataColumn.column_name;
dc.name = property.dataColumn.name;
dc.title = property.dataColumn.title;
dc.description = property.dataColumn.description;
dc.mime_type = property.dataColumn.mime_type;
dc.constraint_name = property.dataColumn.constraint_name;
dataColumns.push(dc);
}
}
return this.createAttributesTable(tableName, attributeColumns, new constraints_1.Constraints(), dataColumns);
};
/**
* Create attributes table for these columns, will add id column if no primary key column is defined
* @param tableName
* @param additionalColumns
* @param constraints
* @param dataColumns
*/
GeoPackage.prototype.createAttributesTable = function (tableName, additionalColumns, constraints, dataColumns) {
var columns = [];
// Check for primary key field
if (additionalColumns.findIndex(function (c) { return c.isPrimaryKey(); }) === -1) {
columns.push(attributesColumn_1.AttributesColumn.createPrimaryKeyColumn(attributesColumn_1.AttributesColumn.NO_INDEX, 'id'));
}
additionalColumns.forEach(function (c) {
columns.push(c.copy());
});
// Build the user attributes table
var table = new attributesTable_1.AttributesTable(tableName, columns);
// Add unique constraints
if (constraints !== null && constraints !== undefined) {
table.addConstraints(constraints);
}
// Create the user attributes table
this.tableCreator.createUserTable(table);
try {
// Create the contents
var contents = new contents_2.Contents();
contents.table_name = tableName;
contents.data_type = contentsDataType_1.ContentsDataType.ATTRIBUTES;
contents.identifier = tableName;
contents.last_change = new Date().toISOString();
this.contentsDao.create(contents);
table.setContents(contents);
// create passed in data columns
if (dataColumns && dataColumns.length) {
this.createDataColumns();
var dataColumnsDao_2 = this.dataColumnsDao;
dataColumns.forEach(function (dataColumn) {
dataColumnsDao_2.create(dataColumn);
});
}
}
catch (e) {
this.deleteTableQuietly(tableName);
throw new Error("Failed to create table and metadata: " + tableName);
}
return true;
};
/**
* Create a media table with the properties specified. These properties are added to the required columns
* @param {module:geoPackage~GeoPackage} geopackage the geopackage object
* @param {Object[]} properties properties to create columns from
* @param {string} properties.name name of the column
* @param {string} properties.dataType name of the data type
* @return {Promise}
*/
GeoPackage.prototype.createMediaTable = function (tableName, properties) {
var relatedTables = this.relatedTablesExtension;
var columns = [];
var columnNumber = mediaTable_1.MediaTable.numRequiredColumns();
if (properties) {
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
columns.push(userColumn_1.UserColumn.createColumn(columnNumber++, property.name, geoPackageDataType_1.GeoPackageDataType.fromName(property.dataType), property.notNull, property.defaultValue, property.max));
}
}
var mediaTable = mediaTable_1.MediaTable.create(tableName, columns);
relatedTables.createRelatedTable(mediaTable);
return relatedTables.getMediaDao(mediaTable);
};
GeoPackage.prototype.linkMedia = function (baseTableName, baseId, mediaTableName, mediaId) {
return this.linkRelatedRows(baseTableName, baseId, mediaTableName, mediaId, relationType_1.RelationType.MEDIA);
};
/**
* Links related rows together
* @param baseId
* @param baseTableName
* @param relatedId
* @param relatedTableName
* @param {string} relationType relation type
* @param {string|UserMappingTable} [mappingTable] mapping table
* @param {module:dao/columnValues~ColumnValues} [mappingColumnValues] column values
* @return {number}
*/
GeoPackage.prototype.linkRelatedRows = function (baseTableName, baseId, relatedTableName, relatedId, relationType, mappingTable, mappingColumnValues) {
var rte = this.relatedTablesExtension;
var relationship = rte
.getRelationshipBuilder()
.setBaseTableName(baseTableName)
.setRelatedTableName(relatedTableName)
.setRelationType(relationType);
var mappingTableName;
if (!mappingTable || typeof mappingTable === 'string') {
mappingTable = mappingTable || baseTableName + '_' + relatedTableName;
relationship.setMappingTableName(mappingTable);
mappingTableName = mappingTable;
}
else {
relationship.setUserMappingTable(mappingTable);
mappingTableName = mappingTable.getTableName();
}
rte.addRelationship(relationship);
var userMappingDao = rte.getMappingDao(mappingTableName);
var userMappingRow = userMappingDao.newRow();
userMappingRow.baseId = baseId;
userMappingRow.relatedId = relatedId;
for (var column in mappingColumnValues) {
userMappingRow.setValueWithColumnName(column, mappingColumnValues[column]);
}
return userMappingDao.create(userMappingRow);
};
GeoPackage.prototype.getLinkedMedia = function (baseTableName, baseId) {
var relationships = this.getRelatedRows(baseTableName, baseId);
var mediaRelationships = [];
for (var i = 0; i < relationships.length; i++) {
var relationship = relationships[i];
if (relationship.relation_name === relationType_1.RelationType.MEDIA.name) {
for (var r = 0; r < relationship.mappingRows.length; r++) {
var row = relationship.mappingRows[r].row;
mediaRelationships.push(row);
}
}
}
return mediaRelationships;
};
/**
* Adds a list of features to a FeatureTable. Inserts features from the list in batches, providing progress updates
* after each batch completes.
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @param {object} features GeoJSON features to add
* @param {string} tableName name of the table that will store the feature
* @param {boolean} index updates the FeatureTableIndex extension if it exists
* @param {number} batchSize how many features are inserted in a single transaction,
* progress is published after each batch is inserted. 1000 is recommended, 100 is about 25% slower,
* but provides more updates and keeps the thread open.
* @param {function} progress optional progress function that is called after a batch of features has been
* processed. The number of features added is sent as an argument to that function.
* @return {Promise<number>} number of features inserted
*/
GeoPackage.prototype.addGeoJSONFeaturesToGeoPackage = function (features, tableName, index, batchSize, progress) {
if (index === void 0) { index = false; }
if (batchSize === void 0) { batchSize = 1000; }
return __awaiter(this, void 0, void 0, function () {
var inserted, featureDao, srs, geometryData, featureRow, emptyPoint, reprojectionNeeded, progressFunction, insertSql, stepFunction;
var _this = this;
return __generator(this, function (_a) {
inserted = 0;
featureDao = this.getFeatureDao(tableName);
srs = featureDao.srs;
featureRow = featureDao.newRow();
emptyPoint = wkx_1.default.Geometry.parse('POINT EMPTY');
reprojectionNeeded = !(srs.organization === projectionConstants_1.ProjectionConstants.EPSG && srs.organization_coordsys_id === projectionConstants_1.ProjectionConstants.EPSG_CODE_4326);
progressFunction = function (featuresAdded) {
setTimeout((progress || function () { }), 0, featuresAdded);
};
insertSql = sqliteQueryBuilder_1.SqliteQueryBuilder.buildInsert("'" + featureDao.gpkgTableName + "'", featureRow);
stepFunction = function (start, end, resolve) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
// execute step if there are still features
if (start < end) {
featureDao.connection.transaction(function () {
// builds the insert sql statement
var insertStatement = featureDao.connection.adapter.prepareStatement(insertSql);
// determine if indexing is needed
var fti;
var tableIndex;
if (index) {
fti = featureDao.featureTableIndex;
tableIndex = fti.tableIndex;
}
for (var i = start; i < end; i++) {
var feature = features[i];
featureRow = featureDao.newRow();
geometryData = new geometryData_1.GeometryData();
geometryData.setSrsId(srs.srs_id);
if (reprojectionNeeded) {
feature = reproject_1.default.reproject(feature, projectionConstants_1.ProjectionConstants.EPSG_4326, featureDao.projection);
}
var featureGeometry = typeof feature.geometry === 'string' ? JSON.parse(feature.geometry) : feature.geometry;
geometryData.setGeometry(featureGeometry ? wkx_1.default.Geometry.parseGeoJSON(featureGeometry) : emptyPoint);
featureRow.geometry = geometryData;
for (var propertyKey in feature.properties) {
if (Object.prototype.hasOwnProperty.call(feature.properties, propertyKey)) {
featureRow.setValueWithColumnName(propertyKey, feature.properties[propertyKey]);
}
}
// bind this feature's data to the insert statement and insert into the table
var id = featureDao.connection.adapter.bindAndInsert(insertStatement, sqliteQueryBuilder_1.SqliteQueryBuilder.buildUpdateOrInsertObject(featureRow));
inserted++;
// if table index exists, be sure to index the row (note, rtree will run using a trigger)
if (tableIndex != null) {
fti.indexRow(tableIndex, id, geometryData);
}
}
if (tableIndex != null) {
fti.updateLastIndexed(tableIndex);
}
// close the prepared statement
featureDao.connection.adapter.closeStatement(insertStatement);
});
progressFunction(end);
setTimeout(function () {
stepFunction(end, Math.min(end + batchSize, features.length), resolve);
});
}
else {
resolve(inserted);
}
return [2 /*return*/];
});
}); };
return [2 /*return*/, new Promise(function (resolve) {
setTimeout(function () {
stepFunction(0, Math.min(batchSize, features.length), resolve);
});
})];
});
});
};
GeoPackage.prototype.addGeoJSONFeatureToGeoPackage = function (feature, tableName, index) {
if (index === void 0) { index = false; }
var featureDao = this.getFeatureDao(tableName);
return this.addGeoJSONFeatureToGeoPackageWithFeatureDaoAndSrs(feature, featureDao, featureDao.srs, index);
};
/**
* Adds a GeoJSON feature to the GeoPackage
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @param {object} feature GeoJSON feature to add
* @param {string} featureDao feature dao for the table
* @param {string} srs srs of the table
* @param {boolean} index updates the FeatureTableIndex extension if it exists
*/
GeoPackage.prototype.addGeoJSONFeatureToGeoPackageWithFeatureDaoAndSrs = function (feature, featureDao, srs, index) {
if (index === void 0) { index = false; }
var featureRow = featureDao.newRow();
var geometryData = new geometryData_1.GeometryData();
geometryData.setSrsId(srs.srs_id);
if (!(srs.organization === projectionConstants_1.ProjectionConstants.EPSG && srs.organization_coordsys_id === projectionConstants_1.ProjectionConstants.EPSG_CODE_4326)) {
feature = reproject_1.default.reproject(feature, projectionConstants_1.ProjectionConstants.EPSG_4326, featureDao.projection);
}
var featureGeometry = typeof feature.geometry === 'string' ? JSON.parse(feature.geometry) : feature.geometry;
if (featureGeometry !== null) {
var geometry = wkx_1.default.Geometry.parseGeoJSON(featureGeometry);
geometryData.setGeometry(geometry);
}
else {
var temp = wkx_1.default.Geometry.parse('POINT EMPTY');
geometryData.setGeometry(temp);
}
featureRow.geometry = geometryData;
for (var propertyKey in feature.properties) {
if (Object.prototype.hasOwnProperty.call(feature.properties, propertyKey)) {
featureRow.setValueWithColumnName(propertyKey, feature.properties[propertyKey]);
}
}
var id = featureDao.create(featureRow);
if (index) {
var fti = featureDao.featureTableIndex;
var tableIndex = fti.tableIndex;
if (!tableIndex)
return id;
fti.indexRow(tableIndex, id, geometryData);
fti.updateLastIndexed(tableIndex);
}
return id;
};
GeoPackage.prototype.addAttributeRow = function (tableName, row) {
var attributeDao = this.getAttributeDao(tableName);
var attributeRow = attributeDao.getRow(row);
return attributeDao.create(attributeRow);
};
/**
* Create a simple attributes table with the properties specified.
* @param {Object[]} properties properties to create columns from
* @param {string} properties.name name of the column
* @param {string} properties.dataType name of the data type
* @return {Promise}
*/
GeoPackage.prototype.createSimpleAttributesTable = function (tableName, properties) {
var relatedTables = this.relatedTablesExtension;
var columns = [];
var columnNumber = simpleAttributesTable_1.SimpleAttributesTable.numRequiredColumns();
if (properties) {
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
columns.push(userColumn_1.UserColumn.createColumn(columnNumber++, property.name, geoPackageDataType_1.GeoPackageDataType.fromName(property.dataType), true));
}
}
var simpleAttributesTable = simpleAttributesTable_1.SimpleAttributesTable.create(tableName, columns);
relatedTables.createRelatedTable(simpleAttributesTable);
return relatedTables.getSimpleAttributesDao(simpleAttributesTable);
};
GeoPackage.prototype.addMedia = function (tableName, dataBuffer, contentType, additionalProperties) {
var relatedTables = this.relatedTablesExtension;
var mediaDao = relatedTables.getMediaDao(tableName);
var row = mediaDao.newRow();
row.contentType = contentType;
row.data = dataBuffer;
for (var key in additionalProperties) {
row.setValueWithColumnName(key, additionalProperties[key]);
}
return mediaDao.create(row);
};
GeoPackage.prototype.getRelatedRows = function (baseTableName, baseId) {
return this.relatedTablesExtension.getRelatedRows(baseTableName, baseId);
};
/**
* Create the given {@link module:features/user/featureTable~FeatureTable}
* @param {FeatureTable} featureTable feature table
*/
GeoPackage.prototype.createUserFeatureTable = function (featureTable) {
return this.tableCreator.createUserTable(featureTable);
};
GeoPackage.prototype.createFeatureTableFromProperties = function (tableName, properties) {
var geometryColumn = new geometryColumns_1.GeometryColumns();
geometryColumn.table_name = tableName;
geometryColumn.column_name = 'geometry';
geometryColumn.geometry_type_name = 'GEOMETRY';
geometryColumn.z = 0;
geometryColumn.m = 0;
var columns = [];
var columnNumber = 0;
columns.push(featureColumn_1.FeatureColumn.createPrimaryKeyColumn(columnNumber++, 'id'));
columns.push(featureColumn_1.FeatureColumn.createGeometryColumn(columnNumber++, geometryColumn.column_name, geometryType_1.GeometryType.GEOMETRY, false, null));
for (var i = 0; properties && i < properties.length; i++) {
var property = properties[i];
columns.push(featureColumn_1.FeatureColumn.createColumn(columnNumber++, property.name, geoPackageDataType_1.GeoPackageDataType.fromName(property.dataType)));
}
return this.createFeatureTable(tableName, geometryColumn, columns);
};
GeoPackage.prototype.createFeatureTable = function (tableName, geometryColumns, featureColumns, boundingBox, srsId, dataColumns) {
if (boundingBox === void 0) { boundingBox = new boundingBox_1.BoundingBox(-180, 180, -90, 90); }
if (srsId === void 0) { srsId = projectionConstants_1.ProjectionConstants.EPSG_CODE_4326; }
var srs = this.spatialReferenceSystemDao.getBySrsId(srsId);
if (!srs) {
throw new Error('Spatial reference system (' + srsId + ') is not defined.');
}
this.createGeometryColumnsTable();
var geometryColumn;
if (geometryColumns) {
geometryColumn = geometryColumns;
}
else {
geometryColumn = new geometryColumns_1.GeometryColumns();
geometryColumn.table_name = tableName;
geometryColumn.column_name = 'geometry';
geometryColumn.geometry_type_name = 'GEOMETRY';
geometryColumn.z = 0;
geometryColumn.m = 0;
}
var columns = [];
if (featureColumns && featureColumns.length > 0 && featureColumns[0] instanceof userColumn_1.UserColumn) {
columns = featureColumns;
}
else {
var columnNumber = 0;
columns.push(featureColumn_1.FeatureColumn.createPrimaryKeyColumn(columnNumber++, 'id'));
columns.push(featureColumn_1.FeatureColumn.createGeometryColumn(columnNumber++, geometryColumn.column_name, geometryType_1.GeometryType.GEOMETRY, false, null));
for (var i = 0; featureColumns && i < featureColumns.length; i++) {
var property = featureColumns[i];
columns.push(featureColumn_1.FeatureColumn.createColumn(columnNumber++, property.name, geoPackageDataType_1.GeoPackageDataType.fromName(property.dataType)));
}
}
var featureTable = new featureTable_1.FeatureTable(geometryColumn.table_name, geometryColumn.column_name, columns);
this.createUserFeatureTable(featureTable);
var contents = new contents_2.Contents();
contents.table_name = geometryColumn.table_name;
contents.data_type = contentsDataType_1.ContentsDataType.FEATURES;
contents.identifier = geometryColumn.table_name;
contents.last_change = new Date().toISOString();
contents.min_x = boundingBox.minLongitude;
contents.min_y = boundingBox.minLatitude;
contents.max_x = boundingBox.maxLongitude;
contents.max_y = boundingBox.maxLatitude;
contents.srs_id = srsId;
this.contentsDao.create(contents);
geometryColumn.srs_id = srsId;
this.geometryColumnsDao.create(geometryColumn);
if (dataColumns) {
this.createDataColumns();
var dataColumnsDao_3 = this.dataColumnsDao;
dataColumns.forEach(function (dataColumn) {
dataColumnsDao_3.create(dataColumn);
});
}
return true;
};
/**
* Create the Tile Matrix Set table if it does not already exist
* @returns {Promise} resolves when the table is created
*/
GeoPackage.prototype.createTileMatrixSetTable = function () {
if (this.tileMatrixSetDao.isTableExists()) {
return true;
}
return this.tableCreator.createTileMatrixSet();
};
/**
* Create the Tile Matrix table if it does not already exist
* @returns {Promise} resolves when the table is created
*/
GeoPackage.prototype.createTileMatrixTable = function () {
if (this.tileMatrixDao.isTableExists()) {
return true;
}
return this.tableCreator.createTileMatrix();
};
/**
* Create the given tile table in this GeoPackage.
*
* @param {module:tiles/user/tileTable~TileTable} tileTable
* @return {object} the result of {@link module:db/geoPackageConnection~GeoPackageConnection#run}
*/
GeoPackage.prototype.createTileTable = function (tileTable) {
return this.tableCreator.createUserTable(tileTable);
};
/**
* Adds a spatial reference system to the gpkg_spatial_ref_sys table to be used by feature and tile tables.
* @param spatialReferenceSystem
*/
GeoPackage.prototype.createSpatialReferenceSystem = function (spatialReferenceSystem) {
projection_1.Projection.loadProjection([spatialReferenceSystem.organization.toUpperCase(), spatialReferenceSystem.organization_coordsys_id].join(':'), spatialReferenceSystem.definition);
this.spatialReferenceSystemDao.create(spatialReferenceSystem);
};
/**
* Create a new [tile table]{@link module:tiles/user/tileTable~TileTable} in this GeoPackage.
*
* @param {String} tableName tile table name
* @param {BoundingBox} contentsBoundingBox bounding box of the contents table
* @param {Number} contentsSrsId srs id of the contents table
* @param {BoundingBox} tileMatrixSetBoundingBox bounding box of the matrix set
* @param {Number} tileMatrixSetSrsId srs id of the matrix set
* @returns {TileMatrixSet} `Promise` of the created {@link module:tiles/matrixset~TileMatrixSet}
*/
GeoPackage.prototype.createTileTableWithTableName = function (tableName, contentsBoundingBox, contentsSrsId, tileMatrixSetBoundingBox, tileMatrixSetSrsId) {
var srs = this.spatialReferenceSystemDao.getBySrsId(contentsSrsId);
if (!srs) {
throw new Error('Spatial reference system (' + contentsSrsId + ') is not defined.');
}
srs = this.spatialReferenceSystemDao.getBySrsId(tileMatrixSetSrsId);
if (!srs) {
throw new Error('Spatial reference system (' + tileMatrixSetSrsId + ') is not defined.');
}
var columns = tileTable_1.TileTable.createRequiredColumns(0);
var tileTable = new tileTable_1.TileTable(tableName, columns);
var contents = new contents_2.Contents();
contents.table_name = tableName;
contents.data_type = contentsDataType_1.ContentsDataType.TILES;
contents.identifier = tableName;
contents.last_change = new Date().toISOString();
contents.min_x = contentsBoundingBox.minLongitude;
contents.min_y = contentsBoundingBox.minLatitude;
contents.max_x = contentsBoundingBox.maxLongitude;
contents.max_y = contentsBoundingBox.maxLatitude;
contents.srs_id = contentsSrsId;
var tileMatrixSet = new tileMatrixSet_1.TileMatrixSet();
tileMatrixSet.contents = contents;
tileMatrixSet.srs_id = tileMatrixSetSrsId;
tileMatrixSet.min_x = tileMatrixSetBoundingBox.minLongitude;
tileMatrixSet.min_y = tileMatrixSetBoundingBox.minLatitude;
tileMatrixSet.max_x = tileMatrixSetBoundingBox.maxLongitude;
tileMatrixSet.max_y = tileMatrixSetBoundingBox.maxLatitude;
this.createTileMatrixSetTable();
this.createTileMatrixTable();
this.createTileTable(tileTable);
this.contentsDao.create(contents);
this.tileMatrixSetDao.create(tileMatrixSet);
return tileMatrixSet;
};
/**
* Create the [tables and rows](https://www.geopackage.org/spec121/index.html#tiles)
* necessary to store tiles according to the ubiquitous [XYZ web/slippy-map tiles](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames) scheme.
* The extent for the [contents table]{@link module:core/contents~Contents} row,
* `contentsBoundingBox`, is [informational only](https://www.geopackage.org/spec121/index.html#gpkg_contents_cols),
* and need not match the [tile matrix set]{@link module:tiles/matrixset~TileMatrixSet}
* extent, `tileMatrixSetBoundingBox`, which should be the precise bounding box
* used to calculate the tile row and column coordinates of all tiles in the
* tile set. The two SRS ID parameters, `contentsSrsId` and `tileMatrixSetSrsId`,
* must match, however. See {@link module:tiles/matrixset~TileMatrixSet} for
* more information about how GeoPackage consumers use the bouding boxes for a
* tile set.
*
* @param {string} tableName the name of the table that will store the tiles
* @param {BoundingBox} contentsBoundingBox the bounds stored in the [`gpkg_contents`]{@link module:core/contents~Contents} table row for the tile matrix set
* @param {SRSRef} contentsSrsId the ID of a [spatial reference system]{@link module:core/srs~SpatialReferenceSystem}; must match `tileMatrixSetSrsId`
* @param {BoundingBox} tileMatrixSetBoundingBox the bounds stored in the [`gpkg_tile_matrix_set`]{@link module:tiles/matrixset~TileMatrixSet} table row
* @param {SRSRef} tileMatrixSetSrsId the ID of a [spatial reference system]{@link module:core/srs~SpatialReferenceSystem}
* for the [tile matrix set](https://www.geopackage.org/spec121/index.html#_tile_matrix_set) table; must match `contentsSrsId`
* @param {number} minZoom the zoom level of the lowest resolution [tile matrix]{@link module:tiles/matrix~TileMatrix} in the tile matrix set
* @param {number} maxZoom the zoom level of the highest resolution [tile matrix]{@link module:tiles/matrix~TileMatrix} in the tile matrix set
* @param tileSize the width and height in pixels of the tile images; defaults to 256
* @returns {TileMatrixSet} the created {@link module:tiles/matrixset~TileMatrixSet} object, or rejects with an `Error`
*
* @todo make `tileMatrixSetSrsId` optional because it always has to be the same anyway
*/
GeoPackage.prototype.createStandardWebMercatorTileTable = function (tableName, contentsBoundingBox, contentsSrsId, tileMatrixSetBoundingBox, tileMatrixSetSrsId, minZoom, maxZoom, tileSize) {
if (tileSize === void 0) { tileSize = 256; }
var webMercator = this.spatialReferenceSystemDao.getByOrganizationAndCoordSysId(projectionConstants_1.ProjectionConstants.EPSG, projectionConstants_1.ProjectionConstants.EPSG_CODE_3857);
if (!webMercator) {
this.spatialReferenceSystemDao.createWebMercator();
webMercator = this.spatialReferenceSystemDao.getByOrganizationAndCoordSysId(projectionConstants_1.ProjectionConstants.EPSG, projectionConstants_1.ProjectionConstants.EPSG_CODE_3857);
}
var webMercatorSrsId = webMercator.srs_id;
var srs = this.spatialReferenceSystemDao.getBySrsId(contentsSrsId);
if (!srs) {
throw new Error('Spatial reference system (' + contentsSrsId + ') is not defined.');
}
srs = this.spatialReferenceSystemDao.getBySrsId(tileMatrixSetSrsId);
if (!srs) {
throw new Error('Spatial reference system (' + tileMatrixSetSrsId + ') is not defined.');
}
if (contentsSrsId !== webMercatorSrsId) {
var srsDao = new spatialReferenceSystemDao_1.SpatialReferenceSystemDao(this);
var from = srsDao.getBySrsId(contentsSrsId).projection;
contentsBoundingBox = contentsBoundingBox.projectBoundingBox(from, projectionConstants_1.ProjectionConstants.EPSG_3857);
}
if (tileMatrixSetSrsId !== webMercatorSrsId) {
var srsDao = new spatialReferenceSystemDao_1.SpatialReferenceSystemDao(this);
var from = srsDao.getBySrsId(tileMatrixSetSrsId).projection;
tileMatrixSetBoundingBox = tileMatrixSetBoundingBox.projectBoundingBox(from, projectionConstants_1.ProjectionConstants.EPSG_3857);
}
var tileMatrixSet = this.createTileTableWithTableName(tableName, contentsBoundingBox, webMercatorSrsId, tileMatrixSetBoundingBox, webMercatorSrsId);
this.createStandardWebMercatorTileMatrix(tileMatrixSetBoundingBox, tileMatrixSet, minZoom, maxZoom, tileSize);
return tileMatrixSet;
};
/**
* Create the [tables and rows](https://www.geopackage.org/spec121/index.html#tiles)
* necessary to store tiles according to the ubiquitous [XYZ web/slippy-map tiles](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames) scheme.
* The extent for the [contents table]{@link module:core/contents~Contents} row,
* `contentsBoundingBox`, is [informational only](https://www.geopackage.org/spec121/index.html#gpkg_contents_cols),
* and need not match the [tile matrix set]{@link module:tiles/matrixset~TileMatrixSet}
* extent, `tileMatrixSetBoundingBox`, which should be the precise bounding box
* used to calculate the tile row and column coordinates of all tiles in the
* tile set.
*
* @param {string} tableName the name of the table that will store the tiles
* @param {BoundingBox} contentsBoundingBox the bounds stored in the [`gpkg_contents`]{@link module:core/contents~Contents} table row for the tile matrix set. MUST BE EPSG:3857
* @param {BoundingBox} tileMatrixSetBoundingBox the bounds stored in the [`gpkg_tile_matrix_set`]{@link module:tiles/matrixset~TileMatrixSet} table row. MUST BE EPSG:3857
* @param {Set<number>} zoomLevels create tile of all resolutions in the set.
* @param tileSize the width and height in pixels of the tile images; defaults to 256
* @returns {Promise} a `Promise` that resolves with the created {@link module:tiles/matrixset~TileMatrixSet} object, or rejects with an `Error`
*
* @todo make `tileMatrixSetSrsId` optional because it always has to be the same anyway
*/
GeoPackage.prototype.createStandardWebMercatorTileTableWithZoomLevels = function (tableName, contentsBoundingBox, tileMatrixSetBoundingBox, zoomLevels, tileSize) {
if (tileSize === void 0) { tileSize = 256; }
return __awaiter(this, void 0, void 0, function () {
var webMercator, webMercatorSrsId, tileMatrixSet;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
webMercator = this.spatialReferenceSystemDao.getByOrganizationAndCoordSysId(projectionConstants_1.ProjectionConstants.EPSG, projectionConstants_1.ProjectionConstants.EPSG_CODE_3857);
if (!webMercator) {
this.spatialReferenceSystemDao.createWebMercator();
webMercator = this.spatialReferenceSystemDao.getByOrganizationAndCoordSysId(projectionConstants_1.ProjectionConstants.EPSG, projectionConstants_1.ProjectionConstants.EPSG_CODE_3857);
}
webMercatorSrsId = webMercator.srs_id;
return [4 /*yield*/, this.createTileTableWithTableName(tableName, contentsBoundingBox, webMercatorSrsId, tileMatrixSetBoundingBox, webMercatorSrsId)];
case 1:
tileMatrixSet = _a.sent();
this.createStandardWebMercatorTileMatrixWithZoomLevels(tileMatrixSetBoundingBox, tileMatrixSet, zoomLevels, tileSize);
return [2 /*return*/, tileMatrixSet];
}
});
});
};
/**
* Create the tables and rows necessary to store tiles in a {@link module:tiles/matrixset~TileMatrixSet}.
* This will create a [tile matrix row]{@link module:tiles/matrix~TileMatrix}
* for every integral zoom level in the range `[minZoom..maxZoom]`.
*
* @param {BoundingBox} epsg3857TileBoundingBox
* @param {TileMatrixSet} tileMatrixSet
* @param {number} minZoom
* @param {number} maxZoom
* @param {number} [tileSize=256] optional tile size in pixels
* @returns {module:geoPackage~GeoPackage} `this` `GeoPackage`
*/
GeoPackage.prototype.createStandardWebMercatorTileMatrix = function (epsg3857TileBoundingBox, tileMatrixSet, minZoom, maxZoom, tileSize) {
if (tileSize === void 0) { tileSize = 256; }
tileSize = tileSize || 256;
var tileMatrixDao = this.tileMatrixDao;
for (var zoom = minZoom; zoom <= maxZoom; zoom++) {
this.createTileMatrixRow(epsg3857TileBoundingBox, tileMatrixSet, tileMatrixDao, zoom, tileSize);
}
return this;
};
/**
* Create the tables and rows necessary to store tiles in a {@link module:tiles/matrixset~TileMatrixSet}.
* This will create a [tile matrix row]{@link module:tiles/matrix~TileMatrix}
* for every item in the set zoomLevels.
*
* @param {BoundingBox} epsg3857TileBoundingBox
* @param {TileMatrixSet} tileMatrixSet
* @param {Set<number>} zoomLevels
* @param {number} [tileSize=256] optional tile size in pixels
* @returns {module:geoPackage~GeoPackage} `this` `GeoPackage`
*/
GeoPackage.prototype.createStandardWebMercatorTileMatrixWithZoomLevels = function (epsg3857TileBoundingBox, tileMatrixSet, zoomLevels, tileSize) {
var _this = this;
if (tileSize === void 0) { tileSize = 256; }
tileSize = tileSize || 256;
var tileMatrixDao = this.tileMatrixDao;
zoomLevels.forEach(function (zoomLevel) {
_this.createTileMatrixRow(epsg3857TileBoundingBox, tileMatrixSet, tileMatrixDao, zoomLevel, tileSize);
});
return this;
};
/**
* Adds row to tileMatrixDao
*
* @param {BoundingBox} epsg3857TileBoundingBox
* @param {TileMatrixSet} tileMatrixSet
* @param {TileMatrixDao} tileMatrixDao
* @param {number} zoomLevel
* @param {number} [tileSize=256]
* @returns {number}
* @memberof GeoPackage
*/
GeoPackage.prototype.createTileMatrixRow = function (epsg3857TileBoundingBox, tileMatrixSet, tileMatrixDao, zoomLevel, tileSize) {
if (tileSize === void 0) { tileSize = 256; }
var box = tileBoundingBoxUtils_1.TileBoundingBoxUtils.webMercatorTileBox(epsg3857TileBoundingBox, zoomLevel);
var matrixWidth = box.maxLongitude - box.minLongitude + 1;
var matrixHeight = box.maxLatitude - box.minLatitude + 1;
var pixelXSize = (epsg3857TileBoundingBox.maxLongitude - epsg3857TileBoundingBox.minLongitude) / matrixWidth / tileSize;
var pixelYSize = (epsg3857TileBoundingBox.maxLatitude - epsg3857TileBoundingBox.minLatitude) / matrixHeight / tileSize;
var tileMatrix = new tileMatrix_1.TileMatrix();
tileMatrix.table_name = tileMatrixSet.table_name;
tileMatrix.zoom_level = zoomLevel;
tileMatrix.matrix_width = matrixWidth;
tileMatrix.matrix_height = matrixHeight;
tileMatrix.tile_width = tileSize;
tileMatrix.tile_height = tileSize;
tileMatrix.pixel_x_size = pixelXSize;
tileMatrix.pixel_y_size = pixelYSize;
return tileMatrixDao.create(tileMatrix);
};
/**
* Adds a tile to the GeoPackage
* @param {object} tileStream Byte array or Buffer containing the tile bytes
* @param {String} tableName Table name to add the tile to
* @param {Number} zoom zoom level of this tile
* @param {Number} tileRow row of this tile
* @param {Number} tileColumn column of this tile
*/
GeoPackage.prototype.addTile = function (tileStream, tableName, zoom, tileRow, tileColumn) {
var tileDao = this.getTileDao(tableName);
var newRow = tileDao.newRow();
newRow.zoomLevel = zoom;
newRow.tileColumn = tileColumn;
newRow.tileRow = tileRow;
newRow.tileData = tileStream;
return tileDao.create(newRow);
};
/**
* Gets a tile from the specified table
* @param {string} table name of the table to get the tile from
* @param {Number} zoom zoom level of the tile
* @param {Number} tileRow row of the tile
* @param {Number} tileColumn column of the tile
*
* @todo jsdoc return value
*/
GeoPackage.prototype.getTileFromTable = function (table, zoom, tileRow, tileColumn) {
var tileDao = this.getTileDao(table);
return tileDao.queryForTile(tileColumn, tileRow, zoom);
};
/**
* Gets the tiles in the EPSG:4326 bounding box
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @param {string} table name of the tile table
* @param {Number} zoom Zoom of the tiles to query for
* @param {Number} west EPSG:4326 western boundary
* @param {Number} east EPSG:4326 eastern boundary
* @param {Number} south EPSG:4326 southern boundary
* @param {Number} north EPSG:4326 northern boundary
*/
GeoPackage.prototype.getTilesInBoundingBox = function (table, zoom, west, east, south, north) {
var e_2, _a;
var tiles = {
columns: [],
srs: undefined,
tiles: [],
west: undefined,
east: undefined,
south: undefined,
north: undefined,
zoom: undefined,
};
var tileDao = this.getTileDao(table);
if (zoom < tileDao.minZoom || zoom > tileDao.maxZoom) {
return;
}
for (var i = 0; i < tileDao.table.getUserColumns().getColumns().length; i++) {
var column = tileDao.table.getUserColumns().getColumns()[i];
tiles.columns.push({
index: column.index,
name: column.name,
max: column.max,
min: column.min,
notNull: column.notNull,
primaryKey: column.primaryKey,
});
}
var srs = tileDao.srs;
tiles.srs = srs;
tiles.tiles = [];
var tms = tileDao.tileMatrixSet;
var tm = tileDao.getTileMatrixWithZoomLevel(zoom);
if (!tm) {
return tiles;
}
var mapBoundingBox = new boundingBox_1.BoundingBox(Math.max(-180, west), Math.min(east, 180), south, north);
tiles.west = Math.max(-180, west).toFixed(2);
tiles.east = Math.min(east, 180).toFixed(2);
tiles.south = south.toFixed(2);
tiles.north = north.toFixed(2);
tiles.zoom = zoom;
mapBoundingBox = mapBoundingBox.projectBoundingBox(projectionConstants_1.ProjectionConstants.EPSG_4326, tileDao.srs.organization.toUpperCase() + ':' + tileDao.srs.organization_coordsys_id);
var grid = tileBoundingBoxUtils_1.TileBoundingBoxUtils.getTileGridWithTotalBoundingBox(tms.boundingBox, tm.matrix_width, tm.matrix_height, mapBoundingBox);
var iterator = tileDao.queryByTileGrid(grid, zoom);
try {
for (var iterator_2 = __values(iterator), iterator_2_1 = iterator_2.next(); !iterator_2_1.done; iterator_2_1 = iterator_2.next()) {
var row = iterator_2_1.value;
var tile = {};
tile.tableName = table;
tile.id = row.id;
var tileBB = tileBoundingBoxUtils_1.TileBoundingBoxUtils.getTileBoundingBox(tms.boundingBox, tm, row.tileColumn, row.row);
tile.minLongitude = tileBB.minLongitude;
tile.maxLongitude = tileBB.maxLongitude;
tile.minLatitude = tileBB.minLatitude;
tile.maxLatitude = tileBB.maxLatitude;
tile.projection = tileDao.srs.organization.toUpperCase() + ':' + tileDao.srs.organization_coordsys_id;
tile.values = [];
for (var i = 0; i < tiles.columns.length; i++) {
var value = row.values[tiles.columns[i].name];
if (tiles.columns[i].name === 'tile_data') {
tile.values.push('data');
}
else if (value === null || value === 'null') {
tile.values.push('');
}
else {
tile.values.push(value.toString());
tile[tiles.columns[i].name] = value;
}
}
tiles.tiles.push(tile);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (iterator_2_1 && !iterator_2_1.done && (_a = iterator_2.return)) _a.call(iterator_2);
}
finally { if (e_2) throw e_2.error; }
}
return tiles;
};
/**
* Gets the tiles in the EPSG:4326 bounding box
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @param {string} table name of the tile table
* @param {Number} webZoom Zoom of the tiles to query for
* @param {Number} west EPSG:4326 western boundary
* @param {Number} east EPSG:4326 eastern boundary
* @param {Number} south EPSG:4326 southern boundary
* @param {Number} north EPSG:4326 northern boundary
*/
GeoPackage.prototype.getTilesInBoundingBoxWebZoom = function (table, webZoom, west, east, south, north) {
var e_3, _a;
var tiles = {
columns: [],
srs: undefined,
tiles: [],
west: undefined,
east: undefined,
south: undefined,
north: undefined,
zoom: undefined,
};
var tileDao = this.getTileDao(table);
if (webZoom < tileDao.minWebMapZoom || webZoom > tileDao.maxWebMapZoom) {
return;
}
tiles.columns = [];
for (var i = 0; i < tileDao.table.getUserColumns().getColumns().length; i++) {
var column = tileDao.table.getUserColumns().getColumns()[i];
tiles.columns.push({
index: column.index,
name: column.name,
max: column.max,
min: column.min,
notNull: column.notNull,
primaryKey: column.primaryKey,
});
}
var srs = tileDao.srs;
tiles.srs = srs;
tiles.tiles = [];
var zoom = tileDao.webZoomToGeoPackageZoom(webZoom);
var tms = tileDao.tileMatrixSet;
var tm = tileDao.getTileMatrixWithZoomLevel(zoom);
if (!tm) {
return tiles;
}
var mapBoundingBox = new boundingBox_1.BoundingBox(Math.max(-180, west), Math.min(east, 180), south, north);
tiles.west = Math.max(-180, west).toFixed(2);
tiles.east = Math.min(east, 180).toFixed(2);
tiles.south = south.toFixed(2);
tiles.north = north.toFixed(2);
tiles.zoom = zoom;
mapBoundingBox = mapBoundingBox.projectBoundingBox(projectionConstants_1.ProjectionConstants.EPSG_4326, tileDao.srs.organization.toUpperCase() + ':' + tileDao.srs.organization_coordsys_id);
var grid = tileBoundingBoxUtils_1.TileBoundingBoxUtils.getTileGridWithTotalBoundingBox(tms.boundingBox, tm.matrix_width, tm.matrix_height, mapBoundingBox);
var iterator = tileDao.queryByTileGrid(grid, zoom);
try {
for (var iterator_3 = __values(iterator), iterator_3_1 = iterator_3.next(); !iterator_3_1.done; iterator_3_1 = iterator_3.next()) {
var row = iterator_3_1.value;
var tile = {
tableName: undefined,
id: undefined,
minLongitude: undefined,
maxLongitude: undefined,
minLatitude: undefined,
maxLatitude: undefined,
projection: undefined,
values: [],
};
tile.tableName = table;
tile.id = row.id;
var tileBB = tileBoundingBoxUtils_1.TileBoundingBoxUtils.getTileBoundingBox(tms.boundingBox, tm, row.tileColumn, row.row);
tile.minLongitude = tileBB.minLongitude;
tile.maxLongitude = tileBB.maxLongitude;
tile.minLatitude = tileBB.minLatitude;
tile.maxLatitude = tileBB.maxLatitude;
tile.projection = tileDao.srs.organization.toUpperCase() + ':' + tileDao.srs.organization_coordsys_id;
tile.values = [];
for (var i = 0; i < tiles.columns.length; i++) {
var value = row.values[tiles.columns[i].name];
if (tiles.columns[i].name === 'tile_data') {
tile.values.push('data');
}
else if (value === null || value === 'null') {
tile.values.push('');
}
else {
tile.values.push(value.toString());
tile[tiles.columns[i].name] = value;
}
}
tiles.tiles.push(tile);
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (iterator_3_1 && !iterator_3_1.done && (_a = iterator_3.return)) _a.call(iterator_3);
}
finally { if (e_3) throw e_3.error; }
}
return tiles;
};
GeoPackage.prototype.getFeatureTileFromXYZ = function (table, x, y, z, width, height) {
return __awaiter(this, void 0, void 0, function () {
var featureDao, ft;
return __generator(this, function (_a) {
x = Number(x);
y = Number(y);
z = Number(z);
width = Number(width);
height = Number(height);
featureDao = this.getFeatureDao(table);
if (!featureDao)
return [2 /*return*/];
ft = new features_1.FeatureTiles(featureDao, width, height);
return [2 /*return*/, ft.drawTile(x, y, z)];
});
});
};
GeoPackage.prototype.getClosestFeatureInXYZTile = function (table, x, y, z, latitude, longitude) {
var e_4, _a;
x = Number(x);
y = Number(y);
z = Number(z);
var featureDao = this.getFeatureDao(table);
if (!featureDao)
return;
var ft = new features_1.FeatureTiles(featureDao, 256, 256);
var tileCount = ft.getFeatureCountXYZ(x, y, z);
var boundingBox = tileBoundingBoxUtils_1.TileBoundingBoxUtils.getWebMercatorBoundingBoxFromXYZ(x, y, z);
boundingBox = boundingBox.projectBoundingBox(projectionConstants_1.ProjectionConstants.EPSG_3857, projectionConstants_1.ProjectionConstants.EPSG_4326);
if (tileCount > 10000) {
// too many, send back the entire tile
// add the goepackage name and table
var gj = boundingBox.toGeoJSON();
gj.feature_count = tileCount;
gj.coverage = true;
gj.gp_table = table;
gj.gp_name = this.name;
return gj;
}
var ne = [boundingBox.maxLongitude, boundingBox.maxLatitude];
var sw = [boundingBox.minLongitude, boundingBox.minLatitude];
var width = ne[0] - sw[0];
var widthPerPixel = width / 256;
var tolerance = 10 * widthPerPixel;
boundingBox.maxLongitude = longitude + tolerance;
boundingBox.minLongitude = longitude - tolerance;
boundingBox.maxLatitude = latitude + tolerance;
boundingBox.minLatitude = latitude - tolerance;
var iterator = featureDao.queryForGeoJSONIndexedFeaturesWithBoundingBox(boundingBox);
var features = [];
var closestDistance = 100000000000;
var closest;
var centerPoint = helpers.point([longitude, latitude]);
try {
for (var iterator_4 = __values(iterator), iterator_4_1 = iterator_4.next(); !iterator_4_1.done; iterator_4_1 = iterator_4.next()) {
var feature = iterator_4_1.value;
feature.type = 'Feature';
var distance = GeoPackage.determineDistance(centerPoint.geometry, feature);
if (distance < closestDistance) {
closest = feature;
closestDistance = distance;
}
else if (distance === closestDistance && closest != null && closest.geometry.type !== 'Point') {
closest = feature;
closestDistance = distance;
}
features.push(feature);
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (iterator_4_1 && !iterator_4_1.done && (_a = iterator_4.return)) _a.call(iterator_4);
}
finally { if (e_4) throw e_4.error; }
}
if (closest) {
closest.gp_table = table;
closest.gp_name = this.name;
closest.distance = closestDistance;
}
return closest;
};
GeoPackage.determineDistance = function (point, feature) {
if (feature.type === 'FeatureCollection') {
feature.features.forEach(function (feature) {
GeoPackage.determineDistance(point, feature);
});
}
else {
var geometry = feature.geometry;
if (geometry.type === 'Point') {
return (0, distance_1.default)(point, geometry);
}
if (geometry.type === 'LineString') {
return this.determineDistanceFromLine(point, geometry);
}
if (geometry.type === 'MultiLineString') {
var distance_2 = Number.MAX_SAFE_INTEGER;
geometry.coordinates.forEach(function (lineStringCoordinate) {
var lineString = helpers.lineString(lineStringCoordinate);
distance_2 = Math.min(distance_2, GeoPackage.determineDistance(point, lineString));
});
return distance_2;
}
if (geometry.type === 'Polygon') {
return GeoPackage.determineDistanceFromPolygon(point, geometry);
}
if (geometry.type === 'MultiPolygon') {
return GeoPackage.determineDistanceFromPolygon(point, geometry);
}
return Number.MAX_SAFE_INTEGER;
}
};
GeoPackage.determineDistanceFromLine = function (point, lineString) {
return (0, point_to_line_distance_1.default)(point, lineString);
};
GeoPackage.determineDistanceFromPolygon = function (point, polygon) {
if ((0, boolean_point_in_polygon_1.default)(point, polygon)) {
return 0;
}
return GeoPackage.determineDistance(point, (0, polygon_to_line_1.default)(polygon));
};
/**
* Create the Data Columns table if it does not already exist
*/
GeoPackage.prototype.createDataColumns = function () {
if (this.dataColumnsDao.isTableExists()) {
return true;
}
return this.tableCreator.createDataColumns();
};
/**
* Create the Data Column Constraints table if it does not already exist
*/
GeoPackage.prototype.createDataColumnConstraintsTable = function () {
if (this.dataColumnConstraintsDao.isTableExists()) {
return true;
}
return this.tableCreator.createDataColumnConstraints();
};
GeoPackage.prototype.createMetadataTable = function () {
if (this.metadataDao.isTableExists()) {
return true;
}
return this.tableCreator.createMetadata();
};
GeoPackage.prototype.createMetadataReferenceTable = function () {
if (this.metadataReferenceDao.isTableExists()) {
return true;
}
return this.tableCreator.createMetadataReference();
};
GeoPackage.prototype.createExtensionTable = function () {
if (this.extensionDao.isTableExists()) {
return true;
}
return this.tableCreator.createExtensions();
};
GeoPackage.prototype.createTableIndexTable = function () {
if (this.tableIndexDao.isTableExists()) {
return true;
}
return this.tableCreator.createTableIndex();
};
GeoPackage.prototype.createGeometryIndexTable = function () {
var dao = this.getGeometryIndexDao(null);
if (dao.isTableExists()) {
return true;
}
return this.tableCreator.createGeometryIndex();
};
GeoPackage.prototype.createStyleMappingTable = function (tableName, columns, dataColumns) {
var attributeTable = new styleMappingTable_1.StyleMappingTable(tableName, columns, null);
this.tableCreator.createUserTable(attributeTable);
var contents = new contents_2.Contents();
contents.table_name = tableName;
contents.data_type = contentsDataType_1.ContentsDataType.ATTRIBUTES;
contents.identifier = tableName;
contents.last_change = new Date().toISOString();
this.contentsDao.create(contents);
if (dataColumns) {
this.createDataColumns();
var dataColumnsDao_4 = this.dataColumnsDao;
dataColumns.forEach(function (dataColumn) {
dataColumnsDao_4.create(dataColumn);
});
}
return true;
};
/**
* Get the application id of the GeoPackage
* @returns {string} application id
*/
GeoPackage.prototype.getApplicationId = function () {
return this.database.getApplicationId();
};
GeoPackage.createDataColumnMap = function (featureDao) {
var columnMap = {};
var dcd = new dataColumnsDao_1.DataColumnsDao(featureDao.geoPackage);
featureDao.table.getUserColumns().getColumns().forEach(function (column) {
var dataColumn = dcd.getDataColumns(featureDao.table.getTableName(), column.name);
columnMap[column.name] = {
index: column.index,
name: column.name,
max: column.max,
min: column.min,
notNull: column.notNull,
primaryKey: column.primaryKey,
dataType: column.dataType ? geoPackageDataType_1.GeoPackageDataType.nameFromType(column.dataType) : '',
displayName: dataColumn && dataColumn.name ? dataColumn.name : column.name,
dataColumn: dataColumn,
};
}.bind(this));
return columnMap;
};
GeoPackage.prototype.iterateGeoJSONFeatures = function (tableName, boundingBox) {
var featureDao = this.getFeatureDao(tableName);
return featureDao.queryForGeoJSONIndexedFeaturesWithBoundingBox(boundingBox);
};
/**
* Gets a GeoJSON feature from the table by id
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @param {string} table name of the table to get the feature from
* @param {Number} featureId ID of the feature
*/
GeoPackage.prototype.getFeature = function (table, featureId) {
var featureDao = this.getFeatureDao(table);
var srs = featureDao.srs;
var feature = featureDao.queryForId(featureId);
if (!feature) {
var features = featureDao.queryForAllEq('_feature_id', featureId);
if (features.length) {
feature = featureDao.getRow(features[0]);
}
else {
features = featureDao.queryForAllEq('_properties_id', featureId);
if (features.length) {
feature = featureDao.getRow(features[0]);
}
}
}
if (feature) {
return GeoPackage.parseFeatureRowIntoGeoJSON(feature, srs);
}
};
// eslint-disable-next-line complexity
GeoPackage.parseFeatureRowIntoGeoJSON = function (featureRow, srs, columnMap) {
var geoJson = {
type: 'Feature',
properties: {},
id: undefined,
geometry: undefined,
};
var geometry = featureRow.geometry;
if (geometry && geometry.geometry) {
var geoJsonGeom = geometry.geometry.toGeoJSON();
if (srs.definition &&
srs.definition !== 'undefined' &&
srs.organization.toUpperCase() + ':' + srs.organization_coordsys_id !== projectionConstants_1.ProjectionConstants.EPSG_4326) {
geoJsonGeom = reproject_1.default.reproject(geoJsonGeom, srs.projection, projectionConstants_1.ProjectionConstants.EPSG_4326);
}
geoJson.geometry = geoJsonGeom;
}
for (var key in featureRow.values) {
if (Object.prototype.hasOwnProperty.call(featureRow.values, key) &&
key !== featureRow.geometryColumn.name &&
key !== 'id') {
if (key.toLowerCase() === '_feature_id') {
geoJson.id = featureRow.values[key];
}
else if (key.toLowerCase() === '_properties_id') {
geoJson.properties[key.substring(12)] = featureRow.values[key];
}
else if (columnMap && columnMap[key]) {
geoJson.properties[columnMap[key].displayName] = featureRow.values[key];
}
else {
geoJson.properties[key] = featureRow.values[key];
}
}
else if (featureRow.geometryColumn.name === key) {
// geoJson.properties[key] = geometry && !geometry.geometryError ? 'Valid' : geometry.geometryError;
}
}
geoJson.id = geoJson.id || featureRow.id;
return geoJson;
};
/**
* Gets the features in the EPSG:3857 tile
* @param {string} table name of the feature table
* @param {Number} x x tile number
* @param {Number} y y tile number
* @param {Number} z z tile number
* @param {Boolean} [skipVerification] skip the extra verification to determine if the feature really is within the tile
*/
GeoPackage.prototype.getGeoJSONFeaturesInTile = function (table, x, y, z, skipVerification) {
if (skipVerification === void 0) { skipVerification = false; }
return __awaiter(this, void 0, void 0, function () {
var webMercatorBoundingBox, bb, featureDao, features, iterator, iterator_5, iterator_5_1, feature;
var e_5, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
webMercatorBoundingBox = tileBoundingBoxUtils_1.TileBoundingBoxUtils.getWebMercatorBoundingBoxFromXYZ(x, y, z);
bb = webMercatorBoundingBox.projectBoundingBox(projectionConstants_1.ProjectionConstants.EPSG_3857, projectionConstants_1.ProjectionConstants.EPSG_4326);
return [4 /*yield*/, this.indexFeatureTable(table)];
case 1:
_b.sent();
featureDao = this.getFeatureDao(table);
if (!featureDao)
return [2 /*return*/];
features = [];
iterator = featureDao.queryForGeoJSONIndexedFeaturesWithBoundingBox(bb, skipVerification);
try {
for (iterator_5 = __values(iterator), iterator_5_1 = iterator_5.next(); !iterator_5_1.done; iterator_5_1 = iterator_5.next()) {
feature = iterator_5_1.value;
features.push(feature);
}
}
catch (e_5_1) { e_5 = { error: e_5_1 }; }
finally {
try {
if (iterator_5_1 && !iterator_5_1.done && (_a = iterator_5.return)) _a.call(iterator_5);
}
finally { if (e_5) throw e_5.error; }
}
return [2 /*return*/, features];
}
});
});
};
/**
* Gets the features in the EPSG:4326 bounding box
* @param {string} table name of the feature table
* @param {Number} west EPSG:4326 western boundary
* @param {Number} east EPSG:4326 eastern boundary
* @param {Number} south EPSG:4326 southern boundary
* @param {Number} north EPSG:4326 northern boundary
*/
GeoPackage.prototype.getFeaturesInBoundingBox = function (table, west, east, south, north) {
return __awaiter(this, void 0, void 0, function () {
var featureDao, bb, iterator;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.indexFeatureTable(table)];
case 1:
_a.sent();
featureDao = this.getFeatureDao(table);
if (!featureDao)
throw new Error('Unable to find table ' + table);
bb = new boundingBox_1.BoundingBox(west, east, south, north);
iterator = featureDao.queryIndexedFeaturesWithBoundingBox(bb);
return [2 /*return*/, iterator];
}
});
});
};
/**
* Get the standard 3857 XYZ tile from the GeoPackage. If a canvas is provided, the tile will be drawn in the canvas
* @param {string} table name of the table containing the tiles
* @param {Number} x x index of the tile
* @param {Number} y y index of the tile
* @param {Number} z zoom level of the tile
* @param {Number} width width of the resulting tile
* @param {Number} height height of the resulting tile
* @param {any} canvas canvas element to draw the tile into
*/
GeoPackage.prototype.xyzTile = function (table, x, y, z, width, height, canvas) {
if (width === void 0) { width = 256; }
if (height === void 0) { height = 256; }
return __awaiter(this, void 0, void 0, function () {
var tileDao, retriever, tileScaling;
return __generator(this, function (_a) {
width = Number(width);
height = Number(height);
tileDao = this.getTileDao(table);
retriever = new retriever_1.GeoPackageTileRetriever(tileDao, width, height);
if (this.getTileScalingExtension(table).has()) {
tileScaling = this.getTileScalingExtension(table).dao.queryForTableName(table);
if (tileScaling) {
retriever.setScaling(tileScaling);
}
}
if (!canvas) {
return [2 /*return*/, retriever.getTile(x, y, z)];
}
else {
return [2 /*return*/, retriever.drawTileIn(x, y, z, canvas)];
}
return [2 /*return*/];
});
});
};
/**
* Get the standard 3857 XYZ tile from the GeoPackage. If a canvas is provided, the tile will be drawn in the canvas
* @param {string} table name of the table containing the tiles
* @param {Number} x x index of the tile
* @param {Number} y y index of the tile
* @param {Number} z zoom level of the tile
* @param {Number} width width of the resulting tile
* @param {Number} height height of the resulting tile
* @param {any} canvas canvas element to draw the tile into
*/
GeoPackage.prototype.xyzTileScaled = function (table, x, y, z, width, height, canvas, zoomIn, zoomOut) {
if (width === void 0) { width = 256; }
if (height === void 0) { height = 256; }
return __awaiter(this, void 0, void 0, function () {
var tileDao, retriever, tileScaling, tileScaling_2, tileScalingExtension;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
width = Number(width);
height = Number(height);
tileDao = this.getTileDao(table);
retriever = new retriever_1.GeoPackageTileRetriever(tileDao, width, height);
return [4 /*yield*/, this.getTileScalingExtension(table).getOrCreateExtension()];
case 1:
_a.sent();
tileScaling = this.getTileScalingExtension(table).dao.queryForTableName(table);
if (tileScaling) {
retriever.setScaling(tileScaling);
}
else {
tileScaling_2 = new tileScaling_1.TileScaling();
tileScaling_2.zoom_in = zoomIn;
tileScaling_2.zoom_out = zoomOut;
tileScaling_2.table_name = table;
tileScaling_2.scaling_type = tileScalingType_1.TileScalingType.CLOSEST_IN_OUT;
tileScalingExtension = this.getTileScalingExtension(table);
// await tileScalingExtension.getOrCreateExtension();
tileScalingExtension.createOrUpdate(tileScaling_2);
retriever.setScaling(tileScaling_2);
}
if (!canvas) {
return [2 /*return*/, retriever.getTile(x, y, z)];
}
else {
return [2 /*return*/, retriever.drawTileIn(x, y, z, canvas)];
}
return [2 /*return*/];
}
});
});
};
/**
* Draws a tile projected into the specified projection, bounded by the specified by the bounds in EPSG:4326 into the canvas or the image is returned if no canvas is passed in.
* @param {string} table name of the table containing the tiles
* @param {Number} minLat minimum latitude bounds of tile
* @param {Number} minLon minimum longitude bounds of tile
* @param {Number} maxLat maximum latitude bounds of tile
* @param {Number} maxLon maximum longitude bounds of tile
* @param {Number} z zoom level of the tile
* @param {string} projection project from tile's projection to this one.
* @param {Number} width width of the resulting tile
* @param {Number} height height of the resulting tile
* @param {any} canvas canvas element to draw the tile into
*/
GeoPackage.prototype.projectedTile = function (table, minLat, minLon, maxLat, maxLon, z, projection, width, height, canvas) {
if (projection === void 0) { projection = projectionConstants_1.ProjectionConstants.EPSG_4326; }
if (width === void 0) { width = 256; }
if (height === void 0) { height = 256; }
return __awaiter(this, void 0, void 0, function () {
var tileDao, retriever, bounds;
return __generator(this, function (_a) {
tileDao = this.getTileDao(table);
retriever = new retriever_1.GeoPackageTileRetriever(tileDao, width, height);
bounds = new boundingBox_1.BoundingBox(minLon, maxLon, minLat, maxLat);
return [2 /*return*/, retriever.getTileWithWgs84BoundsInProjection(bounds, z, projection, canvas)];
});
});
};
GeoPackage.prototype.getInfoForTable = function (tableDao) {
var info = {
tableName: tableDao.table_name,
tableType: tableDao.table.tableType,
count: tableDao.getCount(),
geometryColumns: undefined,
minZoom: undefined,
maxZoom: undefined,
minWebMapZoom: undefined,
maxWebMapZoom: undefined,
zoomLevels: undefined,
tileMatrixSet: undefined,
contents: undefined,
srs: undefined,
columns: undefined,
columnMap: undefined,
};
if (tableDao instanceof featureDao_1.FeatureDao) {
info.geometryColumns = {
tableName: tableDao.geometryColumns.table_name,
geometryColumn: tableDao.geometryColumns.column_name,
geometryTypeName: tableDao.geometryColumns.geometry_type_name,
z: tableDao.geometryColumns.z,
m: tableDao.geometryColumns.m,
};
}
if (tableDao instanceof tileDao_1.TileDao) {
info.minZoom = tableDao.minZoom;
info.maxZoom = tableDao.maxZoom;
info.minWebMapZoom = tableDao.minWebMapZoom;
info.maxWebMapZoom = tableDao.maxWebMapZoom;
info.zoomLevels = tableDao.tileMatrices.length;
}
var contents;
if (tableDao instanceof featureDao_1.FeatureDao) {
contents = this.geometryColumnsDao.getContents(tableDao.geometryColumns);
}
else if (tableDao instanceof tileDao_1.TileDao) {
contents = this.tileMatrixSetDao.getContents(tableDao.tileMatrixSet);
info.tileMatrixSet = {
srsId: tableDao.tileMatrixSet.srs_id,
minX: tableDao.tileMatrixSet.min_x,
maxX: tableDao.tileMatrixSet.max_x,
minY: tableDao.tileMatrixSet.min_y,
maxY: tableDao.tileMatrixSet.max_y,
};
}
var contentsSrs = this.contentsDao.getSrs(contents);
info.contents = {
tableName: contents.table_name,
dataType: contents.data_type,
identifier: contents.identifier,
description: contents.description,
lastChange: contents.last_change,
minX: contents.min_x,
maxX: contents.max_x,
minY: contents.min_y,
maxY: contents.max_y,
srs: {
name: contentsSrs.srs_name,
id: contentsSrs.srs_id,
organization: contentsSrs.organization,
organization_coordsys_id: contentsSrs.organization_coordsys_id,
definition: contentsSrs.definition,
description: contentsSrs.description,
},
};
info.contents.srs = {
name: contentsSrs.srs_name,
id: contentsSrs.srs_id,
organization: contentsSrs.organization,
organization_coordsys_id: contentsSrs.organization_coordsys_id,
definition: contentsSrs.definition,
description: contentsSrs.description,
};
var srs = tableDao.srs;
info.srs = {
name: srs.srs_name,
id: srs.srs_id,
organization: srs.organization,
organization_coordsys_id: srs.organization_coordsys_id,
definition: srs.definition,
description: srs.description,
};
info.columns = [];
info.columnMap = {};
var dcd = this.dataColumnsDao;
tableDao.table.getUserColumns().getColumns().forEach(function (column) {
var dataColumn = dcd.getDataColumns(tableDao.table.getTableName(), column.name);
info.columns.push({
index: column.index,
name: column.name,
max: column.max,
min: column.min,
notNull: column.notNull,
primaryKey: column.primaryKey,
dataType: column.dataType,
displayName: dataColumn && dataColumn.name ? dataColumn.name : column.name,
dataColumn: dataColumn,
});
info.columnMap[column.name] = info.columns[info.columns.length - 1];
}.bind(this));
return info;
};
GeoPackage.addProjection = function (name, definition) {
if (!name || !definition)
throw new Error('Invalid projection name/definition');
proj4_1.default.defs(name, definition);
};
GeoPackage.hasProjection = function (name) {
return proj4_1.default.defs(name);
};
GeoPackage.prototype.renameTable = function (tableName, newTableName) {
var tableDataType = this.getTableDataType(tableName);
if (tableDataType !== null && tableDataType !== undefined) {
this.copyTableAndExtensions(tableName, newTableName);
this.deleteTable(tableName);
}
else {
alterTable_1.AlterTable.renameTable(this.connection, tableName, newTableName);
}
};
GeoPackage.prototype.copyTableAndExtensions = function (tableName, newTableName) {
this.copyTable(tableName, newTableName, true, true);
};
GeoPackage.prototype.copyTableNoExtensions = function (tableName, newTableName) {
this.copyTable(tableName, newTableName, true, false);
};
GeoPackage.prototype.copyTableAsEmpty = function (tableName, newTableName) {
this.copyTable(tableName, newTableName, false, false);
};
GeoPackage.prototype.getTableDataType = function (tableName) {
var tableType = null;
var contentsDao = this.contentsDao;
var contents = contentsDao.queryForId(tableName);
if (contents !== null && contents !== undefined) {
tableType = contents.data_type;
}
return tableType;
};
/**
* Copy the table
* @param tableName table name
* @param newTableName new table name
* @param transferContent transfer content flag
* @param extensions extensions copy flag
*/
GeoPackage.prototype.copyTable = function (tableName, newTableName, transferContent, extensions) {
var dataType = this.getTableDataType(tableName);
if (dataType !== null && dataType !== undefined) {
switch (dataType) {
case contentsDataType_1.ContentsDataType.ATTRIBUTES:
this.copyAttributeTable(tableName, newTableName, transferContent);
break;
case contentsDataType_1.ContentsDataType.FEATURES:
this.copyFeatureTable(tableName, newTableName, transferContent);
break;
case contentsDataType_1.ContentsDataType.TILES:
this.copyTileTable(tableName, newTableName, transferContent);
break;
default:
throw new Error('Unsupported data type: ' + dataType);
}
}
else {
this.copyUserTable(tableName, newTableName, transferContent, false);
}
// Copy extensions
if (extensions) {
geoPackageExtensions_1.GeoPackageExtensions.copyTableExtensions(this, tableName, newTableName);
}
};
/**
* Copy the attribute table
* @param tableName table name
* @param newTableName new table name
* @param transferContent transfer content flag
*/
GeoPackage.prototype.copyAttributeTable = function (tableName, newTableName, transferContent) {
this.copyUserTable(tableName, newTableName, transferContent);
};
/**
* Copy the feature table
* @param tableName table name
* @param newTableName new table name
* @param transferContent transfer content flag
*/
GeoPackage.prototype.copyFeatureTable = function (tableName, newTableName, transferContent) {
var geometryColumnsDao = this.geometryColumnsDao;
var geometryColumns = null;
try {
geometryColumns = geometryColumnsDao.queryForTableName(tableName);
}
catch (e) {
throw new Error('Failed to retrieve table geometry columns: ' + tableName);
}
if (geometryColumns === null || geometryColumns === undefined) {
throw new Error('No geometry columns for table: ' + tableName);
}
var contents = this.copyUserTable(tableName, newTableName, transferContent);
geometryColumns.setContents(contents);
try {
geometryColumnsDao.create(geometryColumns);
}
catch (e) {
throw new Error('Failed to create geometry columns for feature table: ' + newTableName);
}
};
/**
* Copy the tile table
* @param tableName table name
* @param newTableName new table name
* @param transferContent transfer content flag
*/
GeoPackage.prototype.copyTileTable = function (tableName, newTableName, transferContent) {
var tileMatrixSetDao = this.tileMatrixSetDao;
var tileMatrixSet = null;
try {
tileMatrixSet = tileMatrixSetDao.queryForId(tableName);
}
catch (e) {
throw new Error('Failed to retrieve table tile matrix set: ' + tableName);
}
if (tileMatrixSet === null || tileMatrixSet === undefined) {
throw new Error('No tile matrix set for table: ' + tableName);
}
var tileMatrixDao = this.tileMatrixDao;
var tileMatrices = null;
try {
tileMatrices = tileMatrixDao.queryForAllEq(tileMatrixDao_1.TileMatrixDao.COLUMN_TABLE_NAME, tableName).map(function (results) { return tileMatrixDao.createObject(results); });
}
catch (e) {
throw new Error('Failed to retrieve table tile matrices: ' + tableName);
}
var contents = this.copyUserTable(tableName, newTableName, transferContent);
tileMatrixSet.contents = contents;
try {
tileMatrixSetDao.create(tileMatrixSet);
}
catch (e) {
throw new Error('Failed to create tile matrix set for tile table: ' + newTableName);
}
tileMatrices.forEach(function (tileMatrix) {
tileMatrix.contents = contents;
try {
tileMatrixDao.create(tileMatrix);
}
catch (e) {
throw new Error('Failed to create tile matrix for tile table: ' + newTableName);
}
});
};
/**
* Copy the user table
*
* @param tableName table name
* @param newTableName new table name
* @param transferContent transfer user table content flag
* @param validateContents true to validate a contents was copied
* @return copied contents
* @since 3.3.0
*/
GeoPackage.prototype.copyUserTable = function (tableName, newTableName, transferContent, validateContents) {
if (validateContents === void 0) { validateContents = true; }
alterTable_1.AlterTable.copyTableWithName(this.database, tableName, newTableName, transferContent);
var contents = this.copyContents(tableName, newTableName);
if ((contents === null || contents === undefined) && validateContents) {
throw new Error('No table contents found for table: ' + tableName);
}
return contents;
};
/**
* Copy the contents
* @param tableName table name
* @param newTableName new table name
* @return copied contents
*/
GeoPackage.prototype.copyContents = function (tableName, newTableName) {
var contents = this.getTableContents(tableName);
if (contents !== null && contents !== undefined) {
contents.table_name = newTableName;
contents.identifier = newTableName;
try {
this.contentsDao.create(contents);
}
catch (e) {
throw new Error('Failed to create contents for table: ' + newTableName + ', copied from table: ' + tableName);
}
}
return contents;
};
return GeoPackage;
}());
exports.GeoPackage = GeoPackage;
//# sourceMappingURL=geoPackage.js.map