UNPKG

node-red-contrib-tak-registration

Version:

A Node-RED node to register to TAK and to help wrap files as datapackages to send to TAK

1,807 lines (1,497 loc) 956 kB
/** * JSTS. See https://github.com/bjornharrtell/jsts * https://github.com/bjornharrtell/jsts/blob/master/LICENSE_EDLv1.txt * https://github.com/bjornharrtell/jsts/blob/master/LICENSE_EPLv1.txt * @license */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.jsts = {})); }(this, (function (exports) { 'use strict'; class NumberUtil { static equalsWithTolerance(x1, x2, tolerance) { return Math.abs(x1 - x2) <= tolerance; } } class Exception extends Error { constructor(message) { super(message); this.name = Object.keys({ Exception })[0]; } toString() { return this.message; } } class IllegalArgumentException extends Exception { constructor(message) { super(message); this.name = Object.keys({ IllegalArgumentException })[0]; } } class Long { constructor(high, low) { this.low = low || 0; this.high = high || 0; } static toBinaryString(i) { let mask; let result = ''; for (mask = 0x80000000; mask > 0; mask >>>= 1) result += (i.high & mask) === mask ? '1' : '0'; for (mask = 0x80000000; mask > 0; mask >>>= 1) result += (i.low & mask) === mask ? '1' : '0'; return result; } } function Double() {} Double.NaN = NaN; Double.isNaN = n => Number.isNaN(n); Double.isInfinite = n => !Number.isFinite(n); Double.MAX_VALUE = Number.MAX_VALUE; Double.POSITIVE_INFINITY = Number.POSITIVE_INFINITY; Double.NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY; if (typeof Float64Array === 'function' && typeof Int32Array === 'function') // Simple and fast conversion between double and long bits // using TypedArrays and ArrayViewBuffers. (function () { const EXP_BIT_MASK = 0x7ff00000; const SIGNIF_BIT_MASK = 0xFFFFF; const f64buf = new Float64Array(1); const i32buf = new Int32Array(f64buf.buffer); Double.doubleToLongBits = function (value) { f64buf[0] = value; let low = i32buf[0] | 0; let high = i32buf[1] | 0; // Check for NaN based on values of bit fields, maximum // exponent and nonzero significand. if ((high & EXP_BIT_MASK) === EXP_BIT_MASK && (high & SIGNIF_BIT_MASK) !== 0 && low !== 0) { low = 0 | 0; high = 0x7ff80000 | 0; } return new Long(high, low); }; Double.longBitsToDouble = function (bits) { i32buf[0] = bits.low; i32buf[1] = bits.high; return f64buf[0]; }; })();else // More complex and slower fallback implementation using // math and the divide-by-two and multiply-by-two algorithms. (function () { const BIAS = 1023; const log2 = Math.log2; const floor = Math.floor; const pow = Math.pow; const MAX_REL_BITS_INTEGER = function () { for (let i = 53; i > 0; i--) { const bits = pow(2, i) - 1; if (floor(log2(bits)) + 1 === i) return bits; } return 0; }(); Double.doubleToLongBits = function (value) { let x, y, f, bits, skip; let sign, exp, high, low; // Get the sign bit and absolute value. if (value < 0 || 1 / value === Number.NEGATIVE_INFINITY) { sign = 1 << 31; value = -value; } else { sign = 0; } // Handle some special values. if (value === 0) { // Handle zeros (+/-0). low = 0 | 0; high = sign; // exponent: 00..00, significand: 00..00 return new Long(high, low); } if (value === Infinity) { // Handle infinity (only positive values for value possible). low = 0 | 0; high = sign | 0x7ff00000; // exponent: 11..11, significand: 00..00 return new Long(high, low); } if (value !== value) { // eslint-disable-line // Handle NaNs (boiled down to only one distinct NaN). low = 0 | 0; high = 0x7ff80000; // exponent: 11..11, significand: 10..00 return new Long(high, low); } // Preinitialize variables, that are not neccessarily set by // the algorithm. bits = 0; low = 0 | 0; // Get the (always positive) integer part of value. x = floor(value); // Process the integer part if it's greater than 1. Zero requires // no bits at all, 1 represents the implicit (hidden) leading bit, // which must not be written as well. if (x > 1) // If we can reliably determine the number of bits required for // the integer part, if (x <= MAX_REL_BITS_INTEGER) { // get the number of bits required to represent it minus 1 bits = floor(log2(x)); /* + 1 - 1 */ // and simply copy/shift the integer bits into low and high. // That's much faster than the divide-by-two algorithm (saves // up to ~60%). // We always need to mask out the most significant bit, which // is the implicit (aka hidden) bit. if (bits <= 20) { // The simple case in which the integer fits into the // lower 20 bits of the high word is worth to be handled // separately (saves ~25%). low = 0 | 0; high = x << 20 - bits & 0xfffff; } else { // Here, the integer part is split into low and high. // Since its value may require more than 32 bits, we // cannot use bitwise operators (which implicitly cast // to Int32), but use arithmetic operators % and / to // get low and high parts. The uppper 20 bits go to high, // the remaining bits (in f) to low. f = bits - 20; // Like (1 << f) but safe with even more than 32 bits. y = pow(2, f); low = x % y << 32 - f; high = x / y & 0xfffff; } } else { // For greater values, we must use the much slower divide-by-two // algorithm. Bits are generated from right to left, that is from // least to most significant bit. For each bit, we left-shift both // low and high by one and carry bit #0 from high to #31 in low. // The next bit is then copied into bit #19 in high, the leftmost // bit of the double's significand. // Preserve x for later user, so work with f. f = x; low = 0 | 0; for (;;) { y = f / 2; f = floor(y); if (f === 0) // We just found the most signigicant (1-)bit, which // is the implicit bit and so, not stored in the double // value. So, it's time to leave the loop. break; // Count this bit, shift low and carry bit #0 from high. bits++; low >>>= 1; low |= (high & 0x1) << 31; // Shift high. high >>>= 1; if (y !== f) // Copy the new bit into bit #19 in high (only required if 1). high |= 0x80000; } } // Bias the exponent. exp = bits + BIAS; // If the integer part is zero, we've not yet seen the implicit // leading bit. Variable skip is later used while processing the // fractional part (if any). skip = x === 0; // Get fraction only into x. x = value - x; // If some significand bits are still left to be filled and // the fractional part is not zero, convert the fraction using // the multiply-by-2 algorithm. if (bits < 52 && x !== 0) { // Initialize 'buffer' f, into which newly created bits get // shifted from right to left. f = 0; for (;;) { y = x * 2; if (y >= 1) { // This is a new 1-bit. Add and count this bit, if not // prohibited by skip. x = y - 1; if (!skip) { f <<= 1; f |= 1; bits++; } else { // Otherwise, decrement the exponent and unset // skip, so that all following bits get written. exp--; skip = false; } } else { // This is a new 0-bit. Add and count this bit, if not // prohibited by skip. x = y; if (!skip) { f <<= 1; bits++; } else if (--exp === 0) { // Otherwise we've just decremented the exponent. If the // biased exponent is zero now (-1023), we process a // subnormal number, which has no impled leading 1-bit. // So, count this 0-bit and unset skip to write out // all the following bits. bits++; skip = false; } } if (bits === 20) { // When 20 bits have been created in total, we're done with // the high word. Copy the bits from 'buffer' f into high // and reset 'buffer' f. Following bits will end up in the // low word. high |= f; f = 0; } else if (bits === 52) { // When 52 bits have been created in total, we're done with // low word as well. Copy the bits from 'buffer' f into low // and exit the loop. low |= f; break; } if (y === 1) { // When y is exactly 1, there is no remainder and the process // is complete (the number is finite). Copy the bits from // 'buffer' f into either low or high and exit the loop. if (bits < 20) high |= f << 20 - bits;else if (bits < 52) low |= f << 52 - bits; break; } } } // Copy/shift the exponent and sign bits into the high word. high |= exp << 20; high |= sign; return new Long(high, low); }; Double.longBitsToDouble = function (bits) { let i; let x, exp, fract; const high = bits.high; const low = bits.low; // Extract the sign. const sign = high & 1 << 31 ? -1 : 1; // Extract the unbiased exponent. exp = ((high & 0x7ff00000) >> 20) - BIAS; // Calculate the fraction from left to right. Start // off with the 20 lower bits from the high word. fract = 0; x = 1 << 19; for (i = 1; i <= 20; i++) { if (high & x) fract += pow(2, -i); x >>>= 1; } // Continue with all 32 bits from the low word. x = 1 << 31; for (i = 21; i <= 52; i++) { if (low & x) fract += pow(2, -i); x >>>= 1; } // Handle special values. // Check for zero and subnormal values. if (exp === -BIAS) { if (fract === 0) // +/-1.0 * 0.0 => +/-0.0 return sign * 0; exp = -1022; } else if (exp === BIAS + 1) { // Check for +/-Infinity or NaN. if (fract === 0) // +/-1.0 / 0.0 => +/-Infinity return sign / 0; return NaN; } else { // Nothing special? Seems to be a normal number. // Add the implicit leading bit (1*2^0). fract += 1; } return sign * fract * pow(2, exp); }; })(); function Comparable() {} function Clonable() {} function Comparator() {} function Serializable() {} class RuntimeException extends Exception { constructor(message) { super(message); this.name = Object.keys({ RuntimeException })[0]; } } class AssertionFailedException extends RuntimeException { constructor() { super(); AssertionFailedException.constructor_.apply(this, arguments); } static constructor_() { if (arguments.length === 0) { RuntimeException.constructor_.call(this); } else if (arguments.length === 1) { const message = arguments[0]; RuntimeException.constructor_.call(this, message); } } } class Assert { static shouldNeverReachHere() { if (arguments.length === 0) { Assert.shouldNeverReachHere(null); } else if (arguments.length === 1) { const message = arguments[0]; throw new AssertionFailedException('Should never reach here' + (message !== null ? ': ' + message : '')); } } static isTrue() { if (arguments.length === 1) { const assertion = arguments[0]; Assert.isTrue(assertion, null); } else if (arguments.length === 2) { const assertion = arguments[0], message = arguments[1]; if (!assertion) if (message === null) throw new AssertionFailedException();else throw new AssertionFailedException(message); } } static equals() { if (arguments.length === 2) { const expectedValue = arguments[0], actualValue = arguments[1]; Assert.equals(expectedValue, actualValue, null); } else if (arguments.length === 3) { const expectedValue = arguments[0], actualValue = arguments[1], message = arguments[2]; if (!actualValue.equals(expectedValue)) throw new AssertionFailedException('Expected ' + expectedValue + ' but encountered ' + actualValue + (message !== null ? ': ' + message : '')); } } } const kBuf = new ArrayBuffer(8); const kBufAsF64 = new Float64Array(kBuf); const kBufAsI32 = new Int32Array(kBuf); class Coordinate { constructor() { Coordinate.constructor_.apply(this, arguments); } static constructor_() { this.x = null; this.y = null; this.z = null; if (arguments.length === 0) { Coordinate.constructor_.call(this, 0.0, 0.0); } else if (arguments.length === 1) { const c = arguments[0]; Coordinate.constructor_.call(this, c.x, c.y, c.getZ()); } else if (arguments.length === 2) { const x = arguments[0], y = arguments[1]; Coordinate.constructor_.call(this, x, y, Coordinate.NULL_ORDINATE); } else if (arguments.length === 3) { const x = arguments[0], y = arguments[1], z = arguments[2]; this.x = x; this.y = y; this.z = z; } } static hashCode(n) { kBufAsF64[0] = n; return kBufAsI32[0] ^ kBufAsI32[1]; } getM() { return Double.NaN; } setOrdinate(ordinateIndex, value) { switch (ordinateIndex) { case Coordinate.X: this.x = value; break; case Coordinate.Y: this.y = value; break; case Coordinate.Z: this.setZ(value); break; default: throw new IllegalArgumentException('Invalid ordinate index: ' + ordinateIndex); } } equals2D() { if (arguments.length === 1) { const other = arguments[0]; if (this.x !== other.x) return false; if (this.y !== other.y) return false; return true; } else if (arguments.length === 2) { const c = arguments[0], tolerance = arguments[1]; if (!NumberUtil.equalsWithTolerance(this.x, c.x, tolerance)) return false; if (!NumberUtil.equalsWithTolerance(this.y, c.y, tolerance)) return false; return true; } } setM(m) { throw new IllegalArgumentException('Invalid ordinate index: ' + Coordinate.M); } getZ() { return this.z; } getOrdinate(ordinateIndex) { switch (ordinateIndex) { case Coordinate.X: return this.x; case Coordinate.Y: return this.y; case Coordinate.Z: return this.getZ(); } throw new IllegalArgumentException('Invalid ordinate index: ' + ordinateIndex); } equals3D(other) { return this.x === other.x && this.y === other.y && (this.getZ() === other.getZ() || Double.isNaN(this.getZ()) && Double.isNaN(other.getZ())); } equals(other) { if (!(other instanceof Coordinate)) return false; return this.equals2D(other); } equalInZ(c, tolerance) { return NumberUtil.equalsWithTolerance(this.getZ(), c.getZ(), tolerance); } setX(x) { this.x = x; } compareTo(o) { const other = o; if (this.x < other.x) return -1; if (this.x > other.x) return 1; if (this.y < other.y) return -1; if (this.y > other.y) return 1; return 0; } getX() { return this.x; } setZ(z) { this.z = z; } clone() { try { const coord = null; return coord; } catch (e) { if (e instanceof CloneNotSupportedException) { Assert.shouldNeverReachHere('this shouldn\'t happen because this class is Cloneable'); return null; } else { throw e; } } finally {} } copy() { return new Coordinate(this); } toString() { return '(' + this.x + ', ' + this.y + ', ' + this.getZ() + ')'; } distance3D(c) { const dx = this.x - c.x; const dy = this.y - c.y; const dz = this.getZ() - c.getZ(); return Math.sqrt(dx * dx + dy * dy + dz * dz); } getY() { return this.y; } setY(y) { this.y = y; } distance(c) { const dx = this.x - c.x; const dy = this.y - c.y; return Math.sqrt(dx * dx + dy * dy); } hashCode() { let result = 17; result = 37 * result + Coordinate.hashCode(this.x); result = 37 * result + Coordinate.hashCode(this.y); return result; } setCoordinate(other) { this.x = other.x; this.y = other.y; this.z = other.getZ(); } get interfaces_() { return [Comparable, Clonable, Serializable]; } } class DimensionalComparator { constructor() { DimensionalComparator.constructor_.apply(this, arguments); } static constructor_() { this._dimensionsToTest = 2; if (arguments.length === 0) { DimensionalComparator.constructor_.call(this, 2); } else if (arguments.length === 1) { const dimensionsToTest = arguments[0]; if (dimensionsToTest !== 2 && dimensionsToTest !== 3) throw new IllegalArgumentException('only 2 or 3 dimensions may be specified'); this._dimensionsToTest = dimensionsToTest; } } static compare(a, b) { if (a < b) return -1; if (a > b) return 1; if (Double.isNaN(a)) { if (Double.isNaN(b)) return 0; return -1; } if (Double.isNaN(b)) return 1; return 0; } compare(c1, c2) { const compX = DimensionalComparator.compare(c1.x, c2.x); if (compX !== 0) return compX; const compY = DimensionalComparator.compare(c1.y, c2.y); if (compY !== 0) return compY; if (this._dimensionsToTest <= 2) return 0; const compZ = DimensionalComparator.compare(c1.getZ(), c2.getZ()); return compZ; } get interfaces_() { return [Comparator]; } } Coordinate.DimensionalComparator = DimensionalComparator; Coordinate.NULL_ORDINATE = Double.NaN; Coordinate.X = 0; Coordinate.Y = 1; Coordinate.Z = 2; Coordinate.M = 3; class CoordinateXY extends Coordinate { constructor() { super(); CoordinateXY.constructor_.apply(this, arguments); } static constructor_() { if (arguments.length === 0) { Coordinate.constructor_.call(this); } else if (arguments.length === 1) { if (arguments[0] instanceof CoordinateXY) { const coord = arguments[0]; Coordinate.constructor_.call(this, coord.x, coord.y); } else if (arguments[0] instanceof Coordinate) { const coord = arguments[0]; Coordinate.constructor_.call(this, coord.x, coord.y); } } else if (arguments.length === 2) { const x = arguments[0], y = arguments[1]; Coordinate.constructor_.call(this, x, y, Coordinate.NULL_ORDINATE); } } setOrdinate(ordinateIndex, value) { switch (ordinateIndex) { case CoordinateXY.X: this.x = value; break; case CoordinateXY.Y: this.y = value; break; default: throw new IllegalArgumentException('Invalid ordinate index: ' + ordinateIndex); } } getZ() { return Coordinate.NULL_ORDINATE; } getOrdinate(ordinateIndex) { switch (ordinateIndex) { case CoordinateXY.X: return this.x; case CoordinateXY.Y: return this.y; } throw new IllegalArgumentException('Invalid ordinate index: ' + ordinateIndex); } setZ(z) { throw new IllegalArgumentException('CoordinateXY dimension 2 does not support z-ordinate'); } copy() { return new CoordinateXY(this); } toString() { return '(' + this.x + ', ' + this.y + ')'; } setCoordinate(other) { this.x = other.x; this.y = other.y; this.z = other.getZ(); } } CoordinateXY.X = 0; CoordinateXY.Y = 1; CoordinateXY.Z = -1; CoordinateXY.M = -1; class CoordinateXYM extends Coordinate { constructor() { super(); CoordinateXYM.constructor_.apply(this, arguments); } static constructor_() { this._m = null; if (arguments.length === 0) { Coordinate.constructor_.call(this); this._m = 0.0; } else if (arguments.length === 1) { if (arguments[0] instanceof CoordinateXYM) { const coord = arguments[0]; Coordinate.constructor_.call(this, coord.x, coord.y); this._m = coord._m; } else if (arguments[0] instanceof Coordinate) { const coord = arguments[0]; Coordinate.constructor_.call(this, coord.x, coord.y); this._m = this.getM(); } } else if (arguments.length === 3) { const x = arguments[0], y = arguments[1], m = arguments[2]; Coordinate.constructor_.call(this, x, y, Coordinate.NULL_ORDINATE); this._m = m; } } getM() { return this._m; } setOrdinate(ordinateIndex, value) { switch (ordinateIndex) { case CoordinateXYM.X: this.x = value; break; case CoordinateXYM.Y: this.y = value; break; case CoordinateXYM.M: this._m = value; break; default: throw new IllegalArgumentException('Invalid ordinate index: ' + ordinateIndex); } } setM(m) { this._m = m; } getZ() { return Coordinate.NULL_ORDINATE; } getOrdinate(ordinateIndex) { switch (ordinateIndex) { case CoordinateXYM.X: return this.x; case CoordinateXYM.Y: return this.y; case CoordinateXYM.M: return this._m; } throw new IllegalArgumentException('Invalid ordinate index: ' + ordinateIndex); } setZ(z) { throw new IllegalArgumentException('CoordinateXY dimension 2 does not support z-ordinate'); } copy() { return new CoordinateXYM(this); } toString() { return '(' + this.x + ', ' + this.y + ' m=' + this.getM() + ')'; } setCoordinate(other) { this.x = other.x; this.y = other.y; this.z = other.getZ(); this._m = other.getM(); } } CoordinateXYM.X = 0; CoordinateXYM.Y = 1; CoordinateXYM.Z = -1; CoordinateXYM.M = 2; class CoordinateXYZM extends Coordinate { constructor() { super(); CoordinateXYZM.constructor_.apply(this, arguments); } static constructor_() { this._m = null; if (arguments.length === 0) { Coordinate.constructor_.call(this); this._m = 0.0; } else if (arguments.length === 1) { if (arguments[0] instanceof CoordinateXYZM) { const coord = arguments[0]; Coordinate.constructor_.call(this, coord); this._m = coord._m; } else if (arguments[0] instanceof Coordinate) { const coord = arguments[0]; Coordinate.constructor_.call(this, coord); this._m = this.getM(); } } else if (arguments.length === 4) { const x = arguments[0], y = arguments[1], z = arguments[2], m = arguments[3]; Coordinate.constructor_.call(this, x, y, z); this._m = m; } } getM() { return this._m; } setOrdinate(ordinateIndex, value) { switch (ordinateIndex) { case Coordinate.X: this.x = value; break; case Coordinate.Y: this.y = value; break; case Coordinate.Z: this.z = value; break; case Coordinate.M: this._m = value; break; default: throw new IllegalArgumentException('Invalid ordinate index: ' + ordinateIndex); } } setM(m) { this._m = m; } getOrdinate(ordinateIndex) { switch (ordinateIndex) { case Coordinate.X: return this.x; case Coordinate.Y: return this.y; case Coordinate.Z: return this.getZ(); case Coordinate.M: return this.getM(); } throw new IllegalArgumentException('Invalid ordinate index: ' + ordinateIndex); } copy() { return new CoordinateXYZM(this); } toString() { return '(' + this.x + ', ' + this.y + ', ' + this.getZ() + ' m=' + this.getM() + ')'; } setCoordinate(other) { this.x = other.x; this.y = other.y; this.z = other.getZ(); this._m = other.getM(); } } function hasInterface (o, i) { return o.interfaces_ && o.interfaces_.indexOf(i) > -1; } /** * @see http://download.oracle.com/javase/6/docs/api/java/util/Collection.html */ class Collection { /** * Ensures that this collection contains the specified element (optional * operation). * @param {Object} e * @return {boolean} */ add() {} /** * Appends all of the elements in the specified collection to the end of this * list, in the order that they are returned by the specified collection's * iterator (optional operation). * @param {javascript.util.Collection} c * @return {boolean} */ addAll() {} /** * Returns true if this collection contains no elements. * @return {boolean} */ isEmpty() {} /** * Returns an iterator over the elements in this collection. * @return {javascript.util.Iterator} */ iterator() {} /** * Returns an iterator over the elements in this collection. * @return {number} */ size() {} /** * Returns an array containing all of the elements in this collection. * @return {Array} */ toArray() {} /** * Removes a single instance of the specified element from this collection if it * is present. (optional) * @param {Object} e * @return {boolean} */ remove() {} } class IndexOutOfBoundsException extends Exception { constructor(message) { super(message); this.name = Object.keys({ IndexOutOfBoundsException })[0]; } } /** * @see http://download.oracle.com/javase/6/docs/api/java/util/List.html */ class List extends Collection { /** * Returns the element at the specified position in this list. * @param {number} index * @return {Object} */ get() {} /** * Replaces the element at the specified position in this list with the * specified element (optional operation). * @param {number} index * @param {Object} e * @return {Object} */ set() {} /** * Returns true if this collection contains no elements. * @return {boolean} */ isEmpty() {} } class NoSuchElementException extends Exception { constructor(message) { super(message); this.name = Object.keys({ NoSuchElementException })[0]; } } /** * @see http://download.oracle.com/javase/6/docs/api/java/util/ArrayList.html */ class ArrayList extends List { constructor(o) { super(); this.array = []; if (o instanceof Collection) this.addAll(o); } get interfaces_() { return [List, Collection]; } ensureCapacity() {} add(e) { if (arguments.length === 1) this.array.push(e);else this.array.splice(arguments[0], 0, arguments[1]); return true; } clear() { this.array = []; } addAll(c) { for (const e of c) this.array.push(e); } set(index, element) { const oldElement = this.array[index]; this.array[index] = element; return oldElement; } iterator() { return new Iterator$3(this); } get(index) { if (index < 0 || index >= this.size()) throw new IndexOutOfBoundsException(); return this.array[index]; } isEmpty() { return this.array.length === 0; } sort(comparator) { if (comparator) this.array.sort((a, b) => comparator.compare(a, b));else this.array.sort(); } size() { return this.array.length; } toArray() { return this.array.slice(); } remove(o) { for (let i = 0, len = this.array.length; i < len; i++) if (this.array[i] === o) return !!this.array.splice(i, 1); return false; } [Symbol.iterator]() { return this.array.values(); } } class Iterator$3 { constructor(arrayList) { this.arrayList = arrayList; this.position = 0; } next() { if (this.position === this.arrayList.size()) throw new NoSuchElementException(); return this.arrayList.get(this.position++); } hasNext() { return this.position < this.arrayList.size(); } set(element) { return this.arrayList.set(this.position - 1, element); } remove() { this.arrayList.remove(this.arrayList.get(this.position)); } } class CoordinateList extends ArrayList { constructor() { super(); CoordinateList.constructor_.apply(this, arguments); } static constructor_() { if (arguments.length === 0) ; else if (arguments.length === 1) { const coord = arguments[0]; this.ensureCapacity(coord.length); this.add(coord, true); } else if (arguments.length === 2) { const coord = arguments[0], allowRepeated = arguments[1]; this.ensureCapacity(coord.length); this.add(coord, allowRepeated); } } getCoordinate(i) { return this.get(i); } addAll() { if (arguments.length === 2 && typeof arguments[1] === 'boolean' && hasInterface(arguments[0], Collection)) { const coll = arguments[0], allowRepeated = arguments[1]; let isChanged = false; for (let i = coll.iterator(); i.hasNext();) { this.add(i.next(), allowRepeated); isChanged = true; } return isChanged; } else { return super.addAll.apply(this, arguments); } } clone() { const clone = super.clone.call(this); for (let i = 0; i < this.size(); i++) clone.add(i, this.get(i).clone()); return clone; } toCoordinateArray() { if (arguments.length === 0) { return this.toArray(CoordinateList.coordArrayType); } else if (arguments.length === 1) { const isForward = arguments[0]; if (isForward) return this.toArray(CoordinateList.coordArrayType); const size = this.size(); const pts = new Array(size).fill(null); for (let i = 0; i < size; i++) pts[i] = this.get(size - i - 1); return pts; } } add() { if (arguments.length === 1) { const coord = arguments[0]; return super.add.call(this, coord); } else if (arguments.length === 2) { if (arguments[0] instanceof Array && typeof arguments[1] === 'boolean') { const coord = arguments[0], allowRepeated = arguments[1]; this.add(coord, allowRepeated, true); return true; } else if (arguments[0] instanceof Coordinate && typeof arguments[1] === 'boolean') { const coord = arguments[0], allowRepeated = arguments[1]; if (!allowRepeated) if (this.size() >= 1) { const last = this.get(this.size() - 1); if (last.equals2D(coord)) return null; } super.add.call(this, coord); } else if (arguments[0] instanceof Object && typeof arguments[1] === 'boolean') { const obj = arguments[0], allowRepeated = arguments[1]; this.add(obj, allowRepeated); return true; } } else if (arguments.length === 3) { if (typeof arguments[2] === 'boolean' && arguments[0] instanceof Array && typeof arguments[1] === 'boolean') { const coord = arguments[0], allowRepeated = arguments[1], direction = arguments[2]; if (direction) for (let i = 0; i < coord.length; i++) this.add(coord[i], allowRepeated);else for (let i = coord.length - 1; i >= 0; i--) this.add(coord[i], allowRepeated); return true; } else if (typeof arguments[2] === 'boolean' && Number.isInteger(arguments[0]) && arguments[1] instanceof Coordinate) { const i = arguments[0], coord = arguments[1], allowRepeated = arguments[2]; if (!allowRepeated) { const size = this.size(); if (size > 0) { if (i > 0) { const prev = this.get(i - 1); if (prev.equals2D(coord)) return null; } if (i < size) { const next = this.get(i); if (next.equals2D(coord)) return null; } } } super.add.call(this, i, coord); } } else if (arguments.length === 4) { const coord = arguments[0], allowRepeated = arguments[1], start = arguments[2], end = arguments[3]; let inc = 1; if (start > end) inc = -1; for (let i = start; i !== end; i += inc) this.add(coord[i], allowRepeated); return true; } } closeRing() { if (this.size() > 0) { const duplicate = this.get(0).copy(); this.add(duplicate, false); } } } CoordinateList.coordArrayType = new Array(0).fill(null); class CoordinateSequenceFilter { filter(seq, i) {} isDone() {} isGeometryChanged() {} } class Envelope { constructor() { Envelope.constructor_.apply(this, arguments); } static constructor_() { this._minx = null; this._maxx = null; this._miny = null; this._maxy = null; if (arguments.length === 0) { this.init(); } else if (arguments.length === 1) { if (arguments[0] instanceof Coordinate) { const p = arguments[0]; this.init(p.x, p.x, p.y, p.y); } else if (arguments[0] instanceof Envelope) { const env = arguments[0]; this.init(env); } } else if (arguments.length === 2) { const p1 = arguments[0], p2 = arguments[1]; this.init(p1.x, p2.x, p1.y, p2.y); } else if (arguments.length === 4) { const x1 = arguments[0], x2 = arguments[1], y1 = arguments[2], y2 = arguments[3]; this.init(x1, x2, y1, y2); } } static intersects() { if (arguments.length === 3) { const p1 = arguments[0], p2 = arguments[1], q = arguments[2]; if (q.x >= (p1.x < p2.x ? p1.x : p2.x) && q.x <= (p1.x > p2.x ? p1.x : p2.x) && q.y >= (p1.y < p2.y ? p1.y : p2.y) && q.y <= (p1.y > p2.y ? p1.y : p2.y)) return true; return false; } else if (arguments.length === 4) { const p1 = arguments[0], p2 = arguments[1], q1 = arguments[2], q2 = arguments[3]; let minq = Math.min(q1.x, q2.x); let maxq = Math.max(q1.x, q2.x); let minp = Math.min(p1.x, p2.x); let maxp = Math.max(p1.x, p2.x); if (minp > maxq) return false; if (maxp < minq) return false; minq = Math.min(q1.y, q2.y); maxq = Math.max(q1.y, q2.y); minp = Math.min(p1.y, p2.y); maxp = Math.max(p1.y, p2.y); if (minp > maxq) return false; if (maxp < minq) return false; return true; } } getArea() { return this.getWidth() * this.getHeight(); } equals(other) { if (!(other instanceof Envelope)) return false; const otherEnvelope = other; if (this.isNull()) return otherEnvelope.isNull(); return this._maxx === otherEnvelope.getMaxX() && this._maxy === otherEnvelope.getMaxY() && this._minx === otherEnvelope.getMinX() && this._miny === otherEnvelope.getMinY(); } intersection(env) { if (this.isNull() || env.isNull() || !this.intersects(env)) return new Envelope(); const intMinX = this._minx > env._minx ? this._minx : env._minx; const intMinY = this._miny > env._miny ? this._miny : env._miny; const intMaxX = this._maxx < env._maxx ? this._maxx : env._maxx; const intMaxY = this._maxy < env._maxy ? this._maxy : env._maxy; return new Envelope(intMinX, intMaxX, intMinY, intMaxY); } isNull() { return this._maxx < this._minx; } getMaxX() { return this._maxx; } covers() { if (arguments.length === 1) { if (arguments[0] instanceof Coordinate) { const p = arguments[0]; return this.covers(p.x, p.y); } else if (arguments[0] instanceof Envelope) { const other = arguments[0]; if (this.isNull() || other.isNull()) return false; return other.getMinX() >= this._minx && other.getMaxX() <= this._maxx && other.getMinY() >= this._miny && other.getMaxY() <= this._maxy; } } else if (arguments.length === 2) { const x = arguments[0], y = arguments[1]; if (this.isNull()) return false; return x >= this._minx && x <= this._maxx && y >= this._miny && y <= this._maxy; } } intersects() { if (arguments.length === 1) { if (arguments[0] instanceof Envelope) { const other = arguments[0]; if (this.isNull() || other.isNull()) return false; return !(other._minx > this._maxx || other._maxx < this._minx || other._miny > this._maxy || other._maxy < this._miny); } else if (arguments[0] instanceof Coordinate) { const p = arguments[0]; return this.intersects(p.x, p.y); } } else if (arguments.length === 2) { if (arguments[0] instanceof Coordinate && arguments[1] instanceof Coordinate) { const a = arguments[0], b = arguments[1]; if (this.isNull()) return false; const envminx = a.x < b.x ? a.x : b.x; if (envminx > this._maxx) return false; const envmaxx = a.x > b.x ? a.x : b.x; if (envmaxx < this._minx) return false; const envminy = a.y < b.y ? a.y : b.y; if (envminy > this._maxy) return false; const envmaxy = a.y > b.y ? a.y : b.y; if (envmaxy < this._miny) return false; return true; } else if (typeof arguments[0] === 'number' && typeof arguments[1] === 'number') { const x = arguments[0], y = arguments[1]; if (this.isNull()) return false; return !(x > this._maxx || x < this._minx || y > this._maxy || y < this._miny); } } } getMinY() { return this._miny; } getDiameter() { if (this.isNull()) return 0; const w = this.getWidth(); const h = this.getHeight(); return Math.sqrt(w * w + h * h); } getMinX() { return this._minx; } expandToInclude() { if (arguments.length === 1) { if (arguments[0] instanceof Coordinate) { const p = arguments[0]; this.expandToInclude(p.x, p.y); } else if (arguments[0] instanceof Envelope) { const other = arguments[0]; if (other.isNull()) return null; if (this.isNull()) { this._minx = other.getMinX(); this._maxx = other.getMaxX(); this._miny = other.getMinY(); this._maxy = other.getMaxY(); } else { if (other._minx < this._minx) this._minx = other._minx; if (other._maxx > this._maxx) this._maxx = other._maxx; if (other._miny < this._miny) this._miny = other._miny; if (other._maxy > this._maxy) this._maxy = other._maxy; } } } else if (arguments.length === 2) { const x = arguments[0], y = arguments[1]; if (this.isNull()) { this._minx = x; this._maxx = x; this._miny = y; this._maxy = y; } else { if (x < this._minx) this._minx = x; if (x > this._maxx) this._maxx = x; if (y < this._miny) this._miny = y; if (y > this._maxy) this._maxy = y; } } } minExtent() { if (this.isNull()) return 0.0; const w = this.getWidth(); const h = this.getHeight(); if (w < h) return w; return h; } getWidth() { if (this.isNull()) return 0; return this._maxx - this._minx; } compareTo(o) { const env = o; if (this.isNull()) { if (env.isNull()) return 0; return -1; } else { if (env.isNull()) return 1; } if (this._minx < env._minx) return -1; if (this._minx > env._minx) return 1; if (this._miny < env._miny) return -1; if (this._miny > env._miny) return 1; if (this._maxx < env._maxx) return -1; if (this._maxx > env._maxx) return 1; if (this._maxy < env._maxy) return -1; if (this._maxy > env._maxy) return 1; return 0; } translate(transX, transY) { if (this.isNull()) return null; this.init(this.getMinX() + transX, this.getMaxX() + transX, this.getMinY() + transY, this.getMaxY() + transY); } copy() { return new Envelope(this); } toString() { return 'Env[' + this._minx + ' : ' + this._maxx + ', ' + this._miny + ' : ' + this._maxy + ']'; } setToNull() { this._minx = 0; this._maxx = -1; this._miny = 0; this._maxy = -1; } disjoint(other) { if (this.isNull() || other.isNull()) return true; return other._minx > this._maxx || other._maxx < this._minx || other._miny > this._maxy || other._maxy < this._miny; } getHeight() { if (this.isNull()) return 0; return this._maxy - this._miny; } maxExtent() { if (this.isNull()) return 0.0; const w = this.getWidth(); const h = this.getHeight(); if (w > h) return w; return h; } expandBy() { if (arguments.length === 1) { const distance = arguments[0]; this.expandBy(distance, distance); } else if (arguments.length === 2) { const deltaX = arguments[0], deltaY = arguments[1]; if (this.isNull()) return null; this._minx -= deltaX; this._maxx += deltaX; this._miny -= deltaY; this._maxy += deltaY; if (this._minx > this._maxx || this._miny > this._maxy) this.setToNull(); } } contains() { if (arguments.length === 1) { if (arguments[0] instanceof Envelope) { const other = arguments[0]; return this.covers(other); } else if (arguments[0] instanceof Coordinate) { const p = arguments[0]; return this.covers(p); } } else if (arguments.length === 2) { const x = arguments[0], y = arguments[1]; return this.covers(x, y); } } centre() { if (this.isNull()) return null; return new Coordinate((this.getMinX() + this.getMaxX()) / 2.0, (this.getMinY() + this.getMaxY()) / 2.0); } init() { if (arguments.length === 0) { this.setToNull(); } else if (arguments.length === 1) { if (arguments[0] instanceof Coordinate) { const p = arguments[0]; this.init(p.x, p.x, p.y, p.y); } else if (arguments[0] instanceof Envelope) { const env = arguments[0]; this._minx = env._minx; this._maxx = env._maxx; this._miny = env._miny; this._maxy = env._maxy; } } else if (arguments.length === 2) { const p1 = arguments[0], p2 = arguments[1]; this.init(p1.x, p2.x, p1.y, p2.y); } else if (arguments.length === 4) { const x1 = arguments[0], x2 = arguments[1], y1 = arguments[2], y2 = arguments[3]; if (x1 < x2) { this._minx = x1; this._maxx = x2; } else { this._minx = x2; this._maxx = x1; } if (y1 < y2) { this._miny = y1; this._maxy = y2; } else { this._miny = y2; this._maxy = y1; } } } getMaxY() { return this._maxy; } distance(env) { if (this.intersects(env)) return 0; let dx = 0.0; if (this._maxx < env._minx) dx = env._minx - this._maxx;else if (this._minx > env._maxx) dx = this._minx - env._maxx; let dy = 0.0; if (this._maxy < env._miny) dy = env._miny - this._maxy;else if (this._miny > env._maxy) dy = this._miny - env._maxy; if (dx === 0.0) return dy; if (dy === 0.0) return dx; return Math.sqrt(dx * dx + dy * dy); } hashCode() { let result = 17; result = 37 * result + Coordinate.hashCode(this._minx); result = 37 * result + Coordinate.hashCode(this._maxx); result = 37 * result + Coordinate.hashCode(this._miny); result = 37 * result + Coordinate.hashCode(this._maxy); return result; } get interfaces_() { return [Comparable, Serializable]; } } class StringBuffer { constructor(str) { this.str = str; } append(e) { this.str += e; } setCharAt(i, c) { this.str = this.str.substr(0, i) + c + this.str.substr(i + 1); } toString() { return this.str; } } class Integer { constructor(value) { this.value = value; } intValue() { return this.value; } compareTo(o) { if (this.value < o) return -1; if (this.value > o) return 1; return 0; } static compare(x, y) { if (x < y) return -1; if (x > y) return 1; return 0; } static isNan(n) { return Number.isNaN(n); } static valueOf(value) { return new Integer(value); } } class Character { static isWhitespace(c) { return c <= 32 && c >= 0 || c === 127; } static toUpperCase(c) { return c.toUpperCase(); } } class DD { constructor() { DD.constructor_.apply(this, arguments); } static constructor_() { this._hi = 0.0; this._lo = 0.0; if (arguments.length === 0) { this.init(0.0); } else if (arguments.length === 1) { if (typeof arguments[0] === 'number') { const x = arguments[0]; this.init(x); } else if (arguments[0] instanceof DD) { const dd = arguments[0]; this.init(dd); } else if (typeof arguments[0] === 'string') { const str = arguments[0]; DD.constructor_.call(this, DD.parse(str)); } } else if (arguments.length === 2) { const hi = arguments[0], lo = arguments[1]; this.init(hi, lo); } } static determinant() { if (typeof arguments[3] === 'number' && typeof arguments[2] === 'number' && typeof arguments[0] === 'number' && typeof arguments[1] === 'number') { const x1 = arguments[0], y1 = arguments[1], x2 = arguments[2], y2 = arguments[3]; return DD.determinant(DD.valueOf(x1), DD.valueOf(y1), DD.valueOf(x2), DD.valueOf(y2)); } else if (arguments[3] instanceof DD && arguments[2] instanceof DD && arguments[0] instanceof DD && arguments[1] instanceof DD) { const x1 = arguments[0], y1 = arguments[1], x2 = arguments[2], y2 = arguments[3]; const det = x1.multiply(y2).selfSubtract(y1.multiply(x2)); return det; } } static sqr(x) { return DD.valueOf(x).selfMultiply(x); } static valueOf() { if (typeof arguments[0] === 'string') { const str = arguments[0]; return DD.parse(str); } else if (typeof arguments[0] =