@letsnova/potree
Version:
WebGL point cloud viewer
1,211 lines (1,091 loc) • 5.98 MB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.geopackage = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
module.exports = require('./lib/api');
var proj4Defs = require('./lib/proj4Defs');
module.exports.proj4Defs = proj4Defs;
module.exports.GeoPackageTileRetriever = require('./lib/tiles/retriever');
module.exports.GeoPackageConnection = require('./lib/db/geoPackageConnection');
module.exports.TableCreator = require('./lib/db/tableCreator');
module.exports.MediaTable = require('./lib/extension/relatedTables/mediaTable');
module.exports.UserMappingTable = require('./lib/extension/relatedTables/userMappingTable');
module.exports.DublinCoreType = require('./lib/extension/relatedTables/dublinCoreType');
module.exports.TileColumn = require('./lib/tiles/user/tileColumn');
module.exports.BoundingBox = require('./lib/boundingBox');
module.exports.TileUtilities = require('./lib/tiles/creator/tileUtilities');
module.exports.FeatureColumn = require('./lib/features/user/featureColumn');
module.exports.UserColumn = require('./lib/user/userColumn');
module.exports.GeometryColumns = require('./lib/features/columns').GeometryColumns;
module.exports.GeometryData = require('./lib/geom/geometryData');
module.exports.DataColumns = require('./lib/dataColumns').DataColumns;
module.exports.DataTypes = require('./lib/db/dataTypes');
module.exports.Metadata = require('./lib/metadata').Metadata;
module.exports.MetadataReference = require('./lib/metadata/reference').MetadataReference;
module.exports.RTreeIndex = require('./lib/extension/rtree').RTreeIndex;
module.exports.CrsWktExtension = require('./lib/extension/crsWkt').CrsWktExtension;
module.exports.SchemaExtension = require('./lib/extension/schema').SchemaExtension;
module.exports.MetadataExtension = require('./lib/extension/metadata').MetadataExtension;
module.exports.WebPExtension = require('./lib/extension/webp').WebPExtension;
module.exports.DataColumnsDao = require('./lib/dataColumns').DataColumnsDao;
module.exports.DataColumnConstraintsDao = require('./lib/dataColumnConstraints').DataColumnConstraintsDao;
},{"./lib/api":2,"./lib/boundingBox":7,"./lib/dataColumnConstraints":12,"./lib/dataColumns":13,"./lib/db/dataTypes":14,"./lib/db/geoPackageConnection":15,"./lib/db/tableCreator":19,"./lib/extension/crsWkt":24,"./lib/extension/metadata":29,"./lib/extension/relatedTables/dublinCoreType":30,"./lib/extension/relatedTables/mediaTable":35,"./lib/extension/relatedTables/userMappingTable":42,"./lib/extension/rtree":44,"./lib/extension/schema":45,"./lib/extension/webp":63,"./lib/features/columns":64,"./lib/features/user/featureColumn":65,"./lib/geom/geometryData":73,"./lib/metadata":74,"./lib/metadata/reference":75,"./lib/proj4Defs":77,"./lib/tiles/creator/tileUtilities":82,"./lib/tiles/retriever":92,"./lib/tiles/user/tileColumn":95,"./lib/user/userColumn":105}],2:[function(require,module,exports){
(function (process){
var wkx = require('wkx')
, reproject = require('reproject')
, path = require('path')
, fs = require('fs')
, geojsonvt = require('geojson-vt')
, vtpbf = require('vt-pbf')
, Pbf = require('pbf')
, VectorTile = require('@mapbox/vector-tile');
var GeoPackage = require('./geoPackage')
, GeoPackageValidate = require('./validate/geoPackageValidate')
, GeoPackageTileRetriever = require('./tiles/retriever')
, GeoPackageConnection = require('./db/geoPackageConnection')
, BoundingBox = require('./boundingBox')
, GeometryData = require('./geom/geometryData')
, TableCreator = require('./db/tableCreator')
, TileBoundingBoxUtils = require('./tiles/tileBoundingBoxUtils')
, FeatureTile = require('./tiles/features')
, FeatureTableIndex = require('./extension/index/featureTableIndex')
, DataColumnsDao = require('./dataColumns').DataColumnsDao
, DataColumns = require('./dataColumns').DataColumns
, DataTypes = require('./db/dataTypes')
, GeometryColumns = require('./features/columns').GeometryColumns
, FeatureColumn = require('./features/user/featureColumn')
, RelationType = require('./extension/relatedTables/relationType')
, MediaTable = require('./extension/relatedTables/mediaTable')
, SimpleAttributesTable = require('./extension/relatedTables/simpleAttributesTable')
, UserColumn = require('./user/userColumn');
/**
* This module is the entry point to the GeoPackage API, providing static
* methods for opening and building GeoPackage files.
*
* @exports api
*/
var GeoPackageAPI = module.exports;
/**
* In Node, open a GeoPackage file at the given path, or in a browser, load an
* in-memory GeoPackage from the given byte array.
* @param {String|Uint8Array} gppathOrByteArray path to the GeoPackage file or `Uint8Array` of GeoPackage bytes
* @param {geopackageCallback=} callback called with an `Error` if one occurred and the open `GeoPackage` object
* @return {Promise} promise that resolves with the open {@link module:geoPackage~GeoPackage} object or rejects with an `Error`
*/
GeoPackageAPI.open = function(gppathOrByteArray, callback) {
return new Promise(function(resolve, reject) {
var valid = (typeof gppathOrByteArray !== 'string') || (typeof gppathOrByteArray === 'string' &&
(gppathOrByteArray.indexOf('http') === 0 || !GeoPackageValidate.validateGeoPackageExtension(gppathOrByteArray)));
if (!valid) {
reject(new Error('Invalid GeoPackage - Invalid GeoPackage Extension'));
} else {
resolve(gppathOrByteArray);
}
}).then(function() {
return GeoPackageConnection.connect(gppathOrByteArray);
}).then(function(connection) {
if (gppathOrByteArray && typeof gppathOrByteArray === 'string') {
return new GeoPackage(path.basename(gppathOrByteArray), gppathOrByteArray, connection);
} else {
return new GeoPackage('geopackage', undefined, connection);
}
})
.then(function(geoPackage) {
if (GeoPackageValidate.hasMinimumTables(geoPackage)) {
return geoPackage;
} else {
throw new Error('Invalid GeoPackage - GeoPackage does not have the minimum required tables');
}
})
.then(function(geoPackage) {
if(callback) callback(null, geoPackage);
return geoPackage;
})
.catch(function(error){
if(callback) {
callback(error);
} else {
throw error;
}
});
};
/**
* In Node, create a GeoPackage file at the given file path, or in a browser,
* create an in-memory GeoPackage.
* @param {String|geopackageCallback} gppath path of the created GeoPackage file; ignored in the browser
* @param {geopackageCallback=} callback called with an `Error` if one occurred and the open {@link module:geoPackage~GeoPackage} object
* @return {Promise} promise that resolves with the open {@link module:geoPackage~GeoPackage} object or rejects with an `Error`
*/
GeoPackageAPI.create = function(gppath, callback) {
if (typeof gppath == 'function') {
callback = gppath;
gppath = undefined;
}
var valid = (typeof gppath !== 'string') || (typeof gppath === 'string' && !GeoPackageValidate.validateGeoPackageExtension(gppath));
if (!valid) {
if (callback) {
return callback(new Error('Invalid GeoPackage'));
}
return Promise.reject(new Error('Invalid GeoPackage'));
}
var promise = new Promise(function(resolve, reject) {
if (typeof(process) !== 'undefined' && process.version && gppath) {
fs.mkdirSync(path.dirname(gppath));
}
resolve(gppath);
})
.catch(function(error) {
// could not create directory, just move on
})
.then(function() {
return GeoPackageConnection.connect(gppath);
})
.then(function(connection) {
connection.setApplicationId();
return connection;
})
.then(function(connection) {
if (gppath) {
return new GeoPackage(path.basename(gppath), gppath, connection);
} else {
return new GeoPackage('geopackage', undefined, connection);
}
})
.then(function(geopackage) {
return geopackage.createRequiredTables();
})
.then(function(geopackage) {
return geopackage.createSupportedExtensions();
})
.then(function(geopackage) {
if (callback) callback(null, geopackage);
return geopackage;
})
.catch(function(error){
if (callback) {
callback(error);
} else {
throw error;
}
});
return promise;
};
/**
* 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 {module:geoPackage~GeoPackage} geopackage the GeoPackage that will store the tiles
* @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 {number=} 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
*/
GeoPackageAPI.createStandardWebMercatorTileTable = function(geopackage, tableName, contentsBoundingBox, contentsSrsId, tileMatrixSetBoundingBox, tileMatrixSetSrsId, minZoom, maxZoom, tileSize) {
tileSize = tileSize || 256;
return geopackage.createTileTableWithTableName(tableName, contentsBoundingBox, contentsSrsId, tileMatrixSetBoundingBox, tileMatrixSetSrsId)
.then(function(tileMatrixSet) {
geopackage.createStandardWebMercatorTileMatrix(tileMatrixSetBoundingBox, tileMatrixSet, minZoom, maxZoom, tileSize);
return tileMatrixSet;
});
}
GeoPackageAPI.createFeatureTable = function(geopackage, tableName, geometryColumn, featureColumns) {
return GeoPackageAPI.createFeatureTableWithDataColumns(geopackage, tableName, geometryColumn, featureColumns, null);
};
GeoPackageAPI.createFeatureTableWithDataColumns = function(geopackage, tableName, geometryColumn, featureColumns, dataColumns) {
var boundingBox = new BoundingBox(-180, 180, -90, 90);
return GeoPackageAPI.createFeatureTableWithDataColumnsAndBoundingBox(geopackage, tableName, geometryColumn, featureColumns, dataColumns, boundingBox, 4326);
};
GeoPackageAPI.createFeatureTableWithDataColumnsAndBoundingBox = function(geopackage, tableName, geometryColumn, featureColumns, dataColumns, boundingBox, boundingBoxSrsId) {
return geopackage.createFeatureTableWithGeometryColumnsAndDataColumns(geometryColumn, boundingBox, boundingBoxSrsId, featureColumns, dataColumns)
.then(function() {
return geopackage.getFeatureDao(tableName);
});
};
/**
* Create a feature table with the properties specified.
* @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}
*/
GeoPackageAPI.createFeatureTableWithProperties = function(geopackage, tableName, properties) {
var geometryColumns = new GeometryColumns();
geometryColumns.table_name = tableName;
geometryColumns.column_name = 'geometry';
geometryColumns.geometry_type_name = 'GEOMETRY';
geometryColumns.z = 0;
geometryColumns.m = 0;
var boundingBox = new BoundingBox(-180, 180, -80, 80);
var columns = [];
var columnNumber = 0;
columns.push(FeatureColumn.createPrimaryKeyColumnWithIndexAndName(columnNumber++, 'id'));
columns.push(FeatureColumn.createGeometryColumn(columnNumber++, 'geometry', 'GEOMETRY', false, null));
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
columns.push(FeatureColumn.createColumnWithIndex(columnNumber++, property.name, DataTypes.fromName(property.dataType)));
}
return geopackage.createFeatureTableWithGeometryColumns(geometryColumns, boundingBox, 4326, columns);
};
/**
* Create a feature table with the properties specified.
* @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}
*/
GeoPackageAPI.createAttributeTableWithProperties = function(geopackage, tableName, properties) {
var columns = [];
var columnNumber = 0;
columns.push(UserColumn.createPrimaryKeyColumnWithIndexAndName(columnNumber++, 'id'));
var dataColumns = [];
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
columns.push(UserColumn.createColumnWithIndex(columnNumber++, property.name, DataTypes.fromName(property.dataType)));
if (property.dataColumn) {
var dc = new 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 geopackage.createAttributeTable(tableName, columns, dataColumns.length ? dataColumns : undefined);
};
GeoPackageAPI.addAttributeRow = function(geopackage, tableName, row) {
var attributeDao = geopackage.getAttributeDaoWithTableName(tableName);
var attributeRow = attributeDao.newRow(row);
return attributeDao.create(attributeRow);
}
/**
* Create a simple attributes table with the properties specified.
* @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}
*/
GeoPackageAPI.createSimpleAttributesTableWithProperties = function(geopackage, tableName, properties) {
var relatedTables = geopackage.getRelatedTablesExtension();
var columns = [];
var columnNumber = SimpleAttributesTable.numRequiredColumns();
if (properties) {
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
columns.push(UserColumn.createColumnWithIndex(columnNumber++, property.name, DataTypes.fromName(property.dataType), true));
}
}
var simpleAttributesTable = SimpleAttributesTable.create(tableName, columns);
relatedTables.createRelatedTable(simpleAttributesTable);
return relatedTables.getSimpleAttributesDao(simpleAttributesTable);
};
/**
* 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}
*/
GeoPackageAPI.createMediaTableWithProperties = function(geopackage, tableName, properties) {
var relatedTables = geopackage.getRelatedTablesExtension();
var columns = [];
var columnNumber = MediaTable.numRequiredColumns();
if (properties) {
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
columns.push(UserColumn.createColumnWithIndex(columnNumber++, property.name, DataTypes.fromName(property.dataType)));
}
}
var mediaTable = MediaTable.create(tableName, columns)
relatedTables.createRelatedTable(mediaTable);
return relatedTables.getMediaDao(mediaTable);
};
GeoPackageAPI.addMedia = function(geopackage, tableName, dataBuffer, contentType, additionalProperties) {
var relatedTables = geopackage.getRelatedTablesExtension();
var mediaDao = relatedTables.getMediaDao(tableName);
var row = mediaDao.newRow();
row.setContentType(contentType);
row.setData(dataBuffer);
for (var key in additionalProperties) {
row.setValueWithColumnName(key, additionalProperties[key]);
}
return mediaDao.create(row);
}
GeoPackageAPI.linkMedia = function(geopackage, baseTableName, baseId, mediaTableName, mediaId) {
var relatedTables = geopackage.getRelatedTablesExtension();
return relatedTables.linkRelatedIds(baseTableName, baseId, mediaTableName, mediaId, RelationType.MEDIA);
}
GeoPackageAPI.getLinkedMedia = function(geopackage, baseTableName, baseId) {
var relationships = GeoPackageAPI.getRelatedRows(geopackage, baseTableName, baseId);
var mediaRelationships = [];
for (var i = 0; i < relationships.length; i++) {
var relationship = relationships[i];
if (relationship.relation_name === RelationType.MEDIA.name) {
for (var r = 0; r < relationship.mappingRows.length; r++) {
var row = relationship.mappingRows[r].row;
mediaRelationships.push(row);
}
}
}
return mediaRelationships;
}
GeoPackageAPI.getRelatedRows = function(geopackage, baseTableName, baseId) {
return geopackage.getRelatedTablesExtension().getRelatedRows(baseTableName, baseId);
}
/**
* Adds a GeoJSON feature to the GeoPackage
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @param {object} feature GeoJSON feature to add
* @param {String} tableName name of the table that will store the feature
*/
GeoPackageAPI.addGeoJSONFeatureToGeoPackage = function(geopackage, feature, tableName) {
var featureDao = geopackage.getFeatureDao(tableName);
var srs = featureDao.getSrs();
var featureRow = featureDao.newRow();
var geometryData = new GeometryData();
geometryData.setSrsId(srs.srs_id);
var srs = featureDao.getSrs();
if (!(srs.organization === 'EPSG' && srs.organization_coordsys_id === 4326)) {
feature = reproject.reproject(feature, 'EPSG:4326', featureDao.projection);
}
var featureGeometry = typeof feature.geometry === 'string' ? JSON.parse(feature.geometry) : feature.geometry;
var geometry = wkx.Geometry.parseGeoJSON(featureGeometry);
geometryData.setGeometry(geometry);
featureRow.setGeometry(geometryData);
for (var propertyKey in feature.properties) {
if (feature.properties.hasOwnProperty(propertyKey)) {
featureRow.setValueWithColumnName(propertyKey, feature.properties[propertyKey]);
}
}
return featureDao.create(featureRow);
};
/**
* Adds a GeoJSON feature to the GeoPackage and updates the FeatureTableIndex extension if it exists
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @param {object} feature GeoJSON feature to add
* @param {String} tableName name of the table that will store the feature
*/
GeoPackageAPI.addGeoJSONFeatureToGeoPackageAndIndex = function(geopackage, feature, tableName) {
var featureDao = geopackage.getFeatureDao(tableName);
if (!featureDao) throw new Error('No feature Dao for table ', + tableName);
var srs = featureDao.getSrs();
var featureRow = featureDao.newRow();
var geometryData = new GeometryData();
geometryData.setSrsId(srs.srs_id);
var reprojectedFeature = reproject.reproject(feature, 'EPSG:4326', featureDao.projection);
var featureGeometry = typeof reprojectedFeature.geometry === 'string' ? JSON.parse(reprojectedFeature.geometry) : reprojectedFeature.geometry;
var geometry = wkx.Geometry.parseGeoJSON(featureGeometry);
geometryData.setGeometry(geometry);
featureRow.setGeometry(geometryData);
for (var propertyKey in feature.properties) {
if (feature.properties.hasOwnProperty(propertyKey)) {
featureRow.setValueWithColumnName(propertyKey, feature.properties[propertyKey]);
}
}
var id = featureDao.create(featureRow);
var fti = featureDao.featureTableIndex;
var tableIndex = fti.getTableIndex();
if (!tableIndex) return id;
fti.indexRow(tableIndex, id, geometryData);
fti.updateLastIndexed(tableIndex);
return id;
};
/**
* Queries for GeoJSON features in a feature tables
* @param {String} geoPackagePath path to the GeoPackage file
* @param {String} tableName Table name to query
* @param {BoundingBox} boundingBox BoundingBox to query
* @param {Function} callback Caled with err, featureArray
*/
GeoPackageAPI.queryForGeoJSONFeaturesInTableFromPath = function(geoPackagePath, tableName, boundingBox) {
return GeoPackageAPI.open(geoPackagePath)
.then(function(geoPackage) {
var features = geoPackage.queryForGeoJSONFeaturesInTable(tableName, boundingBox);
geoPackage.close();
return features;
});
}
/**
* Queries for GeoJSON features in a feature tables
* @param {module:geoPackage~GeoPackage} geoPackage open GeoPackage object
* @param {String} tableName Table name to query
* @param {BoundingBox} boundingBox BoundingBox to query
* @param {Function} callback Caled with err, featureArray
*/
GeoPackageAPI.queryForGeoJSONFeaturesInTable = function(geoPackage, tableName, boundingBox) {
return geoPackage.queryForGeoJSONFeaturesInTable(tableName, boundingBox);
}
/**
* Iterates GeoJSON features in a feature table that matches the bounding box
* @param {module:geoPackage~GeoPackage} geoPackage open GeoPackage object
* @param {String} tableName Table name to query
* @param {BoundingBox} boundingBox BoundingBox to query
* @param {Function} rowCallback Caled with err, and GeoJSON feature
* @param {Function} doneCallback Caled with err if one occurred
*/
GeoPackageAPI.iterateGeoJSONFeaturesInTableWithinBoundingBox = function(geoPackage, tableName, boundingBox) {
return geoPackage.iterateGeoJSONFeaturesInTableWithinBoundingBox(tableName, boundingBox);
}
/**
* Iterates GeoJSON features in a feature table that matches the bounding box
* @param {String} geoPackagePath path to the GeoPackage file
* @param {String} tableName Table name to query
* @param {BoundingBox} boundingBox BoundingBox to query
* @param {Function} rowCallback Caled with err, and GeoJSON feature
* @param {Function} doneCallback Caled with err if one occurred
*/
GeoPackageAPI.iterateGeoJSONFeaturesFromPathInTableWithinBoundingBox = function(geoPackagePath, tableName, boundingBox) {
return GeoPackageAPI.open(geoPackagePath)
.then(function(geoPackage) {
return geoPackage.iterateGeoJSONFeaturesInTableWithinBoundingBox(tableName, boundingBox);
});
}
GeoPackageAPI.createDataColumnMap = function(featureDao) {
var columnMap = {};
var dcd = new DataColumnsDao(featureDao.geoPackage);
featureDao.table.columns.forEach(function(column) {
var dataColumn = dcd.getDataColumns(featureDao.table.table_name, 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 ? DataTypes.name(column.dataType) : '',
displayName: dataColumn && dataColumn.name ? dataColumn.name : column.name,
dataColumn: dataColumn
};
}.bind(this));
return columnMap;
}
/**
* Iterate GeoJSON features from table
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @param {String} table Table name to Iterate
* @return {Iterator<module:user/feature/featureRow~FeatureRow>}
*/
GeoPackageAPI.iterateGeoJSONFeaturesFromTable = function(geopackage, table) {
var featureDao = geopackage.getFeatureDao(table);
if (!featureDao) {
throw new Error('No Table exists with the name ' + table);
}
var columnMap = GeoPackageAPI.createDataColumnMap(featureDao);
var srs = featureDao.getSrs();
var iterator = featureDao.queryForEach();
return {
srs: srs,
featureDao: featureDao,
results: {
[Symbol.iterator]() {
return this;
},
next: function() {
var nextRow = iterator.next();
if (!nextRow.done) {
var featureRow;
var geometry;
while(!nextRow.done && !geometry) {
featureRow = featureDao.getRow(nextRow.value);
return {
value: GeoPackageAPI.parseFeatureRowIntoGeoJSON(featureRow, srs, columnMap),
done: false
};
}
}
return {
done: true
}
}.bind(this)
}
};
};
/**
* 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
* @param {Function} callback called with an error if one occurred and the GeoJSON feature
*/
GeoPackageAPI.getFeature = function(geopackage, table, featureId) {
var srs;
var featureDao = geopackage.getFeatureDao(table)
srs = featureDao.getSrs();
var feature = featureDao.queryForId(featureId);
if (!feature) {
var features = featureDao.queryForAllEq('_feature_id', featureId)
if (features.length) {
feature = featureDao.getRow(features[0]);
} else {
var features = featureDao.queryForAllEq('_properties_id', featureId)
if (features.length) {
feature = featureDao.getRow(features[0]);
}
}
}
if (feature) {
return GeoPackageAPI.parseFeatureRowIntoGeoJSON(feature, srs);
}
};
GeoPackageAPI.parseFeatureRowIntoGeoJSON = function(featureRow, srs, columnMap) {
var geoJson = {
type: 'Feature',
properties: {}
};
var geometry = featureRow.getGeometry();
if (geometry && geometry.geometry) {
var geom = geometry.geometry;
var geoJsonGeom = geometry.geometry.toGeoJSON();
if (srs.definition && srs.definition !== 'undefined' && (srs.organization.toUpperCase() + ':' + srs.organization_coordsys_id) != 'EPSG:4326') {
// geoJsonGeom = reproject.reproject(geoJsonGeom, srs.organization.toUpperCase() + ':' + srs.organization_coordsys_id, 'EPSG:4326');
geoJsonGeom = reproject.reproject(geoJsonGeom, srs.getProjection(), 'EPSG:4326');
}
geoJson.geometry = geoJsonGeom;
}
for (var key in featureRow.values) {
if(featureRow.values.hasOwnProperty(key) && key != featureRow.getGeometryColumn().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.getGeometryColumn().name === key) {
// geoJson.properties[key] = geometry && !geometry.geometryError ? 'Valid' : geometry.geometryError;
}
}
geoJson.id = geoJson.id || featureRow.getId();
return geoJson;
}
/**
* Gets a tile from the specified table
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @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
*/
GeoPackageAPI.getTileFromTable = function(geopackage, table, zoom, tileRow, tileColumn) {
var tileDao = geopackage.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
* @param {Function} callback called with an error if one occurred and a tiles object describing the tiles
*/
GeoPackageAPI.getTilesInBoundingBox = function(geopackage, table, zoom, west, east, south, north) {
var tiles = {};
var tileDao = geopackage.getTileDao(table);
if (zoom < tileDao.minZoom || zoom > tileDao.maxZoom) {
return
}
tiles.columns = [];
for (var i = 0; i < tileDao.table.columns.length; i++) {
var column = tileDao.table.columns[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.getSrs();
tiles.srs = srs;
tiles.tiles = [];
var tms = tileDao.tileMatrixSet;
var tm = tileDao.getTileMatrixWithZoomLevel(zoom);
if (!tm) {
return tiles;
}
var mapBoundingBox = new 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('EPSG:4326', tileDao.srs.organization.toUpperCase() + ':' + tileDao.srs.organization_coordsys_id);
var grid = TileBoundingBoxUtils.getTileGridWithTotalBoundingBox(tms.getBoundingBox(), tm.matrix_width, tm.matrix_height, mapBoundingBox);
var iterator = tileDao.queryByTileGrid(grid, zoom);
for (var row of iterator ) {
var tile = {};
tile.tableName = table;
tile.id = row.getId();
var tileBB = TileBoundingBoxUtils.getTileBoundingBox(tms.getBoundingBox(), tm, row.getTileColumn(), row.getRow());
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);
}
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} 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
* @param {Function} callback called with an error if one occurred and a tiles object describing the tiles
*/
GeoPackageAPI.getTilesInBoundingBoxWebZoom = function(geopackage, table, webZoom, west, east, south, north) {
var tiles = {};
var tileDao = geopackage.getTileDao(table);
if (webZoom < tileDao.minWebZoom || webZoom > tileDao.maxWebZoom) {
return;
}
tiles.columns = [];
for (var i = 0; i < tileDao.table.columns.length; i++) {
var column = tileDao.table.columns[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.getSrs();
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(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('EPSG:4326', tileDao.srs.organization.toUpperCase() + ':' + tileDao.srs.organization_coordsys_id);
var grid = TileBoundingBoxUtils.getTileGridWithTotalBoundingBox(tms.getBoundingBox(), tm.matrix_width, tm.matrix_height, mapBoundingBox);
var iterator = tileDao.queryByTileGrid(grid, zoom);
for (var row of iterator) {
var tile = {};
tile.tableName = table;
tile.id = row.getId();
var tileBB = TileBoundingBoxUtils.getTileBoundingBox(tms.getBoundingBox(), tm, row.getTileColumn(), row.getRow());
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);
}
return tiles;
};
GeoPackageAPI.getFeatureTileFromXYZ = function(geopackage, table, x, y, z, width, height) {
x = Number(x);
y = Number(y);
z = Number(z);
width = Number(width);
height = Number(height);
var featureDao = geopackage.getFeatureDao(table)
if (!featureDao) return;
var ft = new FeatureTile(featureDao, width, height);
return ft.drawTile(x, y, z);
}
/**
* Gets the features in the EPSG:4326 bounding box
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @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
*/
GeoPackageAPI.getGeoJSONFeaturesInTile = function(geopackage, table, x, y, z, skipVerification) {
var webMercatorBoundingBox = TileBoundingBoxUtils.getWebMercatorBoundingBoxFromXYZ(x, y, z);
var bb = webMercatorBoundingBox.projectBoundingBox('EPSG:3857', 'EPSG:4326');
return geopackage.indexFeatureTable(table)
.then(function(indexed) {
return geopackage.getFeatureDao(table);
})
.then(function(featureDao) {
if (!featureDao) return;
var features = [];
var iterator = featureDao.queryForGeoJSONIndexedFeaturesWithBoundingBox(bb, skipVerification);
for (var feature of iterator) {
features.push(feature);
}
return features;
})
.catch(function(error) {
console.log('error', error);
});
}
GeoPackageAPI.convertPBFToVectorTile = function(pbf) {
return new VectorTile.VectorTile(new Pbf(pbf));
}
/**
* Gets a mapbox VectorTile for the x y z web mercator tile specified
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @param {String} table table name
* @param {Number} x x tile
* @param {Number} y y tile
* @param {Number} z web zoom
* @return {VectorTile}
*/
GeoPackageAPI.getVectorTile = function(geopackage, table, x, y, z) {
return GeoPackageAPI.getVectorTileProtobuf(geopackage, table, x, y, z)
.then(function(pbf) {
return new VectorTile.VectorTile(new Pbf(pbf));
});
}
/**
* Gets a protobuf for the x y z web mercator tile specified
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @param {String} table table name
* @param {Number} x x tile
* @param {Number} y y tile
* @param {Number} z web zoom
* @return {Protobuf}
*/
GeoPackageAPI.getVectorTileProtobuf = function(geopackage, table, x, y, z) {
return GeoPackageAPI.getGeoJSONFeaturesInTile(geopackage, table, x, y, z, true)
.then(function(features) {
var featureCollection = {
type: 'FeatureCollection',
features: features
};
var tileBuffer = 8;
var tileIndex = geojsonvt(featureCollection, {buffer: tileBuffer * 8, maxZoom: z});
var layer = {};
var tile = tileIndex.getTile(z, x, y);
var gjvt = {};
if (tile) {
gjvt[table] = tile;
} else {
gjvt[table] = {features:[]};
}
return vtpbf.fromGeojsonVt(gjvt);
});
}
/**
* Gets the features in the EPSG:4326 bounding box
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @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
*/
GeoPackageAPI.getFeaturesInBoundingBox = function(geopackage, table, west, east, south, north) {
return geopackage.indexFeatureTable(table)
.then(function(indexed) {
var featureDao = geopackage.getFeatureDao(table);
if (!featureDao) throw new Error('Unable to find table ' + table);
var features = [];
var bb = new BoundingBox(west, east, south, north);
var iterator = featureDao.queryIndexedFeaturesWithBoundingBox(bb);
return iterator;
});
}
/**
* Gets a tile image for an XYZ tile pyramid location
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @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
* @return {Promise}
*/
GeoPackageAPI.getTileFromXYZ = function(geopackage, table, x, y, z, width, height) {
x = Number(x);
y = Number(y);
z = Number(z);
width = Number(width);
height = Number(height);
var tileDao = geopackage.getTileDao(table);
var retriever = new GeoPackageTileRetriever(tileDao, width, height);
return retriever.getTile(x, y, z);
};
/**
* Draws an XYZ tile pyramid location into the provided canvas
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @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 {Canvas} canvas canvas element to draw the tile into
*/
GeoPackageAPI.drawXYZTileInCanvas = function(geopackage, table, x, y, z, width, height, canvas) {
x = Number(x);
y = Number(y);
z = Number(z);
width = Number(width);
height = Number(height);
var tileDao = geopackage.getTileDao(table)
var retriever = new GeoPackageTileRetriever(tileDao, width, height);
return retriever.drawTileIn(x, y, z, canvas);
};
/**
* Draws a tile specified by the bounds in EPSG:4326 into the canvas
* @param {module:geoPackage~GeoPackage} geopackage open GeoPackage object
* @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 {Number} width width of the resulting tile
* @param {Number} height height of the resulting tile
* @param {Canvas} canvas canvas element to draw the tile into
*/
GeoPackageAPI.draw4326TileInCanvas = function(geopackage, table, minLat, minLon, maxLat, maxLon, z, width, height, canvas) {
z = Number(z);
width = Number(width);
height = Number(height);
var tileDao = geopackage.getTileDao(table);
var retriever = new GeoPackageTileRetriever(tileDao, width, height);
var bounds = new BoundingBox(minLon, maxLon, minLat, maxLat);
return retriever.drawTileWithWgs84BoundsInProjection(bounds, z, 'EPSG:4326', canvas);
}
///////////////////
// JSDoc Globals //
///////////////////
/**
* @callback geopackageCallback
* @param {?Error} error
* @param {module:geoPackage~GeoPackage=} geopackage a GeoPackage instance
*/
/**
* An integer database key referencing a {@link module:core/srs~SpatialReferenceSystem} row in a GeoPackage database
* @typedef {number} SRSRef
* @see https://www.geopackage.org/spec121/index.html#spatial_ref_sys
*/
}).call(this,require('_process'))
},{"./boundingBox":7,"./dataColumns":13,"./db/dataTypes":14,"./db/geoPackageConnection":15,"./db/tableCreator":19,"./extension/index/featureTableIndex":26,"./extension/relatedTables/mediaTable":35,"./extension/relatedTables/relationType":36,"./extension/relatedTables/simpleAttributesTable":39,"./features/columns":64,"./features/user/featureColumn":65,"./geoPackage":70,"./geom/geometryData":73,"./tiles/features":87,"./tiles/retriever":92,"./tiles/tileBoundingBoxUtils":93,"./user/userColumn":105,"./validate/geoPackageValidate":110,"@mapbox/vector-tile":113,"_process":284,"fs":177,"geojson-vt":226,"path":276,"pbf":277,"reproject":315,"vt-pbf":345,"wkx":360}],3:[function(require,module,exports){
/**
* @module attributes/attributeDao
*/
var UserDao = require('../user/userDao')
, AttributeRow = require('./attributeRow');
var util = require('util');
/**
* Attribute DAO for reading attribute user data tables
* @class AttributeDao
* @extends {module:user/userDao~UserDao}
* @param {module:geoPackage~GeoPackage} geopackage geopackage object
* @param {module:attributes/attributeTable~AttributeTable} table attribute table
*/
var AttributeDao = function(geoPackage, table) {
UserDao.call(this, geoPackage, table);
if (!table.contents) {
throw new Error('Attributes table has null Contents');
}
/**
* Contents of this AttributeDao
* @member {module:core/contents~Contents}
*/
this.contents = table.contents;
}
util.inherits(AttributeDao, UserDao);
/**
* Create a new attribute row with the column types and values
* @param {Array} columnTypes column types
* @param {module:dao/columnValues~ColumnValues[]} values values
* @return {moule:attributes/attributeRow~AttributeRow} attribute row
*/
AttributeDao.prototype.newRowWithColumnTypes = function (columnTypes, values) {
return new AttributeRow(this.table, columnTypes, values);
};
/**
* Create a new attribute row
* @return {module:attributes/attributeRow~AttributeRow} attribute row
*/
AttributeDao.prototype.newRow = function () {
return new AttributeRow(this.table);
};
module.exports = AttributeDao;
},{"../user/userDao":106,"./attributeRow":4,"util":343}],4:[function(require,module,exports){
/**
* AttributeRow module.
* @module attributes/attributeRow
*/
var UserRow = require('../user/userRow');
var util = require('util');
/**
* Attribute Row containing the values from a single result set row
* @class AttributeRow
* @extends module:user/userRow~UserRow
* @param {module:attributes/attributeTable~AttributeTable} attributeTable attribute table
* @param {module:db/dataTypes[]} columnTypes column types
* @param {module:dao/columnValues~ColumnValues[]} values values
*/
var AttributeRow = function(attributeTable, columnTypes, values) {
UserRow.call(this, attributeTable, columnTypes, values);
}
util.inherits(AttributeRow, UserRow);
module.exports = AttributeRow;
},{"../user/userRow":107,"util":343}],5:[function(require,module,exports){
/**
* @module attributes/attributeTable
*/
var UserTable = require('../user/userTable')
, ContentsDao = require('../core/contents').ContentsDao;
var util = require('util');
/**
* Represents a user attribute table
* @class AttributeTable
* @extends {module:user/userTable~UserTable}
* @constructor
* @param {string} tableName table name
* @param {module:user/userColumn~UserColumn[]} columns attribute columns
*/
var AttributeTable = function(tableName, columns) {
/**
* Contents of this AttributeTable
* @member {module:core/contents~Contents}
*/
this.contents;
UserTable.call(this, tableName, columns);
}
util.inherits(AttributeTable, UserTable);
/**
* Set the contents
* @param {module:core/contents~Contents} contents the contents
*/
AttributeTable.prototype.setContents = function(contents) {
this.contents = contents;
if (contents.data_type !== ContentsDao.GPKG_CDT_ATTRIBUTES_NAME) {
throw new Error('The Contents of an Attributes Table must have a data type of ' + ContentsDao.GPKG_CDT_ATTRIBUTES_NAME);
}
}
module.exports = AttributeTable;
},{"../core/contents":8,"../user/userTable":108,"util":343}],6:[function(require,module,exports){
/**
* attributeTableReader module.
* @module attributes/attributeTableReader
*/
var UserTableReader = require('../user/userTableReader')
, AttributeTable = require('./attributeTable')
, DataTypes = require('../db/dataTypes');
var util = require('util');
/**
* Reads the metadata from an existing attribute table
* @class AttributeTableReader
* @extends {module:user/userTableReader~UserTableReader}
* @classdesc Reads the metadata from an existing attributes table
*/
var AttributeTableReader = function(tableName) {
UserTableReader.call(this, tableName);
}
util.inherits(AttributeTableReader, UserTableReader);
/**
* @inheritdoc
*/
AttributeTableReader.prototype.createTable = function (tableName, columns) {
return new AttributeTable(tableName, columns);
};
module.exports = AttributeTableReader;
},{"../db/dataTypes":14,"../user/userTableReader":109,"./attributeTable":5,"util":343}],7:[function(require,module,exports){
var proj4 = require('proj4');
proj4 = 'default' in proj4 ? proj4['default'] : proj4;
/**
* Create a new bounding box
* @class BoundingBox
* @param {Number} minLongitudeOrBoundingBox minimum longitude or bounding box to copy (west)
* @param {Number} maxLongitude maximum longitude (east)
* @param {Number} minLatitude Minimum latitude (south)
* @param {Number} maxLatitude Maximum latitude (north)
* @return {BoundingBox} newly constructed bounding box
*/
var BoundingBox = function(minLongitudeOrBoundingBox, maxLongitude, minLatitude, maxLatitude) {
// if there is a second argument the first argument is the minLongitude
if (maxLongitude !== undefined) {
this.minLongitude = minLongitudeOrBoundingBox;
this.maxLongitude = maxLongitude;
this.minLatitude = minLatitude;
this.maxLatitude = maxLatitude;
} else {
var boundingBox = minLongitudeOrBoundingBox;
this.minLongitude = boundingBox.minLongitude;
this.maxLongitude = boundingBox.maxLongitude;
this.minLatitude = boundingBox.minLatitude;
this.maxLatitude = boundingBox.maxLatitude;
}
}
module.exports = BoundingBox;
/**
* Build a Geometry Envelope from the bounding box
*
* @return geometry envelope
*/
BoundingBox.prototype.buildEnvelope = function () {
return {
minY: this.minLatitude,
minX: this.minLongitude,
maxY: this.maxLatitude,
maxX: this.maxLong