@ngageoint/geopackage
Version:
GeoPackage JavaScript Library
230 lines • 9.59 kB
JavaScript
"use strict";
/**
* GeometryData module.
* @module geom/geometryData
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GeometryData = void 0;
var wkx_1 = __importDefault(require("wkx"));
var geoPackageConstants_1 = require("../geoPackageConstants");
var envelope_1 = require("./envelope");
/**
* GeoPackage Geometry Data
*/
var GeometryData = /** @class */ (function () {
function GeometryData(buffer) {
this.empty = true;
this.byteOrder = GeometryData.BIG_ENDIAN;
if (buffer) {
this.fromData(buffer);
}
}
GeometryData.prototype.setSrsId = function (srsId) {
this.srsId = srsId;
};
GeometryData.prototype.setGeometry = function (wkbGeometry) {
this.empty = false;
this.geometry = wkbGeometry;
};
GeometryData.prototype.setEnvelope = function (envelope) {
this.envelope = envelope;
};
GeometryData.prototype.toGeoJSON = function () {
return this.geometry.toGeoJSON();
};
GeometryData.prototype.fromData = function (bufferOrArray) {
if (bufferOrArray instanceof Uint8Array) {
this.buffer = bufferOrArray = Buffer.from(bufferOrArray);
}
else {
this.buffer = bufferOrArray;
}
var magicString = this.buffer.toString('ascii', 0, 2);
if (magicString !== geoPackageConstants_1.GeoPackageConstants.GEOPACKAGE_GEOMETRY_MAGIC_NUMBER) {
throw new Error('Unexpected GeoPackage Geometry magic number: ' +
magicString +
', Expected: ' +
geoPackageConstants_1.GeoPackageConstants.GEOPACKAGE_GEOMETRY_MAGIC_NUMBER);
}
var version = this.buffer.readUInt8(2);
if (version !== geoPackageConstants_1.GeoPackageConstants.GEOPACKAGE_GEOMETRY_VERSION_1) {
throw new Error('Unexpected GeoPackage Geometry version ' +
version +
', Expected: ' +
geoPackageConstants_1.GeoPackageConstants.GEOPACKAGE_GEOMETRY_VERSION_1);
}
var flags = this.buffer.readUInt8(3);
var envelopeIndicator = this.readFlags(flags);
this.srsId = this.buffer[this.byteOrder ? 'readUInt32LE' : 'readUInt32BE'](4);
var envelopeAndOffset = this.readEnvelope(envelopeIndicator, this.buffer);
this.envelope = envelopeAndOffset.envelope;
var offset = envelopeAndOffset.offset;
var wkbBuffer = this.buffer.slice(offset);
try {
this.geometry = wkx_1.default.Geometry.parse(wkbBuffer);
this.geometryError = undefined;
}
catch (error) {
this.geometryError = error.message;
console.log('Error parsing geometry');
}
};
GeometryData.prototype.toData = function () {
var header = Buffer.alloc(8);
// Write GP as the 2 byte magic number
header.write(geoPackageConstants_1.GeoPackageConstants.GEOPACKAGE_GEOMETRY_MAGIC_NUMBER);
// Write a byte as the version value of 0 = version 1
header.writeUInt8(geoPackageConstants_1.GeoPackageConstants.GEOPACKAGE_GEOMETRY_VERSION_1, 2);
// Build and write a flags byte
var flags = this.buildFlagsByte();
header.writeUInt8(flags, 3);
// write the 4 byte srs id
header[this.byteOrder ? 'writeUInt32LE' : 'writeUInt32BE'](this.srsId, 4);
var envelopeBuffer = this.writeEnvelope();
var concatArray = [header, envelopeBuffer];
try {
concatArray.push(this.geometry.toWkb());
this.geometryError = undefined;
}
catch (error) {
this.geometryError = error.message;
}
this.buffer = Buffer.concat(concatArray);
return this.buffer;
};
GeometryData.prototype.writeEnvelope = function () {
if (!this.envelope)
return Buffer.alloc(0);
var length = 32;
if (this.envelope.hasZ) {
length += 16;
}
if (this.envelope.hasM) {
length += 16;
}
var envelopeBuffer = Buffer.alloc(length);
var writeDoubleMethod;
if (this.byteOrder) {
writeDoubleMethod = envelopeBuffer.writeDoubleLE.bind(envelopeBuffer);
}
else {
writeDoubleMethod = envelopeBuffer.writeDoubleBE.bind(envelopeBuffer);
}
writeDoubleMethod(this.envelope.minX, 0);
writeDoubleMethod(this.envelope.maxX, 8);
writeDoubleMethod(this.envelope.minY, 16);
writeDoubleMethod(this.envelope.maxY, 24);
var position = 32;
if (this.envelope.hasZ) {
writeDoubleMethod(this.envelope.minZ, position);
writeDoubleMethod(this.envelope.maxZ, position + 8);
position = 48;
}
if (this.envelope.hasM) {
writeDoubleMethod(this.envelope.minM, position);
writeDoubleMethod(this.envelope.maxM, position + 8);
}
return envelopeBuffer;
};
GeometryData.prototype.buildFlagsByte = function () {
var flag = 0;
// Add the binary type to bit 5, 0 for standard and 1 for extended
var binaryType = this.extended ? 1 : 0;
flag += binaryType << 5;
// Add the empty geometry flag to bit 4, 0 for non-empty and 1 for empty
var emptyValue = this.empty ? 1 : 0;
flag += emptyValue << 4;
// Add the envelope contents indicator code (3-bit unsigned integer to bits 3, 2, and 1)
var envelopeIndicator = !this.envelope ? 0 : this.getIndicatorWithEnvelope(this.envelope);
flag += envelopeIndicator << 1;
// Add the byte order to bit 0, 0 for Big Endian and 1 for Little Endian
var byteOrderValue = this.byteOrder === GeometryData.BIG_ENDIAN ? 0 : 1;
flag += byteOrderValue;
return flag;
};
GeometryData.prototype.getIndicatorWithEnvelope = function (envelope) {
var indicator = 1;
if (envelope.hasZ) {
indicator++;
}
if (envelope.hasM) {
indicator += 2;
}
return indicator;
};
GeometryData.prototype.readFlags = function (flagsInt) {
// Verify the reserved bits at 7 and 6 are 0
var reserved7 = (flagsInt >> 7) & 1;
var reserved6 = (flagsInt >> 6) & 1;
if (reserved7 !== 0 || reserved6 !== 0) {
throw new Error('Unexpected GeoPackage Geometry flags. Flag bit 7 and 6 should both be 0, 7=' + reserved7 + ', 6=' + reserved6);
}
// Get the binary type from bit 5, 0 for standard and 1 for extended
var binaryType = (flagsInt >> 5) & 1;
this.extended = binaryType === 1;
// Get the empty geometry flag from bit 4, 0 for non-empty and 1 for
// empty
var emptyValue = (flagsInt >> 4) & 1;
this.empty = emptyValue === 1;
// Get the envelope contents indicator code (3-bit unsigned integer from
// bits 3, 2, and 1)
var envelopeIndicator = (flagsInt >> 1) & 7;
if (envelopeIndicator > 4) {
throw new Error('Unexpected GeoPackage Geometry flags. Envelope contents indicator must be between 0 and 4. Actual: ' +
envelopeIndicator);
}
// Get the byte order from bit 0, 0 for Big Endian and 1 for Little Endian
var byteOrderValue = flagsInt & 1;
this.byteOrder = byteOrderValue;
return envelopeIndicator;
};
GeometryData.prototype.readEnvelope = function (envelopeIndicator, buffer) {
var readDoubleMethod;
if (this.byteOrder) {
readDoubleMethod = buffer.readDoubleLE.bind(buffer);
}
else {
readDoubleMethod = buffer.readDoubleBE.bind(buffer);
}
var envelopeByteOffset = 8;
var reads = 0;
var envelopeAndOffset = {
envelope: undefined,
offset: envelopeByteOffset,
};
if (envelopeIndicator <= 0) {
return envelopeAndOffset;
}
var envelope = new envelope_1.Envelope();
// Read x and y values and create envelope
envelope.minX = readDoubleMethod(envelopeByteOffset + 8 * reads++);
envelope.maxX = readDoubleMethod(envelopeByteOffset + 8 * reads++);
envelope.minY = readDoubleMethod(envelopeByteOffset + 8 * reads++);
envelope.maxY = readDoubleMethod(envelopeByteOffset + 8 * reads++);
envelope.hasZ = false;
envelope.hasM = false;
// Read z values
if (envelopeIndicator === 2 || envelopeIndicator === 4) {
envelope.hasZ = true;
envelope.minZ = readDoubleMethod(envelopeByteOffset + 8 * reads++);
envelope.maxZ = readDoubleMethod(envelopeByteOffset + 8 * reads++);
}
// Read m values
if (envelopeIndicator === 3 || envelopeIndicator === 4) {
envelope.hasM = true;
envelope.minM = readDoubleMethod(envelopeByteOffset + 8 * reads++);
envelope.maxM = readDoubleMethod(envelopeByteOffset + 8 * reads++);
}
envelopeAndOffset.envelope = envelope;
envelopeAndOffset.offset = envelopeByteOffset + 8 * reads;
return envelopeAndOffset;
};
GeometryData.BIG_ENDIAN = 0;
GeometryData.LITTLE_ENDIAN = 1;
return GeometryData;
}());
exports.GeometryData = GeometryData;
//# sourceMappingURL=geometryData.js.map