(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.turf = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o * @license MIT */ var base64 = require('base64-js') var ieee754 = require('ieee754') var isArray = require('is-array') exports.Buffer = Buffer exports.SlowBuffer = SlowBuffer exports.INSPECT_MAX_BYTES = 50 Buffer.poolSize = 8192 // not used by this implementation var kMaxLength = 0x3fffffff var rootParent = {} /** * If `Buffer.TYPED_ARRAY_SUPPORT`: * === true Use Uint8Array implementation (fastest) * === false Use Object implementation (most compatible, even IE6) * * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, * Opera 11.6+, iOS 4.2+. * * Note: * * - Implementation must support adding new properties to `Uint8Array` instances. * Firefox 4-29 lacked support, fixed in Firefox 30+. * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. * * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. * * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of * incorrect length in some situations. * * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they will * get the Object implementation, which is slower but will work correctly. */ Buffer.TYPED_ARRAY_SUPPORT = (function () { try { var buf = new ArrayBuffer(0) var arr = new Uint8Array(buf) arr.foo = function () { return 42 } return arr.foo() === 42 && // typed array instances can be augmented typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` } catch (e) { return false } })() /** * Class: Buffer * ============= * * The Buffer constructor returns instances of `Uint8Array` that are augmented * with function properties for all the node `Buffer` API functions. We use * `Uint8Array` so that square bracket notation works as expected -- it returns * a single octet. * * By augmenting the instances, we can avoid modifying the `Uint8Array` * prototype. */ function Buffer (subject, encoding, noZero) { if (!(this instanceof Buffer)) return new Buffer(subject, encoding, noZero) var type = typeof subject // Find the length var length if (type === 'number') { length = +subject } else if (type === 'string') { length = Buffer.byteLength(subject, encoding) } else if (type === 'object' && subject !== null) { // assume object is array-like if (subject.type === 'Buffer' && isArray(subject.data)) subject = subject.data length = +subject.length } else { throw new TypeError('must start with number, buffer, array or string') } if (length > kMaxLength) throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 'size: 0x' + kMaxLength.toString(16) + ' bytes') if (length < 0) length = 0 else length >>>= 0 // Coerce to uint32. var self = this if (Buffer.TYPED_ARRAY_SUPPORT) { // Preferred: Return an augmented `Uint8Array` instance for best performance /*eslint-disable consistent-this */ self = Buffer._augment(new Uint8Array(length)) /*eslint-enable consistent-this */ } else { // Fallback: Return THIS instance of Buffer (created by `new`) self.length = length self._isBuffer = true } var i if (Buffer.TYPED_ARRAY_SUPPORT && typeof subject.byteLength === 'number') { // Speed optimization -- use set if we're copying from a typed array self._set(subject) } else if (isArrayish(subject)) { // Treat array-ish objects as a byte array if (Buffer.isBuffer(subject)) { for (i = 0; i < length; i++) self[i] = subject.readUInt8(i) } else { for (i = 0; i < length; i++) self[i] = ((subject[i] % 256) + 256) % 256 } } else if (type === 'string') { self.write(subject, 0, encoding) } else if (type === 'number' && !Buffer.TYPED_ARRAY_SUPPORT && !noZero) { for (i = 0; i < length; i++) { self[i] = 0 } } if (length > 0 && length <= Buffer.poolSize) self.parent = rootParent return self } function SlowBuffer (subject, encoding, noZero) { if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding, noZero) var buf = new Buffer(subject, encoding, noZero) delete buf.parent return buf } Buffer.isBuffer = function (b) { return !!(b != null && b._isBuffer) } Buffer.compare = function (a, b) { if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) throw new TypeError('Arguments must be Buffers') if (a === b) return 0 var x = a.length var y = b.length for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {} if (i !== len) { x = a[i] y = b[i] } if (x < y) return -1 if (y < x) return 1 return 0 } Buffer.isEncoding = function (encoding) { switch (String(encoding).toLowerCase()) { case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'raw': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return true default: return false } } Buffer.concat = function (list, totalLength) { if (!isArray(list)) throw new TypeError('Usage: Buffer.concat(list[, length])') if (list.length === 0) { return new Buffer(0) } else if (list.length === 1) { return list[0] } var i if (totalLength === undefined) { totalLength = 0 for (i = 0; i < list.length; i++) { totalLength += list[i].length } } var buf = new Buffer(totalLength) var pos = 0 for (i = 0; i < list.length; i++) { var item = list[i] item.copy(buf, pos) pos += item.length } return buf } Buffer.byteLength = function (str, encoding) { var ret str = str + '' switch (encoding || 'utf8') { case 'ascii': case 'binary': case 'raw': ret = str.length break case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': ret = str.length * 2 break case 'hex': ret = str.length >>> 1 break case 'utf8': case 'utf-8': ret = utf8ToBytes(str).length break case 'base64': ret = base64ToBytes(str).length break default: ret = str.length } return ret } // pre-set for values that may exist in the future Buffer.prototype.length = undefined Buffer.prototype.parent = undefined // toString(encoding, start=0, end=buffer.length) Buffer.prototype.toString = function (encoding, start, end) { var loweredCase = false start = start >>> 0 end = end === undefined || end === Infinity ? this.length : end >>> 0 if (!encoding) encoding = 'utf8' if (start < 0) start = 0 if (end > this.length) end = this.length if (end <= start) return '' while (true) { switch (encoding) { case 'hex': return hexSlice(this, start, end) case 'utf8': case 'utf-8': return utf8Slice(this, start, end) case 'ascii': return asciiSlice(this, start, end) case 'binary': return binarySlice(this, start, end) case 'base64': return base64Slice(this, start, end) case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return utf16leSlice(this, start, end) default: if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) encoding = (encoding + '').toLowerCase() loweredCase = true } } } Buffer.prototype.equals = function (b) { if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') if (this === b) return true return Buffer.compare(this, b) === 0 } Buffer.prototype.inspect = function () { var str = '' var max = exports.INSPECT_MAX_BYTES if (this.length > 0) { str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') if (this.length > max) str += ' ... ' } return '' } Buffer.prototype.compare = function (b) { if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') if (this === b) return 0 return Buffer.compare(this, b) } // `get` will be removed in Node 0.13+ Buffer.prototype.get = function (offset) { console.log('.get() is deprecated. Access using array indexes instead.') return this.readUInt8(offset) } // `set` will be removed in Node 0.13+ Buffer.prototype.set = function (v, offset) { console.log('.set() is deprecated. Access using array indexes instead.') return this.writeUInt8(v, offset) } function hexWrite (buf, string, offset, length) { offset = Number(offset) || 0 var remaining = buf.length - offset if (!length) { length = remaining } else { length = Number(length) if (length > remaining) { length = remaining } } // must be an even number of digits var strLen = string.length if (strLen % 2 !== 0) throw new Error('Invalid hex string') if (length > strLen / 2) { length = strLen / 2 } for (var i = 0; i < length; i++) { var byte = parseInt(string.substr(i * 2, 2), 16) if (isNaN(byte)) throw new Error('Invalid hex string') buf[offset + i] = byte } return i } function utf8Write (buf, string, offset, length) { var charsWritten = blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) return charsWritten } function asciiWrite (buf, string, offset, length) { var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length) return charsWritten } function binaryWrite (buf, string, offset, length) { return asciiWrite(buf, string, offset, length) } function base64Write (buf, string, offset, length) { var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length) return charsWritten } function utf16leWrite (buf, string, offset, length) { var charsWritten = blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) return charsWritten } Buffer.prototype.write = function (string, offset, length, encoding) { // Support both (string, offset, length, encoding) // and the legacy (string, encoding, offset, length) if (isFinite(offset)) { if (!isFinite(length)) { encoding = length length = undefined } } else { // legacy var swap = encoding encoding = offset offset = length length = swap } offset = Number(offset) || 0 if (length < 0 || offset < 0 || offset > this.length) throw new RangeError('attempt to write outside buffer bounds') var remaining = this.length - offset if (!length) { length = remaining } else { length = Number(length) if (length > remaining) { length = remaining } } encoding = String(encoding || 'utf8').toLowerCase() var ret switch (encoding) { case 'hex': ret = hexWrite(this, string, offset, length) break case 'utf8': case 'utf-8': ret = utf8Write(this, string, offset, length) break case 'ascii': ret = asciiWrite(this, string, offset, length) break case 'binary': ret = binaryWrite(this, string, offset, length) break case 'base64': ret = base64Write(this, string, offset, length) break case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': ret = utf16leWrite(this, string, offset, length) break default: throw new TypeError('Unknown encoding: ' + encoding) } return ret } Buffer.prototype.toJSON = function () { return { type: 'Buffer', data: Array.prototype.slice.call(this._arr || this, 0) } } function base64Slice (buf, start, end) { if (start === 0 && end === buf.length) { return base64.fromByteArray(buf) } else { return base64.fromByteArray(buf.slice(start, end)) } } function utf8Slice (buf, start, end) { var res = '' var tmp = '' end = Math.min(buf.length, end) for (var i = start; i < end; i++) { if (buf[i] <= 0x7F) { res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) tmp = '' } else { tmp += '%' + buf[i].toString(16) } } return res + decodeUtf8Char(tmp) } function asciiSlice (buf, start, end) { var ret = '' end = Math.min(buf.length, end) for (var i = start; i < end; i++) { ret += String.fromCharCode(buf[i] & 0x7F) } return ret } function binarySlice (buf, start, end) { var ret = '' end = Math.min(buf.length, end) for (var i = start; i < end; i++) { ret += String.fromCharCode(buf[i]) } return ret } function hexSlice (buf, start, end) { var len = buf.length if (!start || start < 0) start = 0 if (!end || end < 0 || end > len) end = len var out = '' for (var i = start; i < end; i++) { out += toHex(buf[i]) } return out } function utf16leSlice (buf, start, end) { var bytes = buf.slice(start, end) var res = '' for (var i = 0; i < bytes.length; i += 2) { res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) } return res } Buffer.prototype.slice = function (start, end) { var len = this.length start = ~~start end = end === undefined ? len : ~~end if (start < 0) { start += len if (start < 0) start = 0 } else if (start > len) { start = len } if (end < 0) { end += len if (end < 0) end = 0 } else if (end > len) { end = len } if (end < start) end = start var newBuf if (Buffer.TYPED_ARRAY_SUPPORT) { newBuf = Buffer._augment(this.subarray(start, end)) } else { var sliceLen = end - start newBuf = new Buffer(sliceLen, undefined, true) for (var i = 0; i < sliceLen; i++) { newBuf[i] = this[i + start] } } if (newBuf.length) newBuf.parent = this.parent || this return newBuf } /* * Need to make sure that buffer isn't trying to write out of bounds. */ function checkOffset (offset, ext, length) { if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') } Buffer.prototype.readUIntLE = function (offset, byteLength, noAssert) { offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var val = this[offset] var mul = 1 var i = 0 while (++i < byteLength && (mul *= 0x100)) val += this[offset + i] * mul return val } Buffer.prototype.readUIntBE = function (offset, byteLength, noAssert) { offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var val = this[offset + --byteLength] var mul = 1 while (byteLength > 0 && (mul *= 0x100)) val += this[offset + --byteLength] * mul return val } Buffer.prototype.readUInt8 = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 1, this.length) return this[offset] } Buffer.prototype.readUInt16LE = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) return this[offset] | (this[offset + 1] << 8) } Buffer.prototype.readUInt16BE = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) return (this[offset] << 8) | this[offset + 1] } Buffer.prototype.readUInt32LE = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return ((this[offset]) | (this[offset + 1] << 8) | (this[offset + 2] << 16)) + (this[offset + 3] * 0x1000000) } Buffer.prototype.readUInt32BE = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset] * 0x1000000) + ((this[offset + 1] << 16) | (this[offset + 2] << 8) | this[offset + 3]) } Buffer.prototype.readIntLE = function (offset, byteLength, noAssert) { offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var val = this[offset] var mul = 1 var i = 0 while (++i < byteLength && (mul *= 0x100)) val += this[offset + i] * mul mul *= 0x80 if (val >= mul) val -= Math.pow(2, 8 * byteLength) return val } Buffer.prototype.readIntBE = function (offset, byteLength, noAssert) { offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) checkOffset(offset, byteLength, this.length) var i = byteLength var mul = 1 var val = this[offset + --i] while (i > 0 && (mul *= 0x100)) val += this[offset + --i] * mul mul *= 0x80 if (val >= mul) val -= Math.pow(2, 8 * byteLength) return val } Buffer.prototype.readInt8 = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 1, this.length) if (!(this[offset] & 0x80)) return (this[offset]) return ((0xff - this[offset] + 1) * -1) } Buffer.prototype.readInt16LE = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) var val = this[offset] | (this[offset + 1] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } Buffer.prototype.readInt16BE = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) var val = this[offset + 1] | (this[offset] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } Buffer.prototype.readInt32LE = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset]) | (this[offset + 1] << 8) | (this[offset + 2] << 16) | (this[offset + 3] << 24) } Buffer.prototype.readInt32BE = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset] << 24) | (this[offset + 1] << 16) | (this[offset + 2] << 8) | (this[offset + 3]) } Buffer.prototype.readFloatLE = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return ieee754.read(this, offset, true, 23, 4) } Buffer.prototype.readFloatBE = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return ieee754.read(this, offset, false, 23, 4) } Buffer.prototype.readDoubleLE = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 8, this.length) return ieee754.read(this, offset, true, 52, 8) } Buffer.prototype.readDoubleBE = function (offset, noAssert) { if (!noAssert) checkOffset(offset, 8, this.length) return ieee754.read(this, offset, false, 52, 8) } function checkInt (buf, value, offset, ext, max, min) { if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') if (value > max || value < min) throw new RangeError('value is out of bounds') if (offset + ext > buf.length) throw new RangeError('index out of range') } Buffer.prototype.writeUIntLE = function (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) var mul = 1 var i = 0 this[offset] = value & 0xFF while (++i < byteLength && (mul *= 0x100)) this[offset + i] = (value / mul) >>> 0 & 0xFF return offset + byteLength } Buffer.prototype.writeUIntBE = function (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) var i = byteLength - 1 var mul = 1 this[offset + i] = value & 0xFF while (--i >= 0 && (mul *= 0x100)) this[offset + i] = (value / mul) >>> 0 & 0xFF return offset + byteLength } Buffer.prototype.writeUInt8 = function (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) this[offset] = value return offset + 1 } function objectWriteUInt16 (buf, value, offset, littleEndian) { if (value < 0) value = 0xffff + value + 1 for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> (littleEndian ? i : 1 - i) * 8 } } Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = value this[offset + 1] = (value >>> 8) } else objectWriteUInt16(this, value, offset, true) return offset + 2 } Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 8) this[offset + 1] = value } else objectWriteUInt16(this, value, offset, false) return offset + 2 } function objectWriteUInt32 (buf, value, offset, littleEndian) { if (value < 0) value = 0xffffffff + value + 1 for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff } } Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset + 3] = (value >>> 24) this[offset + 2] = (value >>> 16) this[offset + 1] = (value >>> 8) this[offset] = value } else objectWriteUInt32(this, value, offset, true) return offset + 4 } Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) this[offset + 3] = value } else objectWriteUInt32(this, value, offset, false) return offset + 4 } Buffer.prototype.writeIntLE = function (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) { checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength - 1) - 1, -Math.pow(2, 8 * byteLength - 1)) } var i = 0 var mul = 1 var sub = value < 0 ? 1 : 0 this[offset] = value & 0xFF while (++i < byteLength && (mul *= 0x100)) this[offset + i] = ((value / mul) >> 0) - sub & 0xFF return offset + byteLength } Buffer.prototype.writeIntBE = function (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) { checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength - 1) - 1, -Math.pow(2, 8 * byteLength - 1)) } var i = byteLength - 1 var mul = 1 var sub = value < 0 ? 1 : 0 this[offset + i] = value & 0xFF while (--i >= 0 && (mul *= 0x100)) this[offset + i] = ((value / mul) >> 0) - sub & 0xFF return offset + byteLength } Buffer.prototype.writeInt8 = function (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) if (value < 0) value = 0xff + value + 1 this[offset] = value return offset + 1 } Buffer.prototype.writeInt16LE = function (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = value this[offset + 1] = (value >>> 8) } else objectWriteUInt16(this, value, offset, true) return offset + 2 } Buffer.prototype.writeInt16BE = function (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 8) this[offset + 1] = value } else objectWriteUInt16(this, value, offset, false) return offset + 2 } Buffer.prototype.writeInt32LE = function (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = value this[offset + 1] = (value >>> 8) this[offset + 2] = (value >>> 16) this[offset + 3] = (value >>> 24) } else objectWriteUInt32(this, value, offset, true) return offset + 4 } Buffer.prototype.writeInt32BE = function (value, offset, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) if (value < 0) value = 0xffffffff + value + 1 if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) this[offset + 3] = value } else objectWriteUInt32(this, value, offset, false) return offset + 4 } function checkIEEE754 (buf, value, offset, ext, max, min) { if (value > max || value < min) throw new RangeError('value is out of bounds') if (offset + ext > buf.length) throw new RangeError('index out of range') if (offset < 0) throw new RangeError('index out of range') } function writeFloat (buf, value, offset, littleEndian, noAssert) { if (!noAssert) checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) ieee754.write(buf, value, offset, littleEndian, 23, 4) return offset + 4 } Buffer.prototype.writeFloatLE = function (value, offset, noAssert) { return writeFloat(this, value, offset, true, noAssert) } Buffer.prototype.writeFloatBE = function (value, offset, noAssert) { return writeFloat(this, value, offset, false, noAssert) } function writeDouble (buf, value, offset, littleEndian, noAssert) { if (!noAssert) checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) ieee754.write(buf, value, offset, littleEndian, 52, 8) return offset + 8 } Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) { return writeDouble(this, value, offset, true, noAssert) } Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) { return writeDouble(this, value, offset, false, noAssert) } // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) Buffer.prototype.copy = function (target, target_start, start, end) { var self = this // source if (!start) start = 0 if (!end && end !== 0) end = this.length if (target_start >= target.length) target_start = target.length if (!target_start) target_start = 0 if (end > 0 && end < start) end = start // Copy 0 bytes; we're done if (end === start) return 0 if (target.length === 0 || self.length === 0) return 0 // Fatal error conditions if (target_start < 0) throw new RangeError('targetStart out of bounds') if (start < 0 || start >= self.length) throw new RangeError('sourceStart out of bounds') if (end < 0) throw new RangeError('sourceEnd out of bounds') // Are we oob? if (end > this.length) end = this.length if (target.length - target_start < end - start) end = target.length - target_start + start var len = end - start if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { for (var i = 0; i < len; i++) { target[i + target_start] = this[i + start] } } else { target._set(this.subarray(start, start + len), target_start) } return len } // fill(value, start=0, end=buffer.length) Buffer.prototype.fill = function (value, start, end) { if (!value) value = 0 if (!start) start = 0 if (!end) end = this.length if (end < start) throw new RangeError('end < start') // Fill 0 bytes; we're done if (end === start) return if (this.length === 0) return if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') if (end < 0 || end > this.length) throw new RangeError('end out of bounds') var i if (typeof value === 'number') { for (i = start; i < end; i++) { this[i] = value } } else { var bytes = utf8ToBytes(value.toString()) var len = bytes.length for (i = start; i < end; i++) { this[i] = bytes[i % len] } } return this } /** * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. * Added in Node 0.12. Only available in browsers that support ArrayBuffer. */ Buffer.prototype.toArrayBuffer = function () { if (typeof Uint8Array !== 'undefined') { if (Buffer.TYPED_ARRAY_SUPPORT) { return (new Buffer(this)).buffer } else { var buf = new Uint8Array(this.length) for (var i = 0, len = buf.length; i < len; i += 1) { buf[i] = this[i] } return buf.buffer } } else { throw new TypeError('Buffer.toArrayBuffer not supported in this browser') } } // HELPER FUNCTIONS // ================ var BP = Buffer.prototype /** * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods */ Buffer._augment = function (arr) { arr.constructor = Buffer arr._isBuffer = true // save reference to original Uint8Array get/set methods before overwriting arr._get = arr.get arr._set = arr.set // deprecated, will be removed in node 0.13+ arr.get = BP.get arr.set = BP.set arr.write = BP.write arr.toString = BP.toString arr.toLocaleString = BP.toString arr.toJSON = BP.toJSON arr.equals = BP.equals arr.compare = BP.compare arr.copy = BP.copy arr.slice = BP.slice arr.readUIntLE = BP.readUIntLE arr.readUIntBE = BP.readUIntBE arr.readUInt8 = BP.readUInt8 arr.readUInt16LE = BP.readUInt16LE arr.readUInt16BE = BP.readUInt16BE arr.readUInt32LE = BP.readUInt32LE arr.readUInt32BE = BP.readUInt32BE arr.readIntLE = BP.readIntLE arr.readIntBE = BP.readIntBE arr.readInt8 = BP.readInt8 arr.readInt16LE = BP.readInt16LE arr.readInt16BE = BP.readInt16BE arr.readInt32LE = BP.readInt32LE arr.readInt32BE = BP.readInt32BE arr.readFloatLE = BP.readFloatLE arr.readFloatBE = BP.readFloatBE arr.readDoubleLE = BP.readDoubleLE arr.readDoubleBE = BP.readDoubleBE arr.writeUInt8 = BP.writeUInt8 arr.writeUIntLE = BP.writeUIntLE arr.writeUIntBE = BP.writeUIntBE arr.writeUInt16LE = BP.writeUInt16LE arr.writeUInt16BE = BP.writeUInt16BE arr.writeUInt32LE = BP.writeUInt32LE arr.writeUInt32BE = BP.writeUInt32BE arr.writeIntLE = BP.writeIntLE arr.writeIntBE = BP.writeIntBE arr.writeInt8 = BP.writeInt8 arr.writeInt16LE = BP.writeInt16LE arr.writeInt16BE = BP.writeInt16BE arr.writeInt32LE = BP.writeInt32LE arr.writeInt32BE = BP.writeInt32BE arr.writeFloatLE = BP.writeFloatLE arr.writeFloatBE = BP.writeFloatBE arr.writeDoubleLE = BP.writeDoubleLE arr.writeDoubleBE = BP.writeDoubleBE arr.fill = BP.fill arr.inspect = BP.inspect arr.toArrayBuffer = BP.toArrayBuffer return arr } var INVALID_BASE64_RE = /[^+\/0-9A-z\-]/g function base64clean (str) { // Node strips out invalid characters like \n and \t from the string, base64-js does not str = stringtrim(str).replace(INVALID_BASE64_RE, '') // Node converts strings with length < 2 to '' if (str.length < 2) return '' // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not while (str.length % 4 !== 0) { str = str + '=' } return str } function stringtrim (str) { if (str.trim) return str.trim() return str.replace(/^\s+|\s+$/g, '') } function isArrayish (subject) { return isArray(subject) || Buffer.isBuffer(subject) || subject && typeof subject === 'object' && typeof subject.length === 'number' } function toHex (n) { if (n < 16) return '0' + n.toString(16) return n.toString(16) } function utf8ToBytes (string, units) { units = units || Infinity var codePoint var length = string.length var leadSurrogate = null var bytes = [] var i = 0 for (; i < length; i++) { codePoint = string.charCodeAt(i) // is surrogate component if (codePoint > 0xD7FF && codePoint < 0xE000) { // last char was a lead if (leadSurrogate) { // 2 leads in a row if (codePoint < 0xDC00) { if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) leadSurrogate = codePoint continue } else { // valid surrogate pair codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 leadSurrogate = null } } else { // no lead yet if (codePoint > 0xDBFF) { // unexpected trail if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) continue } else if (i + 1 === length) { // unpaired lead if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) continue } else { // valid lead leadSurrogate = codePoint continue } } } else if (leadSurrogate) { // valid bmp char, but last char was a lead if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) leadSurrogate = null } // encode utf8 if (codePoint < 0x80) { if ((units -= 1) < 0) break bytes.push(codePoint) } else if (codePoint < 0x800) { if ((units -= 2) < 0) break bytes.push( codePoint >> 0x6 | 0xC0, codePoint & 0x3F | 0x80 ) } else if (codePoint < 0x10000) { if ((units -= 3) < 0) break bytes.push( codePoint >> 0xC | 0xE0, codePoint >> 0x6 & 0x3F | 0x80, codePoint & 0x3F | 0x80 ) } else if (codePoint < 0x200000) { if ((units -= 4) < 0) break bytes.push( codePoint >> 0x12 | 0xF0, codePoint >> 0xC & 0x3F | 0x80, codePoint >> 0x6 & 0x3F | 0x80, codePoint & 0x3F | 0x80 ) } else { throw new Error('Invalid code point') } } return bytes } function asciiToBytes (str) { var byteArray = [] for (var i = 0; i < str.length; i++) { // Node's code seems to be doing this and not & 0x7F.. byteArray.push(str.charCodeAt(i) & 0xFF) } return byteArray } function utf16leToBytes (str, units) { var c, hi, lo var byteArray = [] for (var i = 0; i < str.length; i++) { if ((units -= 2) < 0) break c = str.charCodeAt(i) hi = c >> 8 lo = c % 256 byteArray.push(lo) byteArray.push(hi) } return byteArray } function base64ToBytes (str) { return base64.toByteArray(base64clean(str)) } function blitBuffer (src, dst, offset, length) { for (var i = 0; i < length; i++) { if ((i + offset >= dst.length) || (i >= src.length)) break dst[i + offset] = src[i] } return i } function decodeUtf8Char (str) { try { return decodeURIComponent(str) } catch (err) { return String.fromCharCode(0xFFFD) // UTF 8 invalid char } } },{"base64-js":3,"ieee754":4,"is-array":5}],3:[function(require,module,exports){ var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; ;(function (exports) { 'use strict'; var Arr = (typeof Uint8Array !== 'undefined') ? Uint8Array : Array var PLUS = '+'.charCodeAt(0) var SLASH = '/'.charCodeAt(0) var NUMBER = '0'.charCodeAt(0) var LOWER = 'a'.charCodeAt(0) var UPPER = 'A'.charCodeAt(0) var PLUS_URL_SAFE = '-'.charCodeAt(0) var SLASH_URL_SAFE = '_'.charCodeAt(0) function decode (elt) { var code = elt.charCodeAt(0) if (code === PLUS || code === PLUS_URL_SAFE) return 62 // '+' if (code === SLASH || code === SLASH_URL_SAFE) return 63 // '/' if (code < NUMBER) return -1 //no match if (code < NUMBER + 10) return code - NUMBER + 26 + 26 if (code < UPPER + 26) return code - UPPER if (code < LOWER + 26) return code - LOWER + 26 } function b64ToByteArray (b64) { var i, j, l, tmp, placeHolders, arr if (b64.length % 4 > 0) { throw new Error('Invalid string. Length must be a multiple of 4') } // the number of equal signs (place holders) // if there are two placeholders, than the two characters before it // represent one byte // if there is only one, then the three characters before it represent 2 bytes // this is just a cheap hack to not do indexOf twice var len = b64.length placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 // base64 is 4/3 + up to two characters of the original data arr = new Arr(b64.length * 3 / 4 - placeHolders) // if there are placeholders, only get up to the last complete 4 chars l = placeHolders > 0 ? b64.length - 4 : b64.length var L = 0 function push (v) { arr[L++] = v } for (i = 0, j = 0; i < l; i += 4, j += 3) { tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) push((tmp & 0xFF0000) >> 16) push((tmp & 0xFF00) >> 8) push(tmp & 0xFF) } if (placeHolders === 2) { tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) push(tmp & 0xFF) } else if (placeHolders === 1) { tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) push((tmp >> 8) & 0xFF) push(tmp & 0xFF) } return arr } function uint8ToBase64 (uint8) { var i, extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes output = "", temp, length function encode (num) { return lookup.charAt(num) } function tripletToBase64 (num) { return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) } // go through the array every three bytes, we'll deal with trailing stuff later for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) output += tripletToBase64(temp) } // pad the end with zeros, but make sure to not forget the extra bytes switch (extraBytes) { case 1: temp = uint8[uint8.length - 1] output += encode(temp >> 2) output += encode((temp << 4) & 0x3F) output += '==' break case 2: temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) output += encode(temp >> 10) output += encode((temp >> 4) & 0x3F) output += encode((temp << 2) & 0x3F) output += '=' break } return output } exports.toByteArray = b64ToByteArray exports.fromByteArray = uint8ToBase64 }(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) },{}],4:[function(require,module,exports){ exports.read = function(buffer, offset, isLE, mLen, nBytes) { var e, m, eLen = nBytes * 8 - mLen - 1, eMax = (1 << eLen) - 1, eBias = eMax >> 1, nBits = -7, i = isLE ? (nBytes - 1) : 0, d = isLE ? -1 : 1, s = buffer[offset + i]; i += d; e = s & ((1 << (-nBits)) - 1); s >>= (-nBits); nBits += eLen; for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); m = e & ((1 << (-nBits)) - 1); e >>= (-nBits); nBits += mLen; for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); if (e === 0) { e = 1 - eBias; } else if (e === eMax) { return m ? NaN : ((s ? -1 : 1) * Infinity); } else { m = m + Math.pow(2, mLen); e = e - eBias; } return (s ? -1 : 1) * m * Math.pow(2, e - mLen); }; exports.write = function(buffer, value, offset, isLE, mLen, nBytes) { var e, m, c, eLen = nBytes * 8 - mLen - 1, eMax = (1 << eLen) - 1, eBias = eMax >> 1, rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), i = isLE ? 0 : (nBytes - 1), d = isLE ? 1 : -1, s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; value = Math.abs(value); if (isNaN(value) || value === Infinity) { m = isNaN(value) ? 1 : 0; e = eMax; } else { e = Math.floor(Math.log(value) / Math.LN2); if (value * (c = Math.pow(2, -e)) < 1) { e--; c *= 2; } if (e + eBias >= 1) { value += rt / c; } else { value += rt * Math.pow(2, 1 - eBias); } if (value * c >= 2) { e++; c /= 2; } if (e + eBias >= eMax) { m = 0; e = eMax; } else if (e + eBias >= 1) { m = (value * c - 1) * Math.pow(2, mLen); e = e + eBias; } else { m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); e = 0; } } for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); e = (e << mLen) | m; eLen += mLen; for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); buffer[offset + i - d] |= s * 128; }; },{}],5:[function(require,module,exports){ /** * isArray */ var isArray = Array.isArray; /** * toString */ var str = Object.prototype.toString; /** * Whether or not the given `val` * is an array. * * example: * * isArray([]); * // > true * isArray(arguments); * // > false * isArray(''); * // > false * * @param {mixed} val * @return {bool} */ module.exports = isArray || function (val) { return !! val && '[object Array]' == str.call(val); }; },{}],6:[function(require,module,exports){ var average = require('turf-average'); var sum = require('turf-sum'); var median = require('turf-median'); var min = require('turf-min'); var max = require('turf-max'); var deviation = require('turf-deviation'); var variance = require('turf-variance'); var count = require('turf-count'); var operations = {}; operations.average = average; operations.sum = sum; operations.median = median; operations.min = min; operations.max = max; operations.deviation = deviation; operations.variance = variance; operations.count = count; /** * Calculates a series of aggregations for a set of {@link Point} features within a set of {@link Polygon} features. Sum, average, count, min, max, and deviation are supported. * * @module turf/aggregate * @category aggregation * @param {FeatureCollection} polygons a FeatureCollection of {@link Polygon} features * @param {FeatureCollection} points a FeatureCollection of {@link Point} features * @param {Array} aggregations an array of aggregation objects * @return {FeatureCollection} a FeatureCollection of {@link Polygon} features with properties listed as `outField` values in `aggregations` * @example * var polygons = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [1.669921, 48.632908], * [1.669921, 49.382372], * [3.636474, 49.382372], * [3.636474, 48.632908], * [1.669921, 48.632908] * ]] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [2.230224, 47.85003], * [2.230224, 48.611121], * [4.361572, 48.611121], * [4.361572, 47.85003], * [2.230224, 47.85003] * ]] * } * } * ] * }; * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [2.054443,49.138596] * } * }, * { * "type": "Feature", * "properties": { * "population": 600 * }, * "geometry": { * "type": "Point", * "coordinates": [3.065185,48.850258] * } * }, * { * "type": "Feature", * "properties": { * "population": 100 * }, * "geometry": { * "type": "Point", * "coordinates": [2.329101,48.79239] * } * }, * { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [2.614746,48.334343] * } * }, * { * "type": "Feature", * "properties": { * "population": 300 * }, * "geometry": { * "type": "Point", * "coordinates": [3.416748,48.056053] * } * } * ] * }; * var aggregations = [ * { * aggregation: 'sum', * inField: 'population', * outField: 'pop_sum' * }, * { * aggregation: 'average', * inField: 'population', * outField: 'pop_avg' * }, * { * aggregation: 'median', * inField: 'population', * outField: 'pop_median' * }, * { * aggregation: 'min', * inField: 'population', * outField: 'pop_min' * }, * { * aggregation: 'max', * inField: 'population', * outField: 'pop_max' * }, * { * aggregation: 'deviation', * inField: 'population', * outField: 'pop_deviation' * }, * { * aggregation: 'variance', * inField: 'population', * outField: 'pop_variance' * }, * { * aggregation: 'count', * inField: '', * outField: 'point_count' * } * ]; * * var aggregated = turf.aggregate( * polygons, points, aggregations); * * var result = turf.featurecollection( * points.features.concat(aggregated.features)); * * //=result */ module.exports = function(polygons, points, aggregations){ for (var i = 0, len = aggregations.length; i < len; i++) { var agg = aggregations[i], operation = agg.aggregation, unrecognizedError; if (isAggregationOperation(operation)) { if (operation === 'count') { polygons = operations[operation](polygons, points, agg.outField); } else { polygons = operations[operation](polygons, points, agg.inField, agg.outField); } } else { throw new Error('"'+ operation +'" is not a recognized aggregation operation.'); } } return polygons; }; function isAggregationOperation(operation) { return operation === 'average' || operation === 'sum' || operation === 'median' || operation === 'min' || operation === 'max' || operation === 'deviation' || operation === 'variance' || operation === 'count'; } },{"turf-average":11,"turf-count":56,"turf-deviation":58,"turf-max":91,"turf-median":92,"turf-min":96,"turf-sum":116,"turf-variance":125}],7:[function(require,module,exports){ var distance = require('turf-distance'); var point = require('turf-point'); var bearing = require('turf-bearing'); var destination = require('turf-destination'); /** * Takes a {@link LineString} feature and returns a {@link Point} feature at a specified distance along a line. * * @module turf/along * @category measurement * @param {LineString} line a LineString feature * @param {Number} distance distance along the line * @param {String} [units=miles] can be degrees, radians, miles, or kilometers * @return {Point} Point along the line at `distance` distance * @example * var line = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "LineString", * "coordinates": [ * [-77.031669, 38.878605], * [-77.029609, 38.881946], * [-77.020339, 38.884084], * [-77.025661, 38.885821], * [-77.021884, 38.889563], * [-77.019824, 38.892368] * ] * } * }; * * var along = turf.along(line, 1, 'miles'); * * var result = { * "type": "FeatureCollection", * "features": [line, along] * }; * * //=result */ module.exports = function (line, dist, units) { var coords; if(line.type === 'Feature') coords = line.geometry.coordinates; else if(line.type === 'LineString') coords = line.geometry.coordinates; else throw new Error('input must be a LineString Feature or Geometry'); var travelled = 0; for(var i = 0; i < coords.length; i++) { if (dist >= travelled && i === coords.length - 1) break; else if(travelled >= dist) { var overshot = dist - travelled; if(!overshot) return point(coords[i]); else { var direction = bearing(point(coords[i]), point(coords[i-1])) - 180; var interpolated = destination(point(coords[i]), overshot, direction, units); return interpolated; } } else { travelled += distance(point(coords[i]), point(coords[i+1]), units); } } return point(coords[coords.length - 1]); } },{"turf-bearing":13,"turf-destination":57,"turf-distance":60,"turf-point":102}],8:[function(require,module,exports){ var geometryArea = require('geojson-area').geometry; /** * Takes a {@link GeoJSON} feature or {@link FeatureCollection} of any type and returns the area of that feature * in square meters. * * @module turf/area * @category measurement * @param {GeoJSON} input a {@link Feature} or {@link FeatureCollection} of any type * @return {Number} area in square meters * @example * var polygons = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-67.031021, 10.458102], * [-67.031021, 10.53372], * [-66.929397, 10.53372], * [-66.929397, 10.458102], * [-67.031021, 10.458102] * ]] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-66.919784, 10.397325], * [-66.919784, 10.513467], * [-66.805114, 10.513467], * [-66.805114, 10.397325], * [-66.919784, 10.397325] * ]] * } * } * ] * }; * * var area = turf.area(polygons); * * //=area */ module.exports = function(_) { if (_.type === 'FeatureCollection') { for (var i = 0, sum = 0; i < _.features.length; i++) { if (_.features[i].geometry) { sum += geometryArea(_.features[i].geometry); } } return sum; } else if (_.type === 'Feature') { return geometryArea(_.geometry); } else { return geometryArea(_); } }; },{"geojson-area":9}],9:[function(require,module,exports){ var wgs84 = require('wgs84'); module.exports.geometry = geometry; module.exports.ring = ringArea; function geometry(_) { var area = 0, i; switch (_.type) { case 'Polygon': return polygonArea(_.coordinates); case 'MultiPolygon': for (i = 0; i < _.coordinates.length; i++) { area += polygonArea(_.coordinates[i]); } return area; case 'Point': case 'MultiPoint': case 'LineString': case 'MultiLineString': return 0; case 'GeometryCollection': for (i = 0; i < _.geometries.length; i++) { area += geometry(_.geometries[i]); } return area; } } function polygonArea(coords) { var area = 0; if (coords && coords.length > 0) { area += Math.abs(ringArea(coords[0])); for (var i = 1; i < coords.length; i++) { area -= Math.abs(ringArea(coords[i])); } } return area; } /** * Calculate the approximate area of the polygon were it projected onto * the earth. Note that this area will be positive if ring is oriented * clockwise, otherwise it will be negative. * * Reference: * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for * Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion * Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409 * * Returns: * {float} The approximate signed geodesic area of the polygon in square * meters. */ function ringArea(coords) { var area = 0; if (coords.length > 2) { var p1, p2; for (var i = 0; i < coords.length - 1; i++) { p1 = coords[i]; p2 = coords[i + 1]; area += rad(p2[0] - p1[0]) * (2 + Math.sin(rad(p1[1])) + Math.sin(rad(p2[1]))); } area = area * wgs84.RADIUS * wgs84.RADIUS / 2; } return area; } function rad(_) { return _ * Math.PI / 180; } },{"wgs84":10}],10:[function(require,module,exports){ module.exports.RADIUS = 6378137; module.exports.FLATTENING = 1/298.257223563; module.exports.POLAR_RADIUS = 6356752.3142; },{}],11:[function(require,module,exports){ var inside = require('turf-inside'); /** * Calculates the average value of a field for a set of {@link Point} features within a set of {@link Polygon} features. * * @module turf/average * @category aggregation * @param {FeatureCollection} polygons a FeatureCollection of {@link Polygon} features * @param {FeatureCollection} points a FeatureCollection of {@link Point} features * @param {string} field the field in the `points` features from which to pull values to average * @param {string} outputField the field in the `polygons` FeatureCollection to put results of the averages * @return {FeatureCollection} a FeatureCollection of {@link Polygon} features with the value of `outField` set to the calculated average * @example * var polygons = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [10.666351, 59.890659], * [10.666351, 59.936784], * [10.762481, 59.936784], * [10.762481, 59.890659], * [10.666351, 59.890659] * ]] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [10.764541, 59.889281], * [10.764541, 59.937128], * [10.866165, 59.937128], * [10.866165, 59.889281], * [10.764541, 59.889281] * ]] * } * } * ] * }; * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [10.724029, 59.926807] * } * }, { * "type": "Feature", * "properties": { * "population": 600 * }, * "geometry": { * "type": "Point", * "coordinates": [10.715789, 59.904778] * } * }, { * "type": "Feature", * "properties": { * "population": 100 * }, * "geometry": { * "type": "Point", * "coordinates": [10.746002, 59.908566] * } * }, { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [10.806427, 59.908910] * } * }, { * "type": "Feature", * "properties": { * "population": 300 * }, * "geometry": { * "type": "Point", * "coordinates": [10.79544, 59.931624] * } * } * ] * }; * * var averaged = turf.average( * polygons, points, 'population', 'pop_avg'); * * var resultFeatures = points.features.concat( * averaged.features); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ module.exports = function(polyFC, ptFC, inField, outField, done){ polyFC.features.forEach(function(poly){ if(!poly.properties) poly.properties = {}; var values = []; ptFC.features.forEach(function(pt){ if (inside(pt, poly)) values.push(pt.properties[inField]); }); poly.properties[outField] = average(values); }); return polyFC; } function average(values) { var sum = 0; for (var i = 0; i < values.length; i++) { sum += values[i]; } return sum / values.length; } },{"turf-inside":76}],12:[function(require,module,exports){ var polygon = require('turf-polygon'); /** * Takes a bbox and returns the equivalent {@link Polygon} feature. * * @module turf/bbox-polygon * @category measurement * @param {Array} bbox an Array of bounding box coordinates in the form: ```[xLow, yLow, xHigh, yHigh]``` * @return {Polygon} a Polygon representation of the bounding box * @example * var bbox = [0, 0, 10, 10]; * * var poly = turf.bboxPolygon(bbox); * * //=poly */ module.exports = function(bbox){ var lowLeft = [bbox[0], bbox[1]]; var topLeft = [bbox[0], bbox[3]]; var topRight = [bbox[2], bbox[3]]; var lowRight = [bbox[2], bbox[1]]; var poly = polygon([[ lowLeft, lowRight, topRight, topLeft, lowLeft ]]); return poly; } },{"turf-polygon":103}],13:[function(require,module,exports){ //http://en.wikipedia.org/wiki/Haversine_formula //http://www.movable-type.co.uk/scripts/latlong.html /** * Takes two {@link Point} features and finds the bearing between them. * * @module turf/bearing * @category measurement * @param {Point} start starting Point * @param {Point} end ending Point * @category measurement * @returns {Number} bearing in decimal degrees * @example * var point1 = { * "type": "Feature", * "properties": { * "marker-color": '#f00' * }, * "geometry": { * "type": "Point", * "coordinates": [-75.343, 39.984] * } * }; * var point2 = { * "type": "Feature", * "properties": { * "marker-color": '#0f0' * }, * "geometry": { * "type": "Point", * "coordinates": [-75.534, 39.123] * } * }; * * var points = { * "type": "FeatureCollection", * "features": [point1, point2] * }; * * //=points * * var bearing = turf.bearing(point1, point2); * * //=bearing */ module.exports = function (point1, point2) { var coordinates1 = point1.geometry.coordinates; var coordinates2 = point2.geometry.coordinates; var lon1 = toRad(coordinates1[0]); var lon2 = toRad(coordinates2[0]); var lat1 = toRad(coordinates1[1]); var lat2 = toRad(coordinates2[1]); var a = Math.sin(lon2 - lon1) * Math.cos(lat2); var b = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1); var bearing = toDeg(Math.atan2(a, b)); return bearing; }; function toRad(degree) { return degree * Math.PI / 180; } function toDeg(radian) { return radian * 180 / Math.PI; } },{}],14:[function(require,module,exports){ var linestring = require('turf-linestring'); var Spline = require('./spline.js'); /** * Takes a {@link LineString} feature and returns a curved version of the line * by applying a [Bezier spline](http://en.wikipedia.org/wiki/B%C3%A9zier_spline) * algorithm. * * The bezier spline implementation is by [Leszek Rybicki](http://leszek.rybicki.cc/). * * @module turf/bezier * @category transformation * @param {LineString} line the input LineString * @param {number} [resolution=10000] time in milliseconds between points * @param {number} [sharpness=0.85] a measure of how curvy the path should be between splines * @returns {LineString} curved line * @example * var line = { * "type": "Feature", * "properties": { * "stroke": "#f00" * }, * "geometry": { * "type": "LineString", * "coordinates": [ * [-76.091308, 18.427501], * [-76.695556, 18.729501], * [-76.552734, 19.40443], * [-74.61914, 19.134789], * [-73.652343, 20.07657], * [-73.157958, 20.210656] * ] * } * }; * * var curved = turf.bezier(line); * curved.properties = { stroke: '#0f0' }; * * var result = { * "type": "FeatureCollection", * "features": [line, curved] * }; * * //=result */ module.exports = function(line, resolution, sharpness){ var lineOut = linestring([]); lineOut.properties = line.properties; var pts = line.geometry.coordinates.map(function(pt){ return {x: pt[0], y: pt[1]}; }); var spline = new Spline({ points: pts, duration: resolution, sharpness: sharpness }); for (var i=0; i. */ /* Usage: var spline = new Spline({ points: array_of_control_points, duration: time_in_miliseconds, sharpness: how_curvy, stepLength: distance_between_points_to_cache }); */ var Spline = function(options){ this.points = options.points || []; this.duration = options.duration || 10000; this.sharpness = options.sharpness || 0.85; this.centers = []; this.controls = []; this.stepLength = options.stepLength || 60; this.length = this.points.length; this.delay = 0; // this is to ensure compatibility with the 2d version for(var i=0; imindist){ steps.push(t); laststep = step; } } return steps; }; /* returns angle and speed in the given point in the curve */ Spline.prototype.vector = function(t){ var p1 = this.pos(t+10); var p2 = this.pos(t-10); return { angle:180*Math.atan2(p1.y-p2.y, p1.x-p2.x)/3.14, speed:Math.sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y)+(p2.z-p1.z)*(p2.z-p1.z)) }; }; /* Gets the position of the point, given time. WARNING: The speed is not constant. The time it takes between control points is constant. For constant speed, use Spline.steps[i]; */ Spline.prototype.pos = function(time){ function bezier(t, p1, c1, c2, p2){ var B = function(t) { var t2=t*t, t3=t2*t; return [(t3),(3*t2*(1-t)),(3*t*(1-t)*(1-t)),((1-t)*(1-t)*(1-t))] } var b = B(t) var pos = { x : p2.x * b[0] + c2.x * b[1] +c1.x * b[2] + p1.x * b[3], y : p2.y * b[0] + c2.y * b[1] +c1.y * b[2] + p1.y * b[3], z : p2.z * b[0] + c2.z * b[1] +c1.z * b[2] + p1.z * b[3] } return pos; } var t = time-this.delay; if(t<0) t=0; if(t>this.duration) t=this.duration-1; //t = t-this.delay; var t2 = (t)/this.duration; if(t2>=1) return this.points[this.length-1]; var n = Math.floor((this.points.length-1)*t2); var t1 = (this.length-1)*t2-n; return bezier(t1,this.points[n],this.controls[n][1],this.controls[n+1][0],this.points[n+1]); } module.exports = Spline; },{}],16:[function(require,module,exports){ // http://stackoverflow.com/questions/839899/how-do-i-calculate-a-point-on-a-circles-circumference // radians = degrees * (pi/180) // https://github.com/bjornharrtell/jsts/blob/master/examples/buffer.html var featurecollection = require('turf-featurecollection'); var polygon = require('turf-polygon'); var combine = require('turf-combine'); var jsts = require('jsts'); /** * Calculates a buffer for a {@link Point}, {@link LineString}, or {@link Polygon} {@link Feature}/{@link FeatureCollection} for a given radius. Units supported are miles, kilometers, and degrees. * * @module turf/buffer * @category transformation * @param {FeatureCollection} feature a Feature or FeatureCollection of any type * @param {Number} distance distance to draw the buffer * @param {String} unit 'miles' or 'kilometers' * @return {FeatureCollection} a FeatureCollection containing {@link Polygon} features representing buffers * * @example * var pt = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-90.548630, 14.616599] * } * }; * var unit = 'miles'; * * var buffered = turf.buffer(pt, 500, unit); * * var resultFeatures = buffered.features.concat(pt); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ module.exports = function(feature, radius, units){ var buffered; switch(units){ case 'miles': radius = radius / 69.047; break case 'feet': radius = radius / 364568.0; break case 'kilometers': radius = radius / 111.12; break case 'meters': radius = radius / 111120.0; break case 'degrees': break } if(feature.type === 'FeatureCollection'){ var multi = combine(feature); multi.properties = {}; buffered = bufferOp(multi, radius); return buffered; } else{ buffered = bufferOp(feature, radius); return buffered; } } var bufferOp = function(feature, radius){ var reader = new jsts.io.GeoJSONReader(); var geom = reader.read(JSON.stringify(feature.geometry)); var buffered = geom.buffer(radius); var parser = new jsts.io.GeoJSONParser(); buffered = parser.write(buffered); if(buffered.type === 'MultiPolygon'){ buffered = { type: 'Feature', geometry: buffered, properties: {} }; buffered = featurecollection([buffered]); } else{ buffered = featurecollection([polygon(buffered.coordinates)]); } return buffered; } },{"jsts":17,"turf-combine":24,"turf-featurecollection":72,"turf-polygon":103}],17:[function(require,module,exports){ require('javascript.util'); var jsts = require('./lib/jsts'); module.exports = jsts },{"./lib/jsts":18,"javascript.util":20}],18:[function(require,module,exports){ /* The JSTS Topology Suite is a collection of JavaScript classes that implement the fundamental operations required to validate a given geo-spatial data set to a known topological specification. Copyright (C) 2011 The Authors This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ jsts={version:'0.15.0',algorithm:{distance:{},locate:{}},error:{},geom:{util:{}},geomgraph:{index:{}},index:{bintree:{},chain:{},kdtree:{},quadtree:{},strtree:{}},io:{},noding:{snapround:{}},operation:{buffer:{},distance:{},overlay:{snap:{}},polygonize:{},predicate:{},relate:{},union:{},valid:{}},planargraph:{},simplify:{},triangulate:{quadedge:{}},util:{}};if(typeof String.prototype.trim!=='function'){String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,'');};} jsts.abstractFunc=function(){throw new jsts.error.AbstractMethodInvocationError();};jsts.error={};jsts.error.IllegalArgumentError=function(message){this.name='IllegalArgumentError';this.message=message;};jsts.error.IllegalArgumentError.prototype=new Error();jsts.error.TopologyError=function(message,pt){this.name='TopologyError';this.message=pt?message+' [ '+pt+' ]':message;};jsts.error.TopologyError.prototype=new Error();jsts.error.AbstractMethodInvocationError=function(){this.name='AbstractMethodInvocationError';this.message='Abstract method called, should be implemented in subclass.';};jsts.error.AbstractMethodInvocationError.prototype=new Error();jsts.error.NotImplementedError=function(){this.name='NotImplementedError';this.message='This method has not yet been implemented.';};jsts.error.NotImplementedError.prototype=new Error();jsts.error.NotRepresentableError=function(message){this.name='NotRepresentableError';this.message=message;};jsts.error.NotRepresentableError.prototype=new Error();jsts.error.LocateFailureError=function(message){this.name='LocateFailureError';this.message=message;};jsts.error.LocateFailureError.prototype=new Error();if(typeof module!=="undefined")module.exports=jsts;jsts.geom.GeometryFilter=function(){};jsts.geom.GeometryFilter.prototype.filter=function(geom){throw new jsts.error.AbstractMethodInvocationError();};jsts.geom.util.PolygonExtracter=function(comps){this.comps=comps;};jsts.geom.util.PolygonExtracter.prototype=new jsts.geom.GeometryFilter();jsts.geom.util.PolygonExtracter.prototype.comps=null;jsts.geom.util.PolygonExtracter.getPolygons=function(geom,list){if(list===undefined){list=[];} if(geom instanceof jsts.geom.Polygon){list.push(geom);}else if(geom instanceof jsts.geom.GeometryCollection){geom.apply(new jsts.geom.util.PolygonExtracter(list));} return list;};jsts.geom.util.PolygonExtracter.prototype.filter=function(geom){if(geom instanceof jsts.geom.Polygon) this.comps.push(geom);};jsts.io.WKTParser=function(geometryFactory){this.geometryFactory=geometryFactory||new jsts.geom.GeometryFactory();this.regExes={'typeStr':/^\s*(\w+)\s*\(\s*(.*)\s*\)\s*$/,'emptyTypeStr':/^\s*(\w+)\s*EMPTY\s*$/,'spaces':/\s+/,'parenComma':/\)\s*,\s*\(/,'doubleParenComma':/\)\s*\)\s*,\s*\(\s*\(/,'trimParens':/^\s*\(?(.*?)\)?\s*$/};};jsts.io.WKTParser.prototype.read=function(wkt){var geometry,type,str;wkt=wkt.replace(/[\n\r]/g,' ');var matches=this.regExes.typeStr.exec(wkt);if(wkt.search('EMPTY')!==-1){matches=this.regExes.emptyTypeStr.exec(wkt);matches[2]=undefined;} if(matches){type=matches[1].toLowerCase();str=matches[2];if(this.parse[type]){geometry=this.parse[type].apply(this,[str]);}} if(geometry===undefined) throw new Error('Could not parse WKT '+wkt);return geometry;};jsts.io.WKTParser.prototype.write=function(geometry){return this.extractGeometry(geometry);};jsts.io.WKTParser.prototype.extractGeometry=function(geometry){var type=geometry.CLASS_NAME.split('.')[2].toLowerCase();if(!this.extract[type]){return null;} var wktType=type.toUpperCase();var data;if(geometry.isEmpty()){data=wktType+' EMPTY';}else{data=wktType+'('+this.extract[type].apply(this,[geometry])+')';} return data;};jsts.io.WKTParser.prototype.extract={'coordinate':function(coordinate){return coordinate.x+' '+coordinate.y;},'point':function(point){return point.coordinate.x+' '+point.coordinate.y;},'multipoint':function(multipoint){var array=[];for(var i=0,len=multipoint.geometries.length;ihiPt.y){hiPt=p;hiIndex=i;}} iPrev=hiIndex;do{iPrev=iPrev-1;if(iPrev<0){iPrev=nPts;}}while(ring[iPrev].equals2D(hiPt)&&iPrev!==hiIndex);iNext=hiIndex;do{iNext=(iNext+1)%nPts;}while(ring[iNext].equals2D(hiPt)&&iNext!==hiIndex);prev=ring[iPrev];next=ring[iNext];if(prev.equals2D(hiPt)||next.equals2D(hiPt)||prev.equals2D(next)){return false;} disc=jsts.algorithm.CGAlgorithms.computeOrientation(prev,hiPt,next);isCCW=false;if(disc===0){isCCW=(prev.x>next.x);}else{isCCW=(disc>0);} return isCCW;};jsts.algorithm.CGAlgorithms.computeOrientation=function(p1,p2,q){return jsts.algorithm.CGAlgorithms.orientationIndex(p1,p2,q);};jsts.algorithm.CGAlgorithms.distancePointLine=function(p,A,B){if(!(A instanceof jsts.geom.Coordinate)){jsts.algorithm.CGAlgorithms.distancePointLine2.apply(this,arguments);} if(A.x===B.x&&A.y===B.y){return p.distance(A);} var r,s;r=((p.x-A.x)*(B.x-A.x)+(p.y-A.y)*(B.y-A.y))/((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y));if(r<=0.0){return p.distance(A);} if(r>=1.0){return p.distance(B);} s=((A.y-p.y)*(B.x-A.x)-(A.x-p.x)*(B.y-A.y))/((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y));return Math.abs(s)*Math.sqrt(((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y)));};jsts.algorithm.CGAlgorithms.distancePointLinePerpendicular=function(p,A,B){var s=((A.y-p.y)*(B.x-A.x)-(A.x-p.x)*(B.y-A.y))/((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y));return Math.abs(s)*Math.sqrt(((B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y)));};jsts.algorithm.CGAlgorithms.distancePointLine2=function(p,line){var minDistance,i,il,dist;if(line.length===0){throw new jsts.error.IllegalArgumentError('Line array must contain at least one vertex');} minDistance=p.distance(line[0]);for(i=0,il=line.length-1;i1)||(s<0)||(s>1)){return Math.min(jsts.algorithm.CGAlgorithms.distancePointLine(A,C,D),Math.min(jsts.algorithm.CGAlgorithms.distancePointLine(B,C,D),Math.min(jsts.algorithm.CGAlgorithms.distancePointLine(C,A,B),jsts.algorithm.CGAlgorithms.distancePointLine(D,A,B))));} return 0.0;};jsts.algorithm.CGAlgorithms.signedArea=function(ring){if(ring.length<3){return 0.0;} var sum,i,il,bx,by,cx,cy;sum=0.0;for(i=0,il=ring.length-1;i0;};jsts.algorithm.Angle.isObtuse=function(p0,p1,p2){var dx0,dy0,dx1,dy1,dotprod;dx0=p0.x-p1.x;dy0=p0.y-p1.y;dx1=p2.x-p1.x;dy1=p2.y-p1.y;dotprod=dx0*dx1+dy0*dy1;return dotprod<0;};jsts.algorithm.Angle.angleBetween=function(tip1,tail,tip2){var a1,a2;a1=jsts.algorithm.Angle.angle(tail,tip1);a2=jsts.algorithm.Angle.angle(tail,tip2);return jsts.algorithm.Angle.diff(a1,a2);};jsts.algorithm.Angle.angleBetweenOriented=function(tip1,tail,tip2){var a1,a2,angDel;a1=jsts.algorithm.Angle.angle(tail,tip1);a2=jsts.algorithm.Angle.angle(tail,tip2);angDel=a2-a1;if(angDel<=-Math.PI){return angDel+jsts.algorithm.Angle.PI_TIMES_2;} if(angDel>Math.PI){return angDel-jsts.algorithm.Angle.PI_TIMES_2;} return angDel;};jsts.algorithm.Angle.interiorAngle=function(p0,p1,p2){var anglePrev,angleNext;anglePrev=jsts.algorithm.Angle.angle(p1,p0);angleNext=jsts.algorithm.Angle.angle(p1,p2);return Math.abs(angleNext-anglePrev);};jsts.algorithm.Angle.getTurn=function(ang1,ang2){var crossproduct=Math.sin(ang2-ang1);if(crossproduct>0){return jsts.algorithm.Angle.COUNTERCLOCKWISE;} if(crossproduct<0){return jsts.algorithm.Angle.CLOCKWISE;} return jsts.algorithm.Angle.NONE;};jsts.algorithm.Angle.normalize=function(angle){while(angle>Math.PI){angle-=jsts.algorithm.Angle.PI_TIMES_2;} while(angle<=-Math.PI){angle+=jsts.algorithm.Angle.PI_TIMES_2;} return angle;};jsts.algorithm.Angle.normalizePositive=function(angle){if(angle<0.0){while(angle<0.0){angle+=jsts.algorithm.Angle.PI_TIMES_2;} if(angle>=jsts.algorithm.Angle.PI_TIMES_2){angle=0.0;}} else{while(angle>=jsts.algorithm.Angle.PI_TIMES_2){angle-=jsts.algorithm.Angle.PI_TIMES_2;} if(angle<0.0){angle=0.0;}} return angle;};jsts.algorithm.Angle.diff=function(ang1,ang2){var delAngle;if(ang1Math.PI){delAngle=(2*Math.PI)-delAngle;} return delAngle;};jsts.geom.GeometryComponentFilter=function(){};jsts.geom.GeometryComponentFilter.prototype.filter=function(geom){throw new jsts.error.AbstractMethodInvocationError();};jsts.geom.util.LinearComponentExtracter=function(lines,isForcedToLineString){this.lines=lines;this.isForcedToLineString=isForcedToLineString;};jsts.geom.util.LinearComponentExtracter.prototype=new jsts.geom.GeometryComponentFilter();jsts.geom.util.LinearComponentExtracter.prototype.lines=null;jsts.geom.util.LinearComponentExtracter.prototype.isForcedToLineString=false;jsts.geom.util.LinearComponentExtracter.getLines=function(geoms,lines){if(arguments.length==1){return jsts.geom.util.LinearComponentExtracter.getLines5.apply(this,arguments);} else if(arguments.length==2&&typeof lines==='boolean'){return jsts.geom.util.LinearComponentExtracter.getLines6.apply(this,arguments);} else if(arguments.length==2&&geoms instanceof jsts.geom.Geometry){return jsts.geom.util.LinearComponentExtracter.getLines3.apply(this,arguments);} else if(arguments.length==3&&geoms instanceof jsts.geom.Geometry){return jsts.geom.util.LinearComponentExtracter.getLines4.apply(this,arguments);} else if(arguments.length==3){return jsts.geom.util.LinearComponentExtracter.getLines2.apply(this,arguments);} for(var i=0;idistance){return false;} return DistanceOp.isWithinDistance(this,geom,distance);};jsts.geom.Geometry.prototype.isRectangle=function(){return false;};jsts.geom.Geometry.prototype.getArea=function(){return 0.0;};jsts.geom.Geometry.prototype.getLength=function(){return 0.0;};jsts.geom.Geometry.prototype.getCentroid=function(){if(this.isEmpty()){return null;} var cent;var centPt=null;var dim=this.getDimension();if(dim===0){cent=new jsts.algorithm.CentroidPoint();cent.add(this);centPt=cent.getCentroid();}else if(dim===1){cent=new jsts.algorithm.CentroidLine();cent.add(this);centPt=cent.getCentroid();}else{cent=new jsts.algorithm.CentroidArea();cent.add(this);centPt=cent.getCentroid();} return this.createPointFromInternalCoord(centPt,this);};jsts.geom.Geometry.prototype.getInteriorPoint=function(){var intPt;var interiorPt=null;var dim=this.getDimension();if(dim===0){intPt=new jsts.algorithm.InteriorPointPoint(this);interiorPt=intPt.getInteriorPoint();}else if(dim===1){intPt=new jsts.algorithm.InteriorPointLine(this);interiorPt=intPt.getInteriorPoint();}else{intPt=new jsts.algorithm.InteriorPointArea(this);interiorPt=intPt.getInteriorPoint();} return this.createPointFromInternalCoord(interiorPt,this);};jsts.geom.Geometry.prototype.getDimension=function(){throw new jsts.error.AbstractMethodInvocationError();};jsts.geom.Geometry.prototype.getBoundary=function(){throw new jsts.error.AbstractMethodInvocationError();};jsts.geom.Geometry.prototype.getBoundaryDimension=function(){throw new jsts.error.AbstractMethodInvocationError();};jsts.geom.Geometry.prototype.getEnvelope=function(){return this.getFactory().toGeometry(this.getEnvelopeInternal());};jsts.geom.Geometry.prototype.getEnvelopeInternal=function(){if(this.envelope===null){this.envelope=this.computeEnvelopeInternal();} return this.envelope;};jsts.geom.Geometry.prototype.disjoint=function(g){return!this.intersects(g);};jsts.geom.Geometry.prototype.touches=function(g){if(!this.getEnvelopeInternal().intersects(g.getEnvelopeInternal())){return false;} return this.relate(g).isTouches(this.getDimension(),g.getDimension());};jsts.geom.Geometry.prototype.intersects=function(g){if(!this.getEnvelopeInternal().intersects(g.getEnvelopeInternal())){return false;} if(this.isRectangle()){return jsts.operation.predicate.RectangleIntersects.intersects(this,g);} if(g.isRectangle()){return jsts.operation.predicate.RectangleIntersects.intersects(g,this);} return this.relate(g).isIntersects();};jsts.geom.Geometry.prototype.crosses=function(g){if(!this.getEnvelopeInternal().intersects(g.getEnvelopeInternal())){return false;} return this.relate(g).isCrosses(this.getDimension(),g.getDimension());};jsts.geom.Geometry.prototype.within=function(g){return g.contains(this);};jsts.geom.Geometry.prototype.contains=function(g){if(!this.getEnvelopeInternal().contains(g.getEnvelopeInternal())){return false;} if(this.isRectangle()){return jsts.operation.predicate.RectangleContains.contains(this,g);} return this.relate(g).isContains();};jsts.geom.Geometry.prototype.overlaps=function(g){if(!this.getEnvelopeInternal().intersects(g.getEnvelopeInternal())){return false;} return this.relate(g).isOverlaps(this.getDimension(),g.getDimension());};jsts.geom.Geometry.prototype.covers=function(g){if(!this.getEnvelopeInternal().covers(g.getEnvelopeInternal())){return false;} if(this.isRectangle()){return true;} return this.relate(g).isCovers();};jsts.geom.Geometry.prototype.coveredBy=function(g){return g.covers(this);};jsts.geom.Geometry.prototype.relate=function(g,intersectionPattern){if(arguments.length===1){return this.relate2.apply(this,arguments);} return this.relate2(g).matches(intersectionPattern);};jsts.geom.Geometry.prototype.relate2=function(g){this.checkNotGeometryCollection(this);this.checkNotGeometryCollection(g);return jsts.operation.relate.RelateOp.relate(this,g);};jsts.geom.Geometry.prototype.equalsTopo=function(g){if(!this.getEnvelopeInternal().equals(g.getEnvelopeInternal())){return false;} return this.relate(g).isEquals(this.getDimension(),g.getDimension());};jsts.geom.Geometry.prototype.equals=function(o){if(o instanceof jsts.geom.Geometry||o instanceof jsts.geom.LinearRing||o instanceof jsts.geom.Polygon||o instanceof jsts.geom.GeometryCollection||o instanceof jsts.geom.MultiPoint||o instanceof jsts.geom.MultiLineString||o instanceof jsts.geom.MultiPolygon){return this.equalsExact(o);} return false;};jsts.geom.Geometry.prototype.buffer=function(distance,quadrantSegments,endCapStyle){var params=new jsts.operation.buffer.BufferParameters(quadrantSegments,endCapStyle) return jsts.operation.buffer.BufferOp.bufferOp2(this,distance,params);};jsts.geom.Geometry.prototype.convexHull=function(){return new jsts.algorithm.ConvexHull(this).getConvexHull();};jsts.geom.Geometry.prototype.intersection=function(other){if(this.isEmpty()){return this.getFactory().createGeometryCollection(null);} if(other.isEmpty()){return this.getFactory().createGeometryCollection(null);} if(this.isGeometryCollection(this)){var g2=other;} this.checkNotGeometryCollection(this);this.checkNotGeometryCollection(other);return jsts.operation.overlay.snap.SnapIfNeededOverlayOp.overlayOp(this,other,jsts.operation.overlay.OverlayOp.INTERSECTION);};jsts.geom.Geometry.prototype.union=function(other){if(arguments.length===0){return jsts.operation.union.UnaryUnionOp.union(this);} if(this.isEmpty()){return other.clone();} if(other.isEmpty()){return this.clone();} this.checkNotGeometryCollection(this);this.checkNotGeometryCollection(other);return jsts.operation.overlay.snap.SnapIfNeededOverlayOp.overlayOp(this,other,jsts.operation.overlay.OverlayOp.UNION);};jsts.geom.Geometry.prototype.difference=function(other){if(this.isEmpty()){return this.getFactory().createGeometryCollection(null);} if(other.isEmpty()){return this.clone();} this.checkNotGeometryCollection(this);this.checkNotGeometryCollection(other);return jsts.operation.overlay.snap.SnapIfNeededOverlayOp.overlayOp(this,other,jsts.operation.overlay.OverlayOp.DIFFERENCE);};jsts.geom.Geometry.prototype.symDifference=function(other){if(this.isEmpty()){return other.clone();} if(other.isEmpty()){return this.clone();} this.checkNotGeometryCollection(this);this.checkNotGeometryCollection(other);return jsts.operation.overlay.snap.SnapIfNeededOverlayOp.overlayOp(this,other,jsts.operation.overlay.OverlayOp.SYMDIFFERENCE);};jsts.geom.Geometry.prototype.equalsExact=function(other,tolerance){throw new jsts.error.AbstractMethodInvocationError();};jsts.geom.Geometry.prototype.equalsNorm=function(g){if(g===null||g===undefined) return false;return this.norm().equalsExact(g.norm());};jsts.geom.Geometry.prototype.apply=function(filter){throw new jsts.error.AbstractMethodInvocationError();};jsts.geom.Geometry.prototype.clone=function(){throw new jsts.error.AbstractMethodInvocationError();};jsts.geom.Geometry.prototype.normalize=function(){throw new jsts.error.AbstractMethodInvocationError();};jsts.geom.Geometry.prototype.norm=function(){var copy=this.clone();copy.normalize();return copy;};jsts.geom.Geometry.prototype.compareTo=function(o){var other=o;if(this.getClassSortIndex()!==other.getClassSortIndex()){return this.getClassSortIndex()-other.getClassSortIndex();} if(this.isEmpty()&&other.isEmpty()){return 0;} if(this.isEmpty()){return-1;} if(other.isEmpty()){return 1;} return this.compareToSameClass(o);};jsts.geom.Geometry.prototype.isEquivalentClass=function(other){if(this instanceof jsts.geom.Point&&other instanceof jsts.geom.Point){return true;}else if(this instanceof jsts.geom.LineString&&(other instanceof jsts.geom.LineString|other instanceof jsts.geom.LinearRing)){return true;}else if(this instanceof jsts.geom.LinearRing&&(other instanceof jsts.geom.LineString|other instanceof jsts.geom.LinearRing)){return true;}else if(this instanceof jsts.geom.Polygon&&(other instanceof jsts.geom.Polygon)){return true;}else if(this instanceof jsts.geom.MultiPoint&&(other instanceof jsts.geom.MultiPoint)){return true;}else if(this instanceof jsts.geom.MultiLineString&&(other instanceof jsts.geom.MultiLineString)){return true;}else if(this instanceof jsts.geom.MultiPolygon&&(other instanceof jsts.geom.MultiPolygon)){return true;}else if(this instanceof jsts.geom.GeometryCollection&&(other instanceof jsts.geom.GeometryCollection)){return true;} return false;};jsts.geom.Geometry.prototype.checkNotGeometryCollection=function(g){if(g.isGeometryCollectionBase()){throw new jsts.error.IllegalArgumentError('This method does not support GeometryCollection');}};jsts.geom.Geometry.prototype.isGeometryCollection=function(){return(this instanceof jsts.geom.GeometryCollection);};jsts.geom.Geometry.prototype.isGeometryCollectionBase=function(){return(this.CLASS_NAME==='jsts.geom.GeometryCollection');};jsts.geom.Geometry.prototype.computeEnvelopeInternal=function(){throw new jsts.error.AbstractMethodInvocationError();};jsts.geom.Geometry.prototype.compareToSameClass=function(o){throw new jsts.error.AbstractMethodInvocationError();};jsts.geom.Geometry.prototype.compare=function(a,b){var i=a.iterator();var j=b.iterator();while(i.hasNext()&&j.hasNext()){var aElement=i.next();var bElement=j.next();var comparison=aElement.compareTo(bElement);if(comparison!==0){return comparison;}} if(i.hasNext()){return 1;} if(j.hasNext()){return-1;} return 0;};jsts.geom.Geometry.prototype.equal=function(a,b,tolerance){if(tolerance===undefined||tolerance===null||tolerance===0){return a.equals(b);} return a.distance(b)<=tolerance;};jsts.geom.Geometry.prototype.getClassSortIndex=function(){var sortedClasses=[jsts.geom.Point,jsts.geom.MultiPoint,jsts.geom.LineString,jsts.geom.LinearRing,jsts.geom.MultiLineString,jsts.geom.Polygon,jsts.geom.MultiPolygon,jsts.geom.GeometryCollection];for(var i=0;iother.x){return 1;} if(this.yother.y){return 1;} return 0;};jsts.geom.Coordinate.prototype.toString=function(){return'('+this.x+', '+this.y+')';};})();jsts.geom.Envelope=function(){jsts.geom.Envelope.prototype.init.apply(this,arguments);};jsts.geom.Envelope.prototype.minx=null;jsts.geom.Envelope.prototype.maxx=null;jsts.geom.Envelope.prototype.miny=null;jsts.geom.Envelope.prototype.maxy=null;jsts.geom.Envelope.prototype.init=function(){if(typeof arguments[0]==='number'&&arguments.length===4){this.initFromValues(arguments[0],arguments[1],arguments[2],arguments[3]);}else if(arguments[0]instanceof jsts.geom.Coordinate&&arguments.length===1){this.initFromCoordinate(arguments[0]);}else if(arguments[0]instanceof jsts.geom.Coordinate&&arguments.length===2){this.initFromCoordinates(arguments[0],arguments[1]);}else if(arguments[0]instanceof jsts.geom.Envelope&&arguments.length===1){this.initFromEnvelope(arguments[0]);}else{this.setToNull();}};jsts.geom.Envelope.prototype.initFromValues=function(x1,x2,y1,y2){if(x1this.maxx){this.maxx=x;} if(ythis.maxy){this.maxy=y;}}};jsts.geom.Envelope.prototype.expandToIncludeEnvelope=function(other){if(other.isNull()){return;} if(this.isNull()){this.minx=other.getMinX();this.maxx=other.getMaxX();this.miny=other.getMinY();this.maxy=other.getMaxY();}else{if(other.minxthis.maxx){this.maxx=other.maxx;} if(other.minythis.maxy){this.maxy=other.maxy;}}};jsts.geom.Envelope.prototype.expandBy=function(){if(arguments.length===1){this.expandByDistance(arguments[0]);}else{this.expandByDistances(arguments[0],arguments[1]);}};jsts.geom.Envelope.prototype.expandByDistance=function(distance){this.expandByDistances(distance,distance);};jsts.geom.Envelope.prototype.expandByDistances=function(deltaX,deltaY){if(this.isNull()){return;} this.minx-=deltaX;this.maxx+=deltaX;this.miny-=deltaY;this.maxy+=deltaY;if(this.minx>this.maxx||this.miny>this.maxy){this.setToNull();}};jsts.geom.Envelope.prototype.translate=function(transX,transY){if(this.isNull()){return;} this.init(this.minx+transX,this.maxx+transX,this.miny+transY,this.maxy+transY);};jsts.geom.Envelope.prototype.centre=function(){if(this.isNull()){return null;} return new jsts.geom.Coordinate((this.minx+this.maxx)/2.0,(this.miny+this.maxy)/2.0);};jsts.geom.Envelope.prototype.intersection=function(env){if(this.isNull()||env.isNull()||!this.intersects(env)){return new jsts.geom.Envelope();} var intMinX=this.minx>env.minx?this.minx:env.minx;var intMinY=this.miny>env.miny?this.miny:env.miny;var intMaxX=this.maxxthis.maxx||other.maxxthis.maxy||other.maxythis.maxx||xthis.maxy||y=this.minx&&x<=this.maxx&&y>=this.miny&&y<=this.maxy;};jsts.geom.Envelope.prototype.coversCoordinate=function(p){return this.coversValues(p.x,p.y);};jsts.geom.Envelope.prototype.coversEnvelope=function(other){if(this.isNull()||other.isNull()){return false;} return other.minx>=this.minx&&other.maxx<=this.maxx&&other.miny>=this.miny&&other.maxy<=this.maxy;};jsts.geom.Envelope.prototype.distance=function(env){if(this.intersects(env)){return 0;} var dx=0.0;if(this.maxxenv.maxx){dx=this.minx-env.maxx;} var dy=0.0;if(this.maxyenv.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);};jsts.geom.Envelope.prototype.equals=function(other){if(this.isNull()){return other.isNull();} return this.maxx===other.maxx&&this.maxy===other.maxy&&this.minx===other.minx&&this.miny===other.miny;};jsts.geom.Envelope.prototype.toString=function(){return'Env['+this.minx+' : '+this.maxx+', '+this.miny+' : '+ this.maxy+']';};jsts.geom.Envelope.intersects=function(p1,p2,q){if(arguments.length===4){return jsts.geom.Envelope.intersectsEnvelope(arguments[0],arguments[1],arguments[2],arguments[3]);} var xc1=p1.xp2.x?p1.x:p2.x;var yc1=p1.yp2.y?p1.y:p2.y;if(((q.x>=xc1)&&(q.x<=xc2))&&((q.y>=yc1)&&(q.y<=yc2))){return true;} return false;};jsts.geom.Envelope.intersectsEnvelope=function(p1,p2,q1,q2){var minq=Math.min(q1.x,q2.x);var maxq=Math.max(q1.x,q2.x);var minp=Math.min(p1.x,p2.x);var maxp=Math.max(p1.x,p2.x);if(minp>maxq){return false;} if(maxpmaxq){return false;} if(maxp1)return this.combine2.apply(this,arguments);var combiner=new jsts.geom.util.GeometryCombiner(geoms);return combiner.combine();};jsts.geom.util.GeometryCombiner.combine2=function(){var arrayList=new javascript.util.ArrayList();Array.prototype.slice.call(arguments).forEach(function(a){arrayList.add(a);});var combiner=new jsts.geom.util.GeometryCombiner(arrayList);return combiner.combine();};jsts.geom.util.GeometryCombiner.prototype.geomFactory=null;jsts.geom.util.GeometryCombiner.prototype.skipEmpty=false;jsts.geom.util.GeometryCombiner.prototype.inputGeoms;jsts.geom.util.GeometryCombiner.extractFactory=function(geoms){if(geoms.isEmpty())return null;return geoms.iterator().next().getFactory();};jsts.geom.util.GeometryCombiner.prototype.combine=function(){var elems=new javascript.util.ArrayList(),i;for(i=this.inputGeoms.iterator();i.hasNext();){var g=i.next();this.extractElements(g,elems);} if(elems.size()===0){if(this.geomFactory!==null){return this.geomFactory.createGeometryCollection(null);} return null;} return this.geomFactory.buildGeometry(elems);};jsts.geom.util.GeometryCombiner.prototype.extractElements=function(geom,elems){if(geom===null){return;} for(var i=0;imaxDistance){maxDistance=distance;maxIndex=k;}} if(maxDistance<=this.distanceTolerance){for(var l=i+1;lsegmentIndex) return 1;if(this.distdist) return 1;return 0;};jsts.geomgraph.EdgeIntersection.prototype.isEndPoint=function(maxSegmentIndex){if(this.segmentIndex===0&&this.dist===0.0) return true;if(this.segmentIndex===maxSegmentIndex) return true;return false;};jsts.geomgraph.EdgeIntersection.prototype.toString=function(){return''+this.segmentIndex+this.dist;};(function(){var EdgeIntersection=jsts.geomgraph.EdgeIntersection;var TreeMap=javascript.util.TreeMap;jsts.geomgraph.EdgeIntersectionList=function(edge){this.nodeMap=new TreeMap();this.edge=edge;};jsts.geomgraph.EdgeIntersectionList.prototype.nodeMap=null;jsts.geomgraph.EdgeIntersectionList.prototype.edge=null;jsts.geomgraph.EdgeIntersectionList.prototype.isIntersection=function(pt){for(var it=this.iterator();it.hasNext();){var ei=it.next();if(ei.coord.equals(pt)){return true;}} return false;};jsts.geomgraph.EdgeIntersectionList.prototype.add=function(intPt,segmentIndex,dist){var eiNew=new EdgeIntersection(intPt,segmentIndex,dist);var ei=this.nodeMap.get(eiNew);if(ei!==null){return ei;} this.nodeMap.put(eiNew,eiNew);return eiNew;};jsts.geomgraph.EdgeIntersectionList.prototype.iterator=function(){return this.nodeMap.values().iterator();};jsts.geomgraph.EdgeIntersectionList.prototype.addEndpoints=function(){var maxSegIndex=this.edge.pts.length-1;this.add(this.edge.pts[0],0,0.0);this.add(this.edge.pts[maxSegIndex],maxSegIndex,0.0);};jsts.geomgraph.EdgeIntersectionList.prototype.addSplitEdges=function(edgeList) {this.addEndpoints();var it=this.iterator();var eiPrev=it.next();while(it.hasNext()){var ei=it.next();var newEdge=this.createSplitEdge(eiPrev,ei);edgeList.add(newEdge);eiPrev=ei;}};jsts.geomgraph.EdgeIntersectionList.prototype.createSplitEdge=function(ei0,ei1){var npts=ei1.segmentIndex-ei0.segmentIndex+2;var lastSegStartPt=this.edge.pts[ei1.segmentIndex];var useIntPt1=ei1.dist>0.0||!ei1.coord.equals2D(lastSegStartPt);if(!useIntPt1){npts--;} var pts=[];var ipt=0;pts[ipt++]=new jsts.geom.Coordinate(ei0.coord);for(var i=ei0.segmentIndex+1;i<=ei1.segmentIndex;i++){pts[ipt++]=this.edge.pts[i];} if(useIntPt1)pts[ipt]=ei1.coord;return new jsts.geomgraph.Edge(pts,new jsts.geomgraph.Label(this.edge.label));};})();(function(){var AssertionFailedException=function(message){this.message=message;};AssertionFailedException.prototype=new Error();AssertionFailedException.prototype.name='AssertionFailedException';jsts.util.AssertionFailedException=AssertionFailedException;})();(function(){var AssertionFailedException=jsts.util.AssertionFailedException;jsts.util.Assert=function(){};jsts.util.Assert.isTrue=function(assertion,message){if(!assertion){if(message===null){throw new AssertionFailedException();}else{throw new AssertionFailedException(message);}}};jsts.util.Assert.equals=function(expectedValue,actualValue,message){if(!actualValue.equals(expectedValue)){throw new AssertionFailedException('Expected '+expectedValue+' but encountered '+actualValue+ (message!=null?': '+message:''));}};jsts.util.Assert.shouldNeverReachHere=function(message){throw new AssertionFailedException('Should never reach here'+ (message!=null?': '+message:''));};})();(function(){var Location=jsts.geom.Location;var Assert=jsts.util.Assert;var ArrayList=javascript.util.ArrayList;jsts.operation.relate.RelateComputer=function(arg){this.li=new jsts.algorithm.RobustLineIntersector();this.ptLocator=new jsts.algorithm.PointLocator();this.nodes=new jsts.geomgraph.NodeMap(new jsts.operation.relate.RelateNodeFactory());this.isolatedEdges=new ArrayList();this.arg=arg;};jsts.operation.relate.RelateComputer.prototype.li=null;jsts.operation.relate.RelateComputer.prototype.ptLocator=null;jsts.operation.relate.RelateComputer.prototype.arg=null;jsts.operation.relate.RelateComputer.prototype.nodes=null;jsts.operation.relate.RelateComputer.prototype.im=null;jsts.operation.relate.RelateComputer.prototype.isolatedEdges=null;jsts.operation.relate.RelateComputer.prototype.invalidPoint=null;jsts.operation.relate.RelateComputer.prototype.computeIM=function(){var im=new jsts.geom.IntersectionMatrix();im.set(Location.EXTERIOR,Location.EXTERIOR,2);if(!this.arg[0].getGeometry().getEnvelopeInternal().intersects(this.arg[1].getGeometry().getEnvelopeInternal())){this.computeDisjointIM(im);return im;} this.arg[0].computeSelfNodes(this.li,false);this.arg[1].computeSelfNodes(this.li,false);var intersector=this.arg[0].computeEdgeIntersections(this.arg[1],this.li,false);this.computeIntersectionNodes(0);this.computeIntersectionNodes(1);this.copyNodesAndLabels(0);this.copyNodesAndLabels(1);this.labelIsolatedNodes();this.computeProperIntersectionIM(intersector,im);var eeBuilder=new jsts.operation.relate.EdgeEndBuilder();var ee0=eeBuilder.computeEdgeEnds(this.arg[0].getEdgeIterator());this.insertEdgeEnds(ee0);var ee1=eeBuilder.computeEdgeEnds(this.arg[1].getEdgeIterator());this.insertEdgeEnds(ee1);this.labelNodeEdges();this.labelIsolatedEdges(0,1);this.labelIsolatedEdges(1,0);this.updateIM(im);return im;};jsts.operation.relate.RelateComputer.prototype.insertEdgeEnds=function(ee){for(var i=ee.iterator();i.hasNext();){var e=i.next();this.nodes.add(e);}};jsts.operation.relate.RelateComputer.prototype.computeProperIntersectionIM=function(intersector,im){var dimA=this.arg[0].getGeometry().getDimension();var dimB=this.arg[1].getGeometry().getDimension();var hasProper=intersector.hasProperIntersection();var hasProperInterior=intersector.hasProperInteriorIntersection();if(dimA===2&&dimB===2){if(hasProper) im.setAtLeast('212101212');} else if(dimA===2&&dimB===1){if(hasProper) im.setAtLeast('FFF0FFFF2');if(hasProperInterior) im.setAtLeast('1FFFFF1FF');}else if(dimA===1&&dimB===2){if(hasProper) im.setAtLeast('F0FFFFFF2');if(hasProperInterior) im.setAtLeast('1F1FFFFFF');} else if(dimA===1&&dimB===1){if(hasProperInterior) im.setAtLeast('0FFFFFFFF');}};jsts.operation.relate.RelateComputer.prototype.copyNodesAndLabels=function(argIndex){for(var i=this.arg[argIndex].getNodeIterator();i.hasNext();){var graphNode=i.next();var newNode=this.nodes.addNode(graphNode.getCoordinate());newNode.setLabel(argIndex,graphNode.getLabel().getLocation(argIndex));}};jsts.operation.relate.RelateComputer.prototype.computeIntersectionNodes=function(argIndex){for(var i=this.arg[argIndex].getEdgeIterator();i.hasNext();){var e=i.next();var eLoc=e.getLabel().getLocation(argIndex);for(var eiIt=e.getEdgeIntersectionList().iterator();eiIt.hasNext();){var ei=eiIt.next();var n=this.nodes.addNode(ei.coord);if(eLoc===Location.BOUNDARY) n.setLabelBoundary(argIndex);else{if(n.getLabel().isNull(argIndex)) n.setLabel(argIndex,Location.INTERIOR);}}}};jsts.operation.relate.RelateComputer.prototype.labelIntersectionNodes=function(argIndex){for(var i=this.arg[argIndex].getEdgeIterator();i.hasNext();){var e=i.next();var eLoc=e.getLabel().getLocation(argIndex);for(var eiIt=e.getEdgeIntersectionList().iterator();eiIt.hasNext();){var ei=eiIt.next();var n=this.nodes.find(ei.coord);if(n.getLabel().isNull(argIndex)){if(eLoc===Location.BOUNDARY) n.setLabelBoundary(argIndex);else n.setLabel(argIndex,Location.INTERIOR);}}}};jsts.operation.relate.RelateComputer.prototype.computeDisjointIM=function(im){var ga=this.arg[0].getGeometry();if(!ga.isEmpty()){im.set(Location.INTERIOR,Location.EXTERIOR,ga.getDimension());im.set(Location.BOUNDARY,Location.EXTERIOR,ga.getBoundaryDimension());} var gb=this.arg[1].getGeometry();if(!gb.isEmpty()){im.set(Location.EXTERIOR,Location.INTERIOR,gb.getDimension());im.set(Location.EXTERIOR,Location.BOUNDARY,gb.getBoundaryDimension());}};jsts.operation.relate.RelateComputer.prototype.labelNodeEdges=function(){for(var ni=this.nodes.iterator();ni.hasNext();){var node=ni.next();node.getEdges().computeLabelling(this.arg);}};jsts.operation.relate.RelateComputer.prototype.updateIM=function(im){for(var ei=this.isolatedEdges.iterator();ei.hasNext();){var e=ei.next();e.updateIM(im);} for(var ni=this.nodes.iterator();ni.hasNext();){var node=ni.next();node.updateIM(im);node.updateIMFromEdges(im);}};jsts.operation.relate.RelateComputer.prototype.labelIsolatedEdges=function(thisIndex,targetIndex){for(var ei=this.arg[thisIndex].getEdgeIterator();ei.hasNext();){var e=ei.next();if(e.isIsolated()){this.labelIsolatedEdge(e,targetIndex,this.arg[targetIndex].getGeometry());this.isolatedEdges.add(e);}}};jsts.operation.relate.RelateComputer.prototype.labelIsolatedEdge=function(e,targetIndex,target){if(target.getDimension()>0){var loc=this.ptLocator.locate(e.getCoordinate(),target);e.getLabel().setAllLocations(targetIndex,loc);}else{e.getLabel().setAllLocations(targetIndex,Location.EXTERIOR);}};jsts.operation.relate.RelateComputer.prototype.labelIsolatedNodes=function(){for(var ni=this.nodes.iterator();ni.hasNext();){var n=ni.next();var label=n.getLabel();Assert.isTrue(label.getGeometryCount()>0,'node with empty label found');if(n.isIsolated()){if(label.isNull(0)) this.labelIsolatedNode(n,0);else this.labelIsolatedNode(n,1);}}};jsts.operation.relate.RelateComputer.prototype.labelIsolatedNode=function(n,targetIndex){var loc=this.ptLocator.locate(n.getCoordinate(),this.arg[targetIndex].getGeometry());n.getLabel().setAllLocations(targetIndex,loc);};})();(function(){var Assert=jsts.util.Assert;jsts.geomgraph.GraphComponent=function(label){this.label=label;};jsts.geomgraph.GraphComponent.prototype.label=null;jsts.geomgraph.GraphComponent.prototype._isInResult=false;jsts.geomgraph.GraphComponent.prototype._isCovered=false;jsts.geomgraph.GraphComponent.prototype._isCoveredSet=false;jsts.geomgraph.GraphComponent.prototype._isVisited=false;jsts.geomgraph.GraphComponent.prototype.getLabel=function(){return this.label;};jsts.geomgraph.GraphComponent.prototype.setLabel=function(label){if(arguments.length===2){this.setLabel2.apply(this,arguments);return;} this.label=label;};jsts.geomgraph.GraphComponent.prototype.setInResult=function(isInResult){this._isInResult=isInResult;};jsts.geomgraph.GraphComponent.prototype.isInResult=function(){return this._isInResult;};jsts.geomgraph.GraphComponent.prototype.setCovered=function(isCovered){this._isCovered=isCovered;this._isCoveredSet=true;};jsts.geomgraph.GraphComponent.prototype.isCovered=function(){return this._isCovered;};jsts.geomgraph.GraphComponent.prototype.isCoveredSet=function(){return this._isCoveredSet;};jsts.geomgraph.GraphComponent.prototype.isVisited=function(){return this._isVisited;};jsts.geomgraph.GraphComponent.prototype.setVisited=function(isVisited){this._isVisited=isVisited;};jsts.geomgraph.GraphComponent.prototype.getCoordinate=function(){throw new jsts.error.AbstractMethodInvocationError();};jsts.geomgraph.GraphComponent.prototype.computeIM=function(im){throw new jsts.error.AbstractMethodInvocationError();};jsts.geomgraph.GraphComponent.prototype.isIsolated=function(){throw new jsts.error.AbstractMethodInvocationError();};jsts.geomgraph.GraphComponent.prototype.updateIM=function(im){Assert.isTrue(this.label.getGeometryCount()>=2,'found partial label');this.computeIM(im);};})();jsts.geomgraph.Node=function(coord,edges){this.coord=coord;this.edges=edges;this.label=new jsts.geomgraph.Label(0,jsts.geom.Location.NONE);};jsts.geomgraph.Node.prototype=new jsts.geomgraph.GraphComponent();jsts.geomgraph.Node.prototype.coord=null;jsts.geomgraph.Node.prototype.edges=null;jsts.geomgraph.Node.prototype.isIsolated=function(){return(this.label.getGeometryCount()==1);};jsts.geomgraph.Node.prototype.setLabel2=function(argIndex,onLocation){if(this.label===null){this.label=new jsts.geomgraph.Label(argIndex,onLocation);}else this.label.setLocation(argIndex,onLocation);};jsts.geomgraph.Node.prototype.setLabelBoundary=function(argIndex){var loc=jsts.geom.Location.NONE;if(this.label!==null) loc=this.label.getLocation(argIndex);var newLoc;switch(loc){case jsts.geom.Location.BOUNDARY:newLoc=jsts.geom.Location.INTERIOR;break;case jsts.geom.Location.INTERIOR:newLoc=jsts.geom.Location.BOUNDARY;break;default:newLoc=jsts.geom.Location.BOUNDARY;break;} this.label.setLocation(argIndex,newLoc);};jsts.geomgraph.Node.prototype.add=function(e){this.edges.insert(e);e.setNode(this);};jsts.geomgraph.Node.prototype.getCoordinate=function(){return this.coord;};jsts.geomgraph.Node.prototype.getEdges=function(){return this.edges;};jsts.geomgraph.Node.prototype.isIncidentEdgeInResult=function(){for(var it=this.getEdges().getEdges().iterator();it.hasNext();){var de=it.next();if(de.getEdge().isInResult()) return true;} return false;};jsts.geom.Point=function(coordinate,factory){this.factory=factory;if(coordinate===undefined) return;this.coordinate=coordinate;};jsts.geom.Point.prototype=new jsts.geom.Geometry();jsts.geom.Point.constructor=jsts.geom.Point;jsts.geom.Point.CLASS_NAME='jsts.geom.Point';jsts.geom.Point.prototype.coordinate=null;jsts.geom.Point.prototype.getX=function(){return this.coordinate.x;};jsts.geom.Point.prototype.getY=function(){return this.coordinate.y;};jsts.geom.Point.prototype.getCoordinate=function(){return this.coordinate;};jsts.geom.Point.prototype.getCoordinates=function(){return this.isEmpty()?[]:[this.coordinate];};jsts.geom.Point.prototype.getCoordinateSequence=function(){return this.isEmpty()?[]:[this.coordinate];};jsts.geom.Point.prototype.isEmpty=function(){return this.coordinate===null;};jsts.geom.Point.prototype.equalsExact=function(other,tolerance){if(!this.isEquivalentClass(other)){return false;} if(this.isEmpty()&&other.isEmpty()){return true;} return this.equal(other.getCoordinate(),this.getCoordinate(),tolerance);};jsts.geom.Point.prototype.getNumPoints=function(){return this.isEmpty()?0:1;};jsts.geom.Point.prototype.isSimple=function(){return true;};jsts.geom.Point.prototype.getBoundary=function(){return new jsts.geom.GeometryCollection(null);};jsts.geom.Point.prototype.computeEnvelopeInternal=function(){if(this.isEmpty()){return new jsts.geom.Envelope();} return new jsts.geom.Envelope(this.coordinate);};jsts.geom.Point.prototype.apply=function(filter){if(filter instanceof jsts.geom.GeometryFilter||filter instanceof jsts.geom.GeometryComponentFilter){filter.filter(this);}else if(filter instanceof jsts.geom.CoordinateFilter){if(this.isEmpty()){return;} filter.filter(this.getCoordinate());}};jsts.geom.Point.prototype.clone=function(){return new jsts.geom.Point(this.coordinate.clone(),this.factory);};jsts.geom.Point.prototype.getDimension=function(){return 0;};jsts.geom.Point.prototype.getBoundaryDimension=function(){return jsts.geom.Dimension.FALSE;};jsts.geom.Point.prototype.reverse=function(){return this.clone();};jsts.geom.Point.prototype.isValid=function(){if(!jsts.operation.valid.IsValidOp.isValid(this.getCoordinate())){return false;} return true;};jsts.geom.Point.prototype.normalize=function(){};jsts.geom.Point.prototype.compareToSameClass=function(other){var point=other;return this.getCoordinate().compareTo(point.getCoordinate());};jsts.geom.Point.prototype.getGeometryType=function(){return'Point';};jsts.geom.Point.prototype.hashCode=function(){return'Point_'+this.coordinate.hashCode();};jsts.geom.Point.prototype.CLASS_NAME='jsts.geom.Point';jsts.geom.Dimension=function(){};jsts.geom.Dimension.P=0;jsts.geom.Dimension.L=1;jsts.geom.Dimension.A=2;jsts.geom.Dimension.FALSE=-1;jsts.geom.Dimension.TRUE=-2;jsts.geom.Dimension.DONTCARE=-3;jsts.geom.Dimension.toDimensionSymbol=function(dimensionValue){switch(dimensionValue){case jsts.geom.Dimension.FALSE:return'F';case jsts.geom.Dimension.TRUE:return'T';case jsts.geom.Dimension.DONTCARE:return'*';case jsts.geom.Dimension.P:return'0';case jsts.geom.Dimension.L:return'1';case jsts.geom.Dimension.A:return'2';} throw new jsts.IllegalArgumentError('Unknown dimension value: '+ dimensionValue);};jsts.geom.Dimension.toDimensionValue=function(dimensionSymbol){switch(dimensionSymbol.toUpperCase()){case'F':return jsts.geom.Dimension.FALSE;case'T':return jsts.geom.Dimension.TRUE;case'*':return jsts.geom.Dimension.DONTCARE;case'0':return jsts.geom.Dimension.P;case'1':return jsts.geom.Dimension.L;case'2':return jsts.geom.Dimension.A;} throw new jsts.error.IllegalArgumentError('Unknown dimension symbol: '+ dimensionSymbol);};(function(){var Dimension=jsts.geom.Dimension;jsts.geom.LineString=function(points,factory){this.factory=factory;this.points=points||[];};jsts.geom.LineString.prototype=new jsts.geom.Geometry();jsts.geom.LineString.constructor=jsts.geom.LineString;jsts.geom.LineString.prototype.points=null;jsts.geom.LineString.prototype.getCoordinates=function(){return this.points;};jsts.geom.LineString.prototype.getCoordinateSequence=function(){return this.points;};jsts.geom.LineString.prototype.getCoordinateN=function(n){return this.points[n];};jsts.geom.LineString.prototype.getCoordinate=function(){if(this.isEmpty()){return null;} return this.getCoordinateN(0);};jsts.geom.LineString.prototype.getDimension=function(){return 1;};jsts.geom.LineString.prototype.getBoundaryDimension=function(){if(this.isClosed()){return Dimension.FALSE;} return 0;};jsts.geom.LineString.prototype.isEmpty=function(){return this.points.length===0;};jsts.geom.LineString.prototype.getNumPoints=function(){return this.points.length;};jsts.geom.LineString.prototype.getPointN=function(n){return this.getFactory().createPoint(this.points[n]);};jsts.geom.LineString.prototype.getStartPoint=function(){if(this.isEmpty()){return null;} return this.getPointN(0);};jsts.geom.LineString.prototype.getEndPoint=function(){if(this.isEmpty()){return null;} return this.getPointN(this.getNumPoints()-1);};jsts.geom.LineString.prototype.isClosed=function(){if(this.isEmpty()){return false;} return this.getCoordinateN(0).equals2D(this.getCoordinateN(this.points.length-1));};jsts.geom.LineString.prototype.isRing=function(){return this.isClosed()&&this.isSimple();};jsts.geom.LineString.prototype.getGeometryType=function(){return'LineString';};jsts.geom.LineString.prototype.getLength=function(){return jsts.algorithm.CGAlgorithms.computeLength(this.points);};jsts.geom.LineString.prototype.getBoundary=function(){return(new jsts.operation.BoundaryOp(this)).getBoundary();};jsts.geom.LineString.prototype.computeEnvelopeInternal=function(){if(this.isEmpty()){return new jsts.geom.Envelope();} var env=new jsts.geom.Envelope();this.points.forEach(function(component){env.expandToInclude(component);});return env;};jsts.geom.LineString.prototype.equalsExact=function(other,tolerance){if(!this.isEquivalentClass(other)){return false;} if(this.points.length!==other.points.length){return false;} if(this.isEmpty()&&other.isEmpty()){return true;} return this.points.reduce(function(equal,point,i){return equal&&jsts.geom.Geometry.prototype.equal(point,other.points[i],tolerance);});};jsts.geom.LineString.prototype.isEquivalentClass=function(other){return other instanceof jsts.geom.LineString;};jsts.geom.LineString.prototype.compareToSameClass=function(o){var line=o;var i=0,il=this.points.length;var j=0,jl=line.points.length;while(i0){this.points.reverse();} return;}}};jsts.geom.LineString.prototype.CLASS_NAME='jsts.geom.LineString';})();(function(){jsts.geom.Polygon=function(shell,holes,factory){this.shell=shell||factory.createLinearRing(null);this.holes=holes||[];this.factory=factory;};jsts.geom.Polygon.prototype=new jsts.geom.Geometry();jsts.geom.Polygon.constructor=jsts.geom.Polygon;jsts.geom.Polygon.prototype.getCoordinate=function(){return this.shell.getCoordinate();};jsts.geom.Polygon.prototype.getCoordinates=function(){if(this.isEmpty()){return[];} var coordinates=[];var k=-1;var shellCoordinates=this.shell.getCoordinates();for(var x=0;x0){cent.x=this.cg3.x/3/this.areasum2;cent.y=this.cg3.y/3/this.areasum2;}else if(this.totalLength>0){cent.x=this.lineCentSum.x/this.totalLength;cent.y=this.lineCentSum.y/this.totalLength;}else if(this.ptCount>0){cent.x=this.ptCentSum.x/this.ptCount;cent.y=this.ptCentSum.y/this.ptCount;}else{return null;} return cent;};jsts.algorithm.Centroid.prototype.setBasePoint=function(basePt){if(this.areaBasePt===null){this.areaBasePt=basePt;}};jsts.algorithm.Centroid.prototype.addPolygon=function(poly){this.addShell(poly.getExteriorRing().getCoordinates());for(var i=0;i0){this.setBasePoint(pts[0]);} var isPositiveArea=!jsts.algorithm.CGAlgorithms.isCCW(pts);for(var i=0;i0){this.addPoint(pts[0]);}};jsts.algorithm.Centroid.prototype.addPoint=function(pt){this.ptCount+=1;this.ptCentSum.x+=pt.x;this.ptCentSum.y+=pt.y;};(function(){var EdgeRing=function(factory){this.deList=new javascript.util.ArrayList();this.factory=factory;};EdgeRing.findEdgeRingContaining=function(testEr,shellList){var testRing=testEr.getRing();var testEnv=testRing.getEnvelopeInternal();var testPt=testRing.getCoordinateN(0);var minShell=null;var minEnv=null;for(var it=shellList.iterator();it.hasNext();){var tryShell=it.next();var tryRing=tryShell.getRing();var tryEnv=tryRing.getEnvelopeInternal();if(minShell!=null) minEnv=minShell.getRing().getEnvelopeInternal();var isContained=false;if(tryEnv.equals(testEnv)) continue;testPt=jsts.geom.CoordinateArrays.ptNotInList(testRing.getCoordinates(),tryRing.getCoordinates());if(tryEnv.contains(testEnv)&&jsts.algorithm.CGAlgorithms.isPointInRing(testPt,tryRing.getCoordinates())) isContained=true;if(isContained){if(minShell==null||minEnv.contains(tryEnv)){minShell=tryShell;}}} return minShell;};EdgeRing.ptNotInList=function(testPts,pts){for(var i=0;i=0;i--){coordList.add(coords[i],false);}}};jsts.operation.polygonize.EdgeRing=EdgeRing;})();(function(){var GraphComponent=function(){};GraphComponent.setVisited=function(i,visited){while(i.hasNext()){var comp=i.next();comp.setVisited(visited);}};GraphComponent.setMarked=function(i,marked){while(i.hasNext()){var comp=i.next();comp.setMarked(marked);}};GraphComponent.getComponentWithVisitedState=function(i,visitedState){while(i.hasNext()){var comp=i.next();if(comp.isVisited()==visitedState) return comp;} return null;};GraphComponent.prototype._isMarked=false;GraphComponent.prototype._isVisited=false;GraphComponent.prototype.data;GraphComponent.prototype.isVisited=function(){return this._isVisited;};GraphComponent.prototype.setVisited=function(isVisited){this._isVisited=isVisited;};GraphComponent.prototype.isMarked=function(){return this._isMarked;};GraphComponent.prototype.setMarked=function(isMarked){this._isMarked=isMarked;};GraphComponent.prototype.setContext=function(data){this.data=data;};GraphComponent.prototype.getContext=function(){return data;};GraphComponent.prototype.setData=function(data){this.data=data;};GraphComponent.prototype.getData=function(){return data;};GraphComponent.prototype.isRemoved=function(){throw new jsts.error.AbstractMethodInvocationError();};jsts.planargraph.GraphComponent=GraphComponent;})();(function(){var GraphComponent=jsts.planargraph.GraphComponent;var Edge=function(de0,de1){if(de0===undefined){return;} this.setDirectedEdges(de0,de1);};Edge.prototype=new GraphComponent();Edge.prototype.dirEdge=null;Edge.prototype.setDirectedEdges=function(de0,de1){this.dirEdge=[de0,de1];de0.setEdge(this);de1.setEdge(this);de0.setSym(de1);de1.setSym(de0);de0.getFromNode().addOutEdge(de0);de1.getFromNode().addOutEdge(de1);};Edge.prototype.getDirEdge=function(i){if(i instanceof jsts.planargraph.Node){this.getDirEdge2(i);} return this.dirEdge[i];};Edge.prototype.getDirEdge2=function(fromNode){if(this.dirEdge[0].getFromNode()==fromNode) return this.dirEdge[0];if(this.dirEdge[1].getFromNode()==fromNode) return this.dirEdge[1];return null;};Edge.prototype.getOppositeNode=function(node){if(this.dirEdge[0].getFromNode()==node) return this.dirEdge[0].getToNode();if(this.dirEdge[1].getFromNode()==node) return this.dirEdge[1].getToNode();return null;};Edge.prototype.remove=function(){this.dirEdge=null;};Edge.prototype.isRemoved=function(){return dirEdge==null;};jsts.planargraph.Edge=Edge;})();jsts.operation.polygonize.PolygonizeEdge=function(line){this.line=line;};jsts.operation.polygonize.PolygonizeEdge.prototype=new jsts.planargraph.Edge();jsts.operation.polygonize.PolygonizeEdge.prototype.line=null;jsts.operation.polygonize.PolygonizeEdge.prototype.getLine=function(){return this.line;};(function(){var ArrayList=javascript.util.ArrayList;var GraphComponent=jsts.planargraph.GraphComponent;var DirectedEdge=function(from,to,directionPt,edgeDirection){if(from===undefined){return;} this.from=from;this.to=to;this.edgeDirection=edgeDirection;this.p0=from.getCoordinate();this.p1=directionPt;var dx=this.p1.x-this.p0.x;var dy=this.p1.y-this.p0.y;this.quadrant=jsts.geomgraph.Quadrant.quadrant(dx,dy);this.angle=Math.atan2(dy,dx);};DirectedEdge.prototype=new GraphComponent();DirectedEdge.toEdges=function(dirEdges){var edges=new ArrayList();for(var i=dirEdges.iterator();i.hasNext();){edges.add((i.next()).parentEdge);} return edges;};DirectedEdge.prototype.parentEdge=null;DirectedEdge.prototype.from=null;DirectedEdge.prototype.to=null;DirectedEdge.prototype.p0=null;DirectedEdge.prototype.p1=null;DirectedEdge.prototype.sym=null;DirectedEdge.prototype.edgeDirection=null;DirectedEdge.prototype.quadrant=null;DirectedEdge.prototype.angle=null;DirectedEdge.prototype.getEdge=function(){return this.parentEdge;};DirectedEdge.prototype.setEdge=function(parentEdge){this.parentEdge=parentEdge;};DirectedEdge.prototype.getQuadrant=function(){return this.quadrant;};DirectedEdge.prototype.getDirectionPt=function(){return this.p1;};DirectedEdge.prototype.getEdgeDirection=function(){return this.edgeDirection;};DirectedEdge.prototype.getFromNode=function(){return this.from;};DirectedEdge.prototype.getToNode=function(){return this.to;};DirectedEdge.prototype.getCoordinate=function(){return this.from.getCoordinate();};DirectedEdge.prototype.getAngle=function(){return this.angle;};DirectedEdge.prototype.getSym=function(){return this.sym;};DirectedEdge.prototype.setSym=function(sym){this.sym=sym;};DirectedEdge.prototype.remove=function(){this.sym=null;this.parentEdge=null;};DirectedEdge.prototype.isRemoved=function(){return this.parentEdge==null;};DirectedEdge.prototype.compareTo=function(obj){var de=obj;return this.compareDirection(de);};DirectedEdge.prototype.compareDirection=function(e){if(this.quadrant>e.quadrant) return 1;if(this.quadrant1){if(intNodes==null) intNodes=new ArrayList();intNodes.add(node);} de=de.getNext();Assert.isTrue(de!=null,'found null DE in ring');Assert.isTrue(de==startDE||!de.isInRing(),'found DE already in ring');}while(de!=startDE);return intNodes;};PolygonizeGraph.prototype.getEdgeRings=function(){this.computeNextCWEdges();PolygonizeGraph.label(this.dirEdges,-1);var maximalRings=PolygonizeGraph.findLabeledEdgeRings(this.dirEdges);this.convertMaximalToMinimalEdgeRings(maximalRings);var edgeRingList=new ArrayList();for(var i=this.dirEdges.iterator();i.hasNext();){var de=i.next();if(de.isMarked()) continue;if(de.isInRing()) continue;var er=this.findEdgeRing(de);edgeRingList.add(er);} return edgeRingList;};PolygonizeGraph.findLabeledEdgeRings=function(dirEdges){var edgeRingStarts=new ArrayList();var currLabel=1;for(var i=dirEdges.iterator();i.hasNext();){var de=i.next();if(de.isMarked()) continue;if(de.getLabel()>=0) continue;edgeRingStarts.add(de);var edges=PolygonizeGraph.findDirEdgesInRing(de);PolygonizeGraph.label(edges,currLabel);currLabel++;} return edgeRingStarts;};PolygonizeGraph.prototype.deleteCutEdges=function(){this.computeNextCWEdges();PolygonizeGraph.findLabeledEdgeRings(this.dirEdges);var cutLines=new ArrayList();for(var i=this.dirEdges.iterator();i.hasNext();){var de=i.next();if(de.isMarked()) continue;var sym=de.getSym();if(de.getLabel()==sym.getLabel()){de.setMarked(true);sym.setMarked(true);var e=de.getEdge();cutLines.add(e.getLine());}} return cutLines;};PolygonizeGraph.label=function(dirEdges,label){for(var i=dirEdges.iterator();i.hasNext();){var de=i.next();de.setLabel(label);}};PolygonizeGraph.computeNextCWEdges=function(node){var deStar=node.getOutEdges();var startDE=null;var prevDE=null;for(var i=deStar.getEdges().iterator();i.hasNext();){var outDE=i.next();if(outDE.isMarked()) continue;if(startDE==null) startDE=outDE;if(prevDE!=null){var sym=prevDE.getSym();sym.setNext(outDE);} prevDE=outDE;} if(prevDE!=null){var sym=prevDE.getSym();sym.setNext(startDE);}};PolygonizeGraph.computeNextCCWEdges=function(node,label){var deStar=node.getOutEdges();var firstOutDE=null;var prevInDE=null;var edges=deStar.getEdges();for(var i=edges.size()-1;i>=0;i--){var de=edges.get(i);var sym=de.getSym();var outDE=null;if(de.getLabel()==label) outDE=de;var inDE=null;if(sym.getLabel()==label) inDE=sym;if(outDE==null&&inDE==null) continue;if(inDE!=null){prevInDE=inDE;} if(outDE!=null){if(prevInDE!=null){prevInDE.setNext(outDE);prevInDE=null;} if(firstOutDE==null) firstOutDE=outDE;}} if(prevInDE!=null){Assert.isTrue(firstOutDE!=null);prevInDE.setNext(firstOutDE);}};PolygonizeGraph.findDirEdgesInRing=function(startDE){var de=startDE;var edges=new ArrayList();do{edges.add(de);de=de.getNext();Assert.isTrue(de!=null,'found null DE in ring');Assert.isTrue(de==startDE||!de.isInRing(),'found DE already in ring');}while(de!=startDE);return edges;};PolygonizeGraph.prototype.findEdgeRing=function(startDE){var de=startDE;var er=new EdgeRing(this.factory);do{er.add(de);de.setRing(er);de=de.getNext();Assert.isTrue(de!=null,'found null DE in ring');Assert.isTrue(de==startDE||!de.isInRing(),'found DE already in ring');}while(de!=startDE);return er;};PolygonizeGraph.prototype.deleteDangles=function(){var nodesToRemove=this.findNodesOfDegree(1);var dangleLines=new HashSet();var nodeStack=new Stack();for(var i=nodesToRemove.iterator();i.hasNext();){nodeStack.push(i.next());} while(!nodeStack.isEmpty()){var node=nodeStack.pop();PolygonizeGraph.deleteAllEdges(node);var nodeOutEdges=node.getOutEdges().getEdges();for(var i=nodeOutEdges.iterator();i.hasNext();){var de=i.next();de.setMarked(true);var sym=de.getSym();if(sym!=null) sym.setMarked(true);var e=de.getEdge();dangleLines.add(e.getLine());var toNode=de.getToNode();if(PolygonizeGraph.getDegreeNonDeleted(toNode)==1) nodeStack.push(toNode);}} return dangleLines;};PolygonizeGraph.prototype.computeDepthParity=function(){while(true){var de=null;if(de==null) return;this.computeDepthParity(de);}};PolygonizeGraph.prototype.computeDepthParity=function(de){};jsts.operation.polygonize.PolygonizeGraph=PolygonizeGraph;})();jsts.index.strtree.Interval=function(){var other;if(arguments.length===1){other=arguments[0];return jsts.index.strtree.Interval(other.min,other.max);}else if(arguments.length===2){jsts.util.Assert.isTrue(this.min<=this.max);this.min=arguments[0];this.max=arguments[1];}};jsts.index.strtree.Interval.prototype.min=null;jsts.index.strtree.Interval.prototype.max=null;jsts.index.strtree.Interval.prototype.getCentre=function(){return(this.min+this.max)/2;};jsts.index.strtree.Interval.prototype.expandToInclude=function(other){this.max=Math.max(this.max,other.max);this.min=Math.min(this.min,other.min);return this;};jsts.index.strtree.Interval.prototype.intersects=function(other){return!(other.min>this.max||other.max1;if(isCollection){if(geom0 instanceof jsts.geom.Polygon){return this.createMultiPolygon(geomList.toArray());}else if(geom0 instanceof jsts.geom.LineString){return this.createMultiLineString(geomList.toArray());}else if(geom0 instanceof jsts.geom.Point){return this.createMultiPoint(geomList.toArray());} jsts.util.Assert.shouldNeverReachHere('Unhandled class: '+geom0);} return geom0;};jsts.geom.GeometryFactory.prototype.createGeometryCollection=function(geometries){return new jsts.geom.GeometryCollection(geometries,this);};jsts.geom.GeometryFactory.prototype.toGeometry=function(envelope){if(envelope.isNull()){return this.createPoint(null);} if(envelope.getMinX()===envelope.getMaxX()&&envelope.getMinY()===envelope.getMaxY()){return this.createPoint(new jsts.geom.Coordinate(envelope.getMinX(),envelope.getMinY()));} if(envelope.getMinX()===envelope.getMaxX()||envelope.getMinY()===envelope.getMaxY()){return this.createLineString([new jsts.geom.Coordinate(envelope.getMinX(),envelope.getMinY()),new jsts.geom.Coordinate(envelope.getMaxX(),envelope.getMaxY())]);} return this.createPolygon(this.createLinearRing([new jsts.geom.Coordinate(envelope.getMinX(),envelope.getMinY()),new jsts.geom.Coordinate(envelope.getMinX(),envelope.getMaxY()),new jsts.geom.Coordinate(envelope.getMaxX(),envelope.getMaxY()),new jsts.geom.Coordinate(envelope.getMaxX(),envelope.getMinY()),new jsts.geom.Coordinate(envelope.getMinX(),envelope.getMinY())]),null);};jsts.geomgraph.NodeFactory=function(){};jsts.geomgraph.NodeFactory.prototype.createNode=function(coord){return new jsts.geomgraph.Node(coord,null);};(function(){jsts.geomgraph.Position=function(){};jsts.geomgraph.Position.ON=0;jsts.geomgraph.Position.LEFT=1;jsts.geomgraph.Position.RIGHT=2;jsts.geomgraph.Position.opposite=function(position){if(position===jsts.geomgraph.Position.LEFT){return jsts.geomgraph.Position.RIGHT;} if(position===jsts.geomgraph.Position.RIGHT){return jsts.geomgraph.Position.LEFT;} return position;};})();jsts.geomgraph.TopologyLocation=function(){this.location=[];if(arguments.length===3){var on=arguments[0];var left=arguments[1];var right=arguments[2];this.init(3);this.location[jsts.geomgraph.Position.ON]=on;this.location[jsts.geomgraph.Position.LEFT]=left;this.location[jsts.geomgraph.Position.RIGHT]=right;}else if(arguments[0]instanceof jsts.geomgraph.TopologyLocation){var gl=arguments[0];this.init(gl.location.length);if(gl!=null){for(var i=0;i1;};jsts.geomgraph.TopologyLocation.prototype.isLine=function(){return this.location.length===1;};jsts.geomgraph.TopologyLocation.prototype.flip=function(){if(this.location.length<=1) return;var temp=this.location[jsts.geomgraph.Position.LEFT];this.location[jsts.geomgraph.Position.LEFT]=this.location[jsts.geomgraph.Position.RIGHT];this.location[jsts.geomgraph.Position.RIGHT]=temp;};jsts.geomgraph.TopologyLocation.prototype.setAllLocations=function(locValue){for(var i=0;ithis.location.length){var newLoc=[];newLoc[jsts.geomgraph.Position.ON]=this.location[jsts.geomgraph.Position.ON];newLoc[jsts.geomgraph.Position.LEFT]=jsts.geom.Location.NONE;newLoc[jsts.geomgraph.Position.RIGHT]=jsts.geom.Location.NONE;this.location=newLoc;} for(var i=0;ithis.maxNodeDegree) this.maxNodeDegree=degree;de=this.getNext(de);}while(de!==this.startDe);this.maxNodeDegree*=2;};jsts.geomgraph.EdgeRing.prototype.setInResult=function(){var de=this.startDe;do{de.getEdge().setInResult(true);de=de.getNext();}while(de!=this.startDe);};jsts.geomgraph.EdgeRing.prototype.mergeLabel=function(deLabel){this.mergeLabel2(deLabel,0);this.mergeLabel2(deLabel,1);};jsts.geomgraph.EdgeRing.prototype.mergeLabel2=function(deLabel,geomIndex){var loc=deLabel.getLocation(geomIndex,jsts.geomgraph.Position.RIGHT);if(loc==jsts.geom.Location.NONE) return;if(this.label.getLocation(geomIndex)===jsts.geom.Location.NONE){this.label.setLocation(geomIndex,loc);return;}};jsts.geomgraph.EdgeRing.prototype.addPoints=function(edge,isForward,isFirstEdge){var edgePts=edge.getCoordinates();if(isForward){var startIndex=1;if(isFirstEdge) startIndex=0;for(var i=startIndex;i=0;i--){this.pts.push(edgePts[i]);}}};jsts.geomgraph.EdgeRing.prototype.containsPoint=function(p){var shell=this.getLinearRing();var env=shell.getEnvelopeInternal();if(!env.contains(p)) return false;if(!jsts.algorithm.CGAlgorithms.isPointInRing(p,shell.getCoordinates())) return false;for(var i=0;i1,'Node capacity must be greater than 1');this.nodeCapacity=nodeCapacity;};jsts.index.strtree.AbstractSTRtree.IntersectsOp=function(){};jsts.index.strtree.AbstractSTRtree.IntersectsOp.prototype.intersects=function(aBounds,bBounds){throw new jsts.error.AbstractMethodInvocationError();};jsts.index.strtree.AbstractSTRtree.prototype.root=null;jsts.index.strtree.AbstractSTRtree.prototype.built=false;jsts.index.strtree.AbstractSTRtree.prototype.itemBoundables=null;jsts.index.strtree.AbstractSTRtree.prototype.nodeCapacity=null;jsts.index.strtree.AbstractSTRtree.prototype.build=function(){jsts.util.Assert.isTrue(!this.built);this.root=this.itemBoundables.length===0?this.createNode(0):this.createHigherLevels(this.itemBoundables,-1);this.built=true;};jsts.index.strtree.AbstractSTRtree.prototype.createNode=function(level){throw new jsts.error.AbstractMethodInvocationError();};jsts.index.strtree.AbstractSTRtree.prototype.createParentBoundables=function(childBoundables,newLevel){jsts.util.Assert.isTrue(!(childBoundables.length===0));var parentBoundables=[];parentBoundables.push(this.createNode(newLevel));var sortedChildBoundables=[];for(var i=0;ib?1:amaxChildDepth) maxChildDepth=childDepth;}} return maxChildDepth+1;};jsts.index.strtree.AbstractSTRtree.prototype.insert=function(bounds,item){jsts.util.Assert.isTrue(!this.built,'Cannot insert items into an STR packed R-tree after it has been built.');this.itemBoundables.push(new jsts.index.strtree.ItemBoundable(bounds,item));};jsts.index.strtree.AbstractSTRtree.prototype.query=function(searchBounds){if(arguments.length>1){this.query2.apply(this,arguments);} if(!this.built){this.build();} var matches=[];if(this.itemBoundables.length===0){jsts.util.Assert.isTrue(this.root.getBounds()===null);return matches;} if(this.getIntersectsOp().intersects(this.root.getBounds(),searchBounds)){this.query3(searchBounds,this.root,matches);} return matches;};jsts.index.strtree.AbstractSTRtree.prototype.query2=function(searchBounds,visitor){if(arguments.length>2){this.query3.apply(this,arguments);} if(!this.built){this.build();} if(this.itemBoundables.length===0){jsts.util.Assert.isTrue(this.root.getBounds()===null);} if(this.getIntersectsOp().intersects(this.root.getBounds(),searchBounds)){this.query4(searchBounds,this.root,visitor);}};jsts.index.strtree.AbstractSTRtree.prototype.query3=function(searchBounds,node,matches){if(!(arguments[2]instanceof Array)){this.query4.apply(this,arguments);} var childBoundables=node.getChildBoundables();for(var i=0;i1){this.boundablesAtLevel2.apply(this,arguments);return;} var boundables=[];this.boundablesAtLevel2(level,this.root,boundables);return boundables;};jsts.index.strtree.AbstractSTRtree.prototype.boundablesAtLevel2=function(level,top,boundables){jsts.util.Assert.isTrue(level>-2);if(top.getLevel()===level){boundables.add(top);return;} var childBoundables=node.getChildBoundables();for(var i=0;i0);var parentBoundables=[];for(var i=0;i0.0){var bndPair=priQ.pop();var currentDistance=bndPair.getDistance();if(currentDistance>=distanceLowerBound) break;if(bndPair.isLeaves()){distanceLowerBound=currentDistance;minPair=bndPair;}else{bndPair.expandToQueue(priQ,distanceLowerBound);}} return[minPair.getBoundable(0).getItem(),minPair.getBoundable(1).getItem()];};jsts.noding.SegmentString=function(){};jsts.noding.SegmentString.prototype.getData=jsts.abstractFunc;jsts.noding.SegmentString.prototype.setData=jsts.abstractFunc;jsts.noding.SegmentString.prototype.size=jsts.abstractFunc;jsts.noding.SegmentString.prototype.getCoordinate=jsts.abstractFunc;jsts.noding.SegmentString.prototype.getCoordinates=jsts.abstractFunc;jsts.noding.SegmentString.prototype.isClosed=jsts.abstractFunc;jsts.noding.NodableSegmentString=function(){};jsts.noding.NodableSegmentString.prototype=new jsts.noding.SegmentString();jsts.noding.NodableSegmentString.prototype.addIntersection=jsts.abstractFunc;jsts.noding.NodedSegmentString=function(pts,data){this.nodeList=new jsts.noding.SegmentNodeList(this);this.pts=pts;this.data=data;};jsts.noding.NodedSegmentString.prototype=new jsts.noding.NodableSegmentString();jsts.noding.NodedSegmentString.constructor=jsts.noding.NodedSegmentString;jsts.noding.NodedSegmentString.getNodedSubstrings=function(segStrings){if(arguments.length===2){jsts.noding.NodedSegmentString.getNodedSubstrings2.apply(this,arguments);return;} var resultEdgelist=new javascript.util.ArrayList();jsts.noding.NodedSegmentString.getNodedSubstrings2(segStrings,resultEdgelist);return resultEdgelist;};jsts.noding.NodedSegmentString.getNodedSubstrings2=function(segStrings,resultEdgelist){for(var i=segStrings.iterator();i.hasNext();){var ss=i.next();ss.getNodeList().addSplitEdges(resultEdgelist);}};jsts.noding.NodedSegmentString.prototype.nodeList=null;jsts.noding.NodedSegmentString.prototype.pts=null;jsts.noding.NodedSegmentString.prototype.data=null;jsts.noding.NodedSegmentString.prototype.getData=function(){return this.data;};jsts.noding.NodedSegmentString.prototype.setData=function(data){this.data=data;};jsts.noding.NodedSegmentString.prototype.getNodeList=function(){return this.nodeList;};jsts.noding.NodedSegmentString.prototype.size=function(){return this.pts.length;};jsts.noding.NodedSegmentString.prototype.getCoordinate=function(i){return this.pts[i];};jsts.noding.NodedSegmentString.prototype.getCoordinates=function(){return this.pts;};jsts.noding.NodedSegmentString.prototype.isClosed=function(){return this.pts[0].equals(this.pts[this.pts.length-1]);};jsts.noding.NodedSegmentString.prototype.getSegmentOctant=function(index){if(index===this.pts.length-1) return-1;return this.safeOctant(this.getCoordinate(index),this.getCoordinate(index+1));};jsts.noding.NodedSegmentString.prototype.safeOctant=function(p0,p1){if(p0.equals2D(p1)) return 0;return jsts.noding.Octant.octant(p0,p1);};jsts.noding.NodedSegmentString.prototype.addIntersections=function(li,segmentIndex,geomIndex){for(var i=0;i=pts.length-1){return pts.length-1;} var chainQuad=jsts.geomgraph.Quadrant.quadrant(pts[safeStart],pts[safeStart+1]);var last=start+1;while(lastdy){dist=dx;}else{dist=dy;}}else{var pdx=Math.abs(p.x-p0.x);var pdy=Math.abs(p.y-p0.y);if(dx>dy){dist=pdx;}else{dist=pdy;} if(dist===0.0&&!p.equals(p0)){dist=Math.max(pdx,pdy);}} if(dist===0.0&&!p.equals(p0)){throw new jsts.error.IllegalArgumentError('Bad distance calculation');} return dist;};jsts.algorithm.LineIntersector.nonRobustComputeEdgeDistance=function(p,p1,p2){var dx=p.x-p1.x;var dy=p.y-p1.y;var dist=Math.sqrt(dx*dx+dy*dy);if(!(dist===0.0&&!p.equals(p1))){throw new jsts.error.IllegalArgumentError('Invalid distance calculation');} return dist;};jsts.algorithm.LineIntersector.prototype.result=null;jsts.algorithm.LineIntersector.prototype.inputLines=null;jsts.algorithm.LineIntersector.prototype.intPt=null;jsts.algorithm.LineIntersector.prototype.intLineIndex=null;jsts.algorithm.LineIntersector.prototype._isProper=null;jsts.algorithm.LineIntersector.prototype.pa=null;jsts.algorithm.LineIntersector.prototype.pb=null;jsts.algorithm.LineIntersector.prototype.precisionModel=null;jsts.algorithm.LineIntersector.prototype.computeIntersection=function(p,p1,p2){throw new jsts.error.AbstractMethodInvocationError();};jsts.algorithm.LineIntersector.prototype.isCollinear=function(){return this.result===jsts.algorithm.LineIntersector.COLLINEAR_INTERSECTION;};jsts.algorithm.LineIntersector.prototype.computeIntersection=function(p1,p2,p3,p4){this.inputLines[0][0]=p1;this.inputLines[0][1]=p2;this.inputLines[1][0]=p3;this.inputLines[1][1]=p4;this.result=this.computeIntersect(p1,p2,p3,p4);};jsts.algorithm.LineIntersector.prototype.computeIntersect=function(p1,p2,q1,q2){throw new jsts.error.AbstractMethodInvocationError();};jsts.algorithm.LineIntersector.prototype.isEndPoint=function(){return this.hasIntersection()&&!this._isProper;};jsts.algorithm.LineIntersector.prototype.hasIntersection=function(){return this.result!==jsts.algorithm.LineIntersector.NO_INTERSECTION;};jsts.algorithm.LineIntersector.prototype.getIntersectionNum=function(){return this.result;};jsts.algorithm.LineIntersector.prototype.getIntersection=function(intIndex){return this.intPt[intIndex];};jsts.algorithm.LineIntersector.prototype.computeIntLineIndex=function(){if(this.intLineIndex===null){this.intLineIndex=[[],[]];this.computeIntLineIndex(0);this.computeIntLineIndex(1);}};jsts.algorithm.LineIntersector.prototype.isIntersection=function(pt){var i;for(i=0;idist1){this.intLineIndex[segmentIndex][0]=0;this.intLineIndex[segmentIndex][1]=1;}else{this.intLineIndex[segmentIndex][0]=1;this.intLineIndex[segmentIndex][1]=0;}};jsts.algorithm.LineIntersector.prototype.getEdgeDistance=function(segmentIndex,intIndex){var dist=jsts.algorithm.LineIntersector.computeEdgeDistance(this.intPt[intIndex],this.inputLines[segmentIndex][0],this.inputLines[segmentIndex][1]);return dist;};jsts.algorithm.RobustLineIntersector=function(){jsts.algorithm.RobustLineIntersector.prototype.constructor.call(this);};jsts.algorithm.RobustLineIntersector.prototype=new jsts.algorithm.LineIntersector();jsts.algorithm.RobustLineIntersector.prototype.computeIntersection=function(p,p1,p2){if(arguments.length===4){jsts.algorithm.LineIntersector.prototype.computeIntersection.apply(this,arguments);return;} this._isProper=false;if(jsts.geom.Envelope.intersects(p1,p2,p)){if((jsts.algorithm.CGAlgorithms.orientationIndex(p1,p2,p)===0)&&(jsts.algorithm.CGAlgorithms.orientationIndex(p2,p1,p)===0)){this._isProper=true;if(p.equals(p1)||p.equals(p2)){this._isProper=false;} this.result=jsts.algorithm.LineIntersector.POINT_INTERSECTION;return;}} this.result=jsts.algorithm.LineIntersector.NO_INTERSECTION;};jsts.algorithm.RobustLineIntersector.prototype.computeIntersect=function(p1,p2,q1,q2){this._isProper=false;if(!jsts.geom.Envelope.intersects(p1,p2,q1,q2)){return jsts.algorithm.LineIntersector.NO_INTERSECTION;} var Pq1=jsts.algorithm.CGAlgorithms.orientationIndex(p1,p2,q1);var Pq2=jsts.algorithm.CGAlgorithms.orientationIndex(p1,p2,q2);if((Pq1>0&&Pq2>0)||(Pq1<0&&Pq2<0)){return jsts.algorithm.LineIntersector.NO_INTERSECTION;} var Qp1=jsts.algorithm.CGAlgorithms.orientationIndex(q1,q2,p1);var Qp2=jsts.algorithm.CGAlgorithms.orientationIndex(q1,q2,p2);if((Qp1>0&&Qp2>0)||(Qp1<0&&Qp2<0)){return jsts.algorithm.LineIntersector.NO_INTERSECTION;} var collinear=Pq1===0&&Pq2===0&&Qp1===0&&Qp2===0;if(collinear){return this.computeCollinearIntersection(p1,p2,q1,q2);} if(Pq1===0||Pq2===0||Qp1===0||Qp2===0){this._isProper=false;if(p1.equals2D(q1)||p1.equals2D(q2)){this.intPt[0]=p1;}else if(p2.equals2D(q1)||p2.equals2D(q2)){this.intPt[0]=p2;} else if(Pq1===0){this.intPt[0]=new jsts.geom.Coordinate(q1);}else if(Pq2===0){this.intPt[0]=new jsts.geom.Coordinate(q2);}else if(Qp1===0){this.intPt[0]=new jsts.geom.Coordinate(p1);}else if(Qp2===0){this.intPt[0]=new jsts.geom.Coordinate(p2);}}else{this._isProper=true;this.intPt[0]=this.intersection(p1,p2,q1,q2);} return jsts.algorithm.LineIntersector.POINT_INTERSECTION;};jsts.algorithm.RobustLineIntersector.prototype.computeCollinearIntersection=function(p1,p2,q1,q2){var p1q1p2=jsts.geom.Envelope.intersects(p1,p2,q1);var p1q2p2=jsts.geom.Envelope.intersects(p1,p2,q2);var q1p1q2=jsts.geom.Envelope.intersects(q1,q2,p1);var q1p2q2=jsts.geom.Envelope.intersects(q1,q2,p2);if(p1q1p2&&p1q2p2){this.intPt[0]=q1;this.intPt[1]=q2;return jsts.algorithm.LineIntersector.COLLINEAR_INTERSECTION;} if(q1p1q2&&q1p2q2){this.intPt[0]=p1;this.intPt[1]=p2;return jsts.algorithm.LineIntersector.COLLINEAR_INTERSECTION;} if(p1q1p2&&q1p1q2){this.intPt[0]=q1;this.intPt[1]=p1;return q1.equals(p1)&&!p1q2p2&&!q1p2q2?jsts.algorithm.LineIntersector.POINT_INTERSECTION:jsts.algorithm.LineIntersector.COLLINEAR_INTERSECTION;} if(p1q1p2&&q1p2q2){this.intPt[0]=q1;this.intPt[1]=p2;return q1.equals(p2)&&!p1q2p2&&!q1p1q2?jsts.algorithm.LineIntersector.POINT_INTERSECTION:jsts.algorithm.LineIntersector.COLLINEAR_INTERSECTION;} if(p1q2p2&&q1p1q2){this.intPt[0]=q2;this.intPt[1]=p1;return q2.equals(p1)&&!p1q1p2&&!q1p2q2?jsts.algorithm.LineIntersector.POINT_INTERSECTION:jsts.algorithm.LineIntersector.COLLINEAR_INTERSECTION;} if(p1q2p2&&q1p2q2){this.intPt[0]=q2;this.intPt[1]=p2;return q2.equals(p2)&&!p1q1p2&&!q1p1q2?jsts.algorithm.LineIntersector.POINT_INTERSECTION:jsts.algorithm.LineIntersector.COLLINEAR_INTERSECTION;} return jsts.algorithm.LineIntersector.NO_INTERSECTION;};jsts.algorithm.RobustLineIntersector.prototype.intersection=function(p1,p2,q1,q2){var intPt=this.intersectionWithNormalization(p1,p2,q1,q2);if(!this.isInSegmentEnvelopes(intPt)){intPt=jsts.algorithm.CentralEndpointIntersector.getIntersection(p1,p2,q1,q2);} if(this.precisionModel!==null){this.precisionModel.makePrecise(intPt);} return intPt;};jsts.algorithm.RobustLineIntersector.prototype.intersectionWithNormalization=function(p1,p2,q1,q2){var n1=new jsts.geom.Coordinate(p1);var n2=new jsts.geom.Coordinate(p2);var n3=new jsts.geom.Coordinate(q1);var n4=new jsts.geom.Coordinate(q2);var normPt=new jsts.geom.Coordinate();this.normalizeToEnvCentre(n1,n2,n3,n4,normPt);var intPt=this.safeHCoordinateIntersection(n1,n2,n3,n4);intPt.x+=normPt.x;intPt.y+=normPt.y;return intPt;};jsts.algorithm.RobustLineIntersector.prototype.safeHCoordinateIntersection=function(p1,p2,q1,q2){var intPt=null;try{intPt=jsts.algorithm.HCoordinate.intersection(p1,p2,q1,q2);}catch(e){if(e instanceof jsts.error.NotRepresentableError){intPt=jsts.algorithm.CentralEndpointIntersector.getIntersection(p1,p2,q1,q2);}else{throw e;}} return intPt;};jsts.algorithm.RobustLineIntersector.prototype.normalizeToMinimum=function(n1,n2,n3,n4,normPt){normPt.x=this.smallestInAbsValue(n1.x,n2.x,n3.x,n4.x);normPt.y=this.smallestInAbsValue(n1.y,n2.y,n3.y,n4.y);n1.x-=normPt.x;n1.y-=normPt.y;n2.x-=normPt.x;n2.y-=normPt.y;n3.x-=normPt.x;n3.y-=normPt.y;n4.x-=normPt.x;n4.y-=normPt.y;};jsts.algorithm.RobustLineIntersector.prototype.normalizeToEnvCentre=function(n00,n01,n10,n11,normPt){var minX0=n00.xn01.x?n00.x:n01.x;var maxY0=n00.y>n01.y?n00.y:n01.y;var minX1=n10.xn11.x?n10.x:n11.x;var maxY1=n10.y>n11.y?n10.y:n11.y;var intMinX=minX0>minX1?minX0:minX1;var intMaxX=maxX0minY1?minY0:minY1;var intMaxY=maxY0=0&&orient1>=0){return Math.max(orient0,orient1);} if(orient0<=0&&orient1<=0){return Math.max(orient0,orient1);} return 0;};jsts.geom.LineSegment.prototype.orientationIndex2=function(p){return jsts.algorithm.CGAlgorithms.orientationIndex(this.p0,this.p1,p);};jsts.geom.LineSegment.prototype.reverse=function(){var temp=this.p0;this.p0=this.p1;this.p1=temp;};jsts.geom.LineSegment.prototype.normalize=function(){if(this.p1.compareTo(this.p0)<0)this.reverse();};jsts.geom.LineSegment.prototype.angle=function(){return Math.atan2(this.p1.y-this.p0.y,this.p1.x-this.p0.x);};jsts.geom.LineSegment.prototype.midPoint=function(){return jsts.geom.LineSegment.midPoint(this.p0,this.p1);};jsts.geom.LineSegment.prototype.distance=function(arg){if(arg instanceof jsts.geom.LineSegment){return this.distance1(arg);}else if(arg instanceof jsts.geom.Coordinate){return this.distance2(arg);}};jsts.geom.LineSegment.prototype.distance1=function(ls){return jsts.algorithm.CGAlgorithms.distanceLineLine(this.p0,this.p1,ls.p0,ls.p1);};jsts.geom.LineSegment.prototype.distance2=function(p){return jsts.algorithm.CGAlgorithms.distancePointLine(p,this.p0,this.p1);};jsts.geom.LineSegment.prototype.pointAlong=function(segmentLengthFraction){var coord=new jsts.geom.Coordinate();coord.x=this.p0.x+segmentLengthFraction*(this.p1.x-this.p0.x);coord.y=this.p0.y+segmentLengthFraction*(this.p1.y-this.p0.y);return coord;};jsts.geom.LineSegment.prototype.pointAlongOffset=function(segmentLengthFraction,offsetDistance){var segx=this.p0.x+segmentLengthFraction*(this.p1.x-this.p0.x);var segy=this.p0.y+segmentLengthFraction*(this.p1.y-this.p0.y);var dx=this.p1.x-this.p0.x;var dy=this.p1.y-this.p0.y;var len=Math.sqrt(dx*dx+dy*dy);var ux=0;var uy=0;if(offsetDistance!==0){if(len<=0){throw"Cannot compute offset from zero-length line segment";} ux=offsetDistance*dx/len;uy=offsetDistance*dy/len;} var offsetx=segx-uy;var offsety=segy+ux;var coord=new jsts.geom.Coordinate(offsetx,offsety);return coord;};jsts.geom.LineSegment.prototype.projectionFactor=function(p){if(p.equals(this.p0)) return 0.0;if(p.equals(this.p1)) return 1.0;var dx=this.p1.x-this.p0.x;var dy=this.p1.y-this.p0.y;var len2=dx*dx+dy*dy;var r=((p.x-this.p0.x)*dx+(p.y-this.p0.y)*dy)/len2;return r;};jsts.geom.LineSegment.prototype.segmentFraction=function(inputPt){var segFrac=this.projectionFactor(inputPt);if(segFrac<0){segFrac=0;}else if(segFrac>1||isNaN(segFrac)){segFrac=1;} return segFrac;};jsts.geom.LineSegment.prototype.project=function(arg){if(arg instanceof jsts.geom.Coordinate){return this.project1(arg);}else if(arg instanceof jsts.geom.LineSegment){return this.project2(arg);}};jsts.geom.LineSegment.prototype.project1=function(p){if(p.equals(this.p0)||p.equals(this.p1)){return new jsts.geom.Coordinate(p);} var r=this.projectionFactor(p);var coord=new jsts.geom.Coordinate();coord.x=this.p0.x+r*(this.p1.x-this.p0.x);coord.y=this.p0.y+r*(this.p1.y-this.p0.y);return coord;};jsts.geom.LineSegment.prototype.project2=function(seg){var pf0=this.projectionFactor(seg.p0);var pf1=this.projectionFactor(seg.p1);if(pf0>=1&&pf1>=1)return null;if(pf0<=0&&pf1<=0)return null;var newp0=this.project(seg.p0);if(pf0<0)newp0=p0;if(pf0>1)newp0=p1;var newp1=this.project(seg.p1);if(pf1<0.0)newp1=p0;if(pf1>1.0)newp1=p1;return new jsts.geom.LineSegment(newp0,newp1);};jsts.geom.LineSegment.prototype.closestPoint=function(p){var factor=this.projectionFactor(p);if(factor>0&&factor<1){return this.project(p);} var dist0=this.p0.distance(p);var dist1=this.p1.distance(p);if(dist0queryChain.getId()){queryChain.computeOverlaps(testChain,overlapAction);this.nOverlaps++;} if(this.segInt.isDone()) return;}}};jsts.noding.MCIndexNoder.prototype.add=function(segStr){var segChains=MonotoneChainBuilder.getChains(segStr.getCoordinates(),segStr);for(var i=0;i1&&snapPts[0].equals2D(snapPts[snapPts.length-1])){distinctPtCount=snapPts.length-1;} i=0;for(i;i=0){srcCoords.add(index+1,new jsts.geom.Coordinate(snapPt),false);}}};LineStringSnapper.prototype.findSegmentIndexToSnap=function(snapPt,srcCoords){var minDist=Number.MAX_VALUE,snapIndex=-1,i=0,dist;for(i;i0&&seqSize<4&&!this.preserveType) return this.factory.createLineString(seq);return this.factory.createLinearRing(seq);};GeometryTransformer.prototype.transformLineString=function(geom,parent){return this.factory.createLineString(this.transformCoordinates(geom.getCoordinateSequence(),geom));};GeometryTransformer.prototype.transformMultiLineString=function(geom,parent){var transGeomList=new ArrayList();for(var i=0;isnapTolerance) snapTolerance=fixedSnapTol;} return snapTolerance;};GeometrySnapper.computeSizeBasedSnapTolerance=function(g){var env=g.getEnvelopeInternal();var minDimension=Math.min(env.getHeight(),env.getWidth());var snapTol=minDimension*GeometrySnapper.SNAP_PRECISION_FACTOR;return snapTol;};GeometrySnapper.computeOverlaySnapTolerance2=function(g0,g1){return Math.min(this.computeOverlaySnapTolerance(g0),this.computeOverlaySnapTolerance(g1));};GeometrySnapper.snap=function(g0,g1,snapTolerance){var snapGeom=[];var snapper0=new GeometrySnapper(g0);snapGeom[0]=snapper0.snapTo(g1,snapTolerance);var snapper1=new GeometrySnapper(g1);snapGeom[1]=snapper1.snapTo(snapGeom[0],snapTolerance);return snapGeom;};GeometrySnapper.snapToSelf=function(g0,snapTolerance,cleanResult){var snapper0=new GeometrySnapper(g0);return snapper0.snapToSelf(snapTolerance,cleanResult);};GeometrySnapper.prototype.srcGeom=null;GeometrySnapper.prototype.snapTo=function(snapGeom,snapTolerance){var snapPts=this.extractTargetCoordinates(snapGeom);var snapTrans=new SnapTransformer(snapTolerance,snapPts);return snapTrans.transform(this.srcGeom);};GeometrySnapper.prototype.snapToSelf=function(snapTolerance,cleanResult){var snapPts=this.extractTargetCoordinates(srcGeom);var snapTrans=new SnapTransformer(snapTolerance,snapPts,true);var snappedGeom=snapTrans.transform(srcGeom);var result=snappedGeom;if(cleanResult&&result instanceof Polygonal){result=snappedGeom.buffer(0);} return result;};GeometrySnapper.prototype.extractTargetCoordinates=function(g){var ptSet=new TreeSet();var pts=g.getCoordinates();for(var i=0;i0||this.isIn) return jsts.geom.Location.INTERIOR;return jsts.geom.Location.EXTERIOR;};jsts.algorithm.PointLocator.prototype.computeLocation=function(p,geom){if(geom instanceof jsts.geom.Point||geom instanceof jsts.geom.LineString||geom instanceof jsts.geom.Polygon){this.updateLocationInfo(this.locate(p,geom));}else if(geom instanceof jsts.geom.MultiLineString){var ml=geom;for(var i=0;i=segStr.size()-2) return true;return false;};jsts.noding.InteriorIntersectionFinder.prototype.isDone=function(){if(this.findAllIntersections) return false;return this.interiorIntersection!=null;};})();(function(){var RobustLineIntersector=jsts.algorithm.RobustLineIntersector;var InteriorIntersectionFinder=jsts.noding.InteriorIntersectionFinder;var MCIndexNoder=jsts.noding.MCIndexNoder;jsts.noding.FastNodingValidator=function(segStrings){this.li=new RobustLineIntersector();this.segStrings=segStrings;};jsts.noding.FastNodingValidator.prototype.li=null;jsts.noding.FastNodingValidator.prototype.segStrings=null;jsts.noding.FastNodingValidator.prototype.findAllIntersections=false;jsts.noding.FastNodingValidator.prototype.segInt=null;jsts.noding.FastNodingValidator.prototype._isValid=true;jsts.noding.FastNodingValidator.prototype.setFindAllIntersections=function(findAllIntersections){this.findAllIntersections=findAllIntersections;};jsts.noding.FastNodingValidator.prototype.getIntersections=function(){return segInt.getIntersections();};jsts.noding.FastNodingValidator.prototype.isValid=function(){this.execute();return this._isValid;};jsts.noding.FastNodingValidator.prototype.getErrorMessage=function(){if(this._isValid) return'no intersections found';var intSegs=this.segInt.getIntersectionSegments();return'found non-noded intersection between '+ jsts.io.WKTWriter.toLineString(intSegs[0],intSegs[1])+' and '+ jsts.io.WKTWriter.toLineString(intSegs[2],intSegs[3]);};jsts.noding.FastNodingValidator.prototype.checkValid=function(){this.execute();if(!this._isValid) throw new jsts.error.TopologyError(this.getErrorMessage(),this.segInt.getInteriorIntersection());};jsts.noding.FastNodingValidator.prototype.execute=function(){if(this.segInt!=null) return;this.checkInteriorIntersections();};jsts.noding.FastNodingValidator.prototype.checkInteriorIntersections=function(){this._isValid=true;this.segInt=new InteriorIntersectionFinder(this.li);this.segInt.setFindAllIntersections(this.findAllIntersections);var noder=new MCIndexNoder();noder.setSegmentIntersector(this.segInt);noder.computeNodes(this.segStrings);if(this.segInt.hasIntersection()){this._isValid=false;return;}};})();(function(){jsts.noding.BasicSegmentString=function(pts,data){this.pts=pts;this.data=data;};jsts.noding.BasicSegmentString.prototype=new jsts.noding.SegmentString();jsts.noding.BasicSegmentString.prototype.pts=null;jsts.noding.BasicSegmentString.prototype.data=null;jsts.noding.BasicSegmentString.prototype.getData=function(){return this.data;} jsts.noding.BasicSegmentString.prototype.setData=function(data){this.data=data;};jsts.noding.BasicSegmentString.prototype.size=function(){return this.pts.length;};jsts.noding.BasicSegmentString.prototype.getCoordinate=function(i){return this.pts[i];};jsts.noding.BasicSegmentString.prototype.getCoordinates=function(){return this.pts;};jsts.noding.BasicSegmentString.prototype.isClosed=function(){return this.pts[0].equals(this.pts[this.pts.length-1]);};jsts.noding.BasicSegmentString.prototype.getSegmentOctant=function(index){if(index==this.pts.length-1) return-1;return jsts.noding.Octant.octant(this.getCoordinate(index),this.getCoordinate(index+1));};})();(function(){var FastNodingValidator=jsts.noding.FastNodingValidator;var BasicSegmentString=jsts.noding.BasicSegmentString;var ArrayList=javascript.util.ArrayList;jsts.geomgraph.EdgeNodingValidator=function(edges){this.nv=new FastNodingValidator(jsts.geomgraph.EdgeNodingValidator.toSegmentStrings(edges));};jsts.geomgraph.EdgeNodingValidator.checkValid=function(edges){var validator=new jsts.geomgraph.EdgeNodingValidator(edges);validator.checkValid();};jsts.geomgraph.EdgeNodingValidator.toSegmentStrings=function(edges){var segStrings=new ArrayList();for(var i=edges.iterator();i.hasNext();){var e=i.next();segStrings.add(new BasicSegmentString(e.getCoordinates(),e));} return segStrings;};jsts.geomgraph.EdgeNodingValidator.prototype.nv=null;jsts.geomgraph.EdgeNodingValidator.prototype.checkValid=function(){this.nv.checkValid();};})();jsts.operation.GeometryGraphOperation=function(g0,g1,boundaryNodeRule){this.li=new jsts.algorithm.RobustLineIntersector();this.arg=[];if(g0===undefined){return;} if(g1===undefined){this.setComputationPrecision(g0.getPrecisionModel());this.arg[0]=new jsts.geomgraph.GeometryGraph(0,g0);return;} boundaryNodeRule=boundaryNodeRule||jsts.algorithm.BoundaryNodeRule.OGC_SFS_BOUNDARY_RULE;if(g0.getPrecisionModel().compareTo(g1.getPrecisionModel())>=0) this.setComputationPrecision(g0.getPrecisionModel());else this.setComputationPrecision(g1.getPrecisionModel());this.arg[0]=new jsts.geomgraph.GeometryGraph(0,g0,boundaryNodeRule);this.arg[1]=new jsts.geomgraph.GeometryGraph(1,g1,boundaryNodeRule);};jsts.operation.GeometryGraphOperation.prototype.li=null;jsts.operation.GeometryGraphOperation.prototype.resultPrecisionModel=null;jsts.operation.GeometryGraphOperation.prototype.arg=null;jsts.operation.GeometryGraphOperation.prototype.getArgGeometry=function(i){return arg[i].getGeometry();};jsts.operation.GeometryGraphOperation.prototype.setComputationPrecision=function(pm){this.resultPrecisionModel=pm;this.li.setPrecisionModel(this.resultPrecisionModel);};jsts.operation.overlay.OverlayNodeFactory=function(){};jsts.operation.overlay.OverlayNodeFactory.prototype=new jsts.geomgraph.NodeFactory();jsts.operation.overlay.OverlayNodeFactory.constructor=jsts.operation.overlay.OverlayNodeFactory;jsts.operation.overlay.OverlayNodeFactory.prototype.createNode=function(coord){return new jsts.geomgraph.Node(coord,new jsts.geomgraph.DirectedEdgeStar());};jsts.operation.overlay.PolygonBuilder=function(geometryFactory){this.shellList=[];this.geometryFactory=geometryFactory;};jsts.operation.overlay.PolygonBuilder.prototype.geometryFactory=null;jsts.operation.overlay.PolygonBuilder.prototype.shellList=null;jsts.operation.overlay.PolygonBuilder.prototype.add=function(graph){if(arguments.length===2){this.add2.apply(this,arguments);return;} this.add2(graph.getEdgeEnds(),graph.getNodes());};jsts.operation.overlay.PolygonBuilder.prototype.add2=function(dirEdges,nodes){jsts.geomgraph.PlanarGraph.linkResultDirectedEdges(nodes);var maxEdgeRings=this.buildMaximalEdgeRings(dirEdges);var freeHoleList=[];var edgeRings=this.buildMinimalEdgeRings(maxEdgeRings,this.shellList,freeHoleList);this.sortShellsAndHoles(edgeRings,this.shellList,freeHoleList);this.placeFreeHoles(this.shellList,freeHoleList);};jsts.operation.overlay.PolygonBuilder.prototype.getPolygons=function(){var resultPolyList=this.computePolygons(this.shellList);return resultPolyList;};jsts.operation.overlay.PolygonBuilder.prototype.buildMaximalEdgeRings=function(dirEdges){var maxEdgeRings=[];for(var it=dirEdges.iterator();it.hasNext();){var de=it.next();if(de.isInResult()&&de.getLabel().isArea()){if(de.getEdgeRing()==null){var er=new jsts.operation.overlay.MaximalEdgeRing(de,this.geometryFactory);maxEdgeRings.push(er);er.setInResult();}}} return maxEdgeRings;};jsts.operation.overlay.PolygonBuilder.prototype.buildMinimalEdgeRings=function(maxEdgeRings,shellList,freeHoleList){var edgeRings=[];for(var i=0;i2){er.linkDirectedEdgesForMinimalEdgeRings();var minEdgeRings=er.buildMinimalRings();var shell=this.findShell(minEdgeRings);if(shell!==null){this.placePolygonHoles(shell,minEdgeRings);shellList.push(shell);}else{freeHoleList=freeHoleList.concat(minEdgeRings);}}else{edgeRings.push(er);}} return edgeRings;};jsts.operation.overlay.PolygonBuilder.prototype.findShell=function(minEdgeRings){var shellCount=0;var shell=null;for(var i=0;i=0;i--){var nextOut=this.resultAreaEdgeList.get(i);var nextIn=nextOut.getSym();if(firstOut===null&&nextOut.getEdgeRing()===er) firstOut=nextOut;switch(state){case this.SCANNING_FOR_INCOMING:if(nextIn.getEdgeRing()!=er) continue;incoming=nextIn;state=this.LINKING_TO_OUTGOING;break;case this.LINKING_TO_OUTGOING:if(nextOut.getEdgeRing()!==er) continue;incoming.setNextMin(nextOut);state=this.SCANNING_FOR_INCOMING;break;}} if(state===this.LINKING_TO_OUTGOING){Assert.isTrue(firstOut!==null,'found null for first outgoing dirEdge');Assert.isTrue(firstOut.getEdgeRing()===er,'unable to link last incoming dirEdge');incoming.setNextMin(firstOut);}};jsts.geomgraph.DirectedEdgeStar.prototype.linkAllDirectedEdges=function(){this.getEdges();var prevOut=null;var firstIn=null;for(var i=this.edgeList.size()-1;i>=0;i--){var nextOut=this.edgeList.get(i);var nextIn=nextOut.getSym();if(firstIn===null) firstIn=nextIn;if(prevOut!==null) nextIn.setNext(prevOut);prevOut=nextOut;} firstIn.setNext(prevOut);};jsts.geomgraph.DirectedEdgeStar.prototype.findCoveredLineEdges=function(){var startLoc=Location.NONE;for(var it=this.iterator();it.hasNext();){var nextOut=it.next();var nextIn=nextOut.getSym();if(!nextOut.isLineEdge()){if(nextOut.isInResult()){startLoc=Location.INTERIOR;break;} if(nextIn.isInResult()){startLoc=Location.EXTERIOR;break;}}} if(startLoc===Location.NONE) return;var currLoc=startLoc;for(var it=this.iterator();it.hasNext();){var nextOut=it.next();var nextIn=nextOut.getSym();if(nextOut.isLineEdge()){nextOut.getEdge().setCovered(currLoc===Location.INTERIOR);}else{if(nextOut.isInResult()) currLoc=Location.EXTERIOR;if(nextIn.isInResult()) currLoc=Location.INTERIOR;}}};jsts.geomgraph.DirectedEdgeStar.prototype.computeDepths=function(de){if(arguments.length===2){this.computeDepths2.apply(this,arguments);return;} var edgeIndex=this.findIndex(de);var label=de.getLabel();var startDepth=de.getDepth(Position.LEFT);var targetLastDepth=de.getDepth(Position.RIGHT);var nextDepth=this.computeDepths2(edgeIndex+1,this.edgeList.size(),startDepth);var lastDepth=this.computeDepths2(0,edgeIndex,nextDepth);if(lastDepth!=targetLastDepth) throw new jsts.error.TopologyError('depth mismatch at '+ de.getCoordinate());};jsts.geomgraph.DirectedEdgeStar.prototype.computeDepths2=function(startIndex,endIndex,startDepth){var currDepth=startDepth;for(var i=startIndex;i0){return this.pts[0];}else{return null;}} return this.pts[i];};jsts.geomgraph.Edge.prototype.isClosed=function(){return this.pts[0].equals(this.pts[this.pts.length-1]);};jsts.geomgraph.Edge.prototype.setIsolated=function(isIsolated){this._isIsolated=isIsolated;};jsts.geomgraph.Edge.prototype.isIsolated=function(){return this._isIsolated;};jsts.geomgraph.Edge.prototype.addIntersections=function(li,segmentIndex,geomIndex){for(var i=0;i=0){if(dy>=0){if(adx>=ady) return 0;else return 1;} else{if(adx>=ady) return 7;else return 6;}} else{if(dy>=0){if(adx>=ady) return 3;else return 2;} else{if(adx>=ady) return 4;else return 5;}}};jsts.noding.Octant.octant2=function(p0,p1){var dx=p1.x-p0.x;var dy=p1.y-p0.y;if(dx===0.0&&dy===0.0) throw new jsts.error.IllegalArgumentError('Cannot compute the octant for two identical points '+p0);return jsts.noding.Octant.octant(dx,dy);};jsts.operation.union.UnionInteracting=function(g0,g1){this.g0=g0;this.g1=g1;this.geomFactory=g0.getFactory();this.interacts0=[];this.interacts1=[];};jsts.operation.union.UnionInteracting.union=function(g0,g1){var uue=new jsts.operation.union.UnionInteracting(g0,g1);return uue.union();};jsts.operation.union.UnionInteracting.prototype.geomFactory=null;jsts.operation.union.UnionInteracting.prototype.g0=null;jsts.operation.union.UnionInteracting.prototype.g1=null;jsts.operation.union.UnionInteracting.prototype.interacts0=null;jsts.operation.union.UnionInteracting.prototype.interacts1=null;jsts.operation.union.UnionInteracting.prototype.union=function(){this.computeInteracting();var int0=this.extractElements(this.g0,this.interacts0,true);var int1=this.extractElements(this.g1,this.interacts1,true);if(int0.isEmpty()||int1.isEmpty()){} var union=in0.union(int1);var disjoint0=this.extractElements(this.g0,this.interacts0,false);var disjoint1=this.extractElements(this.g1,this.interacts1,false);var overallUnion=jsts.geom.util.GeometryCombiner.combine(union,disjoint0,disjoint1);return overallUnion;};jsts.operation.union.UnionInteracting.prototype.bufferUnion=function(g0,g1){var factory=g0.getFactory();var gColl=factory.createGeometryCollection([g0,g1]);var unionAll=gColl.buffer(0.0);return unionAll;};jsts.operation.union.UnionInteracting.prototype.computeInteracting=function(elem0){if(!elem0){for(var i=0,l=this.g0.getNumGeometries();i0;return isInCircle;};jsts.triangulate.quadedge.TrianglePredicate.isInCircleNormalized=function(a,b,c,p){var adx,ady,bdx,bdy,cdx,cdy,abdet,bcdet,cadet,alift,blift,clift,disc;adx=a.x-p.x;ady=a.y-p.y;bdx=b.x-p.x;bdy=b.y-p.y;cdx=c.x-p.x;cdy=c.y-p.y;abdet=adx*bdy-bdx*ady;bcdet=bdx*cdy-cdx*bdy;cadet=cdx*ady-adx*cdy;alift=adx*adx+ady*ady;blift=bdx*bdx+bdy*bdy;clift=cdx*cdx+cdy*cdy;disc=alift*bcdet+blift*cadet+clift*abdet;return disc>0;};jsts.triangulate.quadedge.TrianglePredicate.triArea=function(a,b,c){return(b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);};jsts.triangulate.quadedge.TrianglePredicate.isInCircleRobust=function(a,b,c,p){return jsts.triangulate.quadedge.TrianglePredicate.isInCircleNormalized(a,b,c,p);};jsts.triangulate.quadedge.TrianglePredicate.isInCircleDDSlow=function(a,b,c,p){var px,py,ax,ay,bx,by,cx,cy,aTerm,bTerm,cTerm,pTerm,sum,isInCircle;px=jsts.math.DD.valueOf(p.x);py=jsts.math.DD.valueOf(p.y);ax=jsts.math.DD.valueOf(a.x);ay=jsts.math.DD.valueOf(a.y);bx=jsts.math.DD.valueOf(b.x);by=jsts.math.DD.valueOf(b.y);cx=jsts.math.DD.valueOf(c.x);cy=jsts.math.DD.valueOf(c.y);aTerm=(ax.multiply(ax).add(ay.multiply(ay))).multiply(jsts.triangulate.quadedge.TrianglePredicate.triAreaDDSlow(bx,by,cx,cy,px,py));bTerm=(bx.multiply(bx).add(by.multiply(by))).multiply(jsts.triangulate.quadedge.TrianglePredicate.triAreaDDSlow(ax,ay,cx,cy,px,py));cTerm=(cx.multiply(cx).add(cy.multiply(cy))).multiply(jsts.triangulate.quadedge.TrianglePredicate.triAreaDDSlow(ax,ay,bx,by,px,py));pTerm=(px.multiply(px).add(py.multiply(py))).multiply(jsts.triangulate.quadedge.TrianglePredicate.triAreaDDSlow(ax,ay,bx,by,cx,cy));sum=aTerm.subtract(bTerm).add(cTerm).subtract(pTerm);isInCircle=sum.doubleValue()>0;return isInCircle;};jsts.triangulate.quadedge.TrianglePredicate.triAreaDDSlow=function(ax,ay,bx,by,cx,cy){return(bx.subtract(ax).multiply(cy.subtract(ay)).subtract(by.subtract(ay).multiply(cx.subtract(ax))));};jsts.triangulate.quadedge.TrianglePredicate.isInCircleDDFast=function(a,b,c,p){var aTerm,bTerm,cTerm,pTerm,sum,isInCircle;aTerm=(jsts.math.DD.sqr(a.x).selfAdd(jsts.math.DD.sqr(a.y))).selfMultiply(jsts.triangulate.quadedge.TrianglePredicate.triAreaDDFast(b,c,p));bTerm=(jsts.math.DD.sqr(b.x).selfAdd(jsts.math.DD.sqr(b.y))).selfMultiply(jsts.triangulate.quadedge.TrianglePredicate.triAreaDDFast(a,c,p));cTerm=(jsts.math.DD.sqr(c.x).selfAdd(jsts.math.DD.sqr(c.y))).selfMultiply(jsts.triangulate.quadedge.TrianglePredicate.triAreaDDFast(a,b,p));pTerm=(jsts.math.DD.sqr(p.x).selfAdd(jsts.math.DD.sqr(p.y))).selfMultiply(jsts.triangulate.quadedge.TrianglePredicate.triAreaDDFast(a,b,c));sum=aTerm.selfSubtract(bTerm).selfAdd(cTerm).selfSubtract(pTerm);isInCircle=sum.doubleValue()>0;return isInCircle;};jsts.triangulate.quadedge.TrianglePredicate.triAreaDDFast=function(a,b,c){var t1,t2;t1=jsts.math.DD.valueOf(b.x).selfSubtract(a.x).selfMultiply(jsts.math.DD.valueOf(c.y).selfSubtract(a.y));t2=jsts.math.DD.valueOf(b.y).selSubtract(a.y).selfMultiply(jsts.math.DD.valueOf(c.x).selfSubtract(a.x));return t1.selfSubtract(t2);};jsts.triangulate.quadedge.TrianglePredicate.isInCircleDDNormalized=function(a,b,c,p){var adx,ady,bdx,bdy,cdx,cdy,abdet,bcdet,cadet,alift,blift,clift,sum,isInCircle;adx=jsts.math.DD.valueOf(a.x).selfSubtract(p.x);ady=jsts.math.DD.valueOf(a.y).selfSubtract(p.y);bdx=jsts.math.DD.valueOf(b.x).selfSubtract(p.x);bdx=jsts.math.DD.valueOf(b.y).selfSubtract(p.y);cdx=jsts.math.DD.valueOf(c.x).selfSubtract(p.x);cdx=jsts.math.DD.valueOf(c.y).selfSubtract(p.y);abdet=adx.multiply(bdy).selfSubtract(bdx.multiply(ady));bcdet=bdx.multiply(cdy).selfSubtract(cdx.multiply(bdy));cadet=cdx.multiply(ady).selfSubtract(adx.multiply(cdy));alift=adx.multiply(adx).selfAdd(ady.multiply(ady));blift=bdx.multiply(bdx).selfAdd(bdy.multiply(bdy));clift=cdx.multiply(cdx).selfAdd(cdy.multiply(cdy));sum=alift.selfMultiply(bcdet).selfAdd(blift.selfMultiply(cadet)).selfAdd(clift.selfMultiply(abdet));isInCircle=sum.doubleValue()>0;return isInCircle;};jsts.triangulate.quadedge.TrianglePredicate.isInCircleCC=function(a,b,c,p){var cc,ccRadius,pRadiusDiff;cc=jsts.geom.Triangle.circumcentre(a,b,c);ccRadius=a.distance(cc);pRadiusDiff=p.distance(cc)-ccRadius;return pRadiusDiff<=0;};jsts.operation.union.PointGeometryUnion=function(pointGeom,otherGeom){this.pointGeom=pointGeom;this.otherGeom=otherGeom;this.geomFact=otherGeom.getFactory();};jsts.operation.union.PointGeometryUnion.union=function(pointGeom,otherGeom){var unioner=new jsts.operation.union.PointGeometryUnion(pointGeom,otherGeom);return unioner.union();};jsts.operation.union.PointGeometryUnion.prototype.pointGeom=null;jsts.operation.union.PointGeometryUnion.prototype.otherGeom=null;jsts.operation.union.PointGeometryUnion.prototype.geomFact=null;jsts.operation.union.PointGeometryUnion.prototype.union=function(){var locator=new jsts.algorithm.PointLocator();var exteriorCoords=[];for(var i=0,l=this.pointGeom.getNumGeometries();i0)&&(y2<=0))||((y2>0)&&(y1<=0))){xInt=jsts.algorithm.RobustDeterminant.signOfDet2x2(x1,y1,x2,y2)/(y2-y1);if(0.0max){this.min=max;this.max=min;}};Interval.prototype.getMin=function(){return this.min;};Interval.prototype.getMax=function(){return this.max;};Interval.prototype.getWidth=function(){return(this.max-this.min);};Interval.prototype.expandToInclude=function(interval){if(interval.max>this.max){this.max=interval.max;} if(interval.minmax||this.max=this.min&&max<=this.max);};Interval.prototype.containsPoint=function(p){return(p>=this.min&&p<=this.max);};jsts.index.bintree.Interval=Interval;})();jsts.index.DoubleBits=function(){};jsts.index.DoubleBits.powerOf2=function(exp){return Math.pow(2,exp);};jsts.index.DoubleBits.exponent=function(d){return jsts.index.DoubleBits.CVTFWD(64,d)-1023;};jsts.index.DoubleBits.CVTFWD=function(NumW,Qty){var Sign,Expo,Mant,Bin,nb01='';var Inf={32:{d:0x7F,c:0x80,b:0,a:0},64:{d:0x7FF0,c:0,b:0,a:0}};var ExW={32:8,64:11}[NumW],MtW=NumW-ExW-1;if(!Bin){Sign=Qty<0||1/Qty<0;if(!isFinite(Qty)){Bin=Inf[NumW];if(Sign){Bin.d+=1<<(NumW/4-1);} Expo=Math.pow(2,ExW)-1;Mant=0;}} if(!Bin){Expo={32:127,64:1023}[NumW];Mant=Math.abs(Qty);while(Mant>=2){Expo++;Mant/=2;} while(Mant<1&&Expo>0){Expo--;Mant*=2;} if(Expo<=0){Mant/=2;nb01='Zero or Denormal';} if(NumW===32&&Expo>254){nb01='Too big for Single';Bin={d:Sign?0xFF:0x7F,c:0x80,b:0,a:0};Expo=Math.pow(2,ExW)-1;Mant=0;}} return Expo;};(function(){var DoubleBits=jsts.index.DoubleBits;var Interval=jsts.index.bintree.Interval;var Key=function(interval){this.pt=0.0;this.level=0;this.computeKey(interval);};Key.computeLevel=function(interval){var dx=interval.getWidth(),level;level=DoubleBits.exponent(dx)+1;return level;};Key.prototype.getPoint=function(){return this.pt;};Key.prototype.getLevel=function(){return this.level;};Key.prototype.getInterval=function(){return this.interval;};Key.prototype.computeKey=function(itemInterval){this.level=Key.computeLevel(itemInterval);this.interval=new Interval();this.computeInterval(this.level,itemInterval);while(!this.interval.contains(itemInterval)){this.level+=1;this.computeInterval(this.level,itemInterval);}};Key.prototype.computeInterval=function(level,itemInterval){var size=DoubleBits.powerOf2(level);this.pt=Math.floor(itemInterval.getMin()/size)*size;this.interval.init(this.pt,this.pt+size);};jsts.index.bintree.Key=Key;})();jsts.operation.buffer.SubgraphDepthLocater=function(subgraphs){this.subgraphs=[];this.seg=new jsts.geom.LineSegment();this.subgraphs=subgraphs;};jsts.operation.buffer.SubgraphDepthLocater.prototype.subgraphs=null;jsts.operation.buffer.SubgraphDepthLocater.prototype.seg=null;jsts.operation.buffer.SubgraphDepthLocater.prototype.getDepth=function(p){var stabbedSegments=this.findStabbedSegments(p);if(stabbedSegments.length===0) return 0;stabbedSegments.sort();var ds=stabbedSegments[0];return ds.leftDepth;};jsts.operation.buffer.SubgraphDepthLocater.prototype.findStabbedSegments=function(stabbingRayLeftPt){if(arguments.length===3){this.findStabbedSegments2.apply(this,arguments);return;} var stabbedSegments=[];for(var i=0;ienv.getMaxY()) continue;this.findStabbedSegments2(stabbingRayLeftPt,bsg.getDirectedEdges(),stabbedSegments);} return stabbedSegments;};jsts.operation.buffer.SubgraphDepthLocater.prototype.findStabbedSegments2=function(stabbingRayLeftPt,dirEdges,stabbedSegments){if(arguments[1]instanceof jsts.geomgraph.DirectedEdge){this.findStabbedSegments3(stabbingRayLeftPt,dirEdges,stabbedSegments);return;} for(var i=dirEdges.iterator();i.hasNext();){var de=i.next();if(!de.isForward()) continue;this.findStabbedSegments3(stabbingRayLeftPt,de,stabbedSegments);}};jsts.operation.buffer.SubgraphDepthLocater.prototype.findStabbedSegments3=function(stabbingRayLeftPt,dirEdge,stabbedSegments){var pts=dirEdge.getEdge().getCoordinates();for(var i=0;ithis.seg.p1.y) this.seg.reverse();var maxx=Math.max(this.seg.p0.x,this.seg.p1.x);if(maxxthis.seg.p1.y) continue;if(jsts.algorithm.CGAlgorithms.computeOrientation(this.seg.p0,this.seg.p1,stabbingRayLeftPt)===jsts.algorithm.CGAlgorithms.RIGHT) continue;var depth=dirEdge.getDepth(jsts.geomgraph.Position.LEFT);if(!this.seg.p0.equals(pts[i])) depth=dirEdge.getDepth(jsts.geomgraph.Position.RIGHT);var ds=new jsts.operation.buffer.SubgraphDepthLocater.DepthSegment(this.seg,depth);stabbedSegments.push(ds);}};jsts.operation.buffer.SubgraphDepthLocater.DepthSegment=function(seg,depth){this.upwardSeg=new jsts.geom.LineSegment(seg);this.leftDepth=depth;};jsts.operation.buffer.SubgraphDepthLocater.DepthSegment.prototype.upwardSeg=null;jsts.operation.buffer.SubgraphDepthLocater.DepthSegment.prototype.leftDepth=null;jsts.operation.buffer.SubgraphDepthLocater.DepthSegment.prototype.compareTo=function(obj){var other=obj;var orientIndex=this.upwardSeg.orientationIndex(other.upwardSeg);if(orientIndex===0) orientIndex=-1*other.upwardSeg.orientationIndex(upwardSeg);if(orientIndex!==0) return orientIndex;return this.compareX(this.upwardSeg,other.upwardSeg);};jsts.operation.buffer.SubgraphDepthLocater.DepthSegment.prototype.compareX=function(seg0,seg1){var compare0=seg0.p0.compareTo(seg1.p0);if(compare0!==0) return compare0;return seg0.p1.compareTo(seg1.p1);};jsts.noding.snapround.HotPixel=function(pt,scaleFactor,li){this.corner=[];this.originalPt=pt;this.pt=pt;this.scaleFactor=scaleFactor;this.li=li;if(this.scaleFactor!==1.0){this.pt=new jsts.geom.Coordinate(this.scale(pt.x),this.scale(pt.y));this.p0Scaled=new jsts.geom.Coordinate();this.p1Scaled=new jsts.geom.Coordinate();} this.initCorners(this.pt);};jsts.noding.snapround.HotPixel.prototype.li=null;jsts.noding.snapround.HotPixel.prototype.pt=null;jsts.noding.snapround.HotPixel.prototype.originalPt=null;jsts.noding.snapround.HotPixel.prototype.ptScaled=null;jsts.noding.snapround.HotPixel.prototype.p0Scaled=null;jsts.noding.snapround.HotPixel.prototype.p1Scaled=null;jsts.noding.snapround.HotPixel.prototype.scaleFactor=undefined;jsts.noding.snapround.HotPixel.prototype.minx=undefined;jsts.noding.snapround.HotPixel.prototype.maxx=undefined;jsts.noding.snapround.HotPixel.prototype.miny=undefined;jsts.noding.snapround.HotPixel.prototype.maxy=undefined;jsts.noding.snapround.HotPixel.prototype.corner=null;jsts.noding.snapround.HotPixel.prototype.safeEnv=null;jsts.noding.snapround.HotPixel.prototype.getCoordinate=function(){return this.originalPt;};jsts.noding.snapround.HotPixel.SAFE_ENV_EXPANSION_FACTOR=0.75;jsts.noding.snapround.HotPixel.prototype.getSafeEnvelope=function(){if(this.safeEnv===null){var safeTolerance=jsts.noding.snapround.HotPixel.SAFE_ENV_EXPANSION_FACTOR/this.scaleFactor;this.safeEnv=new jsts.geom.Envelope(this.originalPt.x-safeTolerance,this.originalPt.x+safeTolerance,this.originalPt.y-safeTolerance,this.originalPt.y+safeTolerance);} return this.safeEnv;};jsts.noding.snapround.HotPixel.prototype.initCorners=function(pt){var tolerance=0.5;this.minx=pt.x-tolerance;this.maxx=pt.x+tolerance;this.miny=pt.y-tolerance;this.maxy=pt.y+tolerance;this.corner[0]=new jsts.geom.Coordinate(this.maxx,this.maxy);this.corner[1]=new jsts.geom.Coordinate(this.minx,this.maxy);this.corner[2]=new jsts.geom.Coordinate(this.minx,this.miny);this.corner[3]=new jsts.geom.Coordinate(this.maxx,this.miny);};jsts.noding.snapround.HotPixel.prototype.scale=function(val){return Math.round(val*this.scaleFactor);};jsts.noding.snapround.HotPixel.prototype.intersects=function(p0,p1){if(this.scaleFactor===1.0) return this.intersectsScaled(p0,p1);this.copyScaled(p0,this.p0Scaled);this.copyScaled(p1,this.p1Scaled);return this.intersectsScaled(this.p0Scaled,this.p1Scaled);};jsts.noding.snapround.HotPixel.prototype.copyScaled=function(p,pScaled){pScaled.x=this.scale(p.x);pScaled.y=this.scale(p.y);};jsts.noding.snapround.HotPixel.prototype.intersectsScaled=function(p0,p1){var segMinx=Math.min(p0.x,p1.x);var segMaxx=Math.max(p0.x,p1.x);var segMiny=Math.min(p0.y,p1.y);var segMaxy=Math.max(p0.y,p1.y);var isOutsidePixelEnv=this.maxxsegMaxx||this.maxysegMaxy;if(isOutsidePixelEnv) return false;var intersects=this.intersectsToleranceSquare(p0,p1);jsts.util.Assert.isTrue(!(isOutsidePixelEnv&&intersects),'Found bad envelope test');return intersects;};jsts.noding.snapround.HotPixel.prototype.intersectsToleranceSquare=function(p0,p1){var intersectsLeft=false;var intersectsBottom=false;this.li.computeIntersection(p0,p1,this.corner[0],this.corner[1]);if(this.li.isProper()) return true;this.li.computeIntersection(p0,p1,this.corner[1],this.corner[2]);if(this.li.isProper()) return true;if(this.li.hasIntersection()) intersectsLeft=true;this.li.computeIntersection(p0,p1,this.corner[2],this.corner[3]);if(this.li.isProper()) return true;if(this.li.hasIntersection()) intersectsBottom=true;this.li.computeIntersection(p0,p1,this.corner[3],this.corner[0]);if(this.li.isProper()) return true;if(intersectsLeft&&intersectsBottom) return true;if(p0.equals(this.pt)) return true;if(p1.equals(this.pt)) return true;return false;};jsts.noding.snapround.HotPixel.prototype.intersectsPixelClosure=function(p0,p1){this.li.computeIntersection(p0,p1,this.corner[0],this.corner[1]);if(this.li.hasIntersection()) return true;this.li.computeIntersection(p0,p1,this.corner[1],this.corner[2]);if(this.li.hasIntersection()) return true;this.li.computeIntersection(p0,p1,this.corner[2],this.corner[3]);if(this.li.hasIntersection()) return true;this.li.computeIntersection(p0,p1,this.corner[3],this.corner[0]);if(this.li.hasIntersection()) return true;return false;};jsts.noding.snapround.HotPixel.prototype.addSnappedNode=function(segStr,segIndex){var p0=segStr.getCoordinate(segIndex);var p1=segStr.getCoordinate(segIndex+1);if(this.intersects(p0,p1)){segStr.addIntersection(this.getCoordinate(),segIndex);return true;} return false;};jsts.operation.buffer.BufferInputLineSimplifier=function(inputLine){this.inputLine=inputLine;};jsts.operation.buffer.BufferInputLineSimplifier.simplify=function(inputLine,distanceTol){var simp=new jsts.operation.buffer.BufferInputLineSimplifier(inputLine);return simp.simplify(distanceTol);};jsts.operation.buffer.BufferInputLineSimplifier.INIT=0;jsts.operation.buffer.BufferInputLineSimplifier.DELETE=1;jsts.operation.buffer.BufferInputLineSimplifier.KEEP=1;jsts.operation.buffer.BufferInputLineSimplifier.prototype.inputLine=null;jsts.operation.buffer.BufferInputLineSimplifier.prototype.distanceTol=null;jsts.operation.buffer.BufferInputLineSimplifier.prototype.isDeleted=null;jsts.operation.buffer.BufferInputLineSimplifier.prototype.angleOrientation=jsts.algorithm.CGAlgorithms.COUNTERCLOCKWISE;jsts.operation.buffer.BufferInputLineSimplifier.prototype.simplify=function(distanceTol){this.distanceTol=Math.abs(distanceTol);if(distanceTol<0) this.angleOrientation=jsts.algorithm.CGAlgorithms.CLOCKWISE;this.isDeleted=[];this.isDeleted.length=this.inputLine.length;var isChanged=false;do{isChanged=this.deleteShallowConcavities();}while(isChanged);return this.collapseLine();};jsts.operation.buffer.BufferInputLineSimplifier.prototype.deleteShallowConcavities=function(){var index=1;var maxIndex=this.inputLine.length-1;var midIndex=this.findNextNonDeletedIndex(index);var lastIndex=this.findNextNonDeletedIndex(midIndex);var isChanged=false;while(lastIndexpe.xValue){return 1;} if(this.eventTypepe.eventType){return 1;} return 0;};jsts.geom.CoordinateList=function(coord,allowRepeated){this.array=[];allowRepeated=(allowRepeated===undefined)?true:allowRepeated;if(coord!==undefined){this.add(coord,allowRepeated);}};jsts.geom.CoordinateList.prototype=new javascript.util.ArrayList();jsts.geom.CoordinateList.prototype.iterator=null;jsts.geom.CoordinateList.prototype.remove=null;jsts.geom.CoordinateList.prototype.get=function(i){return this.array[i];};jsts.geom.CoordinateList.prototype.set=function(i,e){var o=this.array[i];this.array[i]=e;return o;};jsts.geom.CoordinateList.prototype.size=function(){return this.array.length;};jsts.geom.CoordinateList.prototype.add=function(){if(arguments.length>1){return this.addCoordinates.apply(this,arguments);}else{return this.array.push(arguments[0]);}};jsts.geom.CoordinateList.prototype.addCoordinates=function(coord,allowRepeated,direction){if(coord instanceof jsts.geom.Coordinate){return this.addCoordinate.apply(this,arguments);}else if(typeof coord==='number'){return this.insertCoordinate.apply(this,arguments);} direction=direction||true;if(direction){for(var i=0;i=0;i--){this.addCoordinate(coord[i],allowRepeated);}} return true;};jsts.geom.CoordinateList.prototype.addCoordinate=function(coord,allowRepeated){if(!allowRepeated){if(this.size()>=1){var last=this.get(this.size()-1);if(last.equals2D(coord))return;}} this.add(coord);};jsts.geom.CoordinateList.prototype.insertCoordinate=function(index,coord,allowRepeated){if(!allowRepeated){var before=index>0?index-1:-1;if(before!==-1&&this.get(before).equals2D(coord)){return;} var after=index0){this.addCoordinate(new jsts.geom.Coordinate(this.get(0)),false);}};jsts.geom.CoordinateList.prototype.toArray=function(){return this.array;};jsts.geom.CoordinateList.prototype.toCoordinateArray=function(){return this.array;};jsts.operation.buffer.OffsetSegmentGenerator=function(precisionModel,bufParams,distance){this.seg0=new jsts.geom.LineSegment();this.seg1=new jsts.geom.LineSegment();this.offset0=new jsts.geom.LineSegment();this.offset1=new jsts.geom.LineSegment();this.precisionModel=precisionModel;this.bufParams=bufParams;this.li=new jsts.algorithm.RobustLineIntersector();this.filletAngleQuantum=Math.PI/2.0/bufParams.getQuadrantSegments();if(this.bufParams.getQuadrantSegments()>=8&&this.bufParams.getJoinStyle()===jsts.operation.buffer.BufferParameters.JOIN_ROUND){this.closingSegLengthFactor=jsts.operation.buffer.OffsetSegmentGenerator.MAX_CLOSING_SEG_LEN_FACTOR;} this.init(distance);};jsts.operation.buffer.OffsetSegmentGenerator.OFFSET_SEGMENT_SEPARATION_FACTOR=1.0E-3;jsts.operation.buffer.OffsetSegmentGenerator.INSIDE_TURN_VERTEX_SNAP_DISTANCE_FACTOR=1.0E-3;jsts.operation.buffer.OffsetSegmentGenerator.CURVE_VERTEX_SNAP_DISTANCE_FACTOR=1.0E-6;jsts.operation.buffer.OffsetSegmentGenerator.MAX_CLOSING_SEG_LEN_FACTOR=80;jsts.operation.buffer.OffsetSegmentGenerator.prototype.maxCurveSegmentError=0.0;jsts.operation.buffer.OffsetSegmentGenerator.prototype.filletAngleQuantum=null;jsts.operation.buffer.OffsetSegmentGenerator.prototype.closingSegLengthFactor=1;jsts.operation.buffer.OffsetSegmentGenerator.prototype.segList=null;jsts.operation.buffer.OffsetSegmentGenerator.prototype.distance=0.0;jsts.operation.buffer.OffsetSegmentGenerator.prototype.precisionModel=null;jsts.operation.buffer.OffsetSegmentGenerator.prototype.bufParams=null;jsts.operation.buffer.OffsetSegmentGenerator.prototype.li=null;jsts.operation.buffer.OffsetSegmentGenerator.prototype.s0=null;jsts.operation.buffer.OffsetSegmentGenerator.prototype.s1=null;jsts.operation.buffer.OffsetSegmentGenerator.prototype.s2=null;jsts.operation.buffer.OffsetSegmentGenerator.prototype.seg0=null;jsts.operation.buffer.OffsetSegmentGenerator.prototype.seg1=null;jsts.operation.buffer.OffsetSegmentGenerator.prototype.offset0=null;jsts.operation.buffer.OffsetSegmentGenerator.prototype.offset1=null;jsts.operation.buffer.OffsetSegmentGenerator.prototype.side=0;jsts.operation.buffer.OffsetSegmentGenerator.prototype.hasNarrowConcaveAngle=false;jsts.operation.buffer.OffsetSegmentGenerator.prototype.hasNarrowConcaveAngle=function(){return this.hasNarrowConcaveAngle;};jsts.operation.buffer.OffsetSegmentGenerator.prototype.init=function(distance){this.distance=distance;this.maxCurveSegmentError=this.distance*(1-Math.cos(this.filletAngleQuantum/2.0));this.segList=new jsts.operation.buffer.OffsetSegmentString();this.segList.setPrecisionModel(this.precisionModel);this.segList.setMinimumVertexDistance(this.distance*jsts.operation.buffer.OffsetSegmentGenerator.CURVE_VERTEX_SNAP_DISTANCE_FACTOR);};jsts.operation.buffer.OffsetSegmentGenerator.prototype.initSideSegments=function(s1,s2,side){this.s1=s1;this.s2=s2;this.side=side;this.seg1.setCoordinates(this.s1,this.s2);this.computeOffsetSegment(this.seg1,this.side,this.distance,this.offset1);};jsts.operation.buffer.OffsetSegmentGenerator.prototype.getCoordinates=function(){return this.segList.getCoordinates();};jsts.operation.buffer.OffsetSegmentGenerator.prototype.closeRing=function(){this.segList.closeRing();};jsts.operation.buffer.OffsetSegmentGenerator.prototype.addSegments=function(pt,isForward){this.segList.addPts(pt,isForward);};jsts.operation.buffer.OffsetSegmentGenerator.prototype.addFirstSegment=function(){this.segList.addPt(this.offset1.p0);};jsts.operation.buffer.OffsetSegmentGenerator.prototype.addLastSegment=function(){this.segList.addPt(this.offset1.p1);};jsts.operation.buffer.OffsetSegmentGenerator.prototype.addNextSegment=function(p,addStartPoint){this.s0=this.s1;this.s1=this.s2;this.s2=p;this.seg0.setCoordinates(this.s0,this.s1);this.computeOffsetSegment(this.seg0,this.side,this.distance,this.offset0);this.seg1.setCoordinates(this.s1,this.s2);this.computeOffsetSegment(this.seg1,this.side,this.distance,this.offset1);if(this.s1.equals(this.s2)) return;var orientation=jsts.algorithm.CGAlgorithms.computeOrientation(this.s0,this.s1,this.s2);var outsideTurn=(orientation===jsts.algorithm.CGAlgorithms.CLOCKWISE&&this.side===jsts.geomgraph.Position.LEFT)||(orientation===jsts.algorithm.CGAlgorithms.COUNTERCLOCKWISE&&this.side===jsts.geomgraph.Position.RIGHT);if(orientation==0){this.addCollinear(addStartPoint);}else if(outsideTurn){this.addOutsideTurn(orientation,addStartPoint);}else{this.addInsideTurn(orientation,addStartPoint);}};jsts.operation.buffer.OffsetSegmentGenerator.prototype.addCollinear=function(addStartPoint){this.li.computeIntersection(this.s0,this.s1,this.s1,this.s2);var numInt=this.li.getIntersectionNum();if(numInt>=2){if(this.bufParams.getJoinStyle()===jsts.operation.buffer.BufferParameters.JOIN_BEVEL||this.bufParams.getJoinStyle()===jsts.operation.buffer.BufferParameters.JOIN_MITRE){if(addStartPoint) this.segList.addPt(this.offset0.p1);this.segList.addPt(this.offset1.p0);}else{this.addFillet(this.s1,this.offset0.p1,this.offset1.p0,jsts.algorithm.CGAlgorithms.CLOCKWISE,this.distance);}}};jsts.operation.buffer.OffsetSegmentGenerator.prototype.addOutsideTurn=function(orientation,addStartPoint){if(this.offset0.p1.distance(this.offset1.p0)0){var mid0=new jsts.geom.Coordinate((this.closingSegLengthFactor*this.offset0.p1.x+this.s1.x)/(this.closingSegLengthFactor+1),(this.closingSegLengthFactor*this.offset0.p1.y+this.s1.y)/(this.closingSegLengthFactor+1));this.segList.addPt(mid0);var mid1=new jsts.geom.Coordinate((this.closingSegLengthFactor*this.offset1.p0.x+this.s1.x)/(this.closingSegLengthFactor+1),(this.closingSegLengthFactor*this.offset1.p0.y+this.s1.y)/(this.closingSegLengthFactor+1));this.segList.addPt(mid1);}else{this.segList.addPt(this.s1);} this.segList.addPt(this.offset1.p0);}}};jsts.operation.buffer.OffsetSegmentGenerator.prototype.computeOffsetSegment=function(seg,side,distance,offset){var sideSign=side===jsts.geomgraph.Position.LEFT?1:-1;var dx=seg.p1.x-seg.p0.x;var dy=seg.p1.y-seg.p0.y;var len=Math.sqrt(dx*dx+dy*dy);var ux=sideSign*distance*dx/len;var uy=sideSign*distance*dy/len;offset.p0.x=seg.p0.x-uy;offset.p0.y=seg.p0.y+ux;offset.p1.x=seg.p1.x-uy;offset.p1.y=seg.p1.y+ux;};jsts.operation.buffer.OffsetSegmentGenerator.prototype.addLineEndCap=function(p0,p1){var seg=new jsts.geom.LineSegment(p0,p1);var offsetL=new jsts.geom.LineSegment();this.computeOffsetSegment(seg,jsts.geomgraph.Position.LEFT,this.distance,offsetL);var offsetR=new jsts.geom.LineSegment();this.computeOffsetSegment(seg,jsts.geomgraph.Position.RIGHT,this.distance,offsetR);var dx=p1.x-p0.x;var dy=p1.y-p0.y;var angle=Math.atan2(dy,dx);switch(this.bufParams.getEndCapStyle()){case jsts.operation.buffer.BufferParameters.CAP_ROUND:this.segList.addPt(offsetL.p1);this.addFillet(p1,angle+Math.PI/2,angle-Math.PI/2,jsts.algorithm.CGAlgorithms.CLOCKWISE,this.distance);this.segList.addPt(offsetR.p1);break;case jsts.operation.buffer.BufferParameters.CAP_FLAT:this.segList.addPt(offsetL.p1);this.segList.addPt(offsetR.p1);break;case jsts.operation.buffer.BufferParameters.CAP_SQUARE:var squareCapSideOffset=new jsts.geom.Coordinate();squareCapSideOffset.x=Math.abs(this.distance)*Math.cos(angle);squareCapSideOffset.y=Math.abs(this.distance)*Math.sin(angle);var squareCapLOffset=new jsts.geom.Coordinate(offsetL.p1.x+ squareCapSideOffset.x,offsetL.p1.y+squareCapSideOffset.y);var squareCapROffset=new jsts.geom.Coordinate(offsetR.p1.x+ squareCapSideOffset.x,offsetR.p1.y+squareCapSideOffset.y);this.segList.addPt(squareCapLOffset);this.segList.addPt(squareCapROffset);break;}};jsts.operation.buffer.OffsetSegmentGenerator.prototype.addMitreJoin=function(p,offset0,offset1,distance){var isMitreWithinLimit=true;var intPt=null;try{intPt=jsts.algorithm.HCoordinate.intersection(offset0.p0,offset0.p1,offset1.p0,offset1.p1);var mitreRatio=distance<=0.0?1.0:intPt.distance(p)/Math.abs(distance);if(mitreRatio>this.bufParams.getMitreLimit()) this.isMitreWithinLimit=false;}catch(e){if(e instanceof jsts.error.NotRepresentableError){intPt=new jsts.geom.Coordinate(0,0);this.isMitreWithinLimit=false;}} if(isMitreWithinLimit){this.segList.addPt(intPt);}else{this.addLimitedMitreJoin(offset0,offset1,distance,bufParams.getMitreLimit());}};jsts.operation.buffer.OffsetSegmentGenerator.prototype.addLimitedMitreJoin=function(offset0,offset1,distance,mitreLimit){var basePt=this.seg0.p1;var ang0=jsts.algorithm.Angle.angle(basePt,this.seg0.p0);var ang1=jsts.algorithm.Angle.angle(basePt,this.seg1.p1);var angDiff=jsts.algorithm.Angle.angleBetweenOriented(this.seg0.p0,basePt,this.seg1.p1);var angDiffHalf=angDiff/2;var midAng=jsts.algorithm.Angle.normalize(ang0+angDiffHalf);var mitreMidAng=jsts.algorithm.Angle.normalize(midAng+Math.PI);var mitreDist=mitreLimit*distance;var bevelDelta=mitreDist*Math.abs(Math.sin(angDiffHalf));var bevelHalfLen=distance-bevelDelta;var bevelMidX=basePt.x+mitreDist*Math.cos(mitreMidAng);var bevelMidY=basePt.y+mitreDist*Math.sin(mitreMidAng);var bevelMidPt=new jsts.geom.Coordinate(bevelMidX,bevelMidY);var mitreMidLine=new jsts.geom.LineSegment(basePt,bevelMidPt);var bevelEndLeft=mitreMidLine.pointAlongOffset(1.0,bevelHalfLen);var bevelEndRight=mitreMidLine.pointAlongOffset(1.0,-bevelHalfLen);if(this.side==jsts.geomgraph.Position.LEFT){this.segList.addPt(bevelEndLeft);this.segList.addPt(bevelEndRight);}else{this.segList.addPt(bevelEndRight);this.segList.addPt(bevelEndLeft);}};jsts.operation.buffer.OffsetSegmentGenerator.prototype.addBevelJoin=function(offset0,offset1){this.segList.addPt(offset0.p1);this.segList.addPt(offset1.p0);};jsts.operation.buffer.OffsetSegmentGenerator.prototype.addFillet=function(p,p0,p1,direction,radius){if(!(p1 instanceof jsts.geom.Coordinate)){this.addFillet2.apply(this,arguments);return;} var dx0=p0.x-p.x;var dy0=p0.y-p.y;var startAngle=Math.atan2(dy0,dx0);var dx1=p1.x-p.x;var dy1=p1.y-p.y;var endAngle=Math.atan2(dy1,dx1);if(direction===jsts.algorithm.CGAlgorithms.CLOCKWISE){if(startAngle<=endAngle) startAngle+=2.0*Math.PI;}else{if(startAngle>=endAngle) startAngle-=2.0*Math.PI;} this.segList.addPt(p0);this.addFillet(p,startAngle,endAngle,direction,radius);this.segList.addPt(p1);};jsts.operation.buffer.OffsetSegmentGenerator.prototype.addFillet2=function(p,startAngle,endAngle,direction,radius){var directionFactor=direction===jsts.algorithm.CGAlgorithms.CLOCKWISE?-1:1;var totalAngle=Math.abs(startAngle-endAngle);var nSegs=parseInt((totalAngle/this.filletAngleQuantum+0.5));if(nSegs<1) return;var initAngle,currAngleInc;initAngle=0.0;currAngleInc=totalAngle/nSegs;var currAngle=initAngle;var pt=new jsts.geom.Coordinate();while(currAnglex2){return x1;} return x2;};jsts.geomgraph.index.MonotoneChainEdge.prototype.computeIntersects=function(mce,si){for(var i=0;i=iPrev) pPrev=eiPrev.coord;var label=new jsts.geomgraph.Label(edge.getLabel());label.flip();var e=new jsts.geomgraph.EdgeEnd(edge,eiCurr.coord,pPrev,label);l.add(e);};jsts.operation.relate.EdgeEndBuilder.prototype.createEdgeEndForNext=function(edge,l,eiCurr,eiNext){var iNext=eiCurr.segmentIndex+1;if(iNext>=edge.getNumPoints()&&eiNext===null) return;var pNext=edge.getCoordinate(iNext);if(eiNext!==null&&eiNext.segmentIndex===eiCurr.segmentIndex) pNext=eiNext.coord;var e=new jsts.geomgraph.EdgeEnd(edge,eiCurr.coord,pNext,new jsts.geomgraph.Label(edge.getLabel()));l.add(e);};})();(function(){var ArrayList=javascript.util.ArrayList;var TreeSet=javascript.util.TreeSet;var CoordinateFilter=jsts.geom.CoordinateFilter;jsts.util.UniqueCoordinateArrayFilter=function(){this.treeSet=new TreeSet();this.list=new ArrayList();};jsts.util.UniqueCoordinateArrayFilter.prototype=new CoordinateFilter();jsts.util.UniqueCoordinateArrayFilter.prototype.treeSet=null;jsts.util.UniqueCoordinateArrayFilter.prototype.list=null;jsts.util.UniqueCoordinateArrayFilter.prototype.getCoordinates=function(){return this.list.toArray();};jsts.util.UniqueCoordinateArrayFilter.prototype.filter=function(coord){if(!this.treeSet.contains(coord)){this.list.add(coord);this.treeSet.add(coord);}};})();(function(){var CGAlgorithms=jsts.algorithm.CGAlgorithms;var UniqueCoordinateArrayFilter=jsts.util.UniqueCoordinateArrayFilter;var Assert=jsts.util.Assert;var Stack=javascript.util.Stack;var ArrayList=javascript.util.ArrayList;var Arrays=javascript.util.Arrays;var RadialComparator=function(origin){this.origin=origin;};RadialComparator.prototype.origin=null;RadialComparator.prototype.compare=function(o1,o2){var p1=o1;var p2=o2;return RadialComparator.polarCompare(this.origin,p1,p2);};RadialComparator.polarCompare=function(o,p,q){var dxp=p.x-o.x;var dyp=p.y-o.y;var dxq=q.x-o.x;var dyq=q.y-o.y;var orient=CGAlgorithms.computeOrientation(o,p,q);if(orient==CGAlgorithms.COUNTERCLOCKWISE) return 1;if(orient==CGAlgorithms.CLOCKWISE) return-1;var op=dxp*dxp+dyp*dyp;var oq=dxq*dxq+dyq*dyq;if(opoq){return 1;} return 0;};jsts.algorithm.ConvexHull=function(){if(arguments.length===1){var geometry=arguments[0];this.inputPts=jsts.algorithm.ConvexHull.extractCoordinates(geometry);this.geomFactory=geometry.getFactory();}else{this.pts=arguments[0];this.geomFactory=arguments[1];}};jsts.algorithm.ConvexHull.prototype.geomFactory=null;jsts.algorithm.ConvexHull.prototype.inputPts=null;jsts.algorithm.ConvexHull.extractCoordinates=function(geom){var filter=new UniqueCoordinateArrayFilter();geom.apply(filter);return filter.getCoordinates();};jsts.algorithm.ConvexHull.prototype.getConvexHull=function(){if(this.inputPts.length==0){return this.geomFactory.createGeometryCollection(null);} if(this.inputPts.length==1){return this.geomFactory.createPoint(this.inputPts[0]);} if(this.inputPts.length==2){return this.geomFactory.createLineString(this.inputPts);} var reducedPts=this.inputPts;if(this.inputPts.length>50){reducedPts=this.reduce(this.inputPts);} var sortedPts=this.preSort(reducedPts);var cHS=this.grahamScan(sortedPts);var cH=cHS.toArray();return this.lineOrPolygon(cH);};jsts.algorithm.ConvexHull.prototype.reduce=function(inputPts){var polyPts=this.computeOctRing(inputPts);if(polyPts==null) return this.inputPts;var reducedSet=new javascript.util.TreeSet();for(var i=0;i0){p=ps.pop();} p=ps.push(p);p=ps.push(c[i]);} p=ps.push(c[0]);return ps;};jsts.algorithm.ConvexHull.prototype.isBetween=function(c1,c2,c3){if(CGAlgorithms.computeOrientation(c1,c2,c3)!==0){return false;} if(c1.x!=c3.x){if(c1.x<=c2.x&&c2.x<=c3.x){return true;} if(c3.x<=c2.x&&c2.x<=c1.x){return true;}} if(c1.y!=c3.y){if(c1.y<=c2.y&&c2.y<=c3.y){return true;} if(c3.y<=c2.y&&c2.y<=c1.y){return true;}} return false;};jsts.algorithm.ConvexHull.prototype.computeOctRing=function(inputPts){var octPts=this.computeOctPts(inputPts);var coordList=new jsts.geom.CoordinateList();coordList.add(octPts,false);if(coordList.size()<3){return null;} coordList.closeRing();return coordList.toCoordinateArray();};jsts.algorithm.ConvexHull.prototype.computeOctPts=function(inputPts){var pts=[];for(var j=0;j<8;j++){pts[j]=inputPts[0];} for(var i=1;ipts[2].y){pts[2]=inputPts[i];} if(inputPts[i].x+inputPts[i].y>pts[3].x+pts[3].y){pts[3]=inputPts[i];} if(inputPts[i].x>pts[4].x){pts[4]=inputPts[i];} if(inputPts[i].x-inputPts[i].y>pts[5].x-pts[5].y){pts[5]=inputPts[i];} if(inputPts[i].y=pts.length){index=0;} return index;};jsts.algorithm.MinimumDiameter.computeC=function(a,b,p){return a*p.y-b*p.x;};jsts.algorithm.MinimumDiameter.computeSegmentForLine=function(a,b,c){var p0;var p1;if(Math.abs(b)>Math.abs(a)){p0=new jsts.geom.Coordinate(0,c/b);p1=new jsts.geom.Coordinate(1,c/b-a/b);} else{p0=new jsts.geom.Coordinate(c/a,0);p1=new jsts.geom.Coordinate(c/a-b/a,1);} return new jsts.geom.LineSegment(p0,p1);};jsts.algorithm.MinimumDiameter.prototype.getLength=function(){this.computeMinimumDiameter();return this.minWidth;};jsts.algorithm.MinimumDiameter.prototype.getWidthCoordinate=function(){this.computeMinimumDiameter();return this.minWidthPt;};jsts.algorithm.MinimumDiameter.prototype.getSupportingSegment=function(){this.computeMinimumDiameter();var coord=[this.minBaseSeg.p0,this.minBaseSeg.p1];return jsts.algorithm.MinimumDiameter.inputGeom.getFactory().createLineString(coord);};jsts.algorithm.MinimumDiameter.prototype.getDiameter=function(){this.computeMinimumDiameter();if(this.minWidthPt===null){return jsts.algorithm.MinimumDiameter.inputGeom.getFactory().createLineString(null);} var basePt=this.minBaseSeg.project(this.minWidthPt);return jsts.algorithm.MinimumDiameter.inputGeom.getFactory().createLineString([basePt,this.minWidthPt]);};jsts.algorithm.MinimumDiameter.prototype.computeMinimumDiameter=function(){if(this.minWidthPt!==null){return;} if(jsts.algorithm.MinimumDiameter.isConvex) this.computeWidthConvex(jsts.algorithm.MinimumDiameter.inputGeom);else{var convexGeom=new jsts.algorithm.ConvexHull(jsts.algorithm.MinimumDiameter.inputGeom).getConvexHull();this.computeWidthConvex(convexGeom);}};jsts.algorithm.MinimumDiameter.prototype.computeWidthConvex=function(convexGeom){if(convexGeom instanceof jsts.geom.Polygon){this.convexHullPts=convexGeom.getExteriorRing().getCoordinates();}else{this.convexHullPts=convexGeom.getCoordinates();} if(this.convexHullPts.length===0){this.minWidth=0;this.minWidthPt=null;this.minBaseSeg=null;}else if(this.convexHullPts.length===1){this.minWidth=0;this.minWidthPt=this.convexHullPts[0];this.minBaseSeg.p0=this.convexHullPts[0];this.minBaseSeg.p1=this.convexHullPts[0];}else if(this.convexHullPts.length===2||this.convexHullPts.length===3){this.minWidth=0;this.minWidthPt=this.convexHullPts[0];this.minBaseSeg.p0=this.convexHullPts[0];this.minBaseSeg.p1=this.convexHullPts[1];}else{this.computeConvexRingMinDiameter(this.convexHullPts);}};jsts.algorithm.MinimumDiameter.prototype.computeConvexRingMinDiameter=function(pts){this.minWidth=Number.MAX_VALUE;var currMaxIndex=1;var seg=new jsts.geom.LineSegment();for(var i=0;i=maxPerpDistance){maxPerpDistance=nextPerpDistance;maxIndex=nextIndex;nextIndex=jsts.algorithm.MinimumDiameter.nextIndex(pts,maxIndex);nextPerpDistance=seg.distancePerpendicular(pts[nextIndex]);} if(maxPerpDistancemaxPara)maxPara=paraC;if(paraCmaxPerp)maxPerp=perpC;if(perpC0.0){return jsts.triangulate.quadedge.Vertex.LEFT;} if(sa<0.0){return jsts.triangulate.quadedge.Vertex.RIGHT;} if((a.getX()*b.getX()<0.0)||(a.getY()*b.getY()<0.0)){return jsts.triangulate.quadedge.Vertex.BEHIND;} if(a.magn()0);};jsts.triangulate.quadedge.Vertex.prototype.rightOf=function(e){return this.isCCW(e.dest(),e.orig());};jsts.triangulate.quadedge.Vertex.prototype.leftOf=function(e){return this.isCCW(e.orig(),e.dest());};jsts.triangulate.quadedge.Vertex.prototype.bisector=function(a,b){var dx,dy,l1,l2;dx=b.getX()-a.getX();dy=b.getY()-a.getY();l1=new jsts.algorithm.HCoordinate(a.getX()+(dx/2.0),a.getY()+ (dy/2.0),1.0);l2=new jsts.algorithm.HCoordinate(a.getX()-dy+(dx/2.0),a.getY()+ dx+(dy/2.0),1.0);return new jsts.algorithm.HCoordinate(l1,l2);};jsts.triangulate.quadedge.Vertex.prototype.distance=function(v1,v2){return v1.p.distance(v2.p);};jsts.triangulate.quadedge.Vertex.prototype.circumRadiusRatio=function(b,c){var x,radius,edgeLength,el;x=this.circleCenter(b,c);radius=this.distance(x,b);edgeLength=this.distance(this,b);el=this.distance(b,c);if(el=1){pt=ring.getCoordinateN(0);} this.validErr=new jsts.operation.valid.TopologyValidationError(jsts.operation.valid.TopologyValidationError.RING_NOT_CLOSED,pt);}};jsts.operation.valid.IsValidOp.prototype.checkTooFewPoints=function(graph){if(graph.hasTooFewPoints){this.validErr=new jsts.operation.valid.TopologyValidationError(jsts.operation.valid.TopologyValidationError.TOO_FEW_POINTS,graph.getInvalidPoint());return;}};jsts.operation.valid.IsValidOp.prototype.checkConsistentArea=function(graph){var cat=new jsts.operation.valid.ConsistentAreaTester(graph);var isValidArea=cat.isNodeConsistentArea();if(!isValidArea){this.validErr=new jsts.operation.valid.TopologyValidationError(jsts.operation.valid.TopologyValidationError.SELF_INTERSECTION,cat.getInvalidPoint());return;} if(cat.hasDuplicateRings()){this.validErr=new jsts.operation.valid.TopologyValidationError(jsts.operation.valid.TopologyValidationError.DUPLICATE_RINGS,cat.getInvalidPoint());}};jsts.operation.valid.IsValidOp.prototype.checkNoSelfIntersectingRings=function(graph){for(var i=graph.getEdgeIterator();i.hasNext();){var e=i.next();this.checkNoSelfIntersectingRing(e.getEdgeIntersectionList());if(this.validErr!=null){return;}}};jsts.operation.valid.IsValidOp.prototype.checkNoSelfIntersectingRing=function(eiList){var nodeSet=[];var isFirst=true;for(var i=eiList.iterator();i.hasNext();){var ei=i.next();if(isFirst){isFirst=false;continue;} if(nodeSet.indexOf(ei.coord)>=0){this.validErr=new jsts.operation.valid.TopologyValidationError(jsts.operation.valid.TopologyValidationError.RING_SELF_INTERSECTION,ei.coord);return;}else{nodeSet.push(ei.coord);}}};jsts.operation.valid.IsValidOp.prototype.checkHolesInShell=function(p,graph){var shell=p.getExteriorRing();var pir=new jsts.algorithm.MCPointInRing(shell);for(var i=0;i0){if(x2>0){return-sign;} else{return sign;}} else{if(x2>0){return sign;} else{return-sign;}}} if((y1===0.0)||(x2===0.0)){if(y2>0){if(x1>0){return sign;} else{return-sign;}} else{if(x1>0){return-sign;} else{return sign;}}} if(0.0y2){sign=-sign;swap=x1;x1=x2;x2=swap;swap=y1;y1=y2;y2=swap;}} else{if(y1<=-y2){sign=-sign;x2=-x2;y2=-y2;} else{swap=x1;x1=-x2;x2=swap;swap=y1;y1=-y2;y2=swap;}}} else{if(0.0=y2){x1=-x1;y1=-y1;x2=-x2;y2=-y2;} else{sign=-sign;swap=-x1;x1=-x2;x2=swap;swap=-y1;y1=-y2;y2=swap;}}} if(0.0x2){return sign;}} else{return sign;}} else{if(0.0=x2){sign=-sign;x1=-x1;x2=-x2;} else{return-sign;}}} while(true){count=count+1;k=Math.floor(x2/x1);x2=x2-k*x1;y2=y2-k*y1;if(y2<0.0){return-sign;} if(y2>y1){return sign;} if(x1>x2+x2){if(y1y2+y2){return-sign;} else{x2=x1-x2;y2=y1-y2;sign=-sign;}} if(y2===0.0){if(x2===0.0){return 0;} else{return-sign;}} if(x2===0.0){return sign;} k=Math.floor(x1/x2);x1=x1-k*x2;y1=y1-k*y2;if(y1<0.0){return sign;} if(y1>y2){return-sign;} if(x2>x1+x1){if(y2y1+y1){return sign;} else{x1=x2-x1;y1=y2-y1;sign=-sign;}} if(y1===0.0){if(x1===0.0){return 0;} else{return sign;}} if(x1===0.0){return-sign;}}};jsts.algorithm.RobustDeterminant.orientationIndex=function(p1,p2,q){var dx1=p2.x-p1.x;var dy1=p2.y-p1.y;var dx2=q.x-p2.x;var dy2=q.y-p2.y;return jsts.algorithm.RobustDeterminant.signOfDet2x2(dx1,dy1,dx2,dy2);};jsts.index.quadtree.NodeBase=function(){this.subnode=new Array(4);this.subnode[0]=null;this.subnode[1]=null;this.subnode[2]=null;this.subnode[3]=null;this.items=[];};jsts.index.quadtree.NodeBase.prototype.getSubnodeIndex=function(env,centre){var subnodeIndex=-1;if(env.getMinX()>=centre.x){if(env.getMinY()>=centre.y){subnodeIndex=3;} if(env.getMaxY()<=centre.y){subnodeIndex=1;}} if(env.getMaxX()<=centre.x){if(env.getMinY()>=centre.y){subnodeIndex=2;} if(env.getMaxY()<=centre.y){subnodeIndex=0;}} return subnodeIndex;};jsts.index.quadtree.NodeBase.prototype.getItems=function(){return this.items;};jsts.index.quadtree.NodeBase.prototype.hasItems=function(){return(this.items.length>0);};jsts.index.quadtree.NodeBase.prototype.add=function(item){this.items.push(item);};jsts.index.quadtree.NodeBase.prototype.remove=function(itemEnv,item){if(!this.isSearchMatch(itemEnv)){return false;} var found=false,i=0;for(i;i<4;i++){if(this.subnode[i]!==null){found=this.subnode[i].remove(itemEnv,item);if(found){if(this.subnode[i].isPrunable()){this.subnode[i]=null;} break;}}} if(found){return found;} if(this.items.indexOf(item)!==-1){for(var i=this.items.length-1;i>=0;i--){if(this.items[i]===item){this.items.splice(i,1);}} found=true;} return found;};jsts.index.quadtree.NodeBase.prototype.isPrunable=function(){return!(this.hasChildren()||this.hasItems());};jsts.index.quadtree.NodeBase.prototype.hasChildren=function(){var i=0;for(i;i<4;i++){if(this.subnode[i]!==null){return true;}} return false;};jsts.index.quadtree.NodeBase.prototype.isEmpty=function(){var isEmpty=true;if(this.items.length>0){isEmpty=false;} var i=0;for(i;i<4;i++){if(this.subnode[i]!==null){if(!this.subnode[i].isEmpty()){isEmpty=false;}}} return isEmpty;};jsts.index.quadtree.NodeBase.prototype.addAllItems=function(resultItems){resultItems=resultItems.concat(this.items);var i=0;for(i;i<4;i++){if(this.subnode[i]!==null){resultItems=this.subnode[i].addAllItems(resultItems);}} return resultItems;};jsts.index.quadtree.NodeBase.prototype.addAllItemsFromOverlapping=function(searchEnv,resultItems){if(!this.isSearchMatch(searchEnv)){return;} resultItems=resultItems.concat(this.items);var i=0;for(i;i<4;i++){if(this.subnode[i]!==null){resultItems=this.subnode[i].addAllItemsFromOverlapping(searchEnv,resultItems);}}};jsts.index.quadtree.NodeBase.prototype.visit=function(searchEnv,visitor){if(!this.isSearchMatch(searchEnv)){return;} this.visitItems(searchEnv,visitor);var i=0;for(i;i<4;i++){if(this.subnode[i]!==null){this.subnode[i].visit(searchEnv,visitor);}}};jsts.index.quadtree.NodeBase.prototype.visitItems=function(env,visitor){var i=0,il=this.items.length;for(i;imaxSubDepth){maxSubDepth=sqd;}}} return maxSubDepth+1;};jsts.index.quadtree.NodeBase.prototype.size=function(){var subSize=0,i=0;for(i;i<4;i++){if(this.subnode[i]!==null){subSize+=this.subnode[i].size();}} return subSize+this.items.length;};jsts.index.quadtree.NodeBase.prototype.getNodeCount=function(){var subSize=0,i=0;for(i;i<4;i++){if(this.subnode[i]!==null){subSize+=this.subnode[i].size();}} return subSize+1;};jsts.index.quadtree.Node=function(env,level){jsts.index.quadtree.NodeBase.prototype.constructor.apply(this,arguments);this.env=env;this.level=level;this.centre=new jsts.geom.Coordinate();this.centre.x=(env.getMinX()+env.getMaxX())/2;this.centre.y=(env.getMinY()+env.getMaxY())/2;};jsts.index.quadtree.Node.prototype=new jsts.index.quadtree.NodeBase();jsts.index.quadtree.Node.createNode=function(env){var key,node;key=new jsts.index.quadtree.Key(env);node=new jsts.index.quadtree.Node(key.getEnvelope(),key.getLevel());return node;};jsts.index.quadtree.Node.createExpanded=function(node,addEnv){var expandEnv=new jsts.geom.Envelope(addEnv),largerNode;if(node!==null){expandEnv.expandToInclude(node.env);} largerNode=jsts.index.quadtree.Node.createNode(expandEnv);if(node!==null){largerNode.insertNode(node);} return largerNode;};jsts.index.quadtree.Node.prototype.getEnvelope=function(){return this.env;};jsts.index.quadtree.Node.prototype.isSearchMatch=function(searchEnv){return this.env.intersects(searchEnv);};jsts.index.quadtree.Node.prototype.getNode=function(searchEnv){var subnodeIndex=this.getSubnodeIndex(searchEnv,this.centre),node;if(subnodeIndex!==-1){node=this.getSubnode(subnodeIndex);return node.getNode(searchEnv);}else{return this;}};jsts.index.quadtree.Node.prototype.find=function(searchEnv){var subnodeIndex=this.getSubnodeIndex(searchEnv,this.centre),node;if(subnodeIndex===-1){return this;} if(this.subnode[subnodeIndex]!==null){node=this.subnode[subnodeIndex];return node.find(searchEnv);} return this;};jsts.index.quadtree.Node.prototype.insertNode=function(node){var index=this.getSubnodeIndex(node.env,this.centre),childNode;if(node.level===this.level-1){this.subnode[index]=node;}else{childNode=this.createSubnode(index);childNode.insertNode(node);this.subnode[index]=childNode;}};jsts.index.quadtree.Node.prototype.getSubnode=function(index){if(this.subnode[index]===null){this.subnode[index]=this.createSubnode(index);} return this.subnode[index];};jsts.index.quadtree.Node.prototype.createSubnode=function(index){var minx=0.0,maxx=0.0,miny=0.0,maxy=0.0,sqEnv,node;switch(index){case 0:minx=this.env.getMinX();maxx=this.centre.x;miny=this.env.getMinY();maxy=this.centre.y;break;case 1:minx=this.centre.x;maxx=this.env.getMaxX();miny=this.env.getMinY();maxy=this.centre.y;break;case 2:minx=this.env.getMinX();maxx=this.centre.x;miny=this.centre.y;maxy=this.env.getMaxY();break;case 3:minx=this.centre.x;maxx=this.env.getMaxX();miny=this.centre.y;maxy=this.env.getMaxY();break;} sqEnv=new jsts.geom.Envelope(minx,maxx,miny,maxy);node=new jsts.index.quadtree.Node(sqEnv,this.level-1);return node;};(function(){jsts.triangulate.quadedge.QuadEdge=function(){this.rot=null;this.vertex=null;this.next=null;this.data=null;};var QuadEdge=jsts.triangulate.quadedge.QuadEdge;jsts.triangulate.quadedge.QuadEdge.makeEdge=function(o,d){var q0,q1,q2,q3,base;q0=new QuadEdge();q1=new QuadEdge();q2=new QuadEdge();q3=new QuadEdge();q0.rot=q1;q1.rot=q2;q2.rot=q3;q3.rot=q0;q0.setNext(q0);q1.setNext(q3);q2.setNext(q2);q3.setNext(q1);base=q0;base.setOrig(o);base.setDest(d);return base;};jsts.triangulate.quadedge.QuadEdge.connect=function(a,b){var e=QuadEdge.makeEdge(a.dest(),b.orig());QuadEdge.splice(e,a.lNext());QuadEdge.splice(e.sym(),b);return e;};jsts.triangulate.quadedge.QuadEdge.splice=function(a,b){var alpha,beta,t1,t2,t3,t4;alpha=a.oNext().rot;beta=b.oNext().rot;t1=b.oNext();t2=a.oNext();t3=beta.oNext();t4=alpha.oNext();a.setNext(t1);b.setNext(t2);alpha.setNext(t3);beta.setNext(t4);};jsts.triangulate.quadedge.QuadEdge.swap=function(e){var a,b;a=e.oPrev();b=e.sym().oPrev();QuadEdge.splice(e,a);QuadEdge.splice(e.sym(),b);QuadEdge.splice(e,a.lNext());QuadEdge.splice(e.sym(),b.lNext());e.setOrig(a.dest());e.setDest(b.dest());};jsts.triangulate.quadedge.QuadEdge.prototype.getPrimary=function(){if(this.orig().getCoordinate().compareTo(this.dest().getCoordinate())<=0){return this;} else{return this.sym();}};jsts.triangulate.quadedge.QuadEdge.prototype.setData=function(data){this.data=data;};jsts.triangulate.quadedge.QuadEdge.prototype.getData=function(){return this.data;};jsts.triangulate.quadedge.QuadEdge.prototype.delete_jsts=function(){this.rot=null;};jsts.triangulate.quadedge.QuadEdge.prototype.isLive=function(){return this.rot!==null;};jsts.triangulate.quadedge.QuadEdge.prototype.setNext=function(next){this.next=next;};jsts.triangulate.quadedge.QuadEdge.prototype.invRot=function(){return this.rot.sym();};jsts.triangulate.quadedge.QuadEdge.prototype.sym=function(){return this.rot.rot;};jsts.triangulate.quadedge.QuadEdge.prototype.oNext=function(){return this.next;};jsts.triangulate.quadedge.QuadEdge.prototype.oPrev=function(){return this.rot.next.rot;};jsts.triangulate.quadedge.QuadEdge.prototype.dNext=function(){return this.sym().oNext().sym();};jsts.triangulate.quadedge.QuadEdge.prototype.dPrev=function(){return this.invRot().oNext().invRot();};jsts.triangulate.quadedge.QuadEdge.prototype.lNext=function(){return this.invRot().oNext().rot;};jsts.triangulate.quadedge.QuadEdge.prototype.lPrev=function(){return this.next.sym();};jsts.triangulate.quadedge.QuadEdge.prototype.rNext=function(){return this.rot.next.invRot();};jsts.triangulate.quadedge.QuadEdge.prototype.rPrev=function(){return this.sym().oNext();};jsts.triangulate.quadedge.QuadEdge.prototype.setOrig=function(o){this.vertex=o;};jsts.triangulate.quadedge.QuadEdge.prototype.setDest=function(d){this.sym().setOrig(d);};jsts.triangulate.quadedge.QuadEdge.prototype.orig=function(){return this.vertex;};jsts.triangulate.quadedge.QuadEdge.prototype.dest=function(){return this.sym().orig();};jsts.triangulate.quadedge.QuadEdge.prototype.getLength=function(){return this.orig().getCoordinate().distance(dest().getCoordinate());};jsts.triangulate.quadedge.QuadEdge.prototype.equalsNonOriented=function(qe){if(this.equalsOriented(qe)){return true;} if(this.equalsOriented(qe.sym())){return true;} return false;};jsts.triangulate.quadedge.QuadEdge.prototype.equalsOriented=function(qe){if(this.orig().getCoordinate().equals2D(qe.orig().getCoordinate())&&this.dest().getCoordinate().equals2D(qe.dest().getCoordinate())){return true;} return false;};jsts.triangulate.quadedge.QuadEdge.prototype.toLineSegment=function() {return new jsts.geom.LineSegment(this.vertex.getCoordinate(),this.dest().getCoordinate());};jsts.triangulate.quadedge.QuadEdge.prototype.toString=function(){var p0,p1;p0=this.vertex.getCoordinate();p1=this.dest().getCoordinate();return jsts.io.WKTWriter.toLineString(p0,p1);};})();(function(){var Assert=jsts.util.Assert;jsts.geomgraph.EdgeEnd=function(edge,p0,p1,label){this.edge=edge;if(p0&&p1){this.init(p0,p1);} if(label){this.label=label||null;}};jsts.geomgraph.EdgeEnd.prototype.edge=null;jsts.geomgraph.EdgeEnd.prototype.label=null;jsts.geomgraph.EdgeEnd.prototype.node=null;jsts.geomgraph.EdgeEnd.prototype.p0=null;jsts.geomgraph.EdgeEnd.prototype.p1=null;jsts.geomgraph.EdgeEnd.prototype.dx=null;jsts.geomgraph.EdgeEnd.prototype.dy=null;jsts.geomgraph.EdgeEnd.prototype.quadrant=null;jsts.geomgraph.EdgeEnd.prototype.init=function(p0,p1){this.p0=p0;this.p1=p1;this.dx=p1.x-p0.x;this.dy=p1.y-p0.y;this.quadrant=jsts.geomgraph.Quadrant.quadrant(this.dx,this.dy);Assert.isTrue(!(this.dx===0&&this.dy===0),'EdgeEnd with identical endpoints found');};jsts.geomgraph.EdgeEnd.prototype.getEdge=function(){return this.edge;};jsts.geomgraph.EdgeEnd.prototype.getLabel=function(){return this.label;};jsts.geomgraph.EdgeEnd.prototype.getCoordinate=function(){return this.p0;};jsts.geomgraph.EdgeEnd.prototype.getDirectedCoordinate=function(){return this.p1;};jsts.geomgraph.EdgeEnd.prototype.getQuadrant=function(){return this.quadrant;};jsts.geomgraph.EdgeEnd.prototype.getDx=function(){return this.dx;};jsts.geomgraph.EdgeEnd.prototype.getDy=function(){return this.dy;};jsts.geomgraph.EdgeEnd.prototype.setNode=function(node){this.node=node;};jsts.geomgraph.EdgeEnd.prototype.getNode=function(){return this.node;};jsts.geomgraph.EdgeEnd.prototype.compareTo=function(e){return this.compareDirection(e);};jsts.geomgraph.EdgeEnd.prototype.compareDirection=function(e){if(this.dx===e.dx&&this.dy===e.dy) return 0;if(this.quadrant>e.quadrant) return 1;if(this.quadrant0&&this.minIndexthis.minCoord.y&&pNext.y>this.minCoord.y&&orientation===jsts.algorithm.CGAlgorithms.CLOCKWISE){usePrev=true;} if(usePrev){this.minIndex=this.minIndex-1;}};jsts.operation.buffer.RightmostEdgeFinder.prototype.checkForRightmostCoordinate=function(de){var coord=de.getEdge().getCoordinates();for(var i=0;ithis.minCoord.x){this.minDe=de;this.minIndex=i;this.minCoord=coord[i];}}};jsts.operation.buffer.RightmostEdgeFinder.prototype.getRightmostSide=function(de,index){var side=this.getRightmostSideOfSegment(de,index);if(side<0) side=this.getRightmostSideOfSegment(de,index-1);if(side<0){this.minCoord=null;this.checkForRightmostCoordinate(de);} return side;};jsts.operation.buffer.RightmostEdgeFinder.prototype.getRightmostSideOfSegment=function(de,i){var e=de.getEdge();var coord=e.getCoordinates();if(i<0||i+1>=coord.length) return-1;if(coord[i].y==coord[i+1].y) return-1;var pos=jsts.geomgraph.Position.LEFT;if(coord[i].y0.0;};jsts.triangulate.IncrementalDelaunayTriangulator.prototype.insertSites=function(vertices){var i=0,il=vertices.length,v;for(i;i0.0){cent.x=this.cg3.x/3/this.areasum2;cent.y=this.cg3.y/3/this.areasum2;}else{cent.x=this.centSum.x/this.totalLength;cent.y=this.centSum.y/this.totalLength;} return cent;};jsts.algorithm.CentroidArea.prototype.setBasePoint=function(basePt){if(this.basePt==null) this.basePt=basePt;};jsts.algorithm.CentroidArea.prototype.add3=function(poly){this.addShell(poly.getExteriorRing().getCoordinates());for(var i=0;ix2){return x1;} return x2;};jsts.geomgraph.index.SweepLineSegment.prototype.computeIntersections=function(ss,si){si.addIntersections(this.edge,this.ptIndex,ss.edge,ss.ptIndex);};jsts.index.quadtree.Root=function(){jsts.index.quadtree.NodeBase.prototype.constructor.apply(this,arguments);this.origin=new jsts.geom.Coordinate(0.0,0.0);};jsts.index.quadtree.Root.prototype=new jsts.index.quadtree.NodeBase();jsts.index.quadtree.Root.prototype.insert=function(itemEnv,item){var index=this.getSubnodeIndex(itemEnv,this.origin);if(index===-1){this.add(item);return;} var node=this.subnode[index];if(node===null||!node.getEnvelope().contains(itemEnv)){var largerNode=jsts.index.quadtree.Node.createExpanded(node,itemEnv);this.subnode[index]=largerNode;} this.insertContained(this.subnode[index],itemEnv,item);};jsts.index.quadtree.Root.prototype.insertContained=function(tree,itemEnv,item){var isZeroX,isZeroY,node;isZeroX=jsts.index.IntervalSize.isZeroWidth(itemEnv.getMinX(),itemEnv.getMaxX());isZeroY=jsts.index.IntervalSize.isZeroWidth(itemEnv.getMinY(),itemEnv.getMaxY());if(isZeroX||isZeroY){node=tree.find(itemEnv);}else{node=tree.getNode(itemEnv);} node.add(item);};jsts.index.quadtree.Root.prototype.isSearchMatch=function(searchEnv){return true;};jsts.geomgraph.index.MonotoneChainIndexer=function(){};jsts.geomgraph.index.MonotoneChainIndexer.toIntArray=function(list){var array=[];for(var i=list.iterator();i.hasNext();){var element=i.next();array.push(element);} return array;};jsts.geomgraph.index.MonotoneChainIndexer.prototype.getChainStartIndices=function(pts){var start=0;var startIndexList=new javascript.util.ArrayList();startIndexList.add(start);do{var last=this.findChainEnd(pts,start);startIndexList.add(last);start=last;}while(start=list.length){return null;} return list[index];};jsts.operation.union.CascadedPolygonUnion.prototype.reduceToGeometries=function(geomTree){var geoms=[];for(var i=0,l=geomTree.length;i=0;i--){segGen.addNextSegment(simp2[i],true);} segGen.addLastSegment();segGen.addLineEndCap(simp2[1],simp2[0]);segGen.closeRing();};jsts.operation.buffer.OffsetCurveBuilder.prototype.computeSingleSidedBufferCurve=function(inputPts,isRightSide,segGen){var distTol=jsts.operation.buffer.OffsetCurveBuilder.simplifyTolerance(this.distance);if(isRightSide){segGen.addSegments(inputPts,true);var simp2=jsts.operation.buffer.BufferInputLineSimplifier.simplify(inputPts,-distTol);var n2=simp2.length-1;segGen.initSideSegments(simp2[n2],simp2[n2-1],jsts.geomgraph.Position.LEFT);segGen.addFirstSegment();for(var i=n2-2;i>=0;i--){segGen.addNextSegment(simp2[i],true);}}else{segGen.addSegments(inputPts,false);var simp1=jsts.operation.buffer.BufferInputLineSimplifier.simplify(inputPts,distTol);var n1=simp1.length-1;segGen.initSideSegments(simp1[0],simp1[1],jsts.geomgraph.Position.LEFT);segGen.addFirstSegment();for(var i=2;i<=n1;i++){segGen.addNextSegment(simp1[i],true);}} segGen.addLastSegment();segGen.closeRing();};jsts.operation.buffer.OffsetCurveBuilder.prototype.computeOffsetCurve=function(inputPts,isRightSide,segGen){var distTol=jsts.operation.buffer.OffsetCurveBuilder.simplifyTolerance(this.distance);if(isRightSide){var simp2=jsts.operation.buffer.BufferInputLineSimplifier.simplify(inputPts,-distTol);var n2=simp2.length-1;segGen.initSideSegments(simp2[n2],simp2[n2-1],jsts.geomgraph.Position.LEFT);segGen.addFirstSegment();for(var i=n2-2;i>=0;i--){segGen.addNextSegment(simp2[i],true);}}else{var simp1=jsts.operation.buffer.BufferInputLineSimplifier.simplify(inputPts,distTol);var n1=simp1.length-1;segGen.initSideSegments(simp1[0],simp1[1],jsts.geomgraph.Position.LEFT);segGen.addFirstSegment();for(var i=2;i<=n1;i++){segGen.addNextSegment(simp1[i],true);}} segGen.addLastSegment();};jsts.operation.buffer.OffsetCurveBuilder.prototype.computeRingBufferCurve=function(inputPts,side,segGen){var distTol=jsts.operation.buffer.OffsetCurveBuilder.simplifyTolerance(this.distance);if(side===jsts.geomgraph.Position.RIGHT) distTol=-distTol;var simp=jsts.operation.buffer.BufferInputLineSimplifier.simplify(inputPts,distTol);var n=simp.length-1;segGen.initSideSegments(simp[n-1],simp[0],side);for(var i=1;i<=n;i++){var addStartPoint=i!==1;segGen.addNextSegment(simp[i],addStartPoint);} segGen.closeRing();};(function(){var HotPixelSnapAction=function(hotPixel,parentEdge,vertexIndex){this.hotPixel=hotPixel;this.parentEdge=parentEdge;this.vertexIndex=vertexIndex;};HotPixelSnapAction.prototype=new jsts.index.chain.MonotoneChainSelectAction();HotPixelSnapAction.constructor=HotPixelSnapAction;HotPixelSnapAction.prototype.hotPixel=null;HotPixelSnapAction.prototype.parentEdge=null;HotPixelSnapAction.prototype.vertexIndex=null;HotPixelSnapAction.prototype._isNodeAdded=false;HotPixelSnapAction.prototype.isNodeAdded=function(){return this._isNodeAdded;};HotPixelSnapAction.prototype.select=function(mc,startIndex){var ss=mc.getContext();if(this.parentEdge!==null){if(ss===this.parentEdge&&startIndex===this.vertexIndex) return;} this._isNodeAdded=this.hotPixel.addSnappedNode(ss,startIndex);};jsts.noding.snapround.MCIndexPointSnapper=function(index){this.index=index;};jsts.noding.snapround.MCIndexPointSnapper.prototype.index=null;jsts.noding.snapround.MCIndexPointSnapper.prototype.snap=function(hotPixel,parentEdge,vertexIndex){if(arguments.length===1){this.snap2.apply(this,arguments);return;} var pixelEnv=hotPixel.getSafeEnvelope();var hotPixelSnapAction=new HotPixelSnapAction(hotPixel,parentEdge,vertexIndex);this.index.query(pixelEnv,{visitItem:function(testChain){testChain.select(pixelEnv,hotPixelSnapAction);}});return hotPixelSnapAction.isNodeAdded();};jsts.noding.snapround.MCIndexPointSnapper.prototype.snap2=function(hotPixel){return this.snap(hotPixel,null,-1);};})();(function(){var NodeBase=function(){this.items=new javascript.util.ArrayList();this.subnode=[null,null];};NodeBase.getSubnodeIndex=function(interval,centre){var subnodeIndex=-1;if(interval.min>=centre){subnodeIndex=1;} if(interval.max<=centre){subnodeIndex=0;} return subnodeIndex;};NodeBase.prototype.getItems=function(){return this.items;};NodeBase.prototype.add=function(item){this.items.add(item);};NodeBase.prototype.addAllItems=function(items){items.addAll(this.items);var i=0,il=2;for(i;imaxSubDepth){maxSubDepth=sqd;}}} return maxSubDepth+1;};NodeBase.prototype.size=function(){var subSize=0,i=0,il=2;for(i;i=0.0){if(dy>=0.0) return jsts.geomgraph.Quadrant.NE;else return jsts.geomgraph.Quadrant.SE;}else{if(dy>=0.0) return jsts.geomgraph.Quadrant.NW;else return jsts.geomgraph.Quadrant.SW;}};jsts.geomgraph.Quadrant.quadrant2=function(p0,p1){if(p1.x===p0.x&&p1.y===p0.y) throw new jsts.error.IllegalArgumentError('Cannot compute the quadrant for two identical points '+p0);if(p1.x>=p0.x){if(p1.y>=p0.y) return jsts.geomgraph.Quadrant.NE;else return jsts.geomgraph.Quadrant.SE;}else{if(p1.y>=p0.y) return jsts.geomgraph.Quadrant.NW;else return jsts.geomgraph.Quadrant.SW;}};jsts.geomgraph.Quadrant.isOpposite=function(quad1,quad2){if(quad1===quad2) return false;var diff=(quad1-quad2+4)%4;if(diff===2) return true;return false;};jsts.geomgraph.Quadrant.commonHalfPlane=function(quad1,quad2){if(quad1===quad2) return quad1;var diff=(quad1-quad2+4)%4;if(diff===2) return-1;var min=(quad1quad2)?quad1:quad2;if(min===0&&max===3) return 3;return min;};jsts.geomgraph.Quadrant.isInHalfPlane=function(quad,halfPlane){if(halfPlane===jsts.geomgraph.Quadrant.SE){return quad===jsts.geomgraph.Quadrant.SE||quad===jsts.geomgraph.Quadrant.SW;} return quad===halfPlane||quad===halfPlane+1;};jsts.geomgraph.Quadrant.isNorthern=function(quad){return quad===jsts.geomgraph.Quadrant.NE||quad===jsts.geomgraph.Quadrant.NW;};jsts.operation.valid.ConsistentAreaTester=function(geomGraph){this.geomGraph=geomGraph;this.li=new jsts.algorithm.RobustLineIntersector();this.nodeGraph=new jsts.operation.relate.RelateNodeGraph();this.invalidPoint=null;};jsts.operation.valid.ConsistentAreaTester.prototype.getInvalidPoint=function(){return this.invalidPoint;};jsts.operation.valid.ConsistentAreaTester.prototype.isNodeConsistentArea=function(){var intersector=this.geomGraph.computeSelfNodes(this.li,true);if(intersector.hasProperIntersection()){this.invalidPoint=intersector.getProperIntersectionPoint();return false;} this.nodeGraph.build(this.geomGraph);return this.isNodeEdgeAreaLabelsConsistent();};jsts.operation.valid.ConsistentAreaTester.prototype.isNodeEdgeAreaLabelsConsistent=function(){for(var nodeIt=this.nodeGraph.getNodeIterator();nodeIt.hasNext();){var node=nodeIt.next();if(!node.getEdges().isAreaLabelsConsistent(this.geomGraph)){this.invalidPoint=node.getCoordinate().clone();return false;}} return true;};jsts.operation.valid.ConsistentAreaTester.prototype.hasDuplicateRings=function(){for(var nodeIt=this.nodeGraph.getNodeIterator();nodeIt.hasNext();){var node=nodeIt.next();for(var i=node.getEdges().iterator();i.hasNext();){var eeb=i.next();if(eeb.getEdgeEnds().length>1){invalidPoint=eeb.getEdge().getCoordinate(0);return true;}}} return false;};jsts.operation.relate.RelateNode=function(coord,edges){jsts.geomgraph.Node.apply(this,arguments);};jsts.operation.relate.RelateNode.prototype=new jsts.geomgraph.Node();jsts.operation.relate.RelateNode.prototype.computeIM=function(im){im.setAtLeastIfValid(this.label.getLocation(0),this.label.getLocation(1),0);};jsts.operation.relate.RelateNode.prototype.updateIMFromEdges=function(im){this.edges.updateIM(im);};(function(){var Location=jsts.geom.Location;var Position=jsts.geomgraph.Position;var EdgeEnd=jsts.geomgraph.EdgeEnd;jsts.geomgraph.DirectedEdge=function(edge,isForward){EdgeEnd.call(this,edge);this.depth=[0,-999,-999];this._isForward=isForward;if(isForward){this.init(edge.getCoordinate(0),edge.getCoordinate(1));}else{var n=edge.getNumPoints()-1;this.init(edge.getCoordinate(n),edge.getCoordinate(n-1));} this.computeDirectedLabel();};jsts.geomgraph.DirectedEdge.prototype=new EdgeEnd();jsts.geomgraph.DirectedEdge.constructor=jsts.geomgraph.DirectedEdge;jsts.geomgraph.DirectedEdge.depthFactor=function(currLocation,nextLocation){if(currLocation===Location.EXTERIOR&&nextLocation===Location.INTERIOR) return 1;else if(currLocation===Location.INTERIOR&&nextLocation===Location.EXTERIOR) return-1;return 0;};jsts.geomgraph.DirectedEdge.prototype._isForward=null;jsts.geomgraph.DirectedEdge.prototype._isInResult=false;jsts.geomgraph.DirectedEdge.prototype._isVisited=false;jsts.geomgraph.DirectedEdge.prototype.sym=null;jsts.geomgraph.DirectedEdge.prototype.next=null;jsts.geomgraph.DirectedEdge.prototype.nextMin=null;jsts.geomgraph.DirectedEdge.prototype.edgeRing=null;jsts.geomgraph.DirectedEdge.prototype.minEdgeRing=null;jsts.geomgraph.DirectedEdge.prototype.depth=null;jsts.geomgraph.DirectedEdge.prototype.getEdge=function(){return this.edge;};jsts.geomgraph.DirectedEdge.prototype.setInResult=function(isInResult){this._isInResult=isInResult;};jsts.geomgraph.DirectedEdge.prototype.isInResult=function(){return this._isInResult;};jsts.geomgraph.DirectedEdge.prototype.isVisited=function(){return this._isVisited;};jsts.geomgraph.DirectedEdge.prototype.setVisited=function(isVisited){this._isVisited=isVisited;};jsts.geomgraph.DirectedEdge.prototype.setEdgeRing=function(edgeRing){this.edgeRing=edgeRing;};jsts.geomgraph.DirectedEdge.prototype.getEdgeRing=function(){return this.edgeRing;};jsts.geomgraph.DirectedEdge.prototype.setMinEdgeRing=function(minEdgeRing){this.minEdgeRing=minEdgeRing;};jsts.geomgraph.DirectedEdge.prototype.getMinEdgeRing=function(){return this.minEdgeRing;};jsts.geomgraph.DirectedEdge.prototype.getDepth=function(position){return this.depth[position];};jsts.geomgraph.DirectedEdge.prototype.setDepth=function(position,depthVal){if(this.depth[position]!==-999){if(this.depth[position]!==depthVal) throw new jsts.error.TopologyError('assigned depths do not match',this.getCoordinate());} this.depth[position]=depthVal;};jsts.geomgraph.DirectedEdge.prototype.getDepthDelta=function(){var depthDelta=this.edge.getDepthDelta();if(!this._isForward) depthDelta=-depthDelta;return depthDelta;};jsts.geomgraph.DirectedEdge.prototype.setVisitedEdge=function(isVisited){this.setVisited(isVisited);this.sym.setVisited(isVisited);};jsts.geomgraph.DirectedEdge.prototype.getSym=function(){return this.sym;};jsts.geomgraph.DirectedEdge.prototype.isForward=function(){return this._isForward;};jsts.geomgraph.DirectedEdge.prototype.setSym=function(de){this.sym=de;};jsts.geomgraph.DirectedEdge.prototype.getNext=function(){return this.next;};jsts.geomgraph.DirectedEdge.prototype.setNext=function(next){this.next=next;};jsts.geomgraph.DirectedEdge.prototype.getNextMin=function(){return this.nextMin;};jsts.geomgraph.DirectedEdge.prototype.setNextMin=function(nextMin){this.nextMin=nextMin;};jsts.geomgraph.DirectedEdge.prototype.isLineEdge=function(){var isLine=this.label.isLine(0)||this.label.isLine(1);var isExteriorIfArea0=!this.label.isArea(0)||this.label.allPositionsEqual(0,Location.EXTERIOR);var isExteriorIfArea1=!this.label.isArea(1)||this.label.allPositionsEqual(1,Location.EXTERIOR);return isLine&&isExteriorIfArea0&&isExteriorIfArea1;};jsts.geomgraph.DirectedEdge.prototype.isInteriorAreaEdge=function(){var isInteriorAreaEdge=true;for(var i=0;i<2;i++){if(!(this.label.isArea(i)&&this.label.getLocation(i,Position.LEFT)===Location.INTERIOR&&this.label.getLocation(i,Position.RIGHT)===Location.INTERIOR)){isInteriorAreaEdge=false;}} return isInteriorAreaEdge;};jsts.geomgraph.DirectedEdge.prototype.computeDirectedLabel=function(){this.label=new jsts.geomgraph.Label(this.edge.getLabel());if(!this._isForward) this.label.flip();};jsts.geomgraph.DirectedEdge.prototype.setEdgeDepths=function(position,depth){var depthDelta=this.getEdge().getDepthDelta();if(!this._isForward) depthDelta=-depthDelta;var directionFactor=1;if(position===Position.LEFT) directionFactor=-1;var oppositePos=Position.opposite(position);var delta=depthDelta*directionFactor;var oppositeDepth=depth+delta;this.setDepth(position,depth);this.setDepth(oppositePos,oppositeDepth);};})();jsts.operation.distance.DistanceOp=function(g0,g1,terminateDistance){this.ptLocator=new jsts.algorithm.PointLocator();this.geom=[];this.geom[0]=g0;this.geom[1]=g1;this.terminateDistance=terminateDistance;};jsts.operation.distance.DistanceOp.prototype.geom=null;jsts.operation.distance.DistanceOp.prototype.terminateDistance=0.0;jsts.operation.distance.DistanceOp.prototype.ptLocator=null;jsts.operation.distance.DistanceOp.prototype.minDistanceLocation=null;jsts.operation.distance.DistanceOp.prototype.minDistance=Number.MAX_VALUE;jsts.operation.distance.DistanceOp.distance=function(g0,g1){var distOp=new jsts.operation.distance.DistanceOp(g0,g1,0.0);return distOp.distance();};jsts.operation.distance.DistanceOp.isWithinDistance=function(g0,g1,distance){var distOp=new jsts.operation.distance.DistanceOp(g0,g1,distance);return distOp.distance()<=distance;};jsts.operation.distance.DistanceOp.nearestPoints=function(g0,g1){var distOp=new jsts.operation.distance.DistanceOp(g0,g1,0.0);return distOp.nearestPoints();};jsts.operation.distance.DistanceOp.prototype.distance=function(){if(this.geom[0]===null||this.geom[1]===null) throw new jsts.error.IllegalArgumentError('null geometries are not supported');if(this.geom[0].isEmpty()||this.geom[1].isEmpty()) return 0.0;this.computeMinDistance();return this.minDistance;};jsts.operation.distance.DistanceOp.prototype.nearestPoints=function(){this.computeMinDistance();var nearestPts=[this.minDistanceLocation[0].getCoordinate(),this.minDistanceLocation[1].getCoordinate()];return nearestPts;};jsts.operation.distance.DistanceOp.prototype.nearestLocations=function(){this.computeMinDistance();return this.minDistanceLocation;};jsts.operation.distance.DistanceOp.prototype.updateMinDistance=function(locGeom,flip){if(locGeom[0]===null) return;if(flip){this.minDistanceLocation[0]=locGeom[1];this.minDistanceLocation[1]=locGeom[0];}else{this.minDistanceLocation[0]=locGeom[0];this.minDistanceLocation[1]=locGeom[1];}};jsts.operation.distance.DistanceOp.prototype.computeMinDistance=function(){if(arguments.length>0){this.computeMinDistance2.apply(this,arguments);return;} if(this.minDistanceLocation!==null) return;this.minDistanceLocation=[];this.computeContainmentDistance();if(this.minDistance<=this.terminateDistance) return;this.computeFacetDistance();};jsts.operation.distance.DistanceOp.prototype.computeContainmentDistance=function(){if(arguments.length===2){this.computeContainmentDistance2.apply(this,arguments);return;}else if(arguments.length===3&&(!arguments[0]instanceof jsts.operation.distance.GeometryLocation)){this.computeContainmentDistance3.apply(this,arguments);return;}else if(arguments.length===3){this.computeContainmentDistance4.apply(this,arguments);return;} var locPtPoly=[];this.computeContainmentDistance2(0,locPtPoly);if(this.minDistance<=this.terminateDistance) return;this.computeContainmentDistance2(1,locPtPoly);};jsts.operation.distance.DistanceOp.prototype.computeContainmentDistance2=function(polyGeomIndex,locPtPoly){var locationsIndex=1-polyGeomIndex;var polys=jsts.geom.util.PolygonExtracter.getPolygons(this.geom[polyGeomIndex]);if(polys.length>0){var insideLocs=jsts.operation.distance.ConnectedElementLocationFilter.getLocations(this.geom[locationsIndex]);this.computeContainmentDistance3(insideLocs,polys,locPtPoly);if(this.minDistance<=this.terminateDistance){this.minDistanceLocation[locationsIndex]=locPtPoly[0];this.minDistanceLocation[polyGeomIndex]=locPtPoly[1];return;}}};jsts.operation.distance.DistanceOp.prototype.computeContainmentDistance3=function(locs,polys,locPtPoly){for(var i=0;ithis.minDistance){return;} var coord0=line0.getCoordinates();var coord1=line1.getCoordinates();for(var i=0;ithis.minDistance){return;} var coord0=line.getCoordinates();var coord=pt.getCoordinate();for(var i=0;i0){return this.isNull2.apply(this,arguments);} for(var i=0;i<2;i++){for(var j=0;j<3;j++){if(this.depth[i][j]!==jsts.geomgraph.Depth.NULL_VALUE) return false;}} return true;};jsts.geomgraph.Depth.prototype.isNull2=function(geomIndex){if(arguments.length>1){return this.isNull3.apply(this,arguments);} return this.depth[geomIndex][1]==jsts.geomgraph.Depth.NULL_VALUE;};jsts.geomgraph.Depth.prototype.isNull3=function(geomIndex,posIndex){return this.depth[geomIndex][posIndex]==jsts.geomgraph.Depth.NULL_VALUE;};jsts.geomgraph.Depth.prototype.add=function(lbl){for(var i=0;i<2;i++){for(var j=1;j<3;j++){var loc=lbl.getLocation(i,j);if(loc===Location.EXTERIOR||loc===Location.INTERIOR){if(this.isNull(i,j)){this.depth[i][j]=jsts.geomgraph.Depth.depthAtLocation(loc);}else this.depth[i][j]+=jsts.geomgraph.Depth.depthAtLocation(loc);}}}};jsts.geomgraph.Depth.prototype.getDelta=function(geomIndex){return this.depth[geomIndex][Position.RIGHT]- this.depth[geomIndex][Position.LEFT];};jsts.geomgraph.Depth.prototype.normalize=function(){for(var i=0;i<2;i++){if(!this.isNull(i)){var minDepth=this.depth[i][1];if(this.depth[i][2]minDepth) newValue=1;this.depth[i][j]=newValue;}}}};jsts.geomgraph.Depth.prototype.toString=function(){return'A: '+this.depth[0][1]+','+this.depth[0][2]+' B: '+ this.depth[1][1]+','+this.depth[1][2];};})();jsts.algorithm.BoundaryNodeRule=function(){};jsts.algorithm.BoundaryNodeRule.prototype.isInBoundary=function(boundaryCount){throw new jsts.error.AbstractMethodInvocationError();};jsts.algorithm.Mod2BoundaryNodeRule=function(){};jsts.algorithm.Mod2BoundaryNodeRule.prototype=new jsts.algorithm.BoundaryNodeRule();jsts.algorithm.Mod2BoundaryNodeRule.prototype.isInBoundary=function(boundaryCount){return boundaryCount%2===1;};jsts.algorithm.BoundaryNodeRule.MOD2_BOUNDARY_RULE=new jsts.algorithm.Mod2BoundaryNodeRule();jsts.algorithm.BoundaryNodeRule.OGC_SFS_BOUNDARY_RULE=jsts.algorithm.BoundaryNodeRule.MOD2_BOUNDARY_RULE;jsts.operation.distance.GeometryLocation=function(component,segIndex,pt){this.component=component;this.segIndex=segIndex;this.pt=pt;};jsts.operation.distance.GeometryLocation.INSIDE_AREA=-1;jsts.operation.distance.GeometryLocation.prototype.component=null;jsts.operation.distance.GeometryLocation.prototype.segIndex=null;jsts.operation.distance.GeometryLocation.prototype.pt=null;jsts.operation.distance.GeometryLocation.prototype.getGeometryComponent=function(){return this.component;};jsts.operation.distance.GeometryLocation.prototype.getSegmentIndex=function(){return this.segIndex;};jsts.operation.distance.GeometryLocation.prototype.getCoordinate=function(){return this.pt;};jsts.operation.distance.GeometryLocation.prototype.isInsideArea=function(){return this.segIndex===jsts.operation.distance.GeometryLocation.INSIDE_AREA;};jsts.geom.util.PointExtracter=function(pts){this.pts=pts;};jsts.geom.util.PointExtracter.prototype=new jsts.geom.GeometryFilter();jsts.geom.util.PointExtracter.prototype.pts=null;jsts.geom.util.PointExtracter.getPoints=function(geom,list){if(list===undefined){list=[];} if(geom instanceof jsts.geom.Point){list.push(geom);}else if(geom instanceof jsts.geom.GeometryCollection||geom instanceof jsts.geom.MultiPoint||geom instanceof jsts.geom.MultiLineString||geom instanceof jsts.geom.MultiPolygon){geom.apply(new jsts.geom.util.PointExtracter(list));} return list;};jsts.geom.util.PointExtracter.prototype.filter=function(geom){if(geom instanceof jsts.geom.Point) this.pts.push(geom);};(function(){var Location=jsts.geom.Location;jsts.operation.relate.RelateNodeGraph=function(){this.nodes=new jsts.geomgraph.NodeMap(new jsts.operation.relate.RelateNodeFactory());};jsts.operation.relate.RelateNodeGraph.prototype.nodes=null;jsts.operation.relate.RelateNodeGraph.prototype.build=function(geomGraph){this.computeIntersectionNodes(geomGraph,0);this.copyNodesAndLabels(geomGraph,0);var eeBuilder=new jsts.operation.relate.EdgeEndBuilder();var eeList=eeBuilder.computeEdgeEnds(geomGraph.getEdgeIterator());this.insertEdgeEnds(eeList);};jsts.operation.relate.RelateNodeGraph.prototype.computeIntersectionNodes=function(geomGraph,argIndex){for(var edgeIt=geomGraph.getEdgeIterator();edgeIt.hasNext();){var e=edgeIt.next();var eLoc=e.getLabel().getLocation(argIndex);for(var eiIt=e.getEdgeIntersectionList().iterator();eiIt.hasNext();){var ei=eiIt.next();var n=this.nodes.addNode(ei.coord);if(eLoc===Location.BOUNDARY) n.setLabelBoundary(argIndex);else{if(n.getLabel().isNull(argIndex)) n.setLabel(argIndex,Location.INTERIOR);}}}};jsts.operation.relate.RelateNodeGraph.prototype.copyNodesAndLabels=function(geomGraph,argIndex){for(var nodeIt=geomGraph.getNodeIterator();nodeIt.hasNext();){var graphNode=nodeIt.next();var newNode=this.nodes.addNode(graphNode.getCoordinate());newNode.setLabel(argIndex,graphNode.getLabel().getLocation(argIndex));}};jsts.operation.relate.RelateNodeGraph.prototype.insertEdgeEnds=function(ee){for(var i=ee.iterator();i.hasNext();){var e=i.next();this.nodes.add(e);}};jsts.operation.relate.RelateNodeGraph.prototype.getNodeIterator=function(){return this.nodes.iterator();};})();jsts.geomgraph.index.SimpleSweepLineIntersector=function(){};jsts.geomgraph.index.SimpleSweepLineIntersector.prototype=new jsts.geomgraph.index.EdgeSetIntersector();jsts.geomgraph.index.SimpleSweepLineIntersector.prototype.events=[];jsts.geomgraph.index.SimpleSweepLineIntersector.prototype.nOverlaps=null;jsts.geomgraph.index.SimpleSweepLineIntersector.prototype.computeIntersections=function(edges,si,testAllSegments){if(si instanceof javascript.util.List){this.computeIntersections2.apply(this,arguments);return;} if(testAllSegments){this.add(edges,null);}else{this.add(edges);} this.computeIntersections3(si);};jsts.geomgraph.index.SimpleSweepLineIntersector.prototype.computeIntersections2=function(edges0,edges1,si){this.add(edges0,edges0);this.add(edges1,edges1);this.computeIntersections3(si);};jsts.geomgraph.index.SimpleSweepLineIntersector.prototype.add=function(edge,edgeSet){if(edge instanceof javascript.util.List){this.add2.apply(this,arguments);return;} var pts=edge.getCoordinates();for(var i=0;iother.segmentIndex)return 1;if(this.coord.equals2D(other.coord))return 0;return jsts.noding.SegmentPointComparator.compare(this.segmentOctant,this.coord,other.coord);};(function(){jsts.io.GeoJSONWriter=function(){this.parser=new jsts.io.GeoJSONParser(this.geometryFactory);};jsts.io.GeoJSONWriter.prototype.write=function(geometry){var geoJson=this.parser.write(geometry);return geoJson;};})();jsts.io.OpenLayersParser=function(geometryFactory){this.geometryFactory=geometryFactory||new jsts.geom.GeometryFactory();};jsts.io.OpenLayersParser.prototype.read=function(geometry){if(geometry.CLASS_NAME==='OpenLayers.Geometry.Point'){return this.convertFromPoint(geometry);}else if(geometry.CLASS_NAME==='OpenLayers.Geometry.LineString'){return this.convertFromLineString(geometry);}else if(geometry.CLASS_NAME==='OpenLayers.Geometry.LinearRing'){return this.convertFromLinearRing(geometry);}else if(geometry.CLASS_NAME==='OpenLayers.Geometry.Polygon'){return this.convertFromPolygon(geometry);}else if(geometry.CLASS_NAME==='OpenLayers.Geometry.MultiPoint'){return this.convertFromMultiPoint(geometry);}else if(geometry.CLASS_NAME==='OpenLayers.Geometry.MultiLineString'){return this.convertFromMultiLineString(geometry);}else if(geometry.CLASS_NAME==='OpenLayers.Geometry.MultiPolygon'){return this.convertFromMultiPolygon(geometry);}else if(geometry.CLASS_NAME==='OpenLayers.Geometry.Collection'){return this.convertFromCollection(geometry);}};jsts.io.OpenLayersParser.prototype.convertFromPoint=function(point){return this.geometryFactory.createPoint(new jsts.geom.Coordinate(point.x,point.y));};jsts.io.OpenLayersParser.prototype.convertFromLineString=function(lineString){var i;var coordinates=[];for(i=0;i0.0){this.minExtent=delX;} var delY=itemEnv.getHeight();if(delY0.0){this.minExtent=delY;}};jsts.operation.relate.RelateNodeFactory=function(){};jsts.operation.relate.RelateNodeFactory.prototype=new jsts.geomgraph.NodeFactory();jsts.operation.relate.RelateNodeFactory.prototype.createNode=function(coord){return new jsts.operation.relate.RelateNode(coord,new jsts.operation.relate.EdgeEndBundleStar());};jsts.index.quadtree.Key=function(itemEnv){this.pt=new jsts.geom.Coordinate();this.level=0;this.env=null;this.computeKey(itemEnv);};jsts.index.quadtree.Key.computeQuadLevel=function(env){var dx,dy,dMax,level;dx=env.getWidth();dy=env.getHeight();dMax=dx>dy?dx:dy;level=jsts.index.DoubleBits.exponent(dMax)+1;return level;};jsts.index.quadtree.Key.prototype.getPoint=function(){return this.pt;};jsts.index.quadtree.Key.prototype.getLevel=function(){return this.level;};jsts.index.quadtree.Key.prototype.getEnvelope=function(){return this.env;};jsts.index.quadtree.Key.prototype.getCentre=function(){var x,y;x=(this.env.getMinX()+this.env.getMaxX())/2;y=(this.env.getMinY()+this.env.getMaxY())/2;return new jsts.geom.Coordinate(x,y);};jsts.index.quadtree.Key.prototype.computeKey=function(){if(arguments[0]instanceof jsts.geom.Envelope){this.computeKeyFromEnvelope(arguments[0]);}else{this.computeKeyFromLevel(arguments[0],arguments[1]);}};jsts.index.quadtree.Key.prototype.computeKeyFromEnvelope=function(env){this.level=jsts.index.quadtree.Key.computeQuadLevel(env);this.env=new jsts.geom.Envelope();this.computeKey(this.level,env);while(!this.env.contains(env)){this.level+=1;this.computeKey(this.level,env);}};jsts.index.quadtree.Key.prototype.computeKeyFromLevel=function(level,env){var quadSize=jsts.index.DoubleBits.powerOf2(level);this.pt.x=Math.floor(env.getMinX()/quadSize)*quadSize;this.pt.y=Math.floor(env.getMinY()/quadSize)*quadSize;this.env.init(this.pt.x,this.pt.x+quadSize,this.pt.y,this.pt.y+ quadSize);};jsts.geom.CoordinateArrays=function(){throw new jsts.error.AbstractMethodInvocationError();};jsts.geom.CoordinateArrays.copyDeep=function(){if(arguments.length===1){return jsts.geom.CoordinateArrays.copyDeep1(arguments[0]);}else if(arguments.length===5){jsts.geom.CoordinateArrays.copyDeep2(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]);}};jsts.geom.CoordinateArrays.copyDeep1=function(coordinates){var copy=[];for(var i=0;i0){minCoord=coordinates[i];}} return minCoord;};jsts.geom.CoordinateArrays.scroll=function(coordinates,firstCoordinate){var i=jsts.geom.CoordinateArrays.indexOf(firstCoordinate,coordinates);if(i<0) return;var newCoordinates=coordinates.slice(i).concat(coordinates.slice(0,i));for(i=0;imaxx){minx=p2.x;maxx=p1.x;} if(this.p.x>=minx&&this.p.x<=maxx){this.isPointOnSegment=true;} return;} if(((p1.y>this.p.y)&&(p2.y<=this.p.y))||((p2.y>this.p.y)&&(p1.y<=this.p.y))){var x1=p1.x-this.p.x;var y1=p1.y-this.p.y;var x2=p2.x-this.p.x;var y2=p2.y-this.p.y;var xIntSign=jsts.algorithm.RobustDeterminant.signOfDet2x2(x1,y1,x2,y2);if(xIntSign===0.0){this.isPointOnSegment=true;return;} if(y20.0){this.crossingCount++;}}};jsts.algorithm.RayCrossingCounter.prototype.isOnSegment=function(){return jsts.geom.isPointOnSegment;};jsts.algorithm.RayCrossingCounter.prototype.getLocation=function(){if(this.isPointOnSegment) return jsts.geom.Location.BOUNDARY;if((this.crossingCount%2)===1){return jsts.geom.Location.INTERIOR;} return jsts.geom.Location.EXTERIOR;};jsts.algorithm.RayCrossingCounter.prototype.isPointInPolygon=function(){return this.getLocation()!==jsts.geom.Location.EXTERIOR;};jsts.operation.BoundaryOp=function(geom,bnRule){this.geom=geom;this.geomFact=geom.getFactory();this.bnRule=bnRule||jsts.algorithm.BoundaryNodeRule.MOD2_BOUNDARY_RULE;};jsts.operation.BoundaryOp.prototype.geom=null;jsts.operation.BoundaryOp.prototype.geomFact=null;jsts.operation.BoundaryOp.prototype.bnRule=null;jsts.operation.BoundaryOp.prototype.getBoundary=function(){if(this.geom instanceof jsts.geom.LineString)return this.boundaryLineString(this.geom);if(this.geom instanceof jsts.geom.MultiLineString)return this.boundaryMultiLineString(this.geom);return this.geom.getBoundary();};jsts.operation.BoundaryOp.prototype.getEmptyMultiPoint=function(){return this.geomFact.createMultiPoint(null);};jsts.operation.BoundaryOp.prototype.boundaryMultiLineString=function(mLine){if(this.geom.isEmpty()){return this.getEmptyMultiPoint();} var bdyPts=this.computeBoundaryCoordinates(mLine);if(bdyPts.length==1){return this.geomFact.createPoint(bdyPts[0]);} return this.geomFact.createMultiPoint(bdyPts);};jsts.operation.BoundaryOp.prototype.endpoints=null;jsts.operation.BoundaryOp.prototype.computeBoundaryCoordinates=function(mLine){var i,line,endpoint,bdyPts=[];this.endpoints=[];for(i=0;i0.0&&this.isErodedCompletely(hole,-this.distance)) continue;this.addPolygonRing(holeCoord,offsetDistance,jsts.geomgraph.Position.opposite(offsetSide),jsts.geom.Location.INTERIOR,jsts.geom.Location.EXTERIOR);}};jsts.operation.buffer.OffsetCurveSetBuilder.prototype.addPolygonRing=function(coord,offsetDistance,side,cwLeftLoc,cwRightLoc){if(offsetDistance==0.0&&coord.length=jsts.geom.LinearRing.MINIMUM_VALID_SIZE&&jsts.algorithm.CGAlgorithms.isCCW(coord)){leftLoc=cwRightLoc;rightLoc=cwLeftLoc;side=jsts.geomgraph.Position.opposite(side);} var curve=this.curveBuilder.getRingCurve(coord,side,offsetDistance);this.addCurve(curve,leftLoc,rightLoc);};jsts.operation.buffer.OffsetCurveSetBuilder.prototype.isErodedCompletely=function(ring,bufferDistance){var ringCoord=ring.getCoordinates();var minDiam=0.0;if(ringCoord.length<4) return bufferDistance<0;if(ringCoord.length==4) return this.isTriangleErodedCompletely(ringCoord,bufferDistance);var env=ring.getEnvelopeInternal();var envMinDimension=Math.min(env.getHeight(),env.getWidth());if(bufferDistance<0.0&&2*Math.abs(bufferDistance)>envMinDimension) return true;return false;};jsts.operation.buffer.OffsetCurveSetBuilder.prototype.isTriangleErodedCompletely=function(triangleCoord,bufferDistance){var tri=new jsts.geom.Triangle(triangleCoord[0],triangleCoord[1],triangleCoord[2]);var inCentre=tri.inCentre();var distToCentre=jsts.algorithm.CGAlgorithms.distancePointLine(inCentre,tri.p0,tri.p1);return distToCentre=1&&de.getDepth(jsts.geomgraph.Position.LEFT)<=0&&!de.isInteriorAreaEdge()){de.setInResult(true);}}};jsts.operation.buffer.BufferSubgraph.prototype.compareTo=function(o){var graph=o;if(this.rightMostCoord.xgraph.rightMostCoord.x){return 1;} return 0;};jsts.simplify.DPTransformer=function(distanceTolerance,isEnsureValidTopology){this.distanceTolerance=distanceTolerance;this.isEnsureValidTopology=isEnsureValidTopology;};jsts.simplify.DPTransformer.prototype=new jsts.geom.util.GeometryTransformer();jsts.simplify.DPTransformer.prototype.distanceTolerance=null;jsts.simplify.DPTransformer.prototype.isEnsureValidTopology=null;jsts.simplify.DPTransformer.prototype.transformCoordinates=function(coords,parent){var inputPts=coords;var newPts=null;if(inputPts.length==0){newPts=[];}else{newPts=jsts.simplify.DouglasPeuckerLineSimplifier.simplify(inputPts,this.distanceTolerance);} return newPts;};jsts.simplify.DPTransformer.prototype.transformPolygon=function(geom,parent){if(geom.isEmpty()){return null;} var rawGeom=jsts.geom.util.GeometryTransformer.prototype.transformPolygon.apply(this,arguments);if(parent instanceof jsts.geom.MultiPolygon){return rawGeom;} return this.createValidArea(rawGeom);};jsts.simplify.DPTransformer.prototype.transformLinearRing=function(geom,parent){var removeDegenerateRings=parent instanceof jsts.geom.Polygon;var simpResult=jsts.geom.util.GeometryTransformer.prototype.transformLinearRing.apply(this,arguments);if(removeDegenerateRings&&!(simpResult instanceof jsts.geom.LinearRing)){return null;} return simpResult;};jsts.simplify.DPTransformer.prototype.transformMultiPolygon=function(geom,parent){var rawGeom=jsts.geom.util.GeometryTransformer.prototype.transformMultiPolygon.apply(this,arguments);return this.createValidArea(rawGeom);};jsts.simplify.DPTransformer.prototype.createValidArea=function(rawAreaGeom){if(this.isEnsureValidTopology){return rawAreaGeom.buffer(0.0);} return rawAreaGeom;};jsts.geom.util.GeometryExtracter=function(clz,comps){this.clz=clz;this.comps=comps;};jsts.geom.util.GeometryExtracter.prototype=new jsts.geom.GeometryFilter();jsts.geom.util.GeometryExtracter.prototype.clz=null;jsts.geom.util.GeometryExtracter.prototype.comps=null;jsts.geom.util.GeometryExtracter.extract=function(geom,clz,list){list=list||new javascript.util.ArrayList();if(geom instanceof clz){list.add(geom);} else if(geom instanceof jsts.geom.GeometryCollection||geom instanceof jsts.geom.MultiPoint||geom instanceof jsts.geom.MultiLineString||geom instanceof jsts.geom.MultiPolygon){geom.apply(new jsts.geom.util.GeometryExtracter(clz,list));} return list;};jsts.geom.util.GeometryExtracter.prototype.filter=function(geom){if(this.clz===null||geom instanceof this.clz){this.comps.add(geom);}};(function(){var OverlayOp=jsts.operation.overlay.OverlayOp;var SnapOverlayOp=jsts.operation.overlay.snap.SnapOverlayOp;var SnapIfNeededOverlayOp=function(g1,g2){this.geom=[];this.geom[0]=g1;this.geom[1]=g2;};SnapIfNeededOverlayOp.overlayOp=function(g0,g1,opCode){var op=new SnapIfNeededOverlayOp(g0,g1);return op.getResultGeometry(opCode);};SnapIfNeededOverlayOp.intersection=function(g0,g1){return overlayOp(g0,g1,OverlayOp.INTERSECTION);};SnapIfNeededOverlayOp.union=function(g0,g1){return overlayOp(g0,g1,OverlayOp.UNION);};SnapIfNeededOverlayOp.difference=function(g0,g1){return overlayOp(g0,g1,OverlayOp.DIFFERENCE);};SnapIfNeededOverlayOp.symDifference=function(g0,g1){return overlayOp(g0,g1,OverlayOp.SYMDIFFERENCE);};SnapIfNeededOverlayOp.prototype.geom=null;SnapIfNeededOverlayOp.prototype.getResultGeometry=function(opCode){var result=null;var isSuccess=false;var savedException=null;try{result=OverlayOp.overlayOp(this.geom[0],this.geom[1],opCode);var isValid=true;if(isValid) isSuccess=true;}catch(ex){savedException=ex;} if(!isSuccess){try{result=SnapOverlayOp.overlayOp(this.geom[0],this.geom[1],opCode);}catch(ex){throw savedException;}} return result;};jsts.operation.overlay.snap.SnapIfNeededOverlayOp=SnapIfNeededOverlayOp;})();(function(){var GeometryExtracter=jsts.geom.util.GeometryExtracter;var CascadedPolygonUnion=jsts.operation.union.CascadedPolygonUnion;var PointGeometryUnion=jsts.operation.union.PointGeometryUnion;var OverlayOp=jsts.operation.overlay.OverlayOp;var SnapIfNeededOverlayOp=jsts.operation.overlay.snap.SnapIfNeededOverlayOp;var ArrayList=javascript.util.ArrayList;jsts.operation.union.UnaryUnionOp=function(geoms,geomFact){this.polygons=new ArrayList();this.lines=new ArrayList();this.points=new ArrayList();if(geomFact){this.geomFact=geomFact;} this.extract(geoms);};jsts.operation.union.UnaryUnionOp.union=function(geoms,geomFact){var op=new jsts.operation.union.UnaryUnionOp(geoms,geomFact);return op.union();};jsts.operation.union.UnaryUnionOp.prototype.polygons=null;jsts.operation.union.UnaryUnionOp.prototype.lines=null;jsts.operation.union.UnaryUnionOp.prototype.points=null;jsts.operation.union.UnaryUnionOp.prototype.geomFact=null;jsts.operation.union.UnaryUnionOp.prototype.extract=function(geoms){if(geoms instanceof ArrayList){for(var i=geoms.iterator();i.hasNext();){var geom=i.next();this.extract(geom);}}else{if(this.geomFact===null){this.geomFact=geoms.getFactory();} GeometryExtracter.extract(geoms,jsts.geom.Polygon,this.polygons);GeometryExtracter.extract(geoms,jsts.geom.LineString,this.lines);GeometryExtracter.extract(geoms,jsts.geom.Point,this.points);}};jsts.operation.union.UnaryUnionOp.prototype.union=function(){if(this.geomFact===null){return null;} var unionPoints=null;if(this.points.size()>0){var ptGeom=this.geomFact.buildGeometry(this.points);unionPoints=this.unionNoOpt(ptGeom);} var unionLines=null;if(this.lines.size()>0){var lineGeom=this.geomFact.buildGeometry(this.lines);unionLines=this.unionNoOpt(lineGeom);} var unionPolygons=null;if(this.polygons.size()>0){unionPolygons=CascadedPolygonUnion.union(this.polygons);} var unionLA=this.unionWithNull(unionLines,unionPolygons);var union=null;if(unionPoints===null){union=unionLA;}else if(unionLA===null){union=unionPoints;}else{union=PointGeometryUnion(unionPoints,unionLA);} if(union===null){return this.geomFact.createGeometryCollection(null);} return union;};jsts.operation.union.UnaryUnionOp.prototype.unionWithNull=function(g0,g1){if(g0===null&&g1===null){return null;} if(g1===null){return g0;} if(g0===null){return g1;} return g0.union(g1);};jsts.operation.union.UnaryUnionOp.prototype.unionNoOpt=function(g0){var empty=this.geomFact.createPoint(null);return SnapIfNeededOverlayOp.overlayOp(g0,empty,OverlayOp.UNION);};}());jsts.index.kdtree.KdNode=function(){this.left=null;this.right=null;this.count=1;if(arguments.length===2){this.initializeFromCoordinate.apply(this,arguments[0],arguments[1]);}else if(arguments.length===3){this.initializeFromXY.apply(this,arguments[0],arguments[1],arguments[2]);}};jsts.index.kdtree.KdNode.prototype.initializeFromXY=function(x,y,data){this.p=new jsts.geom.Coordinate(x,y);this.data=data;};jsts.index.kdtree.KdNode.prototype.initializeFromCoordinate=function(p,data){this.p=p;this.data=data;};jsts.index.kdtree.KdNode.prototype.getX=function(){return this.p.x;};jsts.index.kdtree.KdNode.prototype.getY=function(){return this.p.y;};jsts.index.kdtree.KdNode.prototype.getCoordinate=function(){return this.p;};jsts.index.kdtree.KdNode.prototype.getData=function(){return this.data;};jsts.index.kdtree.KdNode.prototype.getLeft=function(){return this.left;};jsts.index.kdtree.KdNode.prototype.getRight=function(){return this.right;};jsts.index.kdtree.KdNode.prototype.increment=function(){this.count+=1;};jsts.index.kdtree.KdNode.prototype.getCount=function(){return this.count;};jsts.index.kdtree.KdNode.prototype.isRepeated=function(){return count>1;};jsts.index.kdtree.KdNode.prototype.setLeft=function(left){this.left=left;};jsts.index.kdtree.KdNode.prototype.setRight=function(right){this.right=right;};jsts.algorithm.InteriorPointPoint=function(geometry){this.minDistance=Number.MAX_VALUE;this.interiorPoint=null;this.centroid=geometry.getCentroid().getCoordinate();this.add(geometry);};jsts.algorithm.InteriorPointPoint.prototype.add=function(geometry){if(geometry instanceof jsts.geom.Point){this.addPoint(geometry.getCoordinate());}else if(geometry instanceof jsts.geom.GeometryCollection){for(var i=0;i0.0){this.minExtent=del;}};jsts.index.bintree.Bintree=Bintree;})();jsts.algorithm.InteriorPointArea=function(geometry){this.factory;this.interiorPoint=null;this.maxWidth=0;this.factory=geometry.getFactory();this.add(geometry);};jsts.algorithm.InteriorPointArea.avg=function(a,b){return(a+b)/2;};jsts.algorithm.InteriorPointArea.prototype.getInteriorPoint=function(){return this.interiorPoint;};jsts.algorithm.InteriorPointArea.prototype.add=function(geometry){if(geometry instanceof jsts.geom.Polygon){this.addPolygon(geometry);}else if(geometry instanceof jsts.geom.GeometryCollection){for(var i=0;ithis.maxWidth){this.interiorPoint=intPt;this.maxWidth=width;}};jsts.algorithm.InteriorPointArea.prototype.widestGeometry=function(obj){if(obj instanceof jsts.geom.GeometryCollection){var gc=obj;if(gc.isEmpty()){return gc;} var widestGeometry=gc.getGeometryN(0);for(var i=1;iwidestGeometry.getEnvelopeInternal().getWidth()){widestGeometry=gc.getGeometryN(i);}} return widestGeometry;}else if(obj instanceof jsts.geom.Geometry){return obj;}};jsts.algorithm.InteriorPointArea.prototype.horizontalBisector=function(geometry){var envelope=geometry.getEnvelopeInternal();var bisectY=jsts.algorithm.SafeBisectorFinder.getBisectorY(geometry);return this.factory.createLineString([new jsts.geom.Coordinate(envelope.getMinX(),bisectY),new jsts.geom.Coordinate(envelope.getMaxX(),bisectY)]);};jsts.algorithm.InteriorPointArea.prototype.centre=function(envelope){return new jsts.geom.Coordinate(jsts.algorithm.InteriorPointArea.avg(envelope.getMinX(),envelope.getMaxX()),jsts.algorithm.InteriorPointArea.avg(envelope.getMinY(),envelope.getMaxY()));};jsts.algorithm.SafeBisectorFinder=function(poly){this.poly;this.centreY;this.hiY=Number.MAX_VALUE;this.loY=-Number.MAX_VALUE;this.poly=poly;this.hiY=poly.getEnvelopeInternal().getMaxY();this.loY=poly.getEnvelopeInternal().getMinY();this.centreY=jsts.algorithm.InteriorPointArea.avg(this.loY,this.hiY);};jsts.algorithm.SafeBisectorFinder.getBisectorY=function(poly){var finder=new jsts.algorithm.SafeBisectorFinder(poly);return finder.getBisectorY();};jsts.algorithm.SafeBisectorFinder.prototype.getBisectorY=function(){this.process(this.poly.getExteriorRing());for(var i=0;ithis.loY){this.loY=y;}}else if(y>this.centreY){if(y=rectEnv.getMinX()&&elementEnv.getMaxX()<=rectEnv.getMaxX()){this.intersects=true;return;} if(elementEnv.getMinY()>=rectEnv.getMinY()&&elementEnv.getMaxY()<=rectEnv.getMaxY()){this.intersects=true;return;}} EnvelopeIntersectsVisitor.prototype.isDone=function(){return this.intersects==true;} var GeometryContainsPointVisitor=function(rectangle){this.rectSeq=rectangle.getExteriorRing().getCoordinateSequence();this.rectEnv=rectangle.getEnvelopeInternal();};GeometryContainsPointVisitor.prototype=new jsts.geom.util.ShortCircuitedGeometryVisitor();GeometryContainsPointVisitor.constructor=GeometryContainsPointVisitor;GeometryContainsPointVisitor.prototype.rectSeq=null;GeometryContainsPointVisitor.prototype.rectEnv=null;GeometryContainsPointVisitor.prototype.containsPoint=false;GeometryContainsPointVisitor.prototype.containsPoint=function(){return this.containsPoint;} GeometryContainsPointVisitor.prototype.visit=function(geom){if(!(geom instanceof jsts.geom.Polygon)) return;var elementEnv=geom.getEnvelopeInternal();if(!this.rectEnv.intersects(elementEnv)) return;var rectPt=new jsts.geom.Coordinate();for(var i=0;i<4;i++){this.rectSeq.getCoordinate(i,rectPt);if(!elementEnv.contains(rectPt)) continue;if(SimplePointInAreaLocator.containsPointInPolygon(rectPt,geom)){this.containsPoint=true;return;}}} GeometryContainsPointVisitor.prototype.isDone=function(){return this.containsPoint==true;} var RectangleIntersectsSegmentVisitor=function(rectangle){this.rectEnv=rectangle.getEnvelopeInternal();this.rectIntersector=new RectangleLineIntersector(rectEnv);};RectangleIntersectsSegmentVisitor.prototype=new jsts.geom.util.ShortCircuitedGeometryVisitor();RectangleIntersectsSegmentVisitor.constructor=RectangleIntersectsSegmentVisitor;RectangleIntersectsSegmentVisitor.prototype.rectEnv=null;RectangleIntersectsSegmentVisitor.prototype.rectIntersector=null;RectangleIntersectsSegmentVisitor.prototype.hasIntersection=false;RectangleIntersectsSegmentVisitor.prototype.p0=null;RectangleIntersectsSegmentVisitor.prototype.p1=null;RectangleIntersectsSegmentVisitor.prototype.intersects=function(){return this.hasIntersection;} RectangleIntersectsSegmentVisitor.prototype.visit=function(geom){var elementEnv=geom.getEnvelopeInternal();if(!this.rectEnv.intersects(elementEnv)) return;var lines=LinearComponentExtracter.getLines(geom);this.checkIntersectionWithLineStrings(lines);} RectangleIntersectsSegmentVisitor.prototype.checkIntersectionWithLineStrings=function(lines){for(var i=lines.iterator();i.hasNext();){var testLine=i.next();this.checkIntersectionWithSegments(testLine);if(this.hasIntersection) return;}} RectangleIntersectsSegmentVisitor.prototype.checkIntersectionWithSegments=function(testLine){var seq1=testLine.getCoordinateSequence();for(var j=1;jx1) return 1;return 0;};jsts.noding.SegmentPointComparator.compareValue=function(compareSign0,compareSign1){if(compareSign0<0) return-1;if(compareSign0>0) return 1;if(compareSign1<0) return-1;if(compareSign1>0) return 1;return 0;};jsts.operation.relate.RelateOp=function(){jsts.operation.GeometryGraphOperation.apply(this,arguments);this._relate=new jsts.operation.relate.RelateComputer(this.arg);};jsts.operation.relate.RelateOp.prototype=new jsts.operation.GeometryGraphOperation();jsts.operation.relate.RelateOp.relate=function(a,b,boundaryNodeRule){var relOp=new jsts.operation.relate.RelateOp(a,b,boundaryNodeRule);var im=relOp.getIntersectionMatrix();return im;};jsts.operation.relate.RelateOp.prototype._relate=null;jsts.operation.relate.RelateOp.prototype.getIntersectionMatrix=function(){return this._relate.computeIM();};jsts.index.chain.MonotoneChain=function(pts,start,end,context){this.pts=pts;this.start=start;this.end=end;this.context=context;};jsts.index.chain.MonotoneChain.prototype.pts=null;jsts.index.chain.MonotoneChain.prototype.start=null;jsts.index.chain.MonotoneChain.prototype.end=null;jsts.index.chain.MonotoneChain.prototype.env=null;jsts.index.chain.MonotoneChain.prototype.context=null;jsts.index.chain.MonotoneChain.prototype.id=null;jsts.index.chain.MonotoneChain.prototype.setId=function(id){this.id=id;};jsts.index.chain.MonotoneChain.prototype.getId=function(){return this.id;};jsts.index.chain.MonotoneChain.prototype.getContext=function(){return this.context;};jsts.index.chain.MonotoneChain.prototype.getEnvelope=function(){if(this.env==null){var p0=this.pts[this.start];var p1=this.pts[this.end];this.env=new jsts.geom.Envelope(p0,p1);} return this.env;};jsts.index.chain.MonotoneChain.prototype.getStartIndex=function(){return this.start;};jsts.index.chain.MonotoneChain.prototype.getEndIndex=function(){return this.end;};jsts.index.chain.MonotoneChain.prototype.getLineSegment=function(index,ls){ls.p0=this.pts[index];ls.p1=this.pts[index+1];};jsts.index.chain.MonotoneChain.prototype.getCoordinates=function(){var coord=[];var index=0;for(var i=this.start;i<=this.end;i++){coord[index++]=this.pts[i];} return coord;};jsts.index.chain.MonotoneChain.prototype.select=function(searchEnv,mcs){this.computeSelect2(searchEnv,this.start,this.end,mcs);};jsts.index.chain.MonotoneChain.prototype.computeSelect2=function(searchEnv,start0,end0,mcs){var p0=this.pts[start0];var p1=this.pts[end0];mcs.tempEnv1.init(p0,p1);if(end0-start0===1){mcs.select(this,start0);return;} if(!searchEnv.intersects(mcs.tempEnv1)) return;var mid=parseInt((start0+end0)/2);if(start0=0||actualDimensionValue===Dimension.TRUE)){return true;} if(requiredDimensionSymbol==='F'&&actualDimensionValue===Dimension.FALSE){return true;} if(requiredDimensionSymbol==='0'&&actualDimensionValue===Dimension.P){return true;} if(requiredDimensionSymbol==='1'&&actualDimensionValue===Dimension.L){return true;} if(requiredDimensionSymbol==='2'&&actualDimensionValue===Dimension.A){return true;} return false;};jsts.geom.IntersectionMatrix.matches2=function(actualDimensionSymbols,requiredDimensionSymbols){var m=new jsts.geom.IntersectionMatrix(actualDimensionSymbols);return m.matches(requiredDimensionSymbols);};jsts.geom.IntersectionMatrix.prototype.set=function(row,column,dimensionValue){if(typeof row==='string'){this.set2(row);return;} this.matrix[row][column]=dimensionValue;};jsts.geom.IntersectionMatrix.prototype.set2=function(dimensionSymbols){for(var i=0;i=0&&column>=0){this.setAtLeast(row,column,minimumDimensionValue);}};jsts.geom.IntersectionMatrix.prototype.setAtLeast2=function(minimumDimensionSymbols){var i;for(i=0;idimensionOfGeometryB){return this.isTouches(dimensionOfGeometryB,dimensionOfGeometryA);} if((dimensionOfGeometryA==Dimension.A&&dimensionOfGeometryB==Dimension.A)||(dimensionOfGeometryA==Dimension.L&&dimensionOfGeometryB==Dimension.L)||(dimensionOfGeometryA==Dimension.L&&dimensionOfGeometryB==Dimension.A)||(dimensionOfGeometryA==Dimension.P&&dimensionOfGeometryB==Dimension.A)||(dimensionOfGeometryA==Dimension.P&&dimensionOfGeometryB==Dimension.L)){return this.matrix[Location.INTERIOR][Location.INTERIOR]===Dimension.FALSE&&(jsts.geom.IntersectionMatrix.matches(this.matrix[Location.INTERIOR][Location.BOUNDARY],'T')||jsts.geom.IntersectionMatrix.matches(this.matrix[Location.BOUNDARY][Location.INTERIOR],'T')||jsts.geom.IntersectionMatrix.matches(this.matrix[Location.BOUNDARY][Location.BOUNDARY],'T'));} return false;};jsts.geom.IntersectionMatrix.prototype.isCrosses=function(dimensionOfGeometryA,dimensionOfGeometryB){if((dimensionOfGeometryA==Dimension.P&&dimensionOfGeometryB==Dimension.L)||(dimensionOfGeometryA==Dimension.P&&dimensionOfGeometryB==Dimension.A)||(dimensionOfGeometryA==Dimension.L&&dimensionOfGeometryB==Dimension.A)){return jsts.geom.IntersectionMatrix.matches(this.matrix[Location.INTERIOR][Location.INTERIOR],'T')&&jsts.geom.IntersectionMatrix.matches(this.matrix[Location.INTERIOR][Location.EXTERIOR],'T');} if((dimensionOfGeometryA==Dimension.L&&dimensionOfGeometryB==Dimension.P)||(dimensionOfGeometryA==Dimension.A&&dimensionOfGeometryB==Dimension.P)||(dimensionOfGeometryA==Dimension.A&&dimensionOfGeometryB==Dimension.L)){return jsts.geom.IntersectionMatrix.matches(matrix[Location.INTERIOR][Location.INTERIOR],'T')&&jsts.geom.IntersectionMatrix.matches(this.matrix[Location.EXTERIOR][Location.INTERIOR],'T');} if(dimensionOfGeometryA===Dimension.L&&dimensionOfGeometryB===Dimension.L){return this.matrix[Location.INTERIOR][Location.INTERIOR]===0;} return false;};jsts.geom.IntersectionMatrix.prototype.isWithin=function(){return jsts.geom.IntersectionMatrix.matches(this.matrix[Location.INTERIOR][Location.INTERIOR],'T')&&this.matrix[Location.INTERIOR][Location.EXTERIOR]==Dimension.FALSE&&this.matrix[Location.BOUNDARY][Location.EXTERIOR]==Dimension.FALSE;};jsts.geom.IntersectionMatrix.prototype.isContains=function(){return jsts.geom.IntersectionMatrix.matches(this.matrix[Location.INTERIOR][Location.INTERIOR],'T')&&this.matrix[Location.EXTERIOR][Location.INTERIOR]==Dimension.FALSE&&this.matrix[Location.EXTERIOR][Location.BOUNDARY]==Dimension.FALSE;};jsts.geom.IntersectionMatrix.prototype.isCovers=function(){var hasPointInCommon=jsts.geom.IntersectionMatrix.matches(this.matrix[Location.INTERIOR][Location.INTERIOR],'T')||jsts.geom.IntersectionMatrix.matches(this.matrix[Location.INTERIOR][Location.BOUNDARY],'T')||jsts.geom.IntersectionMatrix.matches(this.matrix[Location.BOUNDARY][Location.INTERIOR],'T')||jsts.geom.IntersectionMatrix.matches(this.matrix[Location.BOUNDARY][Location.BOUNDARY],'T');return hasPointInCommon&&this.matrix[Location.EXTERIOR][Location.INTERIOR]==Dimension.FALSE&&this.matrix[Location.EXTERIOR][Location.BOUNDARY]==Dimension.FALSE;};jsts.geom.IntersectionMatrix.prototype.isCoveredBy=function(){var hasPointInCommon=jsts.geom.IntersectionMatrix.matches(this.matrix[Location.INTERIOR][Location.INTERIOR],'T')||jsts.geom.IntersectionMatrix.matches(this.matrix[Location.INTERIOR][Location.BOUNDARY],'T')||jsts.geom.IntersectionMatrix.matches(this.matrix[Location.BOUNDARY][Location.INTERIOR],'T')||jsts.geom.IntersectionMatrix.matches(this.matrix[Location.BOUNDARY][Location.BOUNDARY],'T');return hasPointInCommon&&this.matrix[Location.INTERIOR][Location.EXTERIOR]===Dimension.FALSE&&this.matrix[Location.BOUNDARY][Location.EXTERIOR]===Dimension.FALSE;};jsts.geom.IntersectionMatrix.prototype.isEquals=function(dimensionOfGeometryA,dimensionOfGeometryB){if(dimensionOfGeometryA!==dimensionOfGeometryB){return false;} return jsts.geom.IntersectionMatrix.matches(this.matrix[Location.INTERIOR][Location.INTERIOR],'T')&&this.matrix[Location.EXTERIOR][Location.INTERIOR]===Dimension.FALSE&&this.matrix[Location.INTERIOR][Location.EXTERIOR]===Dimension.FALSE&&this.matrix[Location.EXTERIOR][Location.BOUNDARY]===Dimension.FALSE&&this.matrix[Location.BOUNDARY][Location.EXTERIOR]===Dimension.FALSE;};jsts.geom.IntersectionMatrix.prototype.isOverlaps=function(dimensionOfGeometryA,dimensionOfGeometryB){if((dimensionOfGeometryA==Dimension.P&&dimensionOfGeometryB===Dimension.P)||(dimensionOfGeometryA==Dimension.A&&dimensionOfGeometryB===Dimension.A)){return jsts.geom.IntersectionMatrix.matches(this.matrix[Location.INTERIOR][Location.INTERIOR],'T')&&jsts.geom.IntersectionMatrix.matches(this.matrix[Location.INTERIOR][Location.EXTERIOR],'T')&&jsts.geom.IntersectionMatrix.matches(this.matrix[Location.EXTERIOR][Location.INTERIOR],'T');} if(dimensionOfGeometryA===Dimension.L&&dimensionOfGeometryB===Dimension.L){return this.matrix[Location.INTERIOR][Location.INTERIOR]==1&&jsts.geom.IntersectionMatrix.matches(this.matrix[Location.INTERIOR][Location.EXTERIOR],'T')&&jsts.geom.IntersectionMatrix.matches(this.matrix[Location.EXTERIOR][Location.INTERIOR],'T');} return false;};jsts.geom.IntersectionMatrix.prototype.matches=function(requiredDimensionSymbols){if(requiredDimensionSymbols.length!=9){throw new jsts.error.IllegalArgumentException('Should be length 9: '+ requiredDimensionSymbols);} for(var ai=0;ai<3;ai++){for(var bi=0;bi<3;bi++){if(!jsts.geom.IntersectionMatrix.matches(this.matrix[ai][bi],requiredDimensionSymbols.charAt(3*ai+bi))){return false;}}} return true;};jsts.geom.IntersectionMatrix.prototype.transpose=function(){var temp=matrix[1][0];this.matrix[1][0]=this.matrix[0][1];this.matrix[0][1]=temp;temp=this.matrix[2][0];this.matrix[2][0]=this.matrix[0][2];this.matrix[0][2]=temp;temp=this.matrix[2][1];this.matrix[2][1]=this.matrix[1][2];this.matrix[1][2]=temp;return this;};jsts.geom.IntersectionMatrix.prototype.toString=function(){var ai,bi,buf='';for(ai=0;ai<3;ai++){for(bi=0;bi<3;bi++){buf+=Dimension.toDimensionSymbol(this.matrix[ai][bi]);}} return buf;};})();jsts.triangulate.quadedge.LastFoundQuadEdgeLocator=function(subdiv){this.subdiv=subdiv;this.lastEdge=null;this.init();};jsts.triangulate.quadedge.LastFoundQuadEdgeLocator.prototype.init=function(){this.lastEdge=this.findEdge();};jsts.triangulate.quadedge.LastFoundQuadEdgeLocator.prototype.findEdge=function(){var edges=this.subdiv.getEdges();return edges[0];};jsts.triangulate.quadedge.LastFoundQuadEdgeLocator.prototype.locate=function(v){if(!this.lastEdge.isLive()){this.init();} var e=this.subdiv.locateFromEdge(v,this.lastEdge);this.lastEdge=e;return e;};jsts.noding.SegmentNodeList=function(edge){this.nodeMap=new javascript.util.TreeMap();this.edge=edge;};jsts.noding.SegmentNodeList.prototype.nodeMap=null;jsts.noding.SegmentNodeList.prototype.iterator=function(){return this.nodeMap.values().iterator();};jsts.noding.SegmentNodeList.prototype.edge=null;jsts.noding.SegmentNodeList.prototype.getEdge=function(){return this.edge;};jsts.noding.SegmentNodeList.prototype.add=function(intPt,segmentIndex){var eiNew=new jsts.noding.SegmentNode(this.edge,intPt,segmentIndex,this.edge.getSegmentOctant(segmentIndex));var ei=this.nodeMap.get(eiNew);if(ei!==null){jsts.util.Assert.isTrue(ei.coord.equals2D(intPt),'Found equal nodes with different coordinates');return ei;} this.nodeMap.put(eiNew,eiNew);return eiNew;};jsts.noding.SegmentNodeList.prototype.addEndpoints=function(){var maxSegIndex=this.edge.size()-1;this.add(this.edge.getCoordinate(0),0);this.add(this.edge.getCoordinate(maxSegIndex),maxSegIndex);};jsts.noding.SegmentNodeList.prototype.addCollapsedNodes=function(){var collapsedVertexIndexes=[];this.findCollapsesFromInsertedNodes(collapsedVertexIndexes);this.findCollapsesFromExistingVertices(collapsedVertexIndexes);for(var i=0;ideltaY){offset=deltaX*10.0;}else{offset=deltaY*10.0;} this.frameVertex[0]=new jsts.triangulate.quadedge.Vertex((env.getMaxX()+env.getMinX())/2.0,env.getMaxY() +offset);this.frameVertex[1]=new jsts.triangulate.quadedge.Vertex(env.getMinX()-offset,env.getMinY()-offset);this.frameVertex[2]=new jsts.triangulate.quadedge.Vertex(env.getMaxX()+offset,env.getMinY()-offset);this.frameEnv=new jsts.geom.Envelope(this.frameVertex[0].getCoordinate(),this.frameVertex[1].getCoordinate());this.frameEnv.expandToInclude(this.frameVertex[2].getCoordinate());};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.initSubdiv=function(){var ea,eb,ec;ea=this.makeEdge(this.frameVertex[0],this.frameVertex[1]);eb=this.makeEdge(this.frameVertex[1],this.frameVertex[2]);jsts.triangulate.quadedge.QuadEdge.splice(ea.sym(),eb);ec=this.makeEdge(this.frameVertex[2],this.frameVertex[0]);jsts.triangulate.quadedge.QuadEdge.splice(eb.sym(),ec);jsts.triangulate.quadedge.QuadEdge.splice(ec.sym(),ea);return ea;};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getTolerance=function(){return this.tolerance;};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getEnvelope=function(){return new jsts.geom.Envelope(this.frameEnv);};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getEdges=function(){if(arguments.length>0){return this.getEdgesByFactory(arguments[0]);}else{return this.quadEdges;}};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.setLocator=function(locator){this.locator=locator;};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.makeEdge=function(o,d){var q=jsts.triangulate.quadedge.QuadEdge.makeEdge(o,d);this.quadEdges.push(q);return q;};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.connect=function(a,b){var q=jsts.triangulate.quadedge.QuadEdge.connect(a,b);this.quadEdges.push(q);return q;};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.delete_jsts=function(e){jsts.triangulate.quadedge.QuadEdge.splice(e,e.oPrev());jsts.triangulate.quadedge.QuadEdge.splice(e.sym(),e.sym().oPrev());var eSym,eRot,eRotSym;e.eSym=e.sym();eRot=e.rot;eRotSym=e.rot.sym();var idx=this.quadEdges.indexOf(e);if(idx!==-1){this.quadEdges.splice(idx,1);} idx=this.quadEdges.indexOf(eSym);if(idx!==-1){this.quadEdges.splice(idx,1);} idx=this.quadEdges.indexOf(eRot);if(idx!==-1){this.quadEdges.splice(idx,1);} idx=this.quadEdges.indexOf(eRotSym);if(idx!==-1){this.quadEdges.splice(idx,1);} e.delete_jsts();eSym.delete_jsts();eRot.delete_jsts();eRotSym.delete_jsts();};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.locateFromEdge=function(v,startEdge){var iter=0,maxIter=this.quadEdges.length,e;e=startEdge;while(true){iter++;if(iter>maxIter){throw new jsts.error.LocateFailureError(e.toLineSegment());} if((v.equals(e.orig()))||(v.equals(e.dest()))){break;}else if(v.rightOf(e)){e=e.sym();}else if(!v.rightOf(e.oNext())){e=e.oNext();}else if(!v.rightOf(e.dPrev())){e=e.dPrev();}else{break;}} return e;};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.locate=function(){if(arguments.length===1){if(arguments[0]instanceof jsts.triangulate.quadedge.Vertex){return this.locateByVertex(arguments[0]);}else{return this.locateByCoordinate(arguments[0]);}}else{return this.locateByCoordinates(arguments[0],arguments[1]);}};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.locateByVertex=function(v){return this.locator.locate(v);};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.locateByCoordinate=function(p){return this.locator.locate(new jsts.triangulate.quadedge.Vertex(p));};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.locateByCoordinates=function(p0,p1){var e,base,locEdge;var e=this.locator.locate(new jsts.triangulate.quadedge.Vertex(p0));if(e===null){return null;} base=e;if(e.dest().getCoordinate().equals2D(p0)){base=e.sym();} locEdge=base;do{if(locEdge.dest().getCoordinate().equals2D(p1)){return locEdge;} locEdge=locEdge.oNext();}while(locEdge!=base);return null;};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.insertSite=function(v){var e,base,startEdge;e=this.locate(v);if((v.equals(e.orig(),this.tolerance))||(v.equals(e.dest(),this.tolerance))){return e;} base=this.makeEdge(e.orig(),v);jsts.triangulate.quadedge.QuadEdge.splice(base,e);startEdge=base;do{base=this.connect(e,base.sym());e=base.oPrev();}while(e.lNext()!=startEdge);return startEdge;};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.isFrameEdge=function(e){if(this.isFrameVertex(e.orig())||this.isFrameVertex(e.dest())){return true;} return false;};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.isFrameBorderEdge=function(e){var leftTri,rightTri,vLeftTriOther,vRightTriOther;leftTri=new Array(3);this.getTriangleEdges(e,leftTri);rightTri=new Array(3);this.getTriangleEdges(e.sym(),rightTri);vLeftTriOther=e.lNext().dest();if(this.isFrameVertex(vLeftTriOther)){return true;} vRightTriOther=e.sym().lNext().dest();if(this.isFrameVertex(vRightTriOther)){return true;} return false;};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.isFrameVertex=function(v){if(v.equals(this.frameVertex[0])){return true;} if(v.equals(this.frameVertex[1])){return true;} if(v.equals(this.frameVertex[2])){return true;} return false;};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.isOnEdge=function(e,p){this.seg.setCoordinates(e.orig().getCoordinate(),e.dest().getCoordinate());var dist=this.seg.distance(p);return dist0){edge=edgeStack.pop();if(visitedEdges.indexOf(edge)===-1){priQE=edge.getPrimary();if(includeFrame||!this.isFrameEdge(priQE)){edges.push(priQE);} edgeStack.push(edge.oNext());edgeStack.push(edge.sym().oNext());visitedEdges.push(edge);visitedEdges.push(edge.sym());}} return edges;};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.visitTriangles=function(triVisitor,includeFrame){this.visitedKey++;var edgeStack,visitedEdges,edge,triEdges;edgeStack=[];edgeStack.push(this.startingEdge);visitedEdges=[];while(edgeStack.length>0){edge=edgeStack.pop();if(visitedEdges.indexOf(edge)===-1){triEdges=this.fetchTriangleToVisit(edge,edgeStack,includeFrame,visitedEdges);if(triEdges!==null) triVisitor.visit(triEdges);}}};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.fetchTriangleToVisit=function(edge,edgeStack,includeFrame,visitedEdges){var curr,edgeCount,isFrame,sym;curr=edge;edgeCount=0;isFrame=false;do{this.triEdges[edgeCount]=curr;if(this.isFrameEdge(curr)){isFrame=true;} sym=curr.sym();if(visitedEdges.indexOf(sym)===-1){edgeStack.push(sym);} visitedEdges.push(curr);edgeCount++;curr=curr.lNext();}while(curr!==edge);if(isFrame&&!includeFrame){return null;} return this.triEdges;};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getTriangleEdges=function(includeFrame){var visitor=new jsts.triangulate.quadedge.TriangleEdgesListVisitor();this.visitTriangles(visitor,includeFrame);return visitor.getTriangleEdges();};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getTriangleVertices=function(includeFrame){var visitor=new TriangleVertexListVisitor();this.visitTriangles(visitor,includeFrame);return visitor.getTriangleVertices();};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getTriangleCoordinates=function(includeFrame){var visitor=new jsts.triangulate.quadedge.TriangleCoordinatesVisitor();this.visitTriangles(visitor,includeFrame);return visitor.getTriangles();};jsts.triangulate.quadedge.QuadEdgeSubdivision.prototype.getEdgesByFactory=function(geomFact){var quadEdges,edges,i,il,qe,coords;quadEdges=this.getPrimaryEdges(false);edges=[];i=0;il=quadEdges.length;for(i;i0){this.coordList.closeRing();pts=this.coordList.toArray();if(pts.length!==4){return;} this.triCoords.push(pts);}};jsts.triangulate.quadedge.TriangleCoordinatesVisitor.prototype.getTriangles=function(){return this.triCoords;};jsts.operation.relate.EdgeEndBundle=function(){this.edgeEnds=[];var e=arguments[0]instanceof jsts.geomgraph.EdgeEnd?arguments[0]:arguments[1];var edge=e.getEdge();var coord=e.getCoordinate();var dirCoord=e.getDirectedCoordinate();var label=new jsts.geomgraph.Label(e.getLabel());jsts.geomgraph.EdgeEnd.call(this,edge,coord,dirCoord,label);this.insert(e);};jsts.operation.relate.EdgeEndBundle.prototype=new jsts.geomgraph.EdgeEnd();jsts.operation.relate.EdgeEndBundle.prototype.edgeEnds=null;jsts.operation.relate.EdgeEndBundle.prototype.getLabel=function(){return this.label;};jsts.operation.relate.EdgeEndBundle.prototype.getEdgeEnds=function(){return this.edgeEnds;};jsts.operation.relate.EdgeEndBundle.prototype.insert=function(e){this.edgeEnds.push(e);};jsts.operation.relate.EdgeEndBundle.prototype.computeLabel=function(boundaryNodeRule){var isArea=false;for(var i=0;i0){loc=jsts.geomgraph.GeometryGraph.determineBoundary(boundaryNodeRule,boundaryCount);} this.label.setLocation(geomIndex,loc);};jsts.operation.relate.EdgeEndBundle.prototype.computeLabelSides=function(geomIndex){this.computeLabelSide(geomIndex,jsts.geomgraph.Position.LEFT);this.computeLabelSide(geomIndex,jsts.geomgraph.Position.RIGHT);};jsts.operation.relate.EdgeEndBundle.prototype.computeLabelSide=function(geomIndex,side){for(var i=0;imaxLen){maxLen=lenBC;} if(lenCA>maxLen){maxLen=lenCA;} return maxLen;};jsts.geom.Triangle.angleBisector=function(a,b,c){var len0,len2,frac,dx,dy,splitPt;len0=b.distance(a);len2=b.distance(c);frac=len0/(len0+len2);dx=c.x-a.x;dy=c.y-a.y;splitPt=new jsts.geom.Coordinate(a.x+frac*dx,a.y+frac*dy);return splitPt;};jsts.geom.Triangle.area=function(a,b,c){return Math.abs(((c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y))/2.0);};jsts.geom.Triangle.signedArea=function(a,b,c){return((c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y))/2.0;};jsts.geom.Triangle.prototype.inCentre=function(){return jsts.geom.Triangle.inCentre(this.p0,this.p1,this.p2);};jsts.noding.OrientedCoordinateArray=function(pts){this.pts=pts;this._orientation=jsts.noding.OrientedCoordinateArray.orientation(pts);};jsts.noding.OrientedCoordinateArray.prototype.pts=null;jsts.noding.OrientedCoordinateArray.prototype._orientation=undefined;jsts.noding.OrientedCoordinateArray.orientation=function(pts){return jsts.geom.CoordinateArrays.increasingDirection(pts)===1;};jsts.noding.OrientedCoordinateArray.prototype.compareTo=function(o1){var oca=o1;var comp=jsts.noding.OrientedCoordinateArray.compareOriented(this.pts,this._orientation,oca.pts,oca._orientation);return comp;};jsts.noding.OrientedCoordinateArray.compareOriented=function(pts1,orientation1,pts2,orientation2){var dir1=orientation1?1:-1;var dir2=orientation2?1:-1;var limit1=orientation1?pts1.length:-1;var limit2=orientation2?pts2.length:-1;var i1=orientation1?0:pts1.length-1;var i2=orientation2?0:pts2.length-1;var comp=0;while(true){var compPt=pts1[i1].compareTo(pts2[i2]);if(compPt!==0) return compPt;i1+=dir1;i2+=dir2;var done1=i1===limit1;var done2=i2===limit2;if(done1&&!done2) return-1;if(!done1&&done2) return 1;if(done1&&done2) return 0;}};jsts.algorithm.CentralEndpointIntersector=function(p00,p01,p10,p11){this.pts=[p00,p01,p10,p11];this.compute();};jsts.algorithm.CentralEndpointIntersector.getIntersection=function(p00,p01,p10,p11){var intor=new jsts.algorithm.CentralEndpointIntersector(p00,p01,p10,p11);return intor.getIntersection();};jsts.algorithm.CentralEndpointIntersector.prototype.pts=null;jsts.algorithm.CentralEndpointIntersector.prototype.intPt=null;jsts.algorithm.CentralEndpointIntersector.prototype.compute=function(){var centroid=jsts.algorithm.CentralEndpointIntersector.average(this.pts);this.intPt=this.findNearestPoint(centroid,this.pts);};jsts.algorithm.CentralEndpointIntersector.prototype.getIntersection=function(){return this.intPt;};jsts.algorithm.CentralEndpointIntersector.average=function(pts){var avg=new jsts.geom.Coordinate();var i,n=pts.length;for(i=0;i0){avg.x/=n;avg.y/=n;} return avg;};jsts.algorithm.CentralEndpointIntersector.prototype.findNearestPoint=function(p,pts){var minDist=Number.MAX_VALUE;var i,result=null,dist;for(i=0;i0.0?distance:0.0;var bufEnvSize=envSize+2*expandByDistance;var bufEnvLog10=(Math.log(bufEnvSize)/Math.log(10)+1.0);var minUnitLog10=bufEnvLog10-maxPrecisionDigits;var scaleFactor=Math.pow(10.0,-minUnitLog10);return scaleFactor;};jsts.operation.buffer.BufferOp.bufferOp=function(g,distance){if(arguments.length>2){return jsts.operation.buffer.BufferOp.bufferOp2.apply(this,arguments);} var gBuf=new jsts.operation.buffer.BufferOp(g);var geomBuf=gBuf.getResultGeometry(distance);return geomBuf;};jsts.operation.buffer.BufferOp.bufferOp2=function(g,distance,params){if(arguments.length>3){return jsts.operation.buffer.BufferOp.bufferOp3.apply(this,arguments);} var bufOp=new jsts.operation.buffer.BufferOp(g,params);var geomBuf=bufOp.getResultGeometry(distance);return geomBuf;};jsts.operation.buffer.BufferOp.bufferOp3=function(g,distance,quadrantSegments){if(arguments.length>4){return jsts.operation.buffer.BufferOp.bufferOp4.apply(this,arguments);} var bufOp=new jsts.operation.buffer.BufferOp(g);bufOp.setQuadrantSegments(quadrantSegments);var geomBuf=bufOp.getResultGeometry(distance);return geomBuf;};jsts.operation.buffer.BufferOp.bufferOp4=function(g,distance,quadrantSegments,endCapStyle){var bufOp=new jsts.operation.buffer.BufferOp(g);bufOp.setQuadrantSegments(quadrantSegments);bufOp.setEndCapStyle(endCapStyle);var geomBuf=bufOp.getResultGeometry(distance);return geomBuf;};jsts.operation.buffer.BufferOp.prototype.argGeom=null;jsts.operation.buffer.BufferOp.prototype.distance=null;jsts.operation.buffer.BufferOp.prototype.bufParams=null;jsts.operation.buffer.BufferOp.prototype.resultGeometry=null;jsts.operation.buffer.BufferOp.prototype.setEndCapStyle=function(endCapStyle){this.bufParams.setEndCapStyle(endCapStyle);};jsts.operation.buffer.BufferOp.prototype.setQuadrantSegments=function(quadrantSegments){this.bufParams.setQuadrantSegments(quadrantSegments);};jsts.operation.buffer.BufferOp.prototype.getResultGeometry=function(dist){this.distance=dist;this.computeGeometry();return this.resultGeometry;};jsts.operation.buffer.BufferOp.prototype.computeGeometry=function(){this.bufferOriginalPrecision();if(this.resultGeometry!==null){return;} var argPM=this.argGeom.getPrecisionModel();if(argPM.getType()===jsts.geom.PrecisionModel.FIXED){this.bufferFixedPrecision(argPM);}else{this.bufferReducedPrecision();}};jsts.operation.buffer.BufferOp.prototype.bufferReducedPrecision=function(){var precDigits;var saveException=null;for(precDigits=jsts.operation.buffer.BufferOp.MAX_PRECISION_DIGITS;precDigits>=0;precDigits--){try{this.bufferReducedPrecision2(precDigits);}catch(ex){saveException=ex;} if(this.resultGeometry!==null){return;}} throw saveException;};jsts.operation.buffer.BufferOp.prototype.bufferOriginalPrecision=function(){try{var bufBuilder=new jsts.operation.buffer.BufferBuilder(this.bufParams);this.resultGeometry=bufBuilder.buffer(this.argGeom,this.distance);}catch(e){}};jsts.operation.buffer.BufferOp.prototype.bufferReducedPrecision2=function(precisionDigits){var sizeBasedScaleFactor=jsts.operation.buffer.BufferOp.precisionScaleFactor(this.argGeom,this.distance,precisionDigits);var fixedPM=new jsts.geom.PrecisionModel(sizeBasedScaleFactor);this.bufferFixedPrecision(fixedPM);};jsts.operation.buffer.BufferOp.prototype.bufferFixedPrecision=function(fixedPM){var noder=new jsts.noding.ScaledNoder(new jsts.noding.snapround.MCIndexSnapRounder(new jsts.geom.PrecisionModel(1.0)),fixedPM.getScale());var bufBuilder=new jsts.operation.buffer.BufferBuilder(this.bufParams);bufBuilder.setWorkingPrecisionModel(fixedPM);bufBuilder.setNoder(noder);this.resultGeometry=bufBuilder.buffer(this.argGeom,this.distance);};(function(){var Location=jsts.geom.Location;var Position=jsts.geomgraph.Position;var Assert=jsts.util.Assert;jsts.geomgraph.GeometryGraph=function(argIndex,parentGeom,boundaryNodeRule){jsts.geomgraph.PlanarGraph.call(this);this.lineEdgeMap=new javascript.util.HashMap();this.ptLocator=new jsts.algorithm.PointLocator();this.argIndex=argIndex;this.parentGeom=parentGeom;this.boundaryNodeRule=boundaryNodeRule||jsts.algorithm.BoundaryNodeRule.OGC_SFS_BOUNDARY_RULE;if(parentGeom!==null){this.add(parentGeom);}};jsts.geomgraph.GeometryGraph.prototype=new jsts.geomgraph.PlanarGraph();jsts.geomgraph.GeometryGraph.constructor=jsts.geomgraph.GeometryGraph;jsts.geomgraph.GeometryGraph.prototype.createEdgeSetIntersector=function(){return new jsts.geomgraph.index.SimpleMCSweepLineIntersector();};jsts.geomgraph.GeometryGraph.determineBoundary=function(boundaryNodeRule,boundaryCount){return boundaryNodeRule.isInBoundary(boundaryCount)?Location.BOUNDARY:Location.INTERIOR;};jsts.geomgraph.GeometryGraph.prototype.parentGeom=null;jsts.geomgraph.GeometryGraph.prototype.lineEdgeMap=null;jsts.geomgraph.GeometryGraph.prototype.boundaryNodeRule=null;jsts.geomgraph.GeometryGraph.prototype.useBoundaryDeterminationRule=true;jsts.geomgraph.GeometryGraph.prototype.argIndex=null;jsts.geomgraph.GeometryGraph.prototype.boundaryNodes=null;jsts.geomgraph.GeometryGraph.prototype.hasTooFewPoints=false;jsts.geomgraph.GeometryGraph.prototype.invalidPoint=null;jsts.geomgraph.GeometryGraph.prototype.areaPtLocator=null;jsts.geomgraph.GeometryGraph.prototype.ptLocator=null;jsts.geomgraph.GeometryGraph.prototype.getGeometry=function(){return this.parentGeom;};jsts.geomgraph.GeometryGraph.prototype.getBoundaryNodes=function(){if(this.boundaryNodes===null) this.boundaryNodes=this.nodes.getBoundaryNodes(this.argIndex);return this.boundaryNodes;};jsts.geomgraph.GeometryGraph.prototype.getBoundaryNodeRule=function(){return this.boundaryNodeRule;};jsts.geomgraph.GeometryGraph.prototype.findEdge=function(line){return this.lineEdgeMap.get(line);};jsts.geomgraph.GeometryGraph.prototype.computeSplitEdges=function(edgelist){for(var i=this.edges.iterator();i.hasNext();){var e=i.next();e.eiList.addSplitEdges(edgelist);}} jsts.geomgraph.GeometryGraph.prototype.add=function(g){if(g.isEmpty()){return;} if(g instanceof jsts.geom.MultiPolygon) this.useBoundaryDeterminationRule=false;if(g instanceof jsts.geom.Polygon) this.addPolygon(g);else if(g instanceof jsts.geom.LineString) this.addLineString(g);else if(g instanceof jsts.geom.Point) this.addPoint(g);else if(g instanceof jsts.geom.MultiPoint) this.addCollection(g);else if(g instanceof jsts.geom.MultiLineString) this.addCollection(g);else if(g instanceof jsts.geom.MultiPolygon) this.addCollection(g);else if(g instanceof jsts.geom.GeometryCollection) this.addCollection(g);else throw new jsts.error.IllegalArgumentError('Geometry type not supported.');};jsts.geomgraph.GeometryGraph.prototype.addCollection=function(gc){for(var i=0;i=2,'found LineString with single point');this.insertBoundaryPoint(this.argIndex,coord[0]);this.insertBoundaryPoint(this.argIndex,coord[coord.length-1]);};jsts.geomgraph.GeometryGraph.prototype.addPolygonRing=function(lr,cwLeft,cwRight){if(lr.isEmpty()) return;var coord=jsts.geom.CoordinateArrays.removeRepeatedPoints(lr.getCoordinates());if(coord.length<4){this.hasTooFewPoints=true;this.invalidPoint=coord[0];return;} var left=cwLeft;var right=cwRight;if(jsts.algorithm.CGAlgorithms.isCCW(coord)){left=cwRight;right=cwLeft;} var e=new jsts.geomgraph.Edge(coord,new jsts.geomgraph.Label(this.argIndex,Location.BOUNDARY,left,right));this.lineEdgeMap.put(lr,e);this.insertEdge(e);this.insertPoint(this.argIndex,coord[0],Location.BOUNDARY);};jsts.geomgraph.GeometryGraph.prototype.addPolygon=function(p){this.addPolygonRing(p.getExteriorRing(),Location.EXTERIOR,Location.INTERIOR);for(var i=0;i=0;i--){this.addPt(pt[i]);}}};jsts.operation.buffer.OffsetSegmentString.prototype.isRedundant=function(pt){if(this.ptList.length<1) return false;var lastPt=this.ptList[this.ptList.length-1];var ptDist=pt.distance(lastPt);if(ptDist=2) last2Pt=this.ptList[this.ptList.length-2];if(startPt.equals(lastPt)) return;this.ptList.push(startPt);};jsts.operation.buffer.OffsetSegmentString.prototype.reverse=function(){};jsts.operation.buffer.OffsetSegmentString.prototype.getCoordinates=function(){return this.ptList;};jsts.algorithm.distance.PointPairDistance=function(){this.pt=[new jsts.geom.Coordinate(),new jsts.geom.Coordinate()];};jsts.algorithm.distance.PointPairDistance.prototype.pt=null;jsts.algorithm.distance.PointPairDistance.prototype.distance=NaN;jsts.algorithm.distance.PointPairDistance.prototype.isNull=true;jsts.algorithm.distance.PointPairDistance.prototype.initialize=function(p0,p1,distance){if(p0===undefined){this.isNull=true;return;} this.pt[0].setCoordinate(p0);this.pt[1].setCoordinate(p1);this.distance=distance!==undefined?distance:p0.distance(p1);this.isNull=false;};jsts.algorithm.distance.PointPairDistance.prototype.getDistance=function(){return this.distance;};jsts.algorithm.distance.PointPairDistance.prototype.getCoordinates=function(){return this.pt;};jsts.algorithm.distance.PointPairDistance.prototype.getCoordinate=function(i){return this.pt[i];};jsts.algorithm.distance.PointPairDistance.prototype.setMaximum=function(ptDist){if(arguments.length===2){this.setMaximum2.apply(this,arguments);return;} this.setMaximum(ptDist.pt[0],ptDist.pt[1]);};jsts.algorithm.distance.PointPairDistance.prototype.setMaximum2=function(p0,p1){if(this.isNull){this.initialize(p0,p1);return;} var dist=p0.distance(p1);if(dist>this.distance) this.initialize(p0,p1,dist);};jsts.algorithm.distance.PointPairDistance.prototype.setMinimum=function(ptDist){if(arguments.length===2){this.setMinimum2.apply(this,arguments);return;} this.setMinimum(ptDist.pt[0],ptDist.pt[1]);};jsts.algorithm.distance.PointPairDistance.prototype.setMinimum2=function(p0,p1){if(this.isNull){this.initialize(p0,p1);return;} var dist=p0.distance(p1);if(dist1.0||densifyFrac<=0.0) throw new jsts.error.IllegalArgumentError('Fraction is not in range (0.0 - 1.0]');this.densifyFrac=densifyFrac;};jsts.algorithm.distance.DiscreteHausdorffDistance.prototype.distance=function(){this.compute(this.g0,this.g1);return ptDist.getDistance();};jsts.algorithm.distance.DiscreteHausdorffDistance.prototype.orientedDistance=function(){this.computeOrientedDistance(this.g0,this.g1,this.ptDist);return this.ptDist.getDistance();};jsts.algorithm.distance.DiscreteHausdorffDistance.prototype.getCoordinates=function(){return ptDist.getCoordinates();};jsts.algorithm.distance.DiscreteHausdorffDistance.prototype.compute=function(g0,g1){this.computeOrientedDistance(g0,g1,this.ptDist);this.computeOrientedDistance(g1,g0,this.ptDist);};jsts.algorithm.distance.DiscreteHausdorffDistance.prototype.computeOrientedDistance=function(discreteGeom,geom,ptDist){var distFilter=new MaxPointDistanceFilter(geom);discreteGeom.apply(distFilter);ptDist.setMaximum(distFilter.getMaxPointDistance());if(this.densifyFrac>0){var fracFilter=new MaxDensifiedByFractionDistanceFilter(geom,this.densifyFrac);discreteGeom.apply(fracFilter);ptDist.setMaximum(fracFilter.getMaxPointDistance());}};})();jsts.algorithm.MinimumBoundingCircle=function(geom){this.input=null;this.extremalPts=null;this.centre=null;this.radius=0;this.input=geom;};jsts.algorithm.MinimumBoundingCircle.prototype.getCircle=function(){this.compute();if(this.centre===null){return this.input.getFactory().createPolygon(null,null);} var centrePoint=this.input.getFactory().createPoint(this.centre);if(this.radius===0){return centrePoint;} return centrePoint.buffer(this.radius);};jsts.algorithm.MinimumBoundingCircle.prototype.getExtremalPoints=function(){this.compute();return this.extremalPts;};jsts.algorithm.MinimumBoundingCircle.prototype.getCentre=function(){this.compute();return this.centre;};jsts.algorithm.MinimumBoundingCircle.prototype.getRadius=function(){this.compute();return this.radius;};jsts.algorithm.MinimumBoundingCircle.prototype.computeCentre=function(){switch(this.extremalPts.length){case 0:this.centre=null;break;case 1:this.centre=this.extremalPts[0];break;case 2:this.centre=new jsts.geom.Coordinate((this.extremalPts[0].x+this.extremalPts[1].x)/2,(this.extremalPts[0].y+this.extremalPts[1].y)/2);break;case 3:this.centre=jsts.geom.Triangle.circumcentre(this.extremalPts[0],this.extremalPts[1],this.extremalPts[2]);break;}};jsts.algorithm.MinimumBoundingCircle.prototype.compute=function(){if(this.extremalPts!==null){return;} this.computeCirclePoints();this.computeCentre();if(this.centre!==null){this.radius=this.centre.distance(this.extremalPts[0]);}};jsts.algorithm.MinimumBoundingCircle.prototype.computeCirclePoints=function(){if(this.input.isEmpty()){this.extremalPts=[];return;} var pts;if(this.input.getNumPoints()===1){pts=this.input.getCoordinates();this.extremalPts=[new jsts.geom.Coordinate(pts[0])];return;} var convexHull=this.input.convexHull();var hullPts=convexHull.getCoordinates();pts=hullPts;if(hullPts[0].equals2D(hullPts[hullPts.length-1])){pts=[];jsts.geom.CoordinateArrays.copyDeep(hullPts,0,pts,0,hullPts.length-1);} if(pts.length<=2){this.extremalPts=jsts.geom.CoordinateArrays.copyDeep(pts);return;} var P=jsts.algorithm.MinimumBoundingCircle.lowestPoint(pts);var Q=jsts.algorithm.MinimumBoundingCircle.pointWitMinAngleWithX(pts,P);for(var i=0;ia||a>=this.size())throw new k;return this.a[a]};s.prototype.get=s.prototype.get;s.prototype.g=function(){return 0===this.a.length};s.prototype.isEmpty=s.prototype.g;s.prototype.size=function(){return this.a.length};s.prototype.size=s.prototype.size;s.prototype.h=function(){for(var a=[],b=0,c=this.a.length;bc)b=b.left;else if(0t)c=c.left;else if(0t?d.left=c:d.right=c;for(c.color=1;null!=c&&c!=this.d&&1==c.parent.color;)D(c)==F(D(D(c)))?(d=G(D(D(c))),1==(null==d?0:d.color)?(E(D(c),0),E(d,0),E(D(D(c)),1),c=D(D(c))):(c==G(D(c))&& (c=D(c),I(this,c)),E(D(c),0),E(D(D(c)),1),J(this,D(D(c))))):(d=F(D(D(c))),1==(null==d?0:d.color)?(E(D(c),0),E(d,0),E(D(D(c)),1),c=D(D(c))):(c==F(D(c))&&(c=D(c),J(this,c)),E(D(c),0),E(D(D(c)),1),I(this,D(D(c)))));this.d.color=0;this.n++;return null};H.prototype.put=H.prototype.put;H.prototype.m=function(){var a=new s,b;b=this.d;if(null!=b)for(;null!=b.left;)b=b.left;if(null!==b)for(a.add(b.value);null!==(b=K(b));)a.add(b.value);return a};H.prototype.values=H.prototype.m; function I(a,b){if(null!=b){var c=b.right;b.right=c.left;null!=c.left&&(c.left.parent=b);c.parent=b.parent;null==b.parent?a.d=c:b.parent.left==b?b.parent.left=c:b.parent.right=c;c.left=b;b.parent=c}}function J(a,b){if(null!=b){var c=b.left;b.left=c.right;null!=c.right&&(c.right.parent=b);c.parent=b.parent;null==b.parent?a.d=c:b.parent.right==b?b.parent.right=c:b.parent.left=c;c.right=b;b.parent=c}} function K(a){if(null===a)return null;if(null!==a.right)for(var b=a.right;null!==b.left;)b=b.left;else for(b=a.parent;null!==b&&a===b.right;)a=b,b=b.parent;return b}H.prototype.size=function(){return this.n};H.prototype.size=H.prototype.size;function L(a){this.a=[];a instanceof m&&this.e(a)}g(L,B);f("javascript.util.TreeSet",L);L.prototype.a=null;L.prototype.contains=function(a){for(var b=0,c=this.a.length;b points[hi][0]) { hi = i } } if(lo < hi) { return [[lo], [hi]] } else if(lo > hi) { return [[hi], [lo]] } else { return [[lo]] } } },{}],29:[function(require,module,exports){ 'use strict' module.exports = convexHull2D var monotoneHull = require('monotone-convex-hull-2d') function convexHull2D(points) { var hull = monotoneHull(points) var h = hull.length if(h <= 2) { return [] } var edges = new Array(h) var a = hull[h-1] for(var i=0; i= front[k]) { x += 1 } } c[j] = x } } } return cells } function convexHullnD(points, d) { try { return ich(points, true) } catch(e) { //If point set is degenerate, try to find a basis and rerun it var ah = aff(points) if(ah.length <= d) { //No basis, no try return [] } var npoints = permute(points, ah) var nhull = ich(npoints, true) return invPermute(nhull, ah) } } },{"affine-hull":31,"incremental-convex-hull":38}],31:[function(require,module,exports){ 'use strict' module.exports = affineHull var orient = require('robust-orientation') function linearlyIndependent(points, d) { var nhull = new Array(d+1) for(var i=0; i= nf)) { a = ei eptr += 1 if(eptr < ne) { ei = e[eptr] ea = abs(ei) } } else { a = fi fptr += 1 if(fptr < nf) { fi = -f[fptr] fa = abs(fi) } } var x = a + b var bv = x - a var y = b - bv var q0 = y var q1 = x var _x, _bv, _av, _br, _ar while(eptr < ne && fptr < nf) { if(ea < fa) { a = ei eptr += 1 if(eptr < ne) { ei = e[eptr] ea = abs(ei) } } else { a = fi fptr += 1 if(fptr < nf) { fi = -f[fptr] fa = abs(fi) } } b = q0 x = a + b bv = x - a y = b - bv if(y) { g[count++] = y } _x = q1 + x _bv = _x - q1 _av = _x - _bv _br = x - _bv _ar = q1 - _av q0 = _ar + _br q1 = _x } while(eptr < ne) { a = ei b = q0 x = a + b bv = x - a y = b - bv if(y) { g[count++] = y } _x = q1 + x _bv = _x - q1 _av = _x - _bv _br = x - _bv _ar = q1 - _av q0 = _ar + _br q1 = _x eptr += 1 if(eptr < ne) { ei = e[eptr] } } while(fptr < nf) { a = fi b = q0 x = a + b bv = x - a y = b - bv if(y) { g[count++] = y } _x = q1 + x _bv = _x - q1 _av = _x - _bv _br = x - _bv _ar = q1 - _av q0 = _ar + _br q1 = _x fptr += 1 if(fptr < nf) { fi = -f[fptr] } } if(q0) { g[count++] = q0 } if(q1) { g[count++] = q1 } if(!count) { g[count++] = 0.0 } g.length = count return g } },{}],35:[function(require,module,exports){ "use strict" module.exports = linearExpansionSum //Easy case: Add two scalars function scalarScalar(a, b) { var x = a + b var bv = x - a var av = x - bv var br = b - bv var ar = a - av var y = ar + br if(y) { return [y, x] } return [x] } function linearExpansionSum(e, f) { var ne = e.length|0 var nf = f.length|0 if(ne === 1 && nf === 1) { return scalarScalar(e[0], f[0]) } var n = ne + nf var g = new Array(n) var count = 0 var eptr = 0 var fptr = 0 var abs = Math.abs var ei = e[eptr] var ea = abs(ei) var fi = f[fptr] var fa = abs(fi) var a, b if(ea < fa) { b = ei eptr += 1 if(eptr < ne) { ei = e[eptr] ea = abs(ei) } } else { b = fi fptr += 1 if(fptr < nf) { fi = f[fptr] fa = abs(fi) } } if((eptr < ne && ea < fa) || (fptr >= nf)) { a = ei eptr += 1 if(eptr < ne) { ei = e[eptr] ea = abs(ei) } } else { a = fi fptr += 1 if(fptr < nf) { fi = f[fptr] fa = abs(fi) } } var x = a + b var bv = x - a var y = b - bv var q0 = y var q1 = x var _x, _bv, _av, _br, _ar while(eptr < ne && fptr < nf) { if(ea < fa) { a = ei eptr += 1 if(eptr < ne) { ei = e[eptr] ea = abs(ei) } } else { a = fi fptr += 1 if(fptr < nf) { fi = f[fptr] fa = abs(fi) } } b = q0 x = a + b bv = x - a y = b - bv if(y) { g[count++] = y } _x = q1 + x _bv = _x - q1 _av = _x - _bv _br = x - _bv _ar = q1 - _av q0 = _ar + _br q1 = _x } while(eptr < ne) { a = ei b = q0 x = a + b bv = x - a y = b - bv if(y) { g[count++] = y } _x = q1 + x _bv = _x - q1 _av = _x - _bv _br = x - _bv _ar = q1 - _av q0 = _ar + _br q1 = _x eptr += 1 if(eptr < ne) { ei = e[eptr] } } while(fptr < nf) { a = fi b = q0 x = a + b bv = x - a y = b - bv if(y) { g[count++] = y } _x = q1 + x _bv = _x - q1 _av = _x - _bv _br = x - _bv _ar = q1 - _av q0 = _ar + _br q1 = _x fptr += 1 if(fptr < nf) { fi = f[fptr] } } if(q0) { g[count++] = q0 } if(q1) { g[count++] = q1 } if(!count) { g[count++] = 0.0 } g.length = count return g } },{}],36:[function(require,module,exports){ "use strict" module.exports = twoProduct var SPLITTER = +(Math.pow(2, 27) + 1.0) function twoProduct(a, b, result) { var x = a * b var c = SPLITTER * a var abig = c - a var ahi = c - abig var alo = a - ahi var d = SPLITTER * b var bbig = d - b var bhi = d - bbig var blo = b - bhi var err1 = x - (ahi * bhi) var err2 = err1 - (alo * bhi) var err3 = err2 - (ahi * blo) var y = alo * blo - err3 if(result) { result[0] = y result[1] = x return result } return [ y, x ] } },{}],37:[function(require,module,exports){ "use strict" var twoProduct = require("two-product") var robustSum = require("robust-sum") var robustScale = require("robust-scale") var robustSubtract = require("robust-subtract") var NUM_EXPAND = 5 var EPSILON = 1.1102230246251565e-16 var ERRBOUND3 = (3.0 + 16.0 * EPSILON) * EPSILON var ERRBOUND4 = (7.0 + 56.0 * EPSILON) * EPSILON function cofactor(m, c) { var result = new Array(m.length-1) for(var i=1; i>1 return ["sum(", generateSum(expr.slice(0, m)), ",", generateSum(expr.slice(m)), ")"].join("") } } function determinant(m) { if(m.length === 2) { return [["sum(prod(", m[0][0], ",", m[1][1], "),prod(-", m[0][1], ",", m[1][0], "))"].join("")] } else { var expr = [] for(var i=0; i 0) { if(r <= 0) { return det } else { s = l + r } } else if(l < 0) { if(r >= 0) { return det } else { s = -(l + r) } } else { return det } var tol = ERRBOUND3 * s if(det >= tol || det <= -tol) { return det } return orientation3Exact(a, b, c) }, function orientation4(a,b,c,d) { var adx = a[0] - d[0] var bdx = b[0] - d[0] var cdx = c[0] - d[0] var ady = a[1] - d[1] var bdy = b[1] - d[1] var cdy = c[1] - d[1] var adz = a[2] - d[2] var bdz = b[2] - d[2] var cdz = c[2] - d[2] var bdxcdy = bdx * cdy var cdxbdy = cdx * bdy var cdxady = cdx * ady var adxcdy = adx * cdy var adxbdy = adx * bdy var bdxady = bdx * ady var det = adz * (bdxcdy - cdxbdy) + bdz * (cdxady - adxcdy) + cdz * (adxbdy - bdxady) var permanent = (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * Math.abs(adz) + (Math.abs(cdxady) + Math.abs(adxcdy)) * Math.abs(bdz) + (Math.abs(adxbdy) + Math.abs(bdxady)) * Math.abs(cdz) var tol = ERRBOUND4 * permanent if ((det > tol) || (-det > tol)) { return det } return orientation4Exact(a,b,c,d) } ] function slowOrient(args) { var proc = CACHED[args.length] if(!proc) { proc = CACHED[args.length] = orientation(args.length) } return proc.apply(undefined, args) } function generateOrientationProc() { while(CACHED.length <= NUM_EXPAND) { CACHED.push(orientation(CACHED.length)) } var args = [] var procArgs = ["slow"] for(var i=0; i<=NUM_EXPAND; ++i) { args.push("a" + i) procArgs.push("o" + i) } var code = [ "function getOrientation(", args.join(), "){switch(arguments.length){case 0:case 1:return 0;" ] for(var i=2; i<=NUM_EXPAND; ++i) { code.push("case ", i, ":return o", i, "(", args.slice(0, i).join(), ");") } code.push("}var s=new Array(arguments.length);for(var i=0;i 0) { code.push(",") } code.push("tuple[", i, "]") } code.push(")}return orient") var proc = new Function("test", code.join("")) var test = orient[d+1] if(!test) { test = orient } return proc(test) } var BAKED = [] function Triangulation(dimension, vertices, simplices) { this.dimension = dimension this.vertices = vertices this.simplices = simplices this.interior = simplices.filter(function(c) { return !c.boundary }) this.tuple = new Array(dimension+1) for(var i=0; i<=dimension; ++i) { this.tuple[i] = this.vertices[i] } var o = BAKED[dimension] if(!o) { o = BAKED[dimension] = bakeOrient(dimension) } this.orient = o } var proto = Triangulation.prototype //Degenerate situation where we are on boundary, but coplanar to face proto.handleBoundaryDegeneracy = function(cell, point) { var d = this.dimension var n = this.vertices.length - 1 var tuple = this.tuple var verts = this.vertices //Dumb solution: Just do dfs from boundary cell until we find any peak, or terminate var toVisit = [ cell ] cell.lastVisited = -n while(toVisit.length > 0) { cell = toVisit.pop() var cellVerts = cell.vertices var cellAdj = cell.adjacent for(var i=0; i<=d; ++i) { var neighbor = cellAdj[i] if(!neighbor.boundary || neighbor.lastVisited <= -n) { continue } var nv = neighbor.vertices for(var j=0; j<=d; ++j) { var vv = nv[j] if(vv < 0) { tuple[j] = point } else { tuple[j] = verts[vv] } } var o = this.orient() if(o > 0) { return neighbor } neighbor.lastVisited = -n if(o === 0) { toVisit.push(neighbor) } } } return null } proto.walk = function(point, random) { //Alias local properties var n = this.vertices.length - 1 var d = this.dimension var verts = this.vertices var tuple = this.tuple //Compute initial jump cell var initIndex = random ? (this.interior.length * Math.random())|0 : (this.interior.length-1) var cell = this.interior[ initIndex ] //Start walking outerLoop: while(!cell.boundary) { var cellVerts = cell.vertices var cellAdj = cell.adjacent for(var i=0; i<=d; ++i) { tuple[i] = verts[cellVerts[i]] } cell.lastVisited = n //Find farthest adjacent cell for(var i=0; i<=d; ++i) { var neighbor = cellAdj[i] if(neighbor.lastVisited >= n) { continue } var prev = tuple[i] tuple[i] = point var o = this.orient() tuple[i] = prev if(o < 0) { cell = neighbor continue outerLoop } else { if(!neighbor.boundary) { neighbor.lastVisited = n } else { neighbor.lastVisited = -n } } } return } return cell } proto.addPeaks = function(point, cell) { var n = this.vertices.length - 1 var d = this.dimension var verts = this.vertices var tuple = this.tuple var interior = this.interior var simplices = this.simplices //Walking finished at boundary, time to add peaks var tovisit = [ cell ] //Stretch initial boundary cell into a peak cell.lastVisited = n cell.vertices[cell.vertices.indexOf(-1)] = n cell.boundary = false interior.push(cell) //Record a list of all new boundaries created by added peaks so we can glue them together when we are all done var glueFacets = [] //Do a traversal of the boundary walking outward from starting peak while(tovisit.length > 0) { //Pop off peak and walk over adjacent cells var cell = tovisit.pop() var cellVerts = cell.vertices var cellAdj = cell.adjacent var indexOfN = cellVerts.indexOf(n) if(indexOfN < 0) { continue } for(var i=0; i<=d; ++i) { if(i === indexOfN) { continue } //For each boundary neighbor of the cell var neighbor = cellAdj[i] if(!neighbor.boundary || neighbor.lastVisited >= n) { continue } var nv = neighbor.vertices //Test if neighbor is a peak if(neighbor.lastVisited !== -n) { //Compute orientation of p relative to each boundary peak var indexOfNeg1 = 0 for(var j=0; j<=d; ++j) { if(nv[j] < 0) { indexOfNeg1 = j tuple[j] = point } else { tuple[j] = verts[nv[j]] } } var o = this.orient() //Test if neighbor cell is also a peak if(o > 0) { nv[indexOfNeg1] = n neighbor.boundary = false interior.push(neighbor) tovisit.push(neighbor) neighbor.lastVisited = n continue } else { neighbor.lastVisited = -n } } var na = neighbor.adjacent //Otherwise, replace neighbor with new face var vverts = cellVerts.slice() var vadj = cellAdj.slice() var ncell = new Simplex(vverts, vadj, true) simplices.push(ncell) //Connect to neighbor var opposite = na.indexOf(cell) if(opposite < 0) { continue } na[opposite] = ncell vadj[indexOfN] = neighbor //Connect to cell vverts[i] = -1 vadj[i] = cell cellAdj[i] = ncell //Flip facet ncell.flip() //Add to glue list for(var j=0; j<=d; ++j) { var uu = vverts[j] if(uu < 0 || uu === n) { continue } var nface = new Array(d-1) var nptr = 0 for(var k=0; k<=d; ++k) { var vv = vverts[k] if(vv < 0 || k === j) { continue } nface[nptr++] = vv } glueFacets.push(new GlueFacet(nface, ncell, j)) } } } //Glue boundary facets together glueFacets.sort(compareGlue) for(var i=0; i+1= 0) { bcell[ptr++] = cv[j] } else { parity = j&1 } } if(parity === (d&1)) { var t = bcell[0] bcell[0] = bcell[1] bcell[1] = t } boundary.push(bcell) } } return boundary } function incrementalConvexHull(points, randomSearch) { var n = points.length if(n === 0) { throw new Error("Must have at least d+1 points") } var d = points[0].length if(n <= d) { throw new Error("Must input at least d+1 points") } //FIXME: This could be degenerate, but need to select d+1 non-coplanar points to bootstrap process var initialSimplex = points.slice(0, d+1) //Make sure initial simplex is positively oriented var o = orient.apply(void 0, initialSimplex) if(o === 0) { throw new Error("Input not in general position") } var initialCoords = new Array(d+1) for(var i=0; i<=d; ++i) { initialCoords[i] = i } if(o < 0) { initialCoords[0] = 1 initialCoords[1] = 0 } //Create initial topological index, glue pointers together (kind of messy) var initialCell = new Simplex(initialCoords, new Array(d+1), false) var boundary = initialCell.adjacent var list = new Array(d+2) for(var i=0; i<=d; ++i) { var verts = initialCoords.slice() for(var j=0; j<=d; ++j) { if(j === i) { verts[j] = -1 } } var t = verts[0] verts[0] = verts[1] verts[1] = t var cell = new Simplex(verts, new Array(d+1), true) boundary[i] = cell list[i] = cell } list[d+1] = initialCell for(var i=0; i<=d; ++i) { var verts = boundary[i].vertices var adj = boundary[i].adjacent for(var j=0; j<=d; ++j) { var v = verts[j] if(v < 0) { adj[j] = initialCell continue } for(var k=0; k<=d; ++k) { if(boundary[k].vertices.indexOf(v) < 0) { adj[j] = boundary[k] } } } } //Initialize triangles var triangles = new Triangulation(d, initialSimplex, list) //Insert remaining points var useRandom = !!randomSearch for(var i=d+1; i 0) - (v < 0); } //Computes absolute value of integer exports.abs = function(v) { var mask = v >> (INT_BITS-1); return (v ^ mask) - mask; } //Computes minimum of integers x and y exports.min = function(x, y) { return y ^ ((x ^ y) & -(x < y)); } //Computes maximum of integers x and y exports.max = function(x, y) { return x ^ ((x ^ y) & -(x < y)); } //Checks if a number is a power of two exports.isPow2 = function(v) { return !(v & (v-1)) && (!!v); } //Computes log base 2 of v exports.log2 = function(v) { var r, shift; r = (v > 0xFFFF) << 4; v >>>= r; shift = (v > 0xFF ) << 3; v >>>= shift; r |= shift; shift = (v > 0xF ) << 2; v >>>= shift; r |= shift; shift = (v > 0x3 ) << 1; v >>>= shift; r |= shift; return r | (v >> 1); } //Computes log base 10 of v exports.log10 = function(v) { return (v >= 1000000000) ? 9 : (v >= 100000000) ? 8 : (v >= 10000000) ? 7 : (v >= 1000000) ? 6 : (v >= 100000) ? 5 : (v >= 10000) ? 4 : (v >= 1000) ? 3 : (v >= 100) ? 2 : (v >= 10) ? 1 : 0; } //Counts number of bits exports.popCount = function(v) { v = v - ((v >>> 1) & 0x55555555); v = (v & 0x33333333) + ((v >>> 2) & 0x33333333); return ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; } //Counts number of trailing zeros function countTrailingZeros(v) { var c = 32; v &= -v; if (v) c--; if (v & 0x0000FFFF) c -= 16; if (v & 0x00FF00FF) c -= 8; if (v & 0x0F0F0F0F) c -= 4; if (v & 0x33333333) c -= 2; if (v & 0x55555555) c -= 1; return c; } exports.countTrailingZeros = countTrailingZeros; //Rounds to next power of 2 exports.nextPow2 = function(v) { v += v === 0; --v; v |= v >>> 1; v |= v >>> 2; v |= v >>> 4; v |= v >>> 8; v |= v >>> 16; return v + 1; } //Rounds down to previous power of 2 exports.prevPow2 = function(v) { v |= v >>> 1; v |= v >>> 2; v |= v >>> 4; v |= v >>> 8; v |= v >>> 16; return v - (v>>>1); } //Computes parity of word exports.parity = function(v) { v ^= v >>> 16; v ^= v >>> 8; v ^= v >>> 4; v &= 0xf; return (0x6996 >>> v) & 1; } var REVERSE_TABLE = new Array(256); (function(tab) { for(var i=0; i<256; ++i) { var v = i, r = i, s = 7; for (v >>>= 1; v; v >>>= 1) { r <<= 1; r |= v & 1; --s; } tab[i] = (r << s) & 0xff; } })(REVERSE_TABLE); //Reverse bits in a 32 bit word exports.reverse = function(v) { return (REVERSE_TABLE[ v & 0xff] << 24) | (REVERSE_TABLE[(v >>> 8) & 0xff] << 16) | (REVERSE_TABLE[(v >>> 16) & 0xff] << 8) | REVERSE_TABLE[(v >>> 24) & 0xff]; } //Interleave bits of 2 coordinates with 16 bits. Useful for fast quadtree codes exports.interleave2 = function(x, y) { x &= 0xFFFF; x = (x | (x << 8)) & 0x00FF00FF; x = (x | (x << 4)) & 0x0F0F0F0F; x = (x | (x << 2)) & 0x33333333; x = (x | (x << 1)) & 0x55555555; y &= 0xFFFF; y = (y | (y << 8)) & 0x00FF00FF; y = (y | (y << 4)) & 0x0F0F0F0F; y = (y | (y << 2)) & 0x33333333; y = (y | (y << 1)) & 0x55555555; return x | (y << 1); } //Extracts the nth interleaved component exports.deinterleave2 = function(v, n) { v = (v >>> n) & 0x55555555; v = (v | (v >>> 1)) & 0x33333333; v = (v | (v >>> 2)) & 0x0F0F0F0F; v = (v | (v >>> 4)) & 0x00FF00FF; v = (v | (v >>> 16)) & 0x000FFFF; return (v << 16) >> 16; } //Interleave bits of 3 coordinates, each with 10 bits. Useful for fast octree codes exports.interleave3 = function(x, y, z) { x &= 0x3FF; x = (x | (x<<16)) & 4278190335; x = (x | (x<<8)) & 251719695; x = (x | (x<<4)) & 3272356035; x = (x | (x<<2)) & 1227133513; y &= 0x3FF; y = (y | (y<<16)) & 4278190335; y = (y | (y<<8)) & 251719695; y = (y | (y<<4)) & 3272356035; y = (y | (y<<2)) & 1227133513; x |= (y << 1); z &= 0x3FF; z = (z | (z<<16)) & 4278190335; z = (z | (z<<8)) & 251719695; z = (z | (z<<4)) & 3272356035; z = (z | (z<<2)) & 1227133513; return x | (z << 2); } //Extracts nth interleaved component of a 3-tuple exports.deinterleave3 = function(v, n) { v = (v >>> n) & 1227133513; v = (v | (v>>>2)) & 3272356035; v = (v | (v>>>4)) & 251719695; v = (v | (v>>>8)) & 4278190335; v = (v | (v>>>16)) & 0x3FF; return (v<<22)>>22; } //Computes next combination in colexicographic order (this is mistakenly called nextPermutation on the bit twiddling hacks page) exports.nextCombination = function(v) { var t = v | (v - 1); return (t + 1) | (((~t & -~t) - 1) >>> (countTrailingZeros(v) + 1)); } },{}],46:[function(require,module,exports){ "use strict"; "use restrict"; module.exports = UnionFind; function UnionFind(count) { this.roots = new Array(count); this.ranks = new Array(count); for(var i=0; i> 1 , s = compareCells(cells[mid], c) if(s <= 0) { if(s === 0) { r = mid } lo = mid + 1 } else if(s > 0) { hi = mid - 1 } } return r } exports.findCell = findCell; //Builds an index for an n-cell. This is more general than dual, but less efficient function incidence(from_cells, to_cells) { var index = new Array(from_cells.length) for(var i=0, il=index.length; i= from_cells.length || compareCells(from_cells[idx], b) !== 0) { break } } } } return index } exports.incidence = incidence //Computes the dual of the mesh. This is basically an optimized version of buildIndex for the situation where from_cells is just the list of vertices function dual(cells, vertex_count) { if(!vertex_count) { return incidence(unique(skeleton(cells, 0)), cells, 0) } var res = new Array(vertex_count) for(var i=0; i>> k) & 1) { b.push(c[k]) } } result.push(b) } } return normalize(result) } exports.explode = explode //Enumerates all of the n-cells of a cell complex function skeleton(cells, n) { if(n < 0) { return [] } var result = [] , k0 = (1<<(n+1))-1 for(var i=0; i 1 && orient( points[lower[m-2]], points[lower[m-1]], p) <= 0) { m -= 1 lower.pop() } lower.push(idx) //Insert into upper list m = upper.length while(m > 1 && orient( points[upper[m-2]], points[upper[m-1]], p) >= 0) { m -= 1 upper.pop() } upper.push(idx) } //Merge lists together var result = new Array(upper.length + lower.length - 2) var ptr = 0 for(var i=0, nl=lower.length; i0; --j) { result[ptr++] = upper[j] } //Return result return result } },{"robust-orientation":54}],49:[function(require,module,exports){ arguments[4][32][0].apply(exports,arguments) },{"dup":32}],50:[function(require,module,exports){ arguments[4][33][0].apply(exports,arguments) },{"dup":33,"two-product":53,"two-sum":49}],51:[function(require,module,exports){ arguments[4][34][0].apply(exports,arguments) },{"dup":34}],52:[function(require,module,exports){ arguments[4][35][0].apply(exports,arguments) },{"dup":35}],53:[function(require,module,exports){ arguments[4][36][0].apply(exports,arguments) },{"dup":36}],54:[function(require,module,exports){ arguments[4][37][0].apply(exports,arguments) },{"dup":37,"robust-scale":50,"robust-subtract":51,"robust-sum":52,"two-product":53}],55:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"dup":23}],56:[function(require,module,exports){ var inside = require('turf-inside'); /** * Takes a {@link FeatureCollection} of {@link Point} features and a {@link FeatureCollection} of {@link Polygon} features and calculates the number of points that fall within the set of polygons. * * @module turf/count * @category aggregation * @param {FeatureCollection} polygons a FeatureCollection of {@link Polygon} features * @param {FeatureCollection} points a FeatureCollection of {@link Point} features * @param {String} countField a field to append to the attributes of the Polygon features representing Point counts * @return {FeatureCollection} a FeatureCollection of Polygon features with `countField` appended * @example * var polygons = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-112.072391,46.586591], * [-112.072391,46.61761], * [-112.028102,46.61761], * [-112.028102,46.586591], * [-112.072391,46.586591] * ]] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-112.023983,46.570426], * [-112.023983,46.615016], * [-111.966133,46.615016], * [-111.966133,46.570426], * [-112.023983,46.570426] * ]] * } * } * ] * }; * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [-112.0372, 46.608058] * } * }, { * "type": "Feature", * "properties": { * "population": 600 * }, * "geometry": { * "type": "Point", * "coordinates": [-112.045955, 46.596264] * } * } * ] * }; * * var counted = turf.count(polygons, points, 'pt_count'); * * var resultFeatures = points.features.concat(counted.features); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ module.exports = function(polyFC, ptFC, outField, done){ for (var i = 0; i < polyFC.features.length; i++) { var poly = polyFC.features[i]; if(!poly.properties) poly.properties = {}; var values = 0; for (var j = 0; j < ptFC.features.length; j++) { var pt = ptFC.features[j]; if (inside(pt, poly)) { values++; } } poly.properties[outField] = values; } return polyFC; }; },{"turf-inside":76}],57:[function(require,module,exports){ //http://en.wikipedia.org/wiki/Haversine_formula //http://www.movable-type.co.uk/scripts/latlong.html var point = require('turf-point'); /** * Takes a {@link Point} feature and calculates the location of a destination point given a distance in degrees, radians, miles, or kilometers; and bearing in degrees. This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature. * * @module turf/destination * @category measurement * @param {Point} start a Point feature at the starting point * @param {Number} distance distance from the starting point * @param {Number} bearing ranging from -180 to 180 * @param {String} units miles, kilometers, degrees, or radians * @returns {Point} a Point feature at the destination * @example * var point = { * "type": "Feature", * "properties": { * "marker-color": "#0f0" * }, * "geometry": { * "type": "Point", * "coordinates": [-75.343, 39.984] * } * }; * var distance = 50; * var bearing = 90; * var units = 'miles'; * * var destination = turf.destination(point, distance, bearing, units); * destination.properties['marker-color'] = '#f00'; * * var result = { * "type": "FeatureCollection", * "features": [point, destination] * }; * * //=result */ module.exports = function (point1, distance, bearing, units) { var coordinates1 = point1.geometry.coordinates; var longitude1 = toRad(coordinates1[0]); var latitude1 = toRad(coordinates1[1]); var bearing_rad = toRad(bearing); var R = 0; switch (units) { case 'miles': R = 3960; break case 'kilometers': R = 6373; break case 'degrees': R = 57.2957795; break case 'radians': R = 1; break } var latitude2 = Math.asin(Math.sin(latitude1) * Math.cos(distance / R) + Math.cos(latitude1) * Math.sin(distance / R) * Math.cos(bearing_rad)); var longitude2 = longitude1 + Math.atan2(Math.sin(bearing_rad) * Math.sin(distance / R) * Math.cos(latitude1), Math.cos(distance / R) - Math.sin(latitude1) * Math.sin(latitude2)); return point([toDeg(longitude2), toDeg(latitude2)]); }; function toRad(degree) { return degree * Math.PI / 180; } function toDeg(rad) { return rad * 180 / Math.PI; } },{"turf-point":102}],58:[function(require,module,exports){ var ss = require('simple-statistics'); var inside = require('turf-inside'); /** * Calculates the standard deviation value of a field for points within a set of polygons. * * @module turf/deviation * @category aggregation * @param {FeatureCollection} polygons a FeatureCollection of {@link Polygon} features * @param {FeatureCollection} points a FeatureCollection of {@link Point} features * @param {String} inField the field in `points` from which to aggregate * @param {String} outField the field to append to `polygons` representing deviation * @return {FeatureCollection} a FeatureCollection of Polygon features with appended field representing deviation * @example * var polygons = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-97.807159, 30.270335], * [-97.807159, 30.369913], * [-97.612838, 30.369913], * [-97.612838, 30.270335], * [-97.807159, 30.270335] * ]] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-97.825698, 30.175405], * [-97.825698, 30.264404], * [-97.630691, 30.264404], * [-97.630691, 30.175405], * [-97.825698, 30.175405] * ]] * } * } * ] * }; * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "population": 500 * }, * "geometry": { * "type": "Point", * "coordinates": [-97.709655, 30.311245] * } * }, { * "type": "Feature", * "properties": { * "population": 400 * }, * "geometry": { * "type": "Point", * "coordinates": [-97.766647, 30.345028] * } * }, { * "type": "Feature", * "properties": { * "population": 600 * }, * "geometry": { * "type": "Point", * "coordinates": [-97.765274, 30.294646] * } * }, { * "type": "Feature", * "properties": { * "population": 500 * }, * "geometry": { * "type": "Point", * "coordinates": [-97.753601, 30.216355] * } * }, { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [-97.667083, 30.208047] * } * } * ] * }; * * var inField = "population"; * var outField = "pop_deviation"; * * var deviated = turf.deviation( * polygons, points, inField, outField); * * var resultFeatures = points.features.concat( * deviated.features); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ module.exports = function(polyFC, ptFC, inField, outField, done){ polyFC.features.forEach(function(poly){ if(!poly.properties){ poly.properties = {}; } var values = []; ptFC.features.forEach(function(pt){ if (inside(pt, poly)) { values.push(pt.properties[inField]); } }); poly.properties[outField] = ss.standard_deviation(values); }) return polyFC; } },{"simple-statistics":59,"turf-inside":76}],59:[function(require,module,exports){ /* global module */ // # simple-statistics // // A simple, literate statistics system. The code below uses the // [Javascript module pattern](http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth), // eventually assigning `simple-statistics` to `ss` in browsers or the // `exports` object for node.js (function() { var ss = {}; if (typeof module !== 'undefined') { // Assign the `ss` object to exports, so that you can require // it in [node.js](http://nodejs.org/) module.exports = ss; } else { // Otherwise, in a browser, we assign `ss` to the window object, // so you can simply refer to it as `ss`. this.ss = ss; } // # [Linear Regression](http://en.wikipedia.org/wiki/Linear_regression) // // [Simple linear regression](http://en.wikipedia.org/wiki/Simple_linear_regression) // is a simple way to find a fitted line // between a set of coordinates. function linear_regression() { var linreg = {}, data = []; // Assign data to the model. Data is assumed to be an array. linreg.data = function(x) { if (!arguments.length) return data; data = x.slice(); return linreg; }; // Calculate the slope and y-intercept of the regression line // by calculating the least sum of squares linreg.mb = function() { var m, b; // Store data length in a local variable to reduce // repeated object property lookups var data_length = data.length; //if there's only one point, arbitrarily choose a slope of 0 //and a y-intercept of whatever the y of the initial point is if (data_length === 1) { m = 0; b = data[0][1]; } else { // Initialize our sums and scope the `m` and `b` // variables that define the line. var sum_x = 0, sum_y = 0, sum_xx = 0, sum_xy = 0; // Use local variables to grab point values // with minimal object property lookups var point, x, y; // Gather the sum of all x values, the sum of all // y values, and the sum of x^2 and (x*y) for each // value. // // In math notation, these would be SS_x, SS_y, SS_xx, and SS_xy for (var i = 0; i < data_length; i++) { point = data[i]; x = point[0]; y = point[1]; sum_x += x; sum_y += y; sum_xx += x * x; sum_xy += x * y; } // `m` is the slope of the regression line m = ((data_length * sum_xy) - (sum_x * sum_y)) / ((data_length * sum_xx) - (sum_x * sum_x)); // `b` is the y-intercept of the line. b = (sum_y / data_length) - ((m * sum_x) / data_length); } // Return both values as an object. return { m: m, b: b }; }; // a shortcut for simply getting the slope of the regression line linreg.m = function() { return linreg.mb().m; }; // a shortcut for simply getting the y-intercept of the regression // line. linreg.b = function() { return linreg.mb().b; }; // ## Fitting The Regression Line // // This is called after `.data()` and returns the // equation `y = f(x)` which gives the position // of the regression line at each point in `x`. linreg.line = function() { // Get the slope, `m`, and y-intercept, `b`, of the line. var mb = linreg.mb(), m = mb.m, b = mb.b; // Return a function that computes a `y` value for each // x value it is given, based on the values of `b` and `a` // that we just computed. return function(x) { return b + (m * x); }; }; return linreg; } // # [R Squared](http://en.wikipedia.org/wiki/Coefficient_of_determination) // // The r-squared value of data compared with a function `f` // is the sum of the squared differences between the prediction // and the actual value. function r_squared(data, f) { if (data.length < 2) return 1; // Compute the average y value for the actual // data set in order to compute the // _total sum of squares_ var sum = 0, average; for (var i = 0; i < data.length; i++) { sum += data[i][1]; } average = sum / data.length; // Compute the total sum of squares - the // squared difference between each point // and the average of all points. var sum_of_squares = 0; for (var j = 0; j < data.length; j++) { sum_of_squares += Math.pow(average - data[j][1], 2); } // Finally estimate the error: the squared // difference between the estimate and the actual data // value at each point. var err = 0; for (var k = 0; k < data.length; k++) { err += Math.pow(data[k][1] - f(data[k][0]), 2); } // As the error grows larger, its ratio to the // sum of squares increases and the r squared // value grows lower. return 1 - (err / sum_of_squares); } // # [Bayesian Classifier](http://en.wikipedia.org/wiki/Naive_Bayes_classifier) // // This is a naïve bayesian classifier that takes // singly-nested objects. function bayesian() { // The `bayes_model` object is what will be exposed // by this closure, with all of its extended methods, and will // have access to all scope variables, like `total_count`. var bayes_model = {}, // The number of items that are currently // classified in the model total_count = 0, // Every item classified in the model data = {}; // ## Train // Train the classifier with a new item, which has a single // dimension of Javascript literal keys and values. bayes_model.train = function(item, category) { // If the data object doesn't have any values // for this category, create a new object for it. if (!data[category]) data[category] = {}; // Iterate through each key in the item. for (var k in item) { var v = item[k]; // Initialize the nested object `data[category][k][item[k]]` // with an object of keys that equal 0. if (data[category][k] === undefined) data[category][k] = {}; if (data[category][k][v] === undefined) data[category][k][v] = 0; // And increment the key for this key/value combination. data[category][k][item[k]]++; } // Increment the number of items classified total_count++; }; // ## Score // Generate a score of how well this item matches all // possible categories based on its attributes bayes_model.score = function(item) { // Initialize an empty array of odds per category. var odds = {}, category; // Iterate through each key in the item, // then iterate through each category that has been used // in previous calls to `.train()` for (var k in item) { var v = item[k]; for (category in data) { // Create an empty object for storing key - value combinations // for this category. if (odds[category] === undefined) odds[category] = {}; // If this item doesn't even have a property, it counts for nothing, // but if it does have the property that we're looking for from // the item to categorize, it counts based on how popular it is // versus the whole population. if (data[category][k]) { odds[category][k + '_' + v] = (data[category][k][v] || 0) / total_count; } else { odds[category][k + '_' + v] = 0; } } } // Set up a new object that will contain sums of these odds by category var odds_sums = {}; for (category in odds) { // Tally all of the odds for each category-combination pair - // the non-existence of a category does not add anything to the // score. for (var combination in odds[category]) { if (odds_sums[category] === undefined) odds_sums[category] = 0; odds_sums[category] += odds[category][combination]; } } return odds_sums; }; // Return the completed model. return bayes_model; } // # sum // // is simply the result of adding all numbers // together, starting from zero. // // This runs on `O(n)`, linear time in respect to the array function sum(x) { var value = 0; for (var i = 0; i < x.length; i++) { value += x[i]; } return value; } // # mean // // is the sum over the number of values // // This runs on `O(n)`, linear time in respect to the array function mean(x) { // The mean of no numbers is null if (x.length === 0) return null; return sum(x) / x.length; } // # geometric mean // // a mean function that is more useful for numbers in different // ranges. // // this is the nth root of the input numbers multiplied by each other // // This runs on `O(n)`, linear time in respect to the array function geometric_mean(x) { // The mean of no numbers is null if (x.length === 0) return null; // the starting value. var value = 1; for (var i = 0; i < x.length; i++) { // the geometric mean is only valid for positive numbers if (x[i] <= 0) return null; // repeatedly multiply the value by each number value *= x[i]; } return Math.pow(value, 1 / x.length); } // # harmonic mean // // a mean function typically used to find the average of rates // // this is the reciprocal of the arithmetic mean of the reciprocals // of the input numbers // // This runs on `O(n)`, linear time in respect to the array function harmonic_mean(x) { // The mean of no numbers is null if (x.length === 0) return null; var reciprocal_sum = 0; for (var i = 0; i < x.length; i++) { // the harmonic mean is only valid for positive numbers if (x[i] <= 0) return null; reciprocal_sum += 1 / x[i]; } // divide n by the the reciprocal sum return x.length / reciprocal_sum; } // # min // // This is simply the minimum number in the set. // // This runs on `O(n)`, linear time in respect to the array function min(x) { var value; for (var i = 0; i < x.length; i++) { // On the first iteration of this loop, min is // undefined and is thus made the minimum element in the array if (x[i] < value || value === undefined) value = x[i]; } return value; } // # max // // This is simply the maximum number in the set. // // This runs on `O(n)`, linear time in respect to the array function max(x) { var value; for (var i = 0; i < x.length; i++) { // On the first iteration of this loop, max is // undefined and is thus made the maximum element in the array if (x[i] > value || value === undefined) value = x[i]; } return value; } // # [variance](http://en.wikipedia.org/wiki/Variance) // // is the sum of squared deviations from the mean // // depends on `mean()` function variance(x) { // The variance of no numbers is null if (x.length === 0) return null; var mean_value = mean(x), deviations = []; // Make a list of squared deviations from the mean. for (var i = 0; i < x.length; i++) { deviations.push(Math.pow(x[i] - mean_value, 2)); } // Find the mean value of that list return mean(deviations); } // # [standard deviation](http://en.wikipedia.org/wiki/Standard_deviation) // // is just the square root of the variance. // // depends on `variance()` function standard_deviation(x) { // The standard deviation of no numbers is null if (x.length === 0) return null; return Math.sqrt(variance(x)); } // The sum of deviations to the Nth power. // When n=2 it's the sum of squared deviations. // When n=3 it's the sum of cubed deviations. // // depends on `mean()` function sum_nth_power_deviations(x, n) { var mean_value = mean(x), sum = 0; for (var i = 0; i < x.length; i++) { sum += Math.pow(x[i] - mean_value, n); } return sum; } // # [variance](http://en.wikipedia.org/wiki/Variance) // // is the sum of squared deviations from the mean // // depends on `sum_nth_power_deviations` function sample_variance(x) { // The variance of no numbers is null if (x.length <= 1) return null; var sum_squared_deviations_value = sum_nth_power_deviations(x, 2); // Find the mean value of that list return sum_squared_deviations_value / (x.length - 1); } // # [standard deviation](http://en.wikipedia.org/wiki/Standard_deviation) // // is just the square root of the variance. // // depends on `sample_variance()` function sample_standard_deviation(x) { // The standard deviation of no numbers is null if (x.length <= 1) return null; return Math.sqrt(sample_variance(x)); } // # [covariance](http://en.wikipedia.org/wiki/Covariance) // // sample covariance of two datasets: // how much do the two datasets move together? // x and y are two datasets, represented as arrays of numbers. // // depends on `mean()` function sample_covariance(x, y) { // The two datasets must have the same length which must be more than 1 if (x.length <= 1 || x.length != y.length){ return null; } // determine the mean of each dataset so that we can judge each // value of the dataset fairly as the difference from the mean. this // way, if one dataset is [1, 2, 3] and [2, 3, 4], their covariance // does not suffer because of the difference in absolute values var xmean = mean(x), ymean = mean(y), sum = 0; // for each pair of values, the covariance increases when their // difference from the mean is associated - if both are well above // or if both are well below // the mean, the covariance increases significantly. for (var i = 0; i < x.length; i++){ sum += (x[i] - xmean) * (y[i] - ymean); } // the covariance is weighted by the length of the datasets. return sum / (x.length - 1); } // # [correlation](http://en.wikipedia.org/wiki/Correlation_and_dependence) // // Gets a measure of how correlated two datasets are, between -1 and 1 // // depends on `sample_standard_deviation()` and `sample_covariance()` function sample_correlation(x, y) { var cov = sample_covariance(x, y), xstd = sample_standard_deviation(x), ystd = sample_standard_deviation(y); if (cov === null || xstd === null || ystd === null) { return null; } return cov / xstd / ystd; } // # [median](http://en.wikipedia.org/wiki/Median) // // The middle number of a list. This is often a good indicator of 'the middle' // when there are outliers that skew the `mean()` value. function median(x) { // The median of an empty list is null if (x.length === 0) return null; // Sorting the array makes it easy to find the center, but // use `.slice()` to ensure the original array `x` is not modified var sorted = x.slice().sort(function (a, b) { return a - b; }); // If the length of the list is odd, it's the central number if (sorted.length % 2 === 1) { return sorted[(sorted.length - 1) / 2]; // Otherwise, the median is the average of the two numbers // at the center of the list } else { var a = sorted[(sorted.length / 2) - 1]; var b = sorted[(sorted.length / 2)]; return (a + b) / 2; } } // # [mode](http://bit.ly/W5K4Yt) // // The mode is the number that appears in a list the highest number of times. // There can be multiple modes in a list: in the event of a tie, this // algorithm will return the most recently seen mode. // // This implementation is inspired by [science.js](https://github.com/jasondavies/science.js/blob/master/src/stats/mode.js) // // This runs on `O(n)`, linear time in respect to the array function mode(x) { // Handle edge cases: // The median of an empty list is null if (x.length === 0) return null; else if (x.length === 1) return x[0]; // Sorting the array lets us iterate through it below and be sure // that every time we see a new number it's new and we'll never // see the same number twice var sorted = x.slice().sort(function (a, b) { return a - b; }); // This assumes it is dealing with an array of size > 1, since size // 0 and 1 are handled immediately. Hence it starts at index 1 in the // array. var last = sorted[0], // store the mode as we find new modes value, // store how many times we've seen the mode max_seen = 0, // how many times the current candidate for the mode // has been seen seen_this = 1; // end at sorted.length + 1 to fix the case in which the mode is // the highest number that occurs in the sequence. the last iteration // compares sorted[i], which is undefined, to the highest number // in the series for (var i = 1; i < sorted.length + 1; i++) { // we're seeing a new number pass by if (sorted[i] !== last) { // the last number is the new mode since we saw it more // often than the old one if (seen_this > max_seen) { max_seen = seen_this; value = last; } seen_this = 1; last = sorted[i]; // if this isn't a new number, it's one more occurrence of // the potential mode } else { seen_this++; } } return value; } // # [t-test](http://en.wikipedia.org/wiki/Student's_t-test) // // This is to compute a one-sample t-test, comparing the mean // of a sample to a known value, x. // // in this case, we're trying to determine whether the // population mean is equal to the value that we know, which is `x` // here. usually the results here are used to look up a // [p-value](http://en.wikipedia.org/wiki/P-value), which, for // a certain level of significance, will let you determine that the // null hypothesis can or cannot be rejected. // // Depends on `standard_deviation()` and `mean()` function t_test(sample, x) { // The mean of the sample var sample_mean = mean(sample); // The standard deviation of the sample var sd = standard_deviation(sample); // Square root the length of the sample var rootN = Math.sqrt(sample.length); // Compute the known value against the sample, // returning the t value return (sample_mean - x) / (sd / rootN); } // # [2-sample t-test](http://en.wikipedia.org/wiki/Student's_t-test) // // This is to compute two sample t-test. // Tests whether "mean(X)-mean(Y) = difference", ( // in the most common case, we often have `difference == 0` to test if two samples // are likely to be taken from populations with the same mean value) with // no prior knowledge on standard deviations of both samples // other than the fact that they have the same standard deviation. // // Usually the results here are used to look up a // [p-value](http://en.wikipedia.org/wiki/P-value), which, for // a certain level of significance, will let you determine that the // null hypothesis can or cannot be rejected. // // `diff` can be omitted if it equals 0. // // [This is used to confirm or deny](http://www.monarchlab.org/Lab/Research/Stats/2SampleT.aspx) // a null hypothesis that the two populations that have been sampled into // `sample_x` and `sample_y` are equal to each other. // // Depends on `sample_variance()` and `mean()` function t_test_two_sample(sample_x, sample_y, difference) { var n = sample_x.length, m = sample_y.length; // If either sample doesn't actually have any values, we can't // compute this at all, so we return `null`. if (!n || !m) return null ; // default difference (mu) is zero if (!difference) difference = 0; var meanX = mean(sample_x), meanY = mean(sample_y); var weightedVariance = ((n - 1) * sample_variance(sample_x) + (m - 1) * sample_variance(sample_y)) / (n + m - 2); return (meanX - meanY - difference) / Math.sqrt(weightedVariance * (1 / n + 1 / m)); } // # chunk // // Split an array into chunks of a specified size. This function // has the same behavior as [PHP's array_chunk](http://php.net/manual/en/function.array-chunk.php) // function, and thus will insert smaller-sized chunks at the end if // the input size is not divisible by the chunk size. // // `sample` is expected to be an array, and `chunkSize` a number. // The `sample` array can contain any kind of data. function chunk(sample, chunkSize) { // a list of result chunks, as arrays in an array var output = []; // `chunkSize` must be zero or higher - otherwise the loop below, // in which we call `start += chunkSize`, will loop infinitely. // So, we'll detect and return null in that case to indicate // invalid input. if (chunkSize <= 0) { return null; } // `start` is the index at which `.slice` will start selecting // new array elements for (var start = 0; start < sample.length; start += chunkSize) { // for each chunk, slice that part of the array and add it // to the output. The `.slice` function does not change // the original array. output.push(sample.slice(start, start + chunkSize)); } return output; } // # shuffle_in_place // // A [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) // in-place - which means that it will change the order of the original // array by reference. function shuffle_in_place(sample, randomSource) { // a custom random number source can be provided if you want to use // a fixed seed or another random number generator, like // [random-js](https://www.npmjs.org/package/random-js) randomSource = randomSource || Math.random; // store the current length of the sample to determine // when no elements remain to shuffle. var length = sample.length; // temporary is used to hold an item when it is being // swapped between indices. var temporary; // The index to swap at each stage. var index; // While there are still items to shuffle while (length > 0) { // chose a random index within the subset of the array // that is not yet shuffled index = Math.floor(randomSource() * length--); // store the value that we'll move temporarily temporary = sample[length]; // swap the value at `sample[length]` with `sample[index]` sample[length] = sample[index]; sample[index] = temporary; } return sample; } // # shuffle // // A [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) // is a fast way to create a random permutation of a finite set. function shuffle(sample, randomSource) { // slice the original array so that it is not modified sample = sample.slice(); // and then shuffle that shallow-copied array, in place return shuffle_in_place(sample.slice(), randomSource); } // # sample // // Create a [simple random sample](http://en.wikipedia.org/wiki/Simple_random_sample) // from a given array of `n` elements. function sample(array, n, randomSource) { // shuffle the original array using a fisher-yates shuffle var shuffled = shuffle(array, randomSource); // and then return a subset of it - the first `n` elements. return shuffled.slice(0, n); } // # quantile // // This is a population quantile, since we assume to know the entire // dataset in this library. Thus I'm trying to follow the // [Quantiles of a Population](http://en.wikipedia.org/wiki/Quantile#Quantiles_of_a_population) // algorithm from wikipedia. // // Sample is a one-dimensional array of numbers, // and p is either a decimal number from 0 to 1 or an array of decimal // numbers from 0 to 1. // In terms of a k/q quantile, p = k/q - it's just dealing with fractions or dealing // with decimal values. // When p is an array, the result of the function is also an array containing the appropriate // quantiles in input order function quantile(sample, p) { // We can't derive quantiles from an empty list if (sample.length === 0) return null; // Sort a copy of the array. We'll need a sorted array to index // the values in sorted order. var sorted = sample.slice().sort(function (a, b) { return a - b; }); if (p.length) { // Initialize the result array var results = []; // For each requested quantile for (var i = 0; i < p.length; i++) { results[i] = quantile_sorted(sorted, p[i]); } return results; } else { return quantile_sorted(sorted, p); } } // # quantile // // This is the internal implementation of quantiles: when you know // that the order is sorted, you don't need to re-sort it, and the computations // are much faster. function quantile_sorted(sample, p) { var idx = (sample.length) * p; if (p < 0 || p > 1) { return null; } else if (p === 1) { // If p is 1, directly return the last element return sample[sample.length - 1]; } else if (p === 0) { // If p is 0, directly return the first element return sample[0]; } else if (idx % 1 !== 0) { // If p is not integer, return the next element in array return sample[Math.ceil(idx) - 1]; } else if (sample.length % 2 === 0) { // If the list has even-length, we'll take the average of this number // and the next value, if there is one return (sample[idx - 1] + sample[idx]) / 2; } else { // Finally, in the simple case of an integer value // with an odd-length list, return the sample value at the index. return sample[idx]; } } // # [Interquartile range](http://en.wikipedia.org/wiki/Interquartile_range) // // A measure of statistical dispersion, or how scattered, spread, or // concentrated a distribution is. It's computed as the difference between // the third quartile and first quartile. function iqr(sample) { // We can't derive quantiles from an empty list if (sample.length === 0) return null; // Interquartile range is the span between the upper quartile, // at `0.75`, and lower quartile, `0.25` return quantile(sample, 0.75) - quantile(sample, 0.25); } // # [Median Absolute Deviation](http://en.wikipedia.org/wiki/Median_absolute_deviation) // // The Median Absolute Deviation (MAD) is a robust measure of statistical // dispersion. It is more resilient to outliers than the standard deviation. function mad(x) { // The mad of nothing is null if (!x || x.length === 0) return null; var median_value = median(x), median_absolute_deviations = []; // Make a list of absolute deviations from the median for (var i = 0; i < x.length; i++) { median_absolute_deviations.push(Math.abs(x[i] - median_value)); } // Find the median value of that list return median(median_absolute_deviations); } // ## Compute Matrices for Jenks // // Compute the matrices required for Jenks breaks. These matrices // can be used for any classing of data with `classes <= n_classes` function jenksMatrices(data, n_classes) { // in the original implementation, these matrices are referred to // as `LC` and `OP` // // * lower_class_limits (LC): optimal lower class limits // * variance_combinations (OP): optimal variance combinations for all classes var lower_class_limits = [], variance_combinations = [], // loop counters i, j, // the variance, as computed at each step in the calculation variance = 0; // Initialize and fill each matrix with zeroes for (i = 0; i < data.length + 1; i++) { var tmp1 = [], tmp2 = []; // despite these arrays having the same values, we need // to keep them separate so that changing one does not change // the other for (j = 0; j < n_classes + 1; j++) { tmp1.push(0); tmp2.push(0); } lower_class_limits.push(tmp1); variance_combinations.push(tmp2); } for (i = 1; i < n_classes + 1; i++) { lower_class_limits[1][i] = 1; variance_combinations[1][i] = 0; // in the original implementation, 9999999 is used but // since Javascript has `Infinity`, we use that. for (j = 2; j < data.length + 1; j++) { variance_combinations[j][i] = Infinity; } } for (var l = 2; l < data.length + 1; l++) { // `SZ` originally. this is the sum of the values seen thus // far when calculating variance. var sum = 0, // `ZSQ` originally. the sum of squares of values seen // thus far sum_squares = 0, // `WT` originally. This is the number of w = 0, // `IV` originally i4 = 0; // in several instances, you could say `Math.pow(x, 2)` // instead of `x * x`, but this is slower in some browsers // introduces an unnecessary concept. for (var m = 1; m < l + 1; m++) { // `III` originally var lower_class_limit = l - m + 1, val = data[lower_class_limit - 1]; // here we're estimating variance for each potential classing // of the data, for each potential number of classes. `w` // is the number of data points considered so far. w++; // increase the current sum and sum-of-squares sum += val; sum_squares += val * val; // the variance at this point in the sequence is the difference // between the sum of squares and the total x 2, over the number // of samples. variance = sum_squares - (sum * sum) / w; i4 = lower_class_limit - 1; if (i4 !== 0) { for (j = 2; j < n_classes + 1; j++) { // if adding this element to an existing class // will increase its variance beyond the limit, break // the class at this point, setting the `lower_class_limit` // at this point. if (variance_combinations[l][j] >= (variance + variance_combinations[i4][j - 1])) { lower_class_limits[l][j] = lower_class_limit; variance_combinations[l][j] = variance + variance_combinations[i4][j - 1]; } } } } lower_class_limits[l][1] = 1; variance_combinations[l][1] = variance; } // return the two matrices. for just providing breaks, only // `lower_class_limits` is needed, but variances can be useful to // evaluate goodness of fit. return { lower_class_limits: lower_class_limits, variance_combinations: variance_combinations }; } // ## Pull Breaks Values for Jenks // // the second part of the jenks recipe: take the calculated matrices // and derive an array of n breaks. function jenksBreaks(data, lower_class_limits, n_classes) { var k = data.length - 1, kclass = [], countNum = n_classes; // the calculation of classes will never include the upper and // lower bounds, so we need to explicitly set them kclass[n_classes] = data[data.length - 1]; kclass[0] = data[0]; // the lower_class_limits matrix is used as indices into itself // here: the `k` variable is reused in each iteration. while (countNum > 1) { kclass[countNum - 1] = data[lower_class_limits[k][countNum] - 2]; k = lower_class_limits[k][countNum] - 1; countNum--; } return kclass; } // # [Jenks natural breaks optimization](http://en.wikipedia.org/wiki/Jenks_natural_breaks_optimization) // // Implementations: [1](http://danieljlewis.org/files/2010/06/Jenks.pdf) (python), // [2](https://github.com/vvoovv/djeo-jenks/blob/master/main.js) (buggy), // [3](https://github.com/simogeo/geostats/blob/master/lib/geostats.js#L407) (works) // // Depends on `jenksBreaks()` and `jenksMatrices()` function jenks(data, n_classes) { if (n_classes > data.length) return null; // sort data in numerical order, since this is expected // by the matrices function data = data.slice().sort(function (a, b) { return a - b; }); // get our basic matrices var matrices = jenksMatrices(data, n_classes), // we only need lower class limits here lower_class_limits = matrices.lower_class_limits; // extract n_classes out of the computed matrices return jenksBreaks(data, lower_class_limits, n_classes); } // # [Skewness](http://en.wikipedia.org/wiki/Skewness) // // A measure of the extent to which a probability distribution of a // real-valued random variable "leans" to one side of the mean. // The skewness value can be positive or negative, or even undefined. // // Implementation is based on the adjusted Fisher-Pearson standardized // moment coefficient, which is the version found in Excel and several // statistical packages including Minitab, SAS and SPSS. // // Depends on `sum_nth_power_deviations()` and `sample_standard_deviation` function sample_skewness(x) { // The skewness of less than three arguments is null if (x.length < 3) return null; var n = x.length, cubed_s = Math.pow(sample_standard_deviation(x), 3), sum_cubed_deviations = sum_nth_power_deviations(x, 3); return n * sum_cubed_deviations / ((n - 1) * (n - 2) * cubed_s); } // # Standard Normal Table // A standard normal table, also called the unit normal table or Z table, // is a mathematical table for the values of Φ (phi), which are the values of // the cumulative distribution function of the normal distribution. // It is used to find the probability that a statistic is observed below, // above, or between values on the standard normal distribution, and by // extension, any normal distribution. // // The probabilities are taken from http://en.wikipedia.org/wiki/Standard_normal_table // The table used is the cumulative, and not cumulative from 0 to mean // (even though the latter has 5 digits precision, instead of 4). var standard_normal_table = [ /* z 0.00 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 */ /* 0.0 */ 0.5000, 0.5040, 0.5080, 0.5120, 0.5160, 0.5199, 0.5239, 0.5279, 0.5319, 0.5359, /* 0.1 */ 0.5398, 0.5438, 0.5478, 0.5517, 0.5557, 0.5596, 0.5636, 0.5675, 0.5714, 0.5753, /* 0.2 */ 0.5793, 0.5832, 0.5871, 0.5910, 0.5948, 0.5987, 0.6026, 0.6064, 0.6103, 0.6141, /* 0.3 */ 0.6179, 0.6217, 0.6255, 0.6293, 0.6331, 0.6368, 0.6406, 0.6443, 0.6480, 0.6517, /* 0.4 */ 0.6554, 0.6591, 0.6628, 0.6664, 0.6700, 0.6736, 0.6772, 0.6808, 0.6844, 0.6879, /* 0.5 */ 0.6915, 0.6950, 0.6985, 0.7019, 0.7054, 0.7088, 0.7123, 0.7157, 0.7190, 0.7224, /* 0.6 */ 0.7257, 0.7291, 0.7324, 0.7357, 0.7389, 0.7422, 0.7454, 0.7486, 0.7517, 0.7549, /* 0.7 */ 0.7580, 0.7611, 0.7642, 0.7673, 0.7704, 0.7734, 0.7764, 0.7794, 0.7823, 0.7852, /* 0.8 */ 0.7881, 0.7910, 0.7939, 0.7967, 0.7995, 0.8023, 0.8051, 0.8078, 0.8106, 0.8133, /* 0.9 */ 0.8159, 0.8186, 0.8212, 0.8238, 0.8264, 0.8289, 0.8315, 0.8340, 0.8365, 0.8389, /* 1.0 */ 0.8413, 0.8438, 0.8461, 0.8485, 0.8508, 0.8531, 0.8554, 0.8577, 0.8599, 0.8621, /* 1.1 */ 0.8643, 0.8665, 0.8686, 0.8708, 0.8729, 0.8749, 0.8770, 0.8790, 0.8810, 0.8830, /* 1.2 */ 0.8849, 0.8869, 0.8888, 0.8907, 0.8925, 0.8944, 0.8962, 0.8980, 0.8997, 0.9015, /* 1.3 */ 0.9032, 0.9049, 0.9066, 0.9082, 0.9099, 0.9115, 0.9131, 0.9147, 0.9162, 0.9177, /* 1.4 */ 0.9192, 0.9207, 0.9222, 0.9236, 0.9251, 0.9265, 0.9279, 0.9292, 0.9306, 0.9319, /* 1.5 */ 0.9332, 0.9345, 0.9357, 0.9370, 0.9382, 0.9394, 0.9406, 0.9418, 0.9429, 0.9441, /* 1.6 */ 0.9452, 0.9463, 0.9474, 0.9484, 0.9495, 0.9505, 0.9515, 0.9525, 0.9535, 0.9545, /* 1.7 */ 0.9554, 0.9564, 0.9573, 0.9582, 0.9591, 0.9599, 0.9608, 0.9616, 0.9625, 0.9633, /* 1.8 */ 0.9641, 0.9649, 0.9656, 0.9664, 0.9671, 0.9678, 0.9686, 0.9693, 0.9699, 0.9706, /* 1.9 */ 0.9713, 0.9719, 0.9726, 0.9732, 0.9738, 0.9744, 0.9750, 0.9756, 0.9761, 0.9767, /* 2.0 */ 0.9772, 0.9778, 0.9783, 0.9788, 0.9793, 0.9798, 0.9803, 0.9808, 0.9812, 0.9817, /* 2.1 */ 0.9821, 0.9826, 0.9830, 0.9834, 0.9838, 0.9842, 0.9846, 0.9850, 0.9854, 0.9857, /* 2.2 */ 0.9861, 0.9864, 0.9868, 0.9871, 0.9875, 0.9878, 0.9881, 0.9884, 0.9887, 0.9890, /* 2.3 */ 0.9893, 0.9896, 0.9898, 0.9901, 0.9904, 0.9906, 0.9909, 0.9911, 0.9913, 0.9916, /* 2.4 */ 0.9918, 0.9920, 0.9922, 0.9925, 0.9927, 0.9929, 0.9931, 0.9932, 0.9934, 0.9936, /* 2.5 */ 0.9938, 0.9940, 0.9941, 0.9943, 0.9945, 0.9946, 0.9948, 0.9949, 0.9951, 0.9952, /* 2.6 */ 0.9953, 0.9955, 0.9956, 0.9957, 0.9959, 0.9960, 0.9961, 0.9962, 0.9963, 0.9964, /* 2.7 */ 0.9965, 0.9966, 0.9967, 0.9968, 0.9969, 0.9970, 0.9971, 0.9972, 0.9973, 0.9974, /* 2.8 */ 0.9974, 0.9975, 0.9976, 0.9977, 0.9977, 0.9978, 0.9979, 0.9979, 0.9980, 0.9981, /* 2.9 */ 0.9981, 0.9982, 0.9982, 0.9983, 0.9984, 0.9984, 0.9985, 0.9985, 0.9986, 0.9986, /* 3.0 */ 0.9987, 0.9987, 0.9987, 0.9988, 0.9988, 0.9989, 0.9989, 0.9989, 0.9990, 0.9990 ]; // # [Cumulative Standard Normal Probability](http://en.wikipedia.org/wiki/Standard_normal_table) // // Since probability tables cannot be // printed for every normal distribution, as there are an infinite variety // of normal distributions, it is common practice to convert a normal to a // standard normal and then use the standard normal table to find probabilities function cumulative_std_normal_probability(z) { // Calculate the position of this value. var absZ = Math.abs(z), // Each row begins with a different // significant digit: 0.5, 0.6, 0.7, and so on. So the row is simply // this value's significant digit: 0.567 will be in row 0, so row=0, // 0.643 will be in row 1, so row=10. row = Math.floor(absZ * 10), column = 10 * (Math.floor(absZ * 100) / 10 - Math.floor(absZ * 100 / 10)), index = Math.min((row * 10) + column, standard_normal_table.length - 1); // The index we calculate must be in the table as a positive value, // but we still pay attention to whether the input is positive // or negative, and flip the output value as a last step. if (z >= 0) { return standard_normal_table[index]; } else { // due to floating-point arithmetic, values in the table with // 4 significant figures can nevertheless end up as repeating // fractions when they're computed here. return +(1 - standard_normal_table[index]).toFixed(4); } } // # [Z-Score, or Standard Score](http://en.wikipedia.org/wiki/Standard_score) // // The standard score is the number of standard deviations an observation // or datum is above or below the mean. Thus, a positive standard score // represents a datum above the mean, while a negative standard score // represents a datum below the mean. It is a dimensionless quantity // obtained by subtracting the population mean from an individual raw // score and then dividing the difference by the population standard // deviation. // // The z-score is only defined if one knows the population parameters; // if one only has a sample set, then the analogous computation with // sample mean and sample standard deviation yields the // Student's t-statistic. function z_score(x, mean, standard_deviation) { return (x - mean) / standard_deviation; } // We use `ε`, epsilon, as a stopping criterion when we want to iterate // until we're "close enough". var epsilon = 0.0001; // # [Factorial](https://en.wikipedia.org/wiki/Factorial) // // A factorial, usually written n!, is the product of all positive // integers less than or equal to n. Often factorial is implemented // recursively, but this iterative approach is significantly faster // and simpler. function factorial(n) { // factorial is mathematically undefined for negative numbers if (n < 0 ) { return null; } // typically you'll expand the factorial function going down, like // 5! = 5 * 4 * 3 * 2 * 1. This is going in the opposite direction, // counting from 2 up to the number in question, and since anything // multiplied by 1 is itself, the loop only needs to start at 2. var accumulator = 1; for (var i = 2; i <= n; i++) { // for each number up to and including the number `n`, multiply // the accumulator my that number. accumulator *= i; } return accumulator; } // # Bernoulli Distribution // // The [Bernoulli distribution](http://en.wikipedia.org/wiki/Bernoulli_distribution) // is the probability discrete // distribution of a random variable which takes value 1 with success // probability `p` and value 0 with failure // probability `q` = 1 - `p`. It can be used, for example, to represent the // toss of a coin, where "1" is defined to mean "heads" and "0" is defined // to mean "tails" (or vice versa). It is // a special case of a Binomial Distribution // where `n` = 1. function bernoulli_distribution(p) { // Check that `p` is a valid probability (0 ≤ p ≤ 1) if (p < 0 || p > 1 ) { return null; } return binomial_distribution(1, p); } // # Binomial Distribution // // The [Binomial Distribution](http://en.wikipedia.org/wiki/Binomial_distribution) is the discrete probability // distribution of the number of successes in a sequence of n independent yes/no experiments, each of which yields // success with probability `probability`. Such a success/failure experiment is also called a Bernoulli experiment or // Bernoulli trial; when trials = 1, the Binomial Distribution is a Bernoulli Distribution. function binomial_distribution(trials, probability) { // Check that `p` is a valid probability (0 ≤ p ≤ 1), // that `n` is an integer, strictly positive. if (probability < 0 || probability > 1 || trials <= 0 || trials % 1 !== 0) { return null; } // a [probability mass function](https://en.wikipedia.org/wiki/Probability_mass_function) function probability_mass(x, trials, probability) { return factorial(trials) / (factorial(x) * factorial(trials - x)) * (Math.pow(probability, x) * Math.pow(1 - probability, trials - x)); } // We initialize `x`, the random variable, and `accumulator`, an accumulator // for the cumulative distribution function to 0. `distribution_functions` // is the object we'll return with the `probability_of_x` and the // `cumulative_probability_of_x`, as well as the calculated mean & // variance. We iterate until the `cumulative_probability_of_x` is // within `epsilon` of 1.0. var x = 0, cumulative_probability = 0, cells = {}; // This algorithm iterates through each potential outcome, // until the `cumulative_probability` is very close to 1, at // which point we've defined the vast majority of outcomes do { cells[x] = probability_mass(x, trials, probability); cumulative_probability += cells[x]; x++; // when the cumulative_probability is nearly 1, we've calculated // the useful range of this distribution } while (cumulative_probability < 1 - epsilon); return cells; } // # Poisson Distribution // // The [Poisson Distribution](http://en.wikipedia.org/wiki/Poisson_distribution) // is a discrete probability distribution that expresses the probability // of a given number of events occurring in a fixed interval of time // and/or space if these events occur with a known average rate and // independently of the time since the last event. // // The Poisson Distribution is characterized by the strictly positive // mean arrival or occurrence rate, `λ`. function poisson_distribution(lambda) { // Check that lambda is strictly positive if (lambda <= 0) { return null; } // our current place in the distribution var x = 0, // and we keep track of the current cumulative probability, in // order to know when to stop calculating chances. cumulative_probability = 0, // the calculated cells to be returned cells = {}; // a [probability mass function](https://en.wikipedia.org/wiki/Probability_mass_function) function probability_mass(x, lambda) { return (Math.pow(Math.E, -lambda) * Math.pow(lambda, x)) / factorial(x); } // This algorithm iterates through each potential outcome, // until the `cumulative_probability` is very close to 1, at // which point we've defined the vast majority of outcomes do { cells[x] = probability_mass(x, lambda); cumulative_probability += cells[x]; x++; // when the cumulative_probability is nearly 1, we've calculated // the useful range of this distribution } while (cumulative_probability < 1 - epsilon); return cells; } // # Percentage Points of the χ2 (Chi-Squared) Distribution // The [χ2 (Chi-Squared) Distribution](http://en.wikipedia.org/wiki/Chi-squared_distribution) is used in the common // chi-squared tests for goodness of fit of an observed distribution to a theoretical one, the independence of two // criteria of classification of qualitative data, and in confidence interval estimation for a population standard // deviation of a normal distribution from a sample standard deviation. // // Values from Appendix 1, Table III of William W. Hines & Douglas C. Montgomery, "Probability and Statistics in // Engineering and Management Science", Wiley (1980). var chi_squared_distribution_table = { 1: { 0.995: 0.00, 0.99: 0.00, 0.975: 0.00, 0.95: 0.00, 0.9: 0.02, 0.5: 0.45, 0.1: 2.71, 0.05: 3.84, 0.025: 5.02, 0.01: 6.63, 0.005: 7.88 }, 2: { 0.995: 0.01, 0.99: 0.02, 0.975: 0.05, 0.95: 0.10, 0.9: 0.21, 0.5: 1.39, 0.1: 4.61, 0.05: 5.99, 0.025: 7.38, 0.01: 9.21, 0.005: 10.60 }, 3: { 0.995: 0.07, 0.99: 0.11, 0.975: 0.22, 0.95: 0.35, 0.9: 0.58, 0.5: 2.37, 0.1: 6.25, 0.05: 7.81, 0.025: 9.35, 0.01: 11.34, 0.005: 12.84 }, 4: { 0.995: 0.21, 0.99: 0.30, 0.975: 0.48, 0.95: 0.71, 0.9: 1.06, 0.5: 3.36, 0.1: 7.78, 0.05: 9.49, 0.025: 11.14, 0.01: 13.28, 0.005: 14.86 }, 5: { 0.995: 0.41, 0.99: 0.55, 0.975: 0.83, 0.95: 1.15, 0.9: 1.61, 0.5: 4.35, 0.1: 9.24, 0.05: 11.07, 0.025: 12.83, 0.01: 15.09, 0.005: 16.75 }, 6: { 0.995: 0.68, 0.99: 0.87, 0.975: 1.24, 0.95: 1.64, 0.9: 2.20, 0.5: 5.35, 0.1: 10.65, 0.05: 12.59, 0.025: 14.45, 0.01: 16.81, 0.005: 18.55 }, 7: { 0.995: 0.99, 0.99: 1.25, 0.975: 1.69, 0.95: 2.17, 0.9: 2.83, 0.5: 6.35, 0.1: 12.02, 0.05: 14.07, 0.025: 16.01, 0.01: 18.48, 0.005: 20.28 }, 8: { 0.995: 1.34, 0.99: 1.65, 0.975: 2.18, 0.95: 2.73, 0.9: 3.49, 0.5: 7.34, 0.1: 13.36, 0.05: 15.51, 0.025: 17.53, 0.01: 20.09, 0.005: 21.96 }, 9: { 0.995: 1.73, 0.99: 2.09, 0.975: 2.70, 0.95: 3.33, 0.9: 4.17, 0.5: 8.34, 0.1: 14.68, 0.05: 16.92, 0.025: 19.02, 0.01: 21.67, 0.005: 23.59 }, 10: { 0.995: 2.16, 0.99: 2.56, 0.975: 3.25, 0.95: 3.94, 0.9: 4.87, 0.5: 9.34, 0.1: 15.99, 0.05: 18.31, 0.025: 20.48, 0.01: 23.21, 0.005: 25.19 }, 11: { 0.995: 2.60, 0.99: 3.05, 0.975: 3.82, 0.95: 4.57, 0.9: 5.58, 0.5: 10.34, 0.1: 17.28, 0.05: 19.68, 0.025: 21.92, 0.01: 24.72, 0.005: 26.76 }, 12: { 0.995: 3.07, 0.99: 3.57, 0.975: 4.40, 0.95: 5.23, 0.9: 6.30, 0.5: 11.34, 0.1: 18.55, 0.05: 21.03, 0.025: 23.34, 0.01: 26.22, 0.005: 28.30 }, 13: { 0.995: 3.57, 0.99: 4.11, 0.975: 5.01, 0.95: 5.89, 0.9: 7.04, 0.5: 12.34, 0.1: 19.81, 0.05: 22.36, 0.025: 24.74, 0.01: 27.69, 0.005: 29.82 }, 14: { 0.995: 4.07, 0.99: 4.66, 0.975: 5.63, 0.95: 6.57, 0.9: 7.79, 0.5: 13.34, 0.1: 21.06, 0.05: 23.68, 0.025: 26.12, 0.01: 29.14, 0.005: 31.32 }, 15: { 0.995: 4.60, 0.99: 5.23, 0.975: 6.27, 0.95: 7.26, 0.9: 8.55, 0.5: 14.34, 0.1: 22.31, 0.05: 25.00, 0.025: 27.49, 0.01: 30.58, 0.005: 32.80 }, 16: { 0.995: 5.14, 0.99: 5.81, 0.975: 6.91, 0.95: 7.96, 0.9: 9.31, 0.5: 15.34, 0.1: 23.54, 0.05: 26.30, 0.025: 28.85, 0.01: 32.00, 0.005: 34.27 }, 17: { 0.995: 5.70, 0.99: 6.41, 0.975: 7.56, 0.95: 8.67, 0.9: 10.09, 0.5: 16.34, 0.1: 24.77, 0.05: 27.59, 0.025: 30.19, 0.01: 33.41, 0.005: 35.72 }, 18: { 0.995: 6.26, 0.99: 7.01, 0.975: 8.23, 0.95: 9.39, 0.9: 10.87, 0.5: 17.34, 0.1: 25.99, 0.05: 28.87, 0.025: 31.53, 0.01: 34.81, 0.005: 37.16 }, 19: { 0.995: 6.84, 0.99: 7.63, 0.975: 8.91, 0.95: 10.12, 0.9: 11.65, 0.5: 18.34, 0.1: 27.20, 0.05: 30.14, 0.025: 32.85, 0.01: 36.19, 0.005: 38.58 }, 20: { 0.995: 7.43, 0.99: 8.26, 0.975: 9.59, 0.95: 10.85, 0.9: 12.44, 0.5: 19.34, 0.1: 28.41, 0.05: 31.41, 0.025: 34.17, 0.01: 37.57, 0.005: 40.00 }, 21: { 0.995: 8.03, 0.99: 8.90, 0.975: 10.28, 0.95: 11.59, 0.9: 13.24, 0.5: 20.34, 0.1: 29.62, 0.05: 32.67, 0.025: 35.48, 0.01: 38.93, 0.005: 41.40 }, 22: { 0.995: 8.64, 0.99: 9.54, 0.975: 10.98, 0.95: 12.34, 0.9: 14.04, 0.5: 21.34, 0.1: 30.81, 0.05: 33.92, 0.025: 36.78, 0.01: 40.29, 0.005: 42.80 }, 23: { 0.995: 9.26, 0.99: 10.20, 0.975: 11.69, 0.95: 13.09, 0.9: 14.85, 0.5: 22.34, 0.1: 32.01, 0.05: 35.17, 0.025: 38.08, 0.01: 41.64, 0.005: 44.18 }, 24: { 0.995: 9.89, 0.99: 10.86, 0.975: 12.40, 0.95: 13.85, 0.9: 15.66, 0.5: 23.34, 0.1: 33.20, 0.05: 36.42, 0.025: 39.36, 0.01: 42.98, 0.005: 45.56 }, 25: { 0.995: 10.52, 0.99: 11.52, 0.975: 13.12, 0.95: 14.61, 0.9: 16.47, 0.5: 24.34, 0.1: 34.28, 0.05: 37.65, 0.025: 40.65, 0.01: 44.31, 0.005: 46.93 }, 26: { 0.995: 11.16, 0.99: 12.20, 0.975: 13.84, 0.95: 15.38, 0.9: 17.29, 0.5: 25.34, 0.1: 35.56, 0.05: 38.89, 0.025: 41.92, 0.01: 45.64, 0.005: 48.29 }, 27: { 0.995: 11.81, 0.99: 12.88, 0.975: 14.57, 0.95: 16.15, 0.9: 18.11, 0.5: 26.34, 0.1: 36.74, 0.05: 40.11, 0.025: 43.19, 0.01: 46.96, 0.005: 49.65 }, 28: { 0.995: 12.46, 0.99: 13.57, 0.975: 15.31, 0.95: 16.93, 0.9: 18.94, 0.5: 27.34, 0.1: 37.92, 0.05: 41.34, 0.025: 44.46, 0.01: 48.28, 0.005: 50.99 }, 29: { 0.995: 13.12, 0.99: 14.26, 0.975: 16.05, 0.95: 17.71, 0.9: 19.77, 0.5: 28.34, 0.1: 39.09, 0.05: 42.56, 0.025: 45.72, 0.01: 49.59, 0.005: 52.34 }, 30: { 0.995: 13.79, 0.99: 14.95, 0.975: 16.79, 0.95: 18.49, 0.9: 20.60, 0.5: 29.34, 0.1: 40.26, 0.05: 43.77, 0.025: 46.98, 0.01: 50.89, 0.005: 53.67 }, 40: { 0.995: 20.71, 0.99: 22.16, 0.975: 24.43, 0.95: 26.51, 0.9: 29.05, 0.5: 39.34, 0.1: 51.81, 0.05: 55.76, 0.025: 59.34, 0.01: 63.69, 0.005: 66.77 }, 50: { 0.995: 27.99, 0.99: 29.71, 0.975: 32.36, 0.95: 34.76, 0.9: 37.69, 0.5: 49.33, 0.1: 63.17, 0.05: 67.50, 0.025: 71.42, 0.01: 76.15, 0.005: 79.49 }, 60: { 0.995: 35.53, 0.99: 37.48, 0.975: 40.48, 0.95: 43.19, 0.9: 46.46, 0.5: 59.33, 0.1: 74.40, 0.05: 79.08, 0.025: 83.30, 0.01: 88.38, 0.005: 91.95 }, 70: { 0.995: 43.28, 0.99: 45.44, 0.975: 48.76, 0.95: 51.74, 0.9: 55.33, 0.5: 69.33, 0.1: 85.53, 0.05: 90.53, 0.025: 95.02, 0.01: 100.42, 0.005: 104.22 }, 80: { 0.995: 51.17, 0.99: 53.54, 0.975: 57.15, 0.95: 60.39, 0.9: 64.28, 0.5: 79.33, 0.1: 96.58, 0.05: 101.88, 0.025: 106.63, 0.01: 112.33, 0.005: 116.32 }, 90: { 0.995: 59.20, 0.99: 61.75, 0.975: 65.65, 0.95: 69.13, 0.9: 73.29, 0.5: 89.33, 0.1: 107.57, 0.05: 113.14, 0.025: 118.14, 0.01: 124.12, 0.005: 128.30 }, 100: { 0.995: 67.33, 0.99: 70.06, 0.975: 74.22, 0.95: 77.93, 0.9: 82.36, 0.5: 99.33, 0.1: 118.50, 0.05: 124.34, 0.025: 129.56, 0.01: 135.81, 0.005: 140.17 } }; // # χ2 (Chi-Squared) Goodness-of-Fit Test // // The [χ2 (Chi-Squared) Goodness-of-Fit Test](http://en.wikipedia.org/wiki/Goodness_of_fit#Pearson.27s_chi-squared_test) // uses a measure of goodness of fit which is the sum of differences between observed and expected outcome frequencies // (that is, counts of observations), each squared and divided by the number of observations expected given the // hypothesized distribution. The resulting χ2 statistic, `chi_squared`, can be compared to the chi-squared distribution // to determine the goodness of fit. In order to determine the degrees of freedom of the chi-squared distribution, one // takes the total number of observed frequencies and subtracts the number of estimated parameters. The test statistic // follows, approximately, a chi-square distribution with (k − c) degrees of freedom where `k` is the number of non-empty // cells and `c` is the number of estimated parameters for the distribution. function chi_squared_goodness_of_fit(data, distribution_type, significance) { // Estimate from the sample data, a weighted mean. var input_mean = mean(data), // Calculated value of the χ2 statistic. chi_squared = 0, // Degrees of freedom, calculated as (number of class intervals - // number of hypothesized distribution parameters estimated - 1) degrees_of_freedom, // Number of hypothesized distribution parameters estimated, expected to be supplied in the distribution test. // Lose one degree of freedom for estimating `lambda` from the sample data. c = 1, // The hypothesized distribution. // Generate the hypothesized distribution. hypothesized_distribution = distribution_type(input_mean), observed_frequencies = [], expected_frequencies = [], k; // Create an array holding a histogram from the sample data, of // the form `{ value: numberOfOcurrences }` for (var i = 0; i < data.length; i++) { if (observed_frequencies[data[i]] === undefined) { observed_frequencies[data[i]] = 0; } observed_frequencies[data[i]]++; } // The histogram we created might be sparse - there might be gaps // between values. So we iterate through the histogram, making // sure that instead of undefined, gaps have 0 values. for (i = 0; i < observed_frequencies.length; i++) { if (observed_frequencies[i] === undefined) { observed_frequencies[i] = 0; } } // Create an array holding a histogram of expected data given the // sample size and hypothesized distribution. for (k in hypothesized_distribution) { if (k in observed_frequencies) { expected_frequencies[k] = hypothesized_distribution[k] * data.length; } } // Working backward through the expected frequencies, collapse classes // if less than three observations are expected for a class. // This transformation is applied to the observed frequencies as well. for (k = expected_frequencies.length - 1; k >= 0; k--) { if (expected_frequencies[k] < 3) { expected_frequencies[k - 1] += expected_frequencies[k]; expected_frequencies.pop(); observed_frequencies[k - 1] += observed_frequencies[k]; observed_frequencies.pop(); } } // Iterate through the squared differences between observed & expected // frequencies, accumulating the `chi_squared` statistic. for (k = 0; k < observed_frequencies.length; k++) { chi_squared += Math.pow( observed_frequencies[k] - expected_frequencies[k], 2) / expected_frequencies[k]; } // Calculate degrees of freedom for this test and look it up in the // `chi_squared_distribution_table` in order to // accept or reject the goodness-of-fit of the hypothesized distribution. degrees_of_freedom = observed_frequencies.length - c - 1; return chi_squared_distribution_table[degrees_of_freedom][significance] < chi_squared; } // # Mixin // // Mixin simple_statistics to a single Array instance if provided // or the Array native object if not. This is an optional // feature that lets you treat simple_statistics as a native feature // of Javascript. function mixin(array) { var support = !!(Object.defineProperty && Object.defineProperties); if (!support) throw new Error('without defineProperty, simple-statistics cannot be mixed in'); // only methods which work on basic arrays in a single step // are supported var arrayMethods = ['median', 'standard_deviation', 'sum', 'sample_skewness', 'mean', 'min', 'max', 'quantile', 'geometric_mean', 'harmonic_mean']; // create a closure with a method name so that a reference // like `arrayMethods[i]` doesn't follow the loop increment function wrap(method) { return function() { // cast any arguments into an array, since they're // natively objects var args = Array.prototype.slice.apply(arguments); // make the first argument the array itself args.unshift(this); // return the result of the ss method return ss[method].apply(ss, args); }; } // select object to extend var extending; if (array) { // create a shallow copy of the array so that our internal // operations do not change it by reference extending = array.slice(); } else { extending = Array.prototype; } // for each array function, define a function that gets // the array as the first argument. // We use [defineProperty](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty) // because it allows these properties to be non-enumerable: // `for (var in x)` loops will not run into problems with this // implementation. for (var i = 0; i < arrayMethods.length; i++) { Object.defineProperty(extending, arrayMethods[i], { value: wrap(arrayMethods[i]), configurable: true, enumerable: false, writable: true }); } return extending; } ss.linear_regression = linear_regression; ss.standard_deviation = standard_deviation; ss.r_squared = r_squared; ss.median = median; ss.mean = mean; ss.mode = mode; ss.min = min; ss.max = max; ss.sum = sum; ss.quantile = quantile; ss.quantile_sorted = quantile_sorted; ss.iqr = iqr; ss.mad = mad; ss.chunk = chunk; ss.shuffle = shuffle; ss.shuffle_in_place = shuffle_in_place; ss.sample = sample; ss.sample_covariance = sample_covariance; ss.sample_correlation = sample_correlation; ss.sample_variance = sample_variance; ss.sample_standard_deviation = sample_standard_deviation; ss.sample_skewness = sample_skewness; ss.geometric_mean = geometric_mean; ss.harmonic_mean = harmonic_mean; ss.variance = variance; ss.t_test = t_test; ss.t_test_two_sample = t_test_two_sample; // jenks ss.jenksMatrices = jenksMatrices; ss.jenksBreaks = jenksBreaks; ss.jenks = jenks; ss.bayesian = bayesian; // Distribution-related methods ss.epsilon = epsilon; // We make ε available to the test suite. ss.factorial = factorial; ss.bernoulli_distribution = bernoulli_distribution; ss.binomial_distribution = binomial_distribution; ss.poisson_distribution = poisson_distribution; ss.chi_squared_goodness_of_fit = chi_squared_goodness_of_fit; // Normal distribution ss.z_score = z_score; ss.cumulative_std_normal_probability = cumulative_std_normal_probability; ss.standard_normal_table = standard_normal_table; // Alias this into its common name ss.average = mean; ss.interquartile_range = iqr; ss.mixin = mixin; ss.median_absolute_deviation = mad; })(this); },{}],60:[function(require,module,exports){ var invariant = require('turf-invariant'); //http://en.wikipedia.org/wiki/Haversine_formula //http://www.movable-type.co.uk/scripts/latlong.html /** * Takes two {@link Point} features and calculates * the distance between them in degress, radians, * miles, or kilometers. This uses the * [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) * to account for global curvature. * * @module turf/distance * @category measurement * @param {Feature} from origin point * @param {Feature} to destination point * @param {String} [units=kilometers] can be degrees, radians, miles, or kilometers * @return {Number} distance between the two points * @example * var point1 = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-75.343, 39.984] * } * }; * var point2 = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-75.534, 39.123] * } * }; * var units = "miles"; * * var points = { * "type": "FeatureCollection", * "features": [point1, point2] * }; * * //=points * * var distance = turf.distance(point1, point2, units); * * //=distance */ module.exports = function(point1, point2, units){ invariant.featureOf(point1, 'Point', 'distance'); invariant.featureOf(point2, 'Point', 'distance'); var coordinates1 = point1.geometry.coordinates; var coordinates2 = point2.geometry.coordinates; var dLat = toRad(coordinates2[1] - coordinates1[1]); var dLon = toRad(coordinates2[0] - coordinates1[0]); var lat1 = toRad(coordinates1[1]); var lat2 = toRad(coordinates2[1]); var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var R; switch(units){ case 'miles': R = 3960; break; case 'kilometers': R = 6373; break; case 'degrees': R = 57.2957795; break; case 'radians': R = 1; break; case undefined: R = 6373; break; default: throw new Error('unknown option given to "units"'); } var distance = R * c; return distance; }; function toRad(degree) { return degree * Math.PI / 180; } },{"turf-invariant":61}],61:[function(require,module,exports){ module.exports.geojsonType = geojsonType; module.exports.collectionOf = collectionOf; module.exports.featureOf = featureOf; /** * Enforce expectations about types of GeoJSON objects for Turf. * * @alias geojsonType * @param {GeoJSON} value any GeoJSON object * @param {string} type expected GeoJSON type * @param {String} name name of calling function * @throws Error if value is not the expected type. */ function geojsonType(value, type, name) { if (!type || !name) throw new Error('type and name required'); if (!value || value.type !== type) { throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + value.type); } } /** * Enforce expectations about types of {@link Feature} inputs for Turf. * Internally this uses {@link geojsonType} to judge geometry types. * * @alias featureOf * @param {Feature} feature a feature with an expected geometry type * @param {string} type expected GeoJSON type * @param {String} name name of calling function * @throws Error if value is not the expected type. */ function featureOf(value, type, name) { if (!name) throw new Error('.featureOf() requires a name'); if (!value || value.type !== 'Feature' || !value.geometry) { throw new Error('Invalid input to ' + name + ', Feature with geometry required'); } if (!value.geometry || value.geometry.type !== type) { throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + value.geometry.type); } } /** * Enforce expectations about types of {@link FeatureCollection} inputs for Turf. * Internally this uses {@link geojsonType} to judge geometry types. * * @alias collectionOf * @param {FeatureCollection} featurecollection a featurecollection for which features will be judged * @param {string} type expected GeoJSON type * @param {String} name name of calling function * @throws Error if value is not the expected type. */ function collectionOf(value, type, name) { if (!name) throw new Error('.collectionOf() requires a name'); if (!value || value.type !== 'FeatureCollection') { throw new Error('Invalid input to ' + name + ', FeatureCollection required'); } for (var i = 0; i < value.features.length; i++) { var feature = value.features[i]; if (!feature || feature.type !== 'Feature' || !feature.geometry) { throw new Error('Invalid input to ' + name + ', Feature with geometry required'); } if (!feature.geometry || feature.geometry.type !== type) { throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + feature.geometry.type); } } } },{}],62:[function(require,module,exports){ var extent = require('turf-extent'); var bboxPolygon = require('turf-bbox-polygon'); /** * Takes a {@link Feature} or {@link FeatureCollection} and returns a rectangular {@link Polygon} feature that encompasses all vertices. * * @module turf/envelope * @category measurement * @param {FeatureCollection} fc a FeatureCollection of any type * @return {Polygon} a rectangular Polygon feature that encompasses all vertices * @example * var fc = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "name": "Location A" * }, * "geometry": { * "type": "Point", * "coordinates": [-75.343, 39.984] * } * }, { * "type": "Feature", * "properties": { * "name": "Location B" * }, * "geometry": { * "type": "Point", * "coordinates": [-75.833, 39.284] * } * }, { * "type": "Feature", * "properties": { * "name": "Location C" * }, * "geometry": { * "type": "Point", * "coordinates": [-75.534, 39.123] * } * } * ] * }; * * var enveloped = turf.envelope(fc); * * var resultFeatures = fc.features.concat(enveloped); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ module.exports = function(features, done){ var bbox = extent(features); var poly = bboxPolygon(bbox); return poly; } },{"turf-bbox-polygon":12,"turf-extent":70}],63:[function(require,module,exports){ // depend on jsts for now https://github.com/bjornharrtell/jsts/blob/master/examples/overlay.html var jsts = require('jsts'); /** * Finds the difference between two polygons by clipping the second * polygon from the first. * * @module turf/erase * @category transformation * @param {Polygon} poly1 input Polygon feaure * @param {Polygon} poly2 Polygon feature to erase from `poly1` * @return {Polygon} a Polygon feature showing the area of `poly1` excluding the area of `poly2` * @example * var poly1 = { * "type": "Feature", * "properties": { * "fill": "#0f0" * }, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-46.738586, -23.596711], * [-46.738586, -23.458207], * [-46.560058, -23.458207], * [-46.560058, -23.596711], * [-46.738586, -23.596711] * ]] * } * }; * var poly2 = { * "type": "Feature", * "properties": { * "fill": "#00f" * }, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-46.650009, -23.631314], * [-46.650009, -23.5237], * [-46.509246, -23.5237], * [-46.509246, -23.631314], * [-46.650009, -23.631314] * ]] * } * }; * * var erased = turf.erase(poly1, poly2); * erased.properties.fill = '#f00'; * * var polygons = { * "type": "FeatureCollection", * "features": [poly1, poly2] * }; * * //=polygons * * //=erased */ module.exports = function(p1, p2, done){ var poly1 = JSON.parse(JSON.stringify(p1)); var poly2 = JSON.parse(JSON.stringify(p2)); if(poly1.type !== 'Feature') { poly1 = { type: 'Feature', properties: {}, geometry: poly1 }; } if(poly2.type !== 'Feature') { poly2 = { type: 'Feature', properties: {}, geometry: poly2 }; } var reader = new jsts.io.GeoJSONReader(); var a = reader.read(JSON.stringify(poly1.geometry)); var b = reader.read(JSON.stringify(poly2.geometry)); var erased = a.difference(b); var parser = new jsts.io.GeoJSONParser(); erased = parser.write(erased); poly1.geometry = erased; if (poly1.geometry.type === 'GeometryCollection' && poly1.geometry.geometries.length === 0) { return; } else { return { type: 'Feature', properties: poly1.properties, geometry: erased }; } }; },{"jsts":64}],64:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"./lib/jsts":65,"dup":17,"javascript.util":67}],65:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"dup":18}],66:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"dup":19}],67:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./dist/javascript.util-node.min.js":66,"dup":20}],68:[function(require,module,exports){ var featureCollection = require('turf-featurecollection'); var each = require('turf-meta').coordEach; var point = require('turf-point'); /** * Takes any {@link GeoJSON} object and return all positions as * a {@link FeatureCollection} of {@link Point} features. * * @module turf/explode * @category misc * @param {GeoJSON} input input features * @return {FeatureCollection} a FeatureCollection of {@link Point} features representing the exploded input features * @throws {Error} if it encounters an unknown geometry type * @example * var poly = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [177.434692, -17.77517], * [177.402076, -17.779093], * [177.38079, -17.803937], * [177.40242, -17.826164], * [177.438468, -17.824857], * [177.454948, -17.796746], * [177.434692, -17.77517] * ]] * } * }; * * var points = turf.explode(poly); * * //=poly * * //=points */ module.exports = function(layer) { var points = []; each(layer, function(coord) { points.push(point(coord)); }); return featureCollection(points); }; },{"turf-featurecollection":72,"turf-meta":69,"turf-point":102}],69:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"dup":23}],70:[function(require,module,exports){ var each = require('turf-meta').coordEach; /** * Takes any {@link GeoJSON} object, calculates the extent of all input features, and returns a bounding box. * * @module turf/extent * @category measurement * @param {GeoJSON} input any valid GeoJSON Object * @return {Array} the bounding box of `input` given * as an array in WSEN order (west, south, east, north) * @example * var input = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [114.175329, 22.2524] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [114.170007, 22.267969] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [114.200649, 22.274641] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [114.186744, 22.265745] * } * } * ] * }; * * var bbox = turf.extent(input); * * var bboxPolygon = turf.bboxPolygon(bbox); * * var resultFeatures = input.features.concat(bboxPolygon); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ module.exports = function(layer) { var extent = [Infinity, Infinity, -Infinity, -Infinity]; each(layer, function(coord) { if (extent[0] > coord[0]) extent[0] = coord[0]; if (extent[1] > coord[1]) extent[1] = coord[1]; if (extent[2] < coord[0]) extent[2] = coord[0]; if (extent[3] < coord[1]) extent[3] = coord[1]; }); return extent; }; },{"turf-meta":71}],71:[function(require,module,exports){ arguments[4][23][0].apply(exports,arguments) },{"dup":23}],72:[function(require,module,exports){ /** * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection} * * @module turf/featurecollection * @category helper * @param {Feature} features input Features * @returns {FeatureCollection} a FeatureCollection of input features * @example * var features = [ * turf.point([-75.343, 39.984], {name: 'Location A'}), * turf.point([-75.833, 39.284], {name: 'Location B'}), * turf.point([-75.534, 39.123], {name: 'Location C'}) * ]; * * var fc = turf.featurecollection(features); * * //=fc */ module.exports = function(features){ return { type: "FeatureCollection", features: features }; }; },{}],73:[function(require,module,exports){ var featureCollection = require('turf-featurecollection'); /** * Takes a {@link FeatureCollection} and filters it by a given property and value * * @module turf/filter * @category data * @param {FeatureCollection} features input FeatureCollection of any type * @param {String} key the property on which to filter * @param {String} value the value of that property on which to filter * @return {FeatureCollection} a filtered collection with only features that match input `key` and `value` * @example * var features = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "species": "oak" * }, * "geometry": { * "type": "Point", * "coordinates": [-72.581777, 44.260875] * } * }, { * "type": "Feature", * "properties": { * "species": "birch" * }, * "geometry": { * "type": "Point", * "coordinates": [-72.570018, 44.260691] * } * }, { * "type": "Feature", * "properties": { * "species": "oak" * }, * "geometry": { * "type": "Point", * "coordinates": [-72.576284, 44.257925] * } * }, { * "type": "Feature", * "properties": { * "species": "redwood" * }, * "geometry": { * "type": "Point", * "coordinates": [-72.56916, 44.254605] * } * }, { * "type": "Feature", * "properties": { * "species": "maple" * }, * "geometry": { * "type": "Point", * "coordinates": [-72.581691, 44.24858] * } * }, { * "type": "Feature", * "properties": { * "species": "oak" * }, * "geometry": { * "type": "Point", * "coordinates": [-72.583837, 44.255773] * } * } * ] * }; * * var key = "species"; * var value = "oak"; * * var filtered = turf.filter(features, key, value); * * //=features * * //=filtered */ module.exports = function(collection, key, val) { var newFC = featureCollection([]); for(var i = 0; i < collection.features.length; i++) { if(collection.features[i].properties[key] === val) { newFC.features.push(collection.features[i]); } } return newFC; }; },{"turf-featurecollection":72}],74:[function(require,module,exports){ /** * Takes a {@link GeoJSON} object of any type and flips all of its coordinates * from `[x, y]` to `[y, x]`. * * @module turf/flip * @category misc * @param {GeoJSON} input input GeoJSON object * @returns {GeoJSON} a GeoJSON object of the same type as `input` with flipped coordinates * @example * var serbia = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [20.566406, 43.421008] * } * }; * * //=serbia * * var saudiArabia = turf.flip(serbia); * * //=saudiArabia */ module.exports = flipAny; function flipAny(_) { // ensure that we don't modify features in-place and changes to the // output do not change the previous feature, including changes to nested // properties. var input = JSON.parse(JSON.stringify(_)); switch (input.type) { case 'FeatureCollection': for (var i = 0; i < input.features.length; i++) flipGeometry(input.features[i].geometry); return input; case 'Feature': flipGeometry(input.geometry); return input; default: flipGeometry(input); return input; } } function flipGeometry(geometry) { var coords = geometry.coordinates; switch(geometry.type) { case 'Point': flip0(coords); break; case 'LineString': case 'MultiPoint': flip1(coords); break; case 'Polygon': case 'MultiLineString': flip2(coords); break; case 'MultiPolygon': flip3(coords); break; case 'GeometryCollection': geometry.geometries.forEach(flipGeometry); break; } } function flip0(coord) { coord.reverse(); } function flip1(coords) { for(var i = 0; i < coords.length; i++) coords[i].reverse(); } function flip2(coords) { for(var i = 0; i < coords.length; i++) for(var j = 0; j < coords[i].length; j++) coords[i][j].reverse(); } function flip3(coords) { for(var i = 0; i < coords.length; i++) for(var j = 0; j < coords[i].length; j++) for(var k = 0; k < coords[i][j].length; k++) coords[i][j][k].reverse(); } },{}],75:[function(require,module,exports){ var point = require('turf-point'); var polygon = require('turf-polygon'); var distance = require('turf-distance'); var featurecollection = require('turf-featurecollection'); /** * Takes a bounding box and a cell size in degrees and returns a {@link FeatureCollection} of flat-topped * hexagons ({@link Polygon} features) aligned in an "odd-q" vertical grid as * described in [Hexagonal Grids](http://www.redblobgames.com/grids/hexagons/) * * @module turf/hex-grid * @category interpolation * @param {Array} bbox bounding box in [minX, minY, maxX, maxY] order * @param {Number} cellWidth width of cell in specified units * @param {String} units used in calculating cellWidth ('miles' or 'kilometers') * @return {FeatureCollection} units used in calculating cellWidth ('miles' or 'kilometers') * @example * var bbox = [-96,31,-84,40]; * var cellWidth = 50; * var units = 'miles'; * * var hexgrid = turf.hexGrid(bbox, cellWidth, units); * * //=hexgrid */ //Precompute cosines and sines of angles used in hexagon creation // for performance gain var cosines = []; var sines = []; for (var i = 0; i < 6; i++) { var angle = 2 * Math.PI/6 * i; cosines.push(Math.cos(angle)); sines.push(Math.sin(angle)); } module.exports = function hexgrid(bbox, cell, units) { var xFraction = cell / (distance(point([bbox[0], bbox[1]]), point([bbox[2], bbox[1]]), units)); var cellWidth = xFraction * (bbox[2] - bbox[0]); var yFraction = cell / (distance(point([bbox[0], bbox[1]]), point([bbox[0], bbox[3]]), units)); var cellHeight = yFraction * (bbox[3] - bbox[1]); var radius = cellWidth / 2; var hex_width = radius * 2; var hex_height = Math.sqrt(3)/2 * hex_width; var box_width = bbox[2] - bbox[0]; var box_height = bbox[3] - bbox[1]; var x_interval = 3/4 * hex_width; var y_interval = hex_height; var x_span = box_width / (hex_width - radius/2); var x_count = Math.ceil(x_span); if (Math.round(x_span) === x_count) { x_count++; } var x_adjust = ((x_count * x_interval - radius/2) - box_width)/2 - radius/2; var y_count = Math.ceil(box_height / hex_height); var y_adjust = (box_height - y_count * hex_height)/2; var hasOffsetY = y_count * hex_height - box_height > hex_height/2; if (hasOffsetY) { y_adjust -= hex_height/4; } var fc = featurecollection([]); for (var x = 0; x < x_count; x++) { for (var y = 0; y <= y_count; y++) { var isOdd = x % 2 === 1; if (y === 0 && isOdd) { continue; } if (y === 0 && hasOffsetY) { continue; } var center_x = x * x_interval + bbox[0] - x_adjust; var center_y = y * y_interval + bbox[1] + y_adjust; if (isOdd) { center_y -= hex_height/2; } fc.features.push(hexagon([center_x, center_y], radius)); } } return fc; }; //Center should be [x, y] function hexagon(center, radius) { var vertices = []; for (var i = 0; i < 6; i++) { var x = center[0] + radius * cosines[i]; var y = center[1] + radius * sines[i]; vertices.push([x,y]); } //first and last vertex must be the same vertices.push(vertices[0]); return polygon([vertices]); } },{"turf-distance":60,"turf-featurecollection":72,"turf-point":102,"turf-polygon":103}],76:[function(require,module,exports){ // http://en.wikipedia.org/wiki/Even%E2%80%93odd_rule // modified from: https://github.com/substack/point-in-polygon/blob/master/index.js // which was modified from http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html /** * Takes a {@link Point} feature and a {@link Polygon} feature and determines if the Point resides inside the Polygon. The Polygon can * be convex or concave. The function accepts any valid Polygon or {@link MultiPolygon} * and accounts for holes. * * @module turf/inside * @category joins * @param {Point} point a Point feature * @param {Polygon} polygon a Polygon feature * @return {Boolean} `true` if the Point is inside the Polygon; `false` if the Point is not inside the Polygon * @example * var pt1 = { * "type": "Feature", * "properties": { * "marker-color": "#f00" * }, * "geometry": { * "type": "Point", * "coordinates": [-111.467285, 40.75766] * } * }; * var pt2 = { * "type": "Feature", * "properties": { * "marker-color": "#0f0" * }, * "geometry": { * "type": "Point", * "coordinates": [-111.873779, 40.647303] * } * }; * var poly = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-112.074279, 40.52215], * [-112.074279, 40.853293], * [-111.610107, 40.853293], * [-111.610107, 40.52215], * [-112.074279, 40.52215] * ]] * } * }; * * var features = { * "type": "FeatureCollection", * "features": [pt1, pt2, poly] * }; * * //=features * * var isInside1 = turf.inside(pt1, poly); * //=isInside1 * * var isInside2 = turf.inside(pt2, poly); * //=isInside2 */ module.exports = function(point, polygon) { var polys = polygon.geometry.coordinates; var pt = [point.geometry.coordinates[0], point.geometry.coordinates[1]]; // normalize to multipolygon if(polygon.geometry.type === 'Polygon') polys = [polys]; var insidePoly = false; var i = 0; while (i < polys.length && !insidePoly) { // check if it is in the outer ring first if(inRing(pt, polys[i][0])) { var inHole = false; var k = 1; // check for the point in any of the holes while(k < polys[i].length && !inHole) { if(inRing(pt, polys[i][k])) { inHole = true; } k++; } if(!inHole) insidePoly = true; } i++; } return insidePoly; } // pt is [x,y] and ring is [[x,y], [x,y],..] function inRing (pt, ring) { var isInside = false; for (var i = 0, j = ring.length - 1; i < ring.length; j = i++) { var xi = ring[i][0], yi = ring[i][1]; var xj = ring[j][0], yj = ring[j][1]; var intersect = ((yi > pt[1]) != (yj > pt[1])) && (pt[0] < (xj - xi) * (pt[1] - yi) / (yj - yi) + xi); if (intersect) isInside = !isInside; } return isInside; } },{}],77:[function(require,module,exports){ // depend on jsts for now https://github.com/bjornharrtell/jsts/blob/master/examples/overlay.html var jsts = require('jsts'); var featurecollection = require('turf-featurecollection'); /** * Takes two {@link Polygon} features and finds their intersection. * * @module turf/intersect * @category transformation * @param {Polygon} poly1 the first Polygon * @param {Polygon} poly2 the second Polygon * @return {Polygon} a Polygon feature representing the area where `poly1` and `poly2` overlap * @example * var poly1 = turf.polygon([[ * [-122.801742, 45.48565], * [-122.801742, 45.60491], * [-122.584762, 45.60491], * [-122.584762, 45.48565], * [-122.801742, 45.48565] * ]]); * poly1.properties.fill = '#0f0'; * var poly2 = turf.polygon([[ * [-122.520217, 45.535693], * [-122.64038, 45.553967], * [-122.720031, 45.526554], * [-122.669906, 45.507309], * [-122.723464, 45.446643], * [-122.532577, 45.408574], * [-122.487258, 45.477466], * [-122.520217, 45.535693] * ]]); * poly2.properties.fill = '#00f'; * var polygons = turf.featurecollection([poly1, poly2]); * * var intersection = turf.intersect(poly1, poly2); * * //=polygons * * //=intersection */ module.exports = function(poly1, poly2){ var geom1; if(poly1.type === 'Feature') geom1 = poly1.geometry; else geom1 = poly1; if(poly2.type === 'Feature') geom2 = poly2.geometry; else geom2 = poly2; var reader = new jsts.io.GeoJSONReader(); var a = reader.read(JSON.stringify(geom1)); var b = reader.read(JSON.stringify(geom2)); var intersection = a.intersection(b); var parser = new jsts.io.GeoJSONParser(); intersection = parser.write(intersection); if(intersection.type === 'GeometryCollection' && intersection.geometries.length === 0) { return; } else { return { type: 'Feature', properties: {}, geometry: intersection }; } }; },{"jsts":78,"turf-featurecollection":72}],78:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"./lib/jsts":79,"dup":17,"javascript.util":81}],79:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"dup":18}],80:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"dup":19}],81:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./dist/javascript.util-node.min.js":80,"dup":20}],82:[function(require,module,exports){ /** * Copyright (c) 2010, Jason Davies. * * All rights reserved. This code is based on Bradley White's Java version, * which is in turn based on Nicholas Yue's C++ version, which in turn is based * on Paul D. Bourke's original Fortran version. See below for the respective * copyright notices. * * See http://local.wasp.uwa.edu.au/~pbourke/papers/conrec/ for the original * paper by Paul D. Bourke. * * The vector conversion code is based on http://apptree.net/conrec.htm by * Graham Cox. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Copyright (c) 1996-1997 Nicholas Yue * * This software is copyrighted by Nicholas Yue. This code is based on Paul D. * Bourke's CONREC.F routine. * * The authors hereby grant permission to use, copy, and distribute this * software and its documentation for any purpose, provided that existing * copyright notices are retained in all copies and that this notice is * included verbatim in any distributions. Additionally, the authors grant * permission to modify this software and its documentation for any purpose, * provided that such modifications are not distributed without the explicit * consent of the authors and that existing copyright notices are retained in * all copies. Some of the algorithms implemented by this software are * patented, observe all applicable patent law. * * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, * EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS * PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR * MODIFICATIONS. */ module.exports = Conrec; var EPSILON = 1e-10; function pointsEqual(a, b) { var x = a.x - b.x, y = a.y - b.y; return x * x + y * y < EPSILON; } function reverseList(list) { var pp = list.head; while (pp) { // swap prev/next pointers var temp = pp.next; pp.next = pp.prev; pp.prev = temp; // continue through the list pp = temp; } // swap head/tail pointers var temp = list.head; list.head = list.tail; list.tail = temp; } function ContourBuilder(level) { this.level = level; this.s = null; this.count = 0; } ContourBuilder.prototype.remove_seq = function(list) { // if list is the first item, static ptr s is updated if (list.prev) { list.prev.next = list.next; } else { this.s = list.next; } if (list.next) { list.next.prev = list.prev; } --this.count; } ContourBuilder.prototype.addSegment = function(a, b) { var ss = this.s; var ma = null; var mb = null; var prependA = false; var prependB = false; while (ss) { if (ma == null) { // no match for a yet if (pointsEqual(a, ss.head.p)) { ma = ss; prependA = true; } else if (pointsEqual(a, ss.tail.p)) { ma = ss; } } if (mb == null) { // no match for b yet if (pointsEqual(b, ss.head.p)) { mb = ss; prependB = true; } else if (pointsEqual(b, ss.tail.p)) { mb = ss; } } // if we matched both no need to continue searching if (mb != null && ma != null) { break; } else { ss = ss.next; } } // c is the case selector based on which of ma and/or mb are set var c = ((ma != null) ? 1 : 0) | ((mb != null) ? 2 : 0); switch(c) { case 0: // both unmatched, add as new sequence var aa = {p: a, prev: null}; var bb = {p: b, next: null}; aa.next = bb; bb.prev = aa; // create sequence element and push onto head of main list. The order // of items in this list is unimportant ma = {head: aa, tail: bb, next: this.s, prev: null, closed: false}; if (this.s) { this.s.prev = ma; } this.s = ma; ++this.count; // not essential - tracks number of unmerged sequences break; case 1: // a matched, b did not - thus b extends sequence ma var pp = {p: b}; if (prependA) { pp.next = ma.head; pp.prev = null; ma.head.prev = pp; ma.head = pp; } else { pp.next = null; pp.prev = ma.tail; ma.tail.next = pp; ma.tail = pp; } break; case 2: // b matched, a did not - thus a extends sequence mb var pp = {p: a}; if (prependB) { pp.next = mb.head; pp.prev = null; mb.head.prev = pp; mb.head = pp; } else { pp.next = null; pp.prev = mb.tail; mb.tail.next = pp; mb.tail = pp; } break; case 3: // both matched, can merge sequences // if the sequences are the same, do nothing, as we are simply closing this path (could set a flag) if (ma === mb) { var pp = {p: ma.tail.p, next: ma.head, prev: null}; ma.head.prev = pp; ma.head = pp; ma.closed = true; break; } // there are 4 ways the sequence pair can be joined. The current setting of prependA and // prependB will tell us which type of join is needed. For head/head and tail/tail joins // one sequence needs to be reversed switch((prependA ? 1 : 0) | (prependB ? 2 : 0)) { case 0: // tail-tail // reverse ma and append to mb reverseList(ma); // fall through to head/tail case case 1: // head-tail // ma is appended to mb and ma discarded mb.tail.next = ma.head; ma.head.prev = mb.tail; mb.tail = ma.tail; //discard ma sequence record this.remove_seq(ma); break; case 3: // head-head // reverse ma and append mb to it reverseList(ma); // fall through to tail/head case case 2: // tail-head // mb is appended to ma and mb is discarded ma.tail.next = mb.head; mb.head.prev = ma.tail; ma.tail = mb.tail; //discard mb sequence record this.remove_seq(mb); break; } } } /** * Implements CONREC. * * @param {function} drawContour function for drawing contour. Defaults to a * custom "contour builder", which populates the * contours property. */ function Conrec(drawContour) { if (!drawContour) { var c = this; c.contours = {}; /** * drawContour - interface for implementing the user supplied method to * render the countours. * * Draws a line between the start and end coordinates. * * @param startX - start coordinate for X * @param startY - start coordinate for Y * @param endX - end coordinate for X * @param endY - end coordinate for Y * @param contourLevel - Contour level for line. */ this.drawContour = function(startX, startY, endX, endY, contourLevel, k) { var cb = c.contours[k]; if (!cb) { cb = c.contours[k] = new ContourBuilder(contourLevel); } cb.addSegment({x: startX, y: startY}, {x: endX, y: endY}); } this.contourList = function() { var l = []; var a = c.contours; for (var k in a) { var s = a[k].s; var level = a[k].level; while (s) { var h = s.head; var l2 = []; l2.level = level; l2.k = k; while (h && h.p) { l2.push(h.p); h = h.next; } l.push(l2); s = s.next; } } l.sort(function(a, b) { return a.k - b.k }); return l; } } else { this.drawContour = drawContour; } this.h = new Array(5); this.sh = new Array(5); this.xh = new Array(5); this.yh = new Array(5); } /** * contour is a contouring subroutine for rectangularily spaced data * * It emits calls to a line drawing subroutine supplied by the user which * draws a contour map corresponding to real*4data on a randomly spaced * rectangular grid. The coordinates emitted are in the same units given in * the x() and y() arrays. * * Any number of contour levels may be specified but they must be in order of * increasing value. * * * @param {number[][]} d - matrix of data to contour * @param {number} ilb,iub,jlb,jub - index bounds of data matrix * * The following two, one dimensional arrays (x and y) contain * the horizontal and vertical coordinates of each sample points. * @param {number[]} x - data matrix column coordinates * @param {number[]} y - data matrix row coordinates * @param {number} nc - number of contour levels * @param {number[]} z - contour levels in increasing order. */ Conrec.prototype.contour = function(d, ilb, iub, jlb, jub, x, y, nc, z) { var h = this.h, sh = this.sh, xh = this.xh, yh = this.yh; var drawContour = this.drawContour; this.contours = {}; /** private */ var xsect = function(p1, p2){ return (h[p2]*xh[p1]-h[p1]*xh[p2])/(h[p2]-h[p1]); } var ysect = function(p1, p2){ return (h[p2]*yh[p1]-h[p1]*yh[p2])/(h[p2]-h[p1]); } var m1; var m2; var m3; var case_value; var dmin; var dmax; var x1 = 0.0; var x2 = 0.0; var y1 = 0.0; var y2 = 0.0; // The indexing of im and jm should be noted as it has to start from zero // unlike the fortran counter part var im = [0, 1, 1, 0]; var jm = [0, 0, 1, 1]; // Note that castab is arranged differently from the FORTRAN code because // Fortran and C/C++ arrays are transposed of each other, in this case // it is more tricky as castab is in 3 dimensions var castab = [ [ [0, 0, 8], [0, 2, 5], [7, 6, 9] ], [ [0, 3, 4], [1, 3, 1], [4, 3, 0] ], [ [9, 6, 7], [5, 2, 0], [8, 0, 0] ] ]; for (var j=(jub-1);j>=jlb;j--) { for (var i=ilb;i<=iub-1;i++) { var temp1, temp2; temp1 = Math.min(d[i][j],d[i][j+1]); temp2 = Math.min(d[i+1][j],d[i+1][j+1]); dmin = Math.min(temp1,temp2); temp1 = Math.max(d[i][j],d[i][j+1]); temp2 = Math.max(d[i+1][j],d[i+1][j+1]); dmax = Math.max(temp1,temp2); if (dmax>=z[0]&&dmin<=z[nc-1]) { for (var k=0;k=dmin&&z[k]<=dmax) { for (var m=4;m>=0;m--) { if (m>0) { // The indexing of im and jm should be noted as it has to // start from zero h[m] = d[i+im[m-1]][j+jm[m-1]]-z[k]; xh[m] = x[i+im[m-1]]; yh[m] = y[j+jm[m-1]]; } else { h[0] = 0.25*(h[1]+h[2]+h[3]+h[4]); xh[0]=0.5*(x[i]+x[i+1]); yh[0]=0.5*(y[j]+y[j+1]); } if (h[m]>EPSILON) { sh[m] = 1; } else if (h[m]<-EPSILON) { sh[m] = -1; } else sh[m] = 0; } // // Note: at this stage the relative heights of the corners and the // centre are in the h array, and the corresponding coordinates are // in the xh and yh arrays. The centre of the box is indexed by 0 // and the 4 corners by 1 to 4 as shown below. // Each triangle is then indexed by the parameter m, and the 3 // vertices of each triangle are indexed by parameters m1,m2,and // m3. // It is assumed that the centre of the box is always vertex 2 // though this isimportant only when all 3 vertices lie exactly on // the same contour level, in which case only the side of the box // is drawn. // // // vertex 4 +-------------------+ vertex 3 // | \ / | // | \ m-3 / | // | \ / | // | \ / | // | m=2 X m=2 | the centre is vertex 0 // | / \ | // | / \ | // | / m=1 \ | // | / \ | // vertex 1 +-------------------+ vertex 2 // // // // Scan each triangle in the box // for (m=1;m<=4;m++) { m1 = m; m2 = 0; if (m!=4) { m3 = m+1; } else { m3 = 1; } case_value = castab[sh[m1]+1][sh[m2]+1][sh[m3]+1]; if (case_value!=0) { switch (case_value) { case 1: // Line between vertices 1 and 2 x1=xh[m1]; y1=yh[m1]; x2=xh[m2]; y2=yh[m2]; break; case 2: // Line between vertices 2 and 3 x1=xh[m2]; y1=yh[m2]; x2=xh[m3]; y2=yh[m3]; break; case 3: // Line between vertices 3 and 1 x1=xh[m3]; y1=yh[m3]; x2=xh[m1]; y2=yh[m1]; break; case 4: // Line between vertex 1 and side 2-3 x1=xh[m1]; y1=yh[m1]; x2=xsect(m2,m3); y2=ysect(m2,m3); break; case 5: // Line between vertex 2 and side 3-1 x1=xh[m2]; y1=yh[m2]; x2=xsect(m3,m1); y2=ysect(m3,m1); break; case 6: // Line between vertex 3 and side 1-2 x1=xh[m3]; y1=yh[m3]; x2=xsect(m1,m2); y2=ysect(m1,m2); break; case 7: // Line between sides 1-2 and 2-3 x1=xsect(m1,m2); y1=ysect(m1,m2); x2=xsect(m2,m3); y2=ysect(m2,m3); break; case 8: // Line between sides 2-3 and 3-1 x1=xsect(m2,m3); y1=ysect(m2,m3); x2=xsect(m3,m1); y2=ysect(m3,m1); break; case 9: // Line between sides 3-1 and 1-2 x1=xsect(m3,m1); y1=ysect(m3,m1); x2=xsect(m1,m2); y2=ysect(m1,m2); break; default: break; } // Put your processing code here and comment out the printf //printf("%f %f %f %f %f\n",x1,y1,x2,y2,z[k]); drawContour(x1,y1,x2,y2,z[k],k); } } } } } } } } },{}],83:[function(require,module,exports){ //https://github.com/jasondavies/conrec.js //http://stackoverflow.com/questions/263305/drawing-a-topographical-map var tin = require('turf-tin'); var inside = require('turf-inside'); var grid = require('turf-grid'); var extent = require('turf-extent'); var planepoint = require('turf-planepoint'); var featurecollection = require('turf-featurecollection'); var linestring = require('turf-linestring'); var square = require('turf-square'); var Conrec = require('./conrec'); /** * Takes a {@link FeatureCollection} of {@link Point} features with z-values and an array of * value breaks and generates [isolines](http://en.wikipedia.org/wiki/Isoline). * * @module turf/isolines * @category interpolation * @param {FeatureCollection} points a FeatureCollection of {@link Point} features * @param {string} z the property name in `points` from which z-values will be pulled * @param {number} resolution resolution of the underlying grid * @param {number[]} breaks where to draw contours * @returns {FeatureCollection} a FeatureCollection of {@link LineString} features representing isolines * @example * // create random points with random * // z-values in their properties * var points = turf.random('point', 100, { * bbox: [0, 30, 20, 50] * }); * for (var i = 0; i < points.features.length; i++) { * points.features[i].properties.z = Math.random() * 10; * } * var breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; * var isolined = turf.isolines(points, 'z', 15, breaks); * //=isolined */ module.exports = function(points, z, resolution, breaks, done){ var tinResult = tin(points, z); var extentBBox = extent(points); var squareBBox = square(extentBBox); var gridResult = grid(squareBBox, resolution); var data = []; for (var i = 0; i < gridResult.features.length; i++) { var pt = gridResult.features[i]; for (var j = 0; j < tinResult.features.length; j++) { var triangle = tinResult.features[j]; if (inside(pt, triangle)) { pt.properties = {}; pt.properties[z] = planepoint(pt, triangle); } } } var depth = Math.sqrt(gridResult.features.length); for (var x=0; x 2){ var polyCoordinates = []; c.forEach(function(coord){ polyCoordinates.push([coord.x, coord.y]); }); var poly = linestring(polyCoordinates); poly.properties = {}; poly.properties[z] = c.level; fc.features.push(poly); } }); return fc; } },{"./conrec":82,"turf-extent":70,"turf-featurecollection":72,"turf-grid":84,"turf-inside":76,"turf-linestring":90,"turf-planepoint":98,"turf-square":115,"turf-tin":118}],84:[function(require,module,exports){ var point = require('turf-point'); /** * Takes a bounding box and a cell depth and returns a {@link FeatureCollection} of {@link Point} features in a grid. * * @module turf/grid * @category interpolation * @param {Array} extent extent in [minX, minY, maxX, maxY] order * @param {Number} depth how many cells to output * @return {FeatureCollection} grid as FeatureCollection with {@link Point} features * @example * var extent = [-70.823364, -33.553984, -70.473175, -33.302986]; * var depth = 10; * * var grid = turf.grid(extent, depth); * * //=grid */ module.exports = function(extents, depth) { var xmin = extents[0]; var ymin = extents[1]; var xmax = extents[2]; var ymax = extents[3]; var interval = (xmax - xmin) / depth; var coords = []; var fc = { type: 'FeatureCollection', features: [] }; for (var x=0; x<=depth; x++){ for (var y=0;y<=depth; y++){ fc.features.push(point([(x * interval) + xmin, (y * interval) + ymin])); } } return fc; } },{"turf-point":102}],85:[function(require,module,exports){ var ss = require('simple-statistics'); /** * Takes a {@FeatureCollection} of any type and returns an array of the [Jenks Natural breaks](http://en.wikipedia.org/wiki/Jenks_natural_breaks_optimization) * for a given property * @module turf/jenks * @param {FeatureCollection} input a FeatureCollection of any type * @param {string} field the property in `input` on which to calculate Jenks natural breaks * @param {number} numberOfBreaks number of classes in which to group the data * @return {Array} the break number for each class plus the minimum and maximum values * @example * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [49.859733, 40.400424] * } * }, { * "type": "Feature", * "properties": { * "population": 600 * }, * "geometry": { * "type": "Point", * "coordinates": [49.83879, 40.401209] * } * }, { * "type": "Feature", * "properties": { * "population": 100 * }, * "geometry": { * "type": "Point", * "coordinates": [49.817848, 40.376889] * } * }, { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [49.840507, 40.386043] * } * }, { * "type": "Feature", * "properties": { * "population": 300 * }, * "geometry": { * "type": "Point", * "coordinates": [49.854583, 40.37532] * } * } * ] * }; * * var breaks = turf.jenks(points, 'population', 3); * * //=breaks */ module.exports = function(fc, field, num){ var vals = []; var breaks = []; fc.features.forEach(function(feature){ if(feature.properties[field]!==undefined){ vals.push(feature.properties[field]); } }); breaks = ss.jenks(vals, num); return breaks; }; },{"simple-statistics":86}],86:[function(require,module,exports){ arguments[4][59][0].apply(exports,arguments) },{"dup":59}],87:[function(require,module,exports){ /** * Takes a {@link Polygon} feature and returns a {@link FeatureCollection} of {@link Point} features at all self-intersections. * * @module turf/kinks * @category misc * @param {Polygon} polygon a Polygon feature * @returns {FeatureCollection} a FeatureCollection of {@link Point} features representing self-intersections * @example * var poly = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-12.034835, 8.901183], * [-12.060413, 8.899826], * [-12.03638, 8.873199], * [-12.059383, 8.871418], * [-12.034835, 8.901183] * ]] * } * }; * * var kinks = turf.kinks(poly); * * var resultFeatures = kinks.intersections.features.concat(poly); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ var polygon = require('turf-polygon'); var point = require('turf-point'); var fc = require('turf-featurecollection'); module.exports = function(polyIn) { var poly; var results = {intersections: fc([]), fixed: null}; if (polyIn.type === 'Feature') { poly = polyIn.geometry; } else { poly = polyIn; } var intersectionHash = {}; poly.coordinates.forEach(function(ring1){ poly.coordinates.forEach(function(ring2){ for(var i = 0; i < ring1.length-1; i++) { for(var k = 0; k < ring2.length-1; k++) { var intersection = lineIntersects(ring1[i][0],ring1[i][1],ring1[i+1][0],ring1[i+1][1], ring2[k][0],ring2[k][1],ring2[k+1][0],ring2[k+1][1]); if(intersection) { results.intersections.features.push(point([intersection[0], intersection[1]])); } } } }) }) return results; } // modified from http://jsfiddle.net/justin_c_rounds/Gd2S2/light/ function lineIntersects(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY) { // if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point var denominator, a, b, numerator1, numerator2, result = { x: null, y: null, onLine1: false, onLine2: false }; denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY)); if (denominator == 0) { if(result.x != null && result.y != null) { return result; } else { return false; } } a = line1StartY - line2StartY; b = line1StartX - line2StartX; numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b); numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b); a = numerator1 / denominator; b = numerator2 / denominator; // if we cast these lines infinitely in both directions, they intersect here: result.x = line1StartX + (a * (line1EndX - line1StartX)); result.y = line1StartY + (a * (line1EndY - line1StartY)); // if line1 is a segment and line2 is infinite, they intersect if: if (a > 0 && a < 1) { result.onLine1 = true; } // if line2 is a segment and line1 is infinite, they intersect if: if (b > 0 && b < 1) { result.onLine2 = true; } // if line1 and line2 are segments, they intersect if both of the above are true if(result.onLine1 && result.onLine2){ return [result.x, result.y]; } else { return false; } } },{"turf-featurecollection":72,"turf-point":102,"turf-polygon":103}],88:[function(require,module,exports){ var distance = require('turf-distance'); var point = require('turf-point'); /** * Takes a {@link LineString} feature and measures its length in the specified units. * * @module turf/line-distance * @category measurement * @param {LineString} Line to measure * @param {String} [units=miles] can be degrees, radians, miles, or kilometers * @return {Number} length of the LineString * @example * var line = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "LineString", * "coordinates": [ * [-77.031669, 38.878605], * [-77.029609, 38.881946], * [-77.020339, 38.884084], * [-77.025661, 38.885821], * [-77.021884, 38.889563], * [-77.019824, 38.892368] * ] * } * }; * * var length = turf.lineDistance(line, 'miles'); * * //=line * * //=length */ module.exports = function (line, units) { var coords; if(line.type === 'Feature') coords = line.geometry.coordinates; else if(line.type === 'LineString') coords = line.geometry.coordinates; else throw new Error('input must be a LineString Feature or Geometry'); var travelled = 0; for(var i = 0; i < coords.length - 1; i++) { travelled += distance(point(coords[i]), point(coords[i+1]), units); } return travelled; } },{"turf-distance":60,"turf-point":102}],89:[function(require,module,exports){ var distance = require('turf-distance'); var point = require('turf-point'); var linestring = require('turf-linestring'); var bearing = require('turf-bearing'); var destination = require('turf-destination'); /** * Slices a LineString at start and stop Points * * @module turf/line-slice * * @param {Point} Point to start the slice * @param {Point} Point to stop the slice * @param {LineString} Line to slice * @return {LineString} Sliced LineString * @example * var line = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "LineString", * "coordinates": [ * [-77.031669, 38.878605], * [-77.029609, 38.881946], * [-77.020339, 38.884084], * [-77.025661, 38.885821], * [-77.021884, 38.889563], * [-77.019824, 38.892368] * ] * } * }; * var start = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-77.029609, 38.881946] * } * }; * var stop = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-77.021884, 38.889563] * } * }; * * var sliced = turf.lineSlice(start, stop, line); * * //=line * * //=sliced */ module.exports = function (startPt, stopPt, line) { var coords; if(line.type === 'Feature') coords = line.geometry.coordinates; else if(line.type === 'LineString') coords = line.geometry.coordinates; else throw new Error('input must be a LineString Feature or Geometry'); var startVertex = pointOnLine(startPt, coords); var stopVertex = pointOnLine(stopPt, coords); var ends; if(startVertex.properties.index <= stopVertex.properties.index) { ends = [startVertex, stopVertex]; } else { ends = [stopVertex, startVertex]; } var clipLine = linestring([ends[0].geometry.coordinates], {}); for(var i = ends[0].properties.index+1; i < ends[1].properties.index+1; i++) { clipLine.geometry.coordinates.push(coords[i]); } clipLine.geometry.coordinates.push(ends[1].geometry.coordinates); return clipLine; } function pointOnLine (pt, coords) { var units = 'miles' var closestPt = point([Infinity, Infinity], {dist: Infinity}); for(var i = 0; i < coords.length - 1; i++) { var start = point(coords[i]) var stop = point(coords[i+1]) //start start.properties.dist = distance(pt, start, units); //stop stop.properties.dist = distance(pt, stop, units); //perpendicular var direction = bearing(start, stop) var perpendicularPt = destination(pt, 1000 , direction + 90, units) // 1000 = gross var intersect = lineIntersects( pt.geometry.coordinates[0], pt.geometry.coordinates[1], perpendicularPt.geometry.coordinates[0], perpendicularPt.geometry.coordinates[1], start.geometry.coordinates[0], start.geometry.coordinates[1], stop.geometry.coordinates[0], stop.geometry.coordinates[1] ); if(!intersect) { perpendicularPt = destination(pt, 1000 , direction - 90, units) // 1000 = gross intersect = lineIntersects( pt.geometry.coordinates[0], pt.geometry.coordinates[1], perpendicularPt.geometry.coordinates[0], perpendicularPt.geometry.coordinates[1], start.geometry.coordinates[0], start.geometry.coordinates[1], stop.geometry.coordinates[0], stop.geometry.coordinates[1] ); } perpendicularPt.properties.dist = Infinity; var intersectPt; if(intersect) { var intersectPt = point(intersect); intersectPt.properties.dist = distance(pt, intersectPt, units); } if(start.properties.dist < closestPt.properties.dist) { closestPt = start; closestPt.properties.index = i; } if(stop.properties.dist < closestPt.properties.dist) { closestPt = stop; closestPt.properties.index = i; } if(intersectPt && intersectPt.properties.dist < closestPt.properties.dist){ closestPt = intersectPt; closestPt.properties.index = i; } } return closestPt; } // modified from http://jsfiddle.net/justin_c_rounds/Gd2S2/light/ function lineIntersects(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY) { // if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point var denominator, a, b, numerator1, numerator2, result = { x: null, y: null, onLine1: false, onLine2: false }; denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY)); if (denominator == 0) { if(result.x != null && result.y != null) { return result; } else { return false; } } a = line1StartY - line2StartY; b = line1StartX - line2StartX; numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b); numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b); a = numerator1 / denominator; b = numerator2 / denominator; // if we cast these lines infinitely in both directions, they intersect here: result.x = line1StartX + (a * (line1EndX - line1StartX)); result.y = line1StartY + (a * (line1EndY - line1StartY)); // if line1 is a segment and line2 is infinite, they intersect if: if (a > 0 && a < 1) { result.onLine1 = true; } // if line2 is a segment and line1 is infinite, they intersect if: if (b > 0 && b < 1) { result.onLine2 = true; } // if line1 and line2 are segments, they intersect if both of the above are true if(result.onLine1 && result.onLine2){ return [result.x, result.y]; } else { return false; } } },{"turf-bearing":13,"turf-destination":57,"turf-distance":60,"turf-linestring":90,"turf-point":102}],90:[function(require,module,exports){ /** * Creates a {@link LineString} {@link Feature} based on a * coordinate array. Properties can be added optionally. * * @module turf/linestring * @category helper * @param {Array>} coordinates an array of Positions * @param {Object} properties an Object of key-value pairs to add as properties * @return {LineString} a LineString feature * @throws {Error} if no coordinates are passed * @example * var linestring1 = turf.linestring([ * [-21.964416, 64.148203], * [-21.956176, 64.141316], * [-21.93901, 64.135924], * [-21.927337, 64.136673] * ]); * var linestring2 = turf.linestring([ * [-21.929054, 64.127985], * [-21.912918, 64.134726], * [-21.916007, 64.141016], * [-21.930084, 64.14446] * ], {name: 'line 1', distance: 145}); * * //=linestring1 * * //=linestring2 */ module.exports = function(coordinates, properties){ if (!coordinates) { throw new Error('No coordinates passed'); } return { "type": "Feature", "geometry": { "type": "LineString", "coordinates": coordinates }, "properties": properties || {} }; }; },{}],91:[function(require,module,exports){ var inside = require('turf-inside'); /** * Calculates the maximum value of a field for a set of {@link Point} features within a set of {@link Polygon} features. * * @module turf/max * @category aggregation * @param {FeatureCollection} polygons a FeatureCollection of {@link Polygon} features * @param {FeatureCollection} points a FeatureCollection of {@link Point} features * @param {string} inField the field in input data to analyze * @param {string} outField the field in which to store results * @return {FeatureCollection} a FeatureCollection of {@link Polygon} features * with properties listed as `outField` values * @example * var polygons = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [101.551437, 3.150114], * [101.551437, 3.250208], * [101.742324, 3.250208], * [101.742324, 3.150114], * [101.551437, 3.150114] * ]] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [101.659927, 3.011612], * [101.659927, 3.143944], * [101.913986, 3.143944], * [101.913986, 3.011612], * [101.659927, 3.011612] * ]] * } * } * ] * }; * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [101.56105, 3.213874] * } * }, { * "type": "Feature", * "properties": { * "population": 600 * }, * "geometry": { * "type": "Point", * "coordinates": [101.709365, 3.211817] * } * }, { * "type": "Feature", * "properties": { * "population": 100 * }, * "geometry": { * "type": "Point", * "coordinates": [101.645507, 3.169311] * } * }, { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [101.708679, 3.071266] * } * }, { * "type": "Feature", * "properties": { * "population": 300 * }, * "geometry": { * "type": "Point", * "coordinates": [101.826782, 3.081551] * } * } * ] * }; * * var aggregated = turf.max( * polygons, points, 'population', 'max'); * * var resultFeatures = points.features.concat( * aggregated.features); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ module.exports = function(polyFC, ptFC, inField, outField){ polyFC.features.forEach(function(poly){ if(!poly.properties){ poly.properties = {}; } var values = []; ptFC.features.forEach(function(pt){ if (inside(pt, poly)) { values.push(pt.properties[inField]); } }); poly.properties[outField] = max(values); }); return polyFC; } function max(x) { var value; for (var i = 0; i < x.length; i++) { // On the first iteration of this loop, max is // undefined and is thus made the maximum element in the array if (x[i] > value || value === undefined) value = x[i]; } return value; } },{"turf-inside":76}],92:[function(require,module,exports){ var inside = require('turf-inside'); /** * Calculates the median value of a field for a set of {@link Point} features within a set of {@link Polygon} features. * * @module turf/median * @category aggregation * @param {FeatureCollection} polygons a FeatureCollection of {@link Polygon} features * @param {FeatureCollection} points a FeatureCollection of {@link Point} features * @param {string} inField the field in input data to analyze * @param {string} outField the field in which to store results * @return {FeatureCollection} a FeatureCollection of {@link Polygon} features * with properties listed as `outField` values * @example * var polygons = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [18.400039, -33.970697], * [18.400039, -33.818518], * [18.665771, -33.818518], * [18.665771, -33.970697], * [18.400039, -33.970697] * ]] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [18.538742, -34.050383], * [18.538742, -33.98721], * [18.703536, -33.98721], * [18.703536, -34.050383], * [18.538742, -34.050383] * ]] * } * } * ] * }; * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [18.514022, -33.860152] * } * }, { * "type": "Feature", * "properties": { * "population": 600 * }, * "geometry": { * "type": "Point", * "coordinates": [18.48999, -33.926269] * } * }, { * "type": "Feature", * "properties": { * "population": 100 * }, * "geometry": { * "type": "Point", * "coordinates": [18.583374, -33.905755] * } * }, { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [18.591613, -34.024778] * } * }, { * "type": "Feature", * "properties": { * "population": 300 * }, * "geometry": { * "type": "Point", * "coordinates": [18.653411, -34.017949] * } * } * ] * }; * * var medians = turf.median( * polygons, points, 'population', 'median'); * * var resultFeatures = points.features.concat( * medians.features); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ module.exports = function(polyFC, ptFC, inField, outField){ polyFC.features.forEach(function(poly){ if(!poly.properties){ poly.properties = {}; } var values = []; ptFC.features.forEach(function(pt){ if (inside(pt, poly)) { values.push(pt.properties[inField]); } }); poly.properties[outField] = median(values); }); return polyFC; }; function median(x) { // The median of an empty list is null if (x.length === 0) return null; // Sorting the array makes it easy to find the center, but // use `.slice()` to ensure the original array `x` is not modified var sorted = x.slice().sort(function (a, b) { return a - b; }); // If the length of the list is odd, it's the central number if (sorted.length % 2 === 1) { return sorted[(sorted.length - 1) / 2]; // Otherwise, the median is the average of the two numbers // at the center of the list } else { var a = sorted[(sorted.length / 2) - 1]; var b = sorted[(sorted.length / 2)]; return (a + b) / 2; } } },{"turf-inside":76}],93:[function(require,module,exports){ var clone = require('clone'); var union = require('turf-union'); /** * Takes a {@link FeatureCollection} of {@link Polygon} features and returns a single merged * polygon feature. If the input Polygon features are not contiguous, this function returns a {@link MultiPolygon} feature. * @module turf/merge * @category transformation * @param {FeatureCollection} fc a FeatureCollection of {@link Polygon} features * @return {Feature} a {@link Polygon} or {@link MultiPolygon} feature * @example * var polygons = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "fill": "#0f0" * }, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [9.994812, 53.549487], * [10.046997, 53.598209], * [10.117721, 53.531737], * [9.994812, 53.549487] * ]] * } * }, { * "type": "Feature", * "properties": { * "fill": "#00f" * }, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [10.000991, 53.50418], * [10.03807, 53.562539], * [9.926834, 53.551731], * [10.000991, 53.50418] * ]] * } * } * ] * }; * * var merged = turf.merge(polygons); * * //=polygons * * //=merged */ module.exports = function(polygons, done){ var merged = clone(polygons.features[0]), features = polygons.features; for (var i = 0, len = features.length; i < len; i++) { var poly = features[i]; if(poly.geometry){ merged = union(merged, poly); } } return merged; }; },{"clone":94,"turf-union":120}],94:[function(require,module,exports){ (function (Buffer){ 'use strict'; function objectToString(o) { return Object.prototype.toString.call(o); } // shim for Node's 'util' package // DO NOT REMOVE THIS! It is required for compatibility with EnderJS (http://enderjs.com/). var util = { isArray: function (ar) { return Array.isArray(ar) || (typeof ar === 'object' && objectToString(ar) === '[object Array]'); }, isDate: function (d) { return typeof d === 'object' && objectToString(d) === '[object Date]'; }, isRegExp: function (re) { return typeof re === 'object' && objectToString(re) === '[object RegExp]'; }, getRegExpFlags: function (re) { var flags = ''; re.global && (flags += 'g'); re.ignoreCase && (flags += 'i'); re.multiline && (flags += 'm'); return flags; } }; if (typeof module === 'object') module.exports = clone; /** * Clones (copies) an Object using deep copying. * * This function supports circular references by default, but if you are certain * there are no circular references in your object, you can save some CPU time * by calling clone(obj, false). * * Caution: if `circular` is false and `parent` contains circular references, * your program may enter an infinite loop and crash. * * @param `parent` - the object to be cloned * @param `circular` - set to true if the object to be cloned may contain * circular references. (optional - true by default) * @param `depth` - set to a number if the object is only to be cloned to * a particular depth. (optional - defaults to Infinity) * @param `prototype` - sets the prototype to be used when cloning an object. * (optional - defaults to parent prototype). */ function clone(parent, circular, depth, prototype) { // maintain two arrays for circular references, where corresponding parents // and children have the same index var allParents = []; var allChildren = []; var useBuffer = typeof Buffer != 'undefined'; if (typeof circular == 'undefined') circular = true; if (typeof depth == 'undefined') depth = Infinity; // recurse this function so we don't reset allParents and allChildren function _clone(parent, depth) { // cloning null always returns null if (parent === null) return null; if (depth == 0) return parent; var child; var proto; if (typeof parent != 'object') { return parent; } if (util.isArray(parent)) { child = []; } else if (util.isRegExp(parent)) { child = new RegExp(parent.source, util.getRegExpFlags(parent)); if (parent.lastIndex) child.lastIndex = parent.lastIndex; } else if (util.isDate(parent)) { child = new Date(parent.getTime()); } else if (useBuffer && Buffer.isBuffer(parent)) { child = new Buffer(parent.length); parent.copy(child); return child; } else { if (typeof prototype == 'undefined') { proto = Object.getPrototypeOf(parent); child = Object.create(proto); } else { child = Object.create(prototype); proto = prototype; } } if (circular) { var index = allParents.indexOf(parent); if (index != -1) { return allChildren[index]; } allParents.push(parent); allChildren.push(child); } for (var i in parent) { var attrs; if (proto) { attrs = Object.getOwnPropertyDescriptor(proto, i); } if (attrs && attrs.set == null) { continue; } child[i] = _clone(parent[i], depth - 1); } return child; } return _clone(parent, depth); } /** * Simple flat clone using prototype, accepts only objects, usefull for property * override on FLAT configuration object (no nested props). * * USE WITH CAUTION! This may not behave as you wish if you do not know how this * works. */ clone.clonePrototype = function(parent) { if (parent === null) return null; var c = function () {}; c.prototype = parent; return new c(); }; }).call(this,require("buffer").Buffer) },{"buffer":2}],95:[function(require,module,exports){ // http://cs.selu.edu/~rbyrd/math/midpoint/ // ((x1+x2)/2), ((y1+y2)/2) var point = require('turf-point'); /** * Takes two {@link Point} features and returns a Point midway between the two. * * @module turf/midpoint * @category measurement * @param {Point} pt1 first point * @param {Point} pt2 second point * @return {Point} a point between the two * @example * var pt1 = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [144.834823, -37.771257] * } * }; * var pt2 = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [145.14244, -37.830937] * } * }; * * var midpointed = turf.midpoint(pt1, pt2); * midpointed.properties['marker-color'] = '#f00'; * * * var result = { * "type": "FeatureCollection", * "features": [pt1, pt2, midpointed] * }; * * //=result */ module.exports = function(point1, point2) { if (point1 === null || point2 === null){ throw new Error('Less than two points passed.'); } var x1 = point1.geometry.coordinates[0]; var x2 = point2.geometry.coordinates[0]; var y1 = point1.geometry.coordinates[1]; var y2 = point2.geometry.coordinates[1]; var x3 = x1 + x2; var midX = x3/2; var y3 = y1 + y2; var midY = y3/2; return point([midX, midY]); }; },{"turf-point":102}],96:[function(require,module,exports){ var inside = require('turf-inside'); /** * Calculates the minimum value of a field for {@link Point} features within a set of {@link Polygon} features. * * @module turf/min * @category aggregation * @param {FeatureCollection} polygons a FeatureCollection of {@link Polygon} features * @param {FeatureCollection} points a FeatureCollection of {@link Point} features * @param {string} inField the field in input data to analyze * @param {string} outField the field in which to store results * @return {FeatureCollection} a FeatureCollection of {@link Polygon} features * with properties listed as `outField` values * @example * var polygons = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [72.809658, 18.961818], * [72.809658, 18.974805], * [72.827167, 18.974805], * [72.827167, 18.961818], * [72.809658, 18.961818] * ]] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [72.820987, 18.947043], * [72.820987, 18.95922], * [72.841243, 18.95922], * [72.841243, 18.947043], * [72.820987, 18.947043] * ]] * } * } * ] * }; * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [72.814464, 18.971396] * } * }, { * "type": "Feature", * "properties": { * "population": 600 * }, * "geometry": { * "type": "Point", * "coordinates": [72.820043, 18.969772] * } * }, { * "type": "Feature", * "properties": { * "population": 100 * }, * "geometry": { * "type": "Point", * "coordinates": [72.817296, 18.964253] * } * }, { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [72.83575, 18.954837] * } * }, { * "type": "Feature", * "properties": { * "population": 300 * }, * "geometry": { * "type": "Point", * "coordinates": [72.828197, 18.95094] * } * } * ] * }; * * var minimums = turf.min( * polygons, points, 'population', 'min'); * * var resultFeatures = points.features.concat( * minimums.features); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ module.exports = function(polyFC, ptFC, inField, outField){ polyFC.features.forEach(function(poly){ if(!poly.properties){ poly.properties = {}; } var values = []; ptFC.features.forEach(function(pt){ if (inside(pt, poly)) { values.push(pt.properties[inField]); } }); poly.properties[outField] = min(values); }); return polyFC; }; function min(x) { var value; for (var i = 0; i < x.length; i++) { // On the first iteration of this loop, min is // undefined and is thus made the minimum element in the array if (x[i] < value || value === undefined) value = x[i]; } return value; } },{"turf-inside":76}],97:[function(require,module,exports){ var distance = require('turf-distance'); /** * Takes a {@link Point} feature and a {@link FeatureCollection} of Point features and returns the Point feature from the FeatureCollection closest to the input point. * * @module turf/nearest * @category classification * @param {Point} point the reference point * @param {FeatureCollection} against a FeatureCollection of Point features * @return {Feature} the closest Point feature in `against` to `point` * @example * var point = { * "type": "Feature", * "properties": { * "marker-color": "#0f0" * }, * "geometry": { * "type": "Point", * "coordinates": [28.965797, 41.010086] * } * }; * var against = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [28.973865, 41.011122] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [28.948459, 41.024204] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [28.938674, 41.013324] * } * } * ] * }; * * var nearest = turf.nearest(point, against); * nearest.properties['marker-color'] = '#f00'; * * var resultFeatures = against.features.concat(point); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ module.exports = function(targetPoint, points){ var nearestPoint; var count = 0; var dist = Infinity; points.features.forEach(function(pt){ if(!nearestPoint){ nearestPoint = pt; var dist = distance(targetPoint, pt, 'miles'); nearestPoint.properties.distance = dist; } else{ var dist = distance(targetPoint, pt, 'miles'); if(dist < nearestPoint.properties.distance){ nearestPoint = pt; nearestPoint.properties.distance = dist; } } }); delete nearestPoint.properties.distance; return nearestPoint; } },{"turf-distance":60}],98:[function(require,module,exports){ /** * Takes a triangular plane as a {@link Polygon} feature * and a {@link Point} feature within that triangle and returns the z-value * at that point. The Polygon needs to have properties `a`, `b`, and `c` * that define the values at its three corners. * * @module turf/planepoint * @category interpolation * @param {Point} interpolatedPoint the Point for which a z-value will be calculated * @param {Polygon} triangle a Polygon feature with three vertices * @return {number} the z-value for `interpolatedPoint` * @example * var point = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-75.3221, 39.529] * } * }; * var point = turf.point([-75.3221, 39.529]); * // triangle is a polygon with "a", "b", * // and "c" values representing * // the values of the coordinates in order. * var triangle = { * "type": "Feature", * "properties": { * "a": 11, * "b": 122, * "c": 44 * }, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-75.1221, 39.57], * [-75.58, 39.18], * [-75.97, 39.86], * [-75.1221, 39.57] * ]] * } * }; * * var features = { * "type": "FeatureCollection", * "features": [triangle, point] * }; * * var zValue = turf.planepoint(point, triangle); * * //=features * * //=zValue */ module.exports = function(point, triangle){ var x = point.geometry.coordinates[0], y = point.geometry.coordinates[1], x1 = triangle.geometry.coordinates[0][0][0], y1 = triangle.geometry.coordinates[0][0][1], z1 = triangle.properties.a, x2 = triangle.geometry.coordinates[0][1][0], y2 = triangle.geometry.coordinates[0][1][1], z2 = triangle.properties.b, x3 = triangle.geometry.coordinates[0][2][0], y3 = triangle.geometry.coordinates[0][2][1], z3 = triangle.properties.c; var z = (z3 * (x-x1) * (y-y2) + z1 * (x-x2) * (y-y3) + z2 * (x-x3) * (y-y1) - z2 * (x-x1) * (y-y3) - z3 * (x-x2) * (y-y1) - z1 * (x-x3) * (y-y2)) / ((x-x1) * (y-y2) + (x-x2) * (y-y3) +(x-x3) * (y-y1) - (x-x1) * (y-y3) - (x-x2) * (y-y1) - (x-x3) * (y-y2)); return z; }; },{}],99:[function(require,module,exports){ var point = require('turf-point'); var featurecollection = require('turf-featurecollection'); var distance = require('turf-distance'); /** * Takes a bounding box and a cell depth and returns a {@link FeatureCollection} of {@link Point} features in a grid. * * @module turf/point-grid * @category interpolation * @param {Array} extent extent in [minX, minY, maxX, maxY] order * @param {Number} depth how many cells to output * @return {FeatureCollection} grid as FeatureCollection with {@link Point} features * @example * var extent = [-70.823364, -33.553984, -70.473175, -33.302986]; * var depth = 10; * * var grid = turf.pointGrid(extent, depth); * * //=grid */ module.exports = function (bbox, cell, units) { var fc = featurecollection([]); var xFraction = cell / (distance(point([bbox[0], bbox[1]]), point([bbox[2], bbox[1]]), units)); var cellWidth = xFraction * (bbox[2] - bbox[0]); var yFraction = cell / (distance(point([bbox[0], bbox[1]]), point([bbox[0], bbox[3]]), units)); var cellHeight = yFraction * (bbox[3] - bbox[1]); var currentX = bbox[0]; while (currentX <= bbox[2]) { var currentY = bbox[1]; while (currentY <= bbox[3]) { fc.features.push(point([currentX, currentY])); currentY += cellHeight; } currentX += cellWidth; } return fc; } },{"turf-distance":60,"turf-featurecollection":72,"turf-point":102}],100:[function(require,module,exports){ var distance = require('turf-distance'); var point = require('turf-point'); var linestring = require('turf-linestring'); var bearing = require('turf-bearing'); var destination = require('turf-destination'); /** * Takes a Point and a LineString and calculates the closest Point on the LineString * * @module turf/point-on-line * * @param {LineString} Line to snap to * @param {Point} Point to snap from * @return {Point} Closest Point on the Line * @example * var line = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "LineString", * "coordinates": [ * [-77.031669, 38.878605], * [-77.029609, 38.881946], * [-77.020339, 38.884084], * [-77.025661, 38.885821], * [-77.021884, 38.889563], * [-77.019824, 38.892368] * ] * } * }; * var pt = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-77.037076, 38.884017] * } * }; * * var snapped = turf.pointOnLine(line, pt); * snapped.properties['marker-color'] = '#00f' * * var result = { * "type": "FeatureCollection", * "features": [line, pt, snapped] * }; * * //=result */ module.exports = function (line, pt) { var coords; if(line.type === 'Feature') coords = line.geometry.coordinates; else if(line.type === 'LineString') coords = line.geometry.coordinates; else throw new Error('input must be a LineString Feature or Geometry'); return pointOnLine(pt, coords); } function pointOnLine (pt, coords) { var units = 'miles' var closestPt = point([Infinity, Infinity], {dist: Infinity}); for(var i = 0; i < coords.length - 1; i++) { var start = point(coords[i]) var stop = point(coords[i+1]) //start start.properties.dist = distance(pt, start, units); //stop stop.properties.dist = distance(pt, stop, units); //perpendicular var direction = bearing(start, stop) var perpendicularPt = destination(pt, 1000 , direction + 90, units) // 1000 = gross var intersect = lineIntersects( pt.geometry.coordinates[0], pt.geometry.coordinates[1], perpendicularPt.geometry.coordinates[0], perpendicularPt.geometry.coordinates[1], start.geometry.coordinates[0], start.geometry.coordinates[1], stop.geometry.coordinates[0], stop.geometry.coordinates[1] ); if(!intersect) { perpendicularPt = destination(pt, 1000 , direction - 90, units) // 1000 = gross intersect = lineIntersects( pt.geometry.coordinates[0], pt.geometry.coordinates[1], perpendicularPt.geometry.coordinates[0], perpendicularPt.geometry.coordinates[1], start.geometry.coordinates[0], start.geometry.coordinates[1], stop.geometry.coordinates[0], stop.geometry.coordinates[1] ); } perpendicularPt.properties.dist = Infinity; var intersectPt; if(intersect) { var intersectPt = point(intersect); intersectPt.properties.dist = distance(pt, intersectPt, units); } if(start.properties.dist < closestPt.properties.dist) { closestPt = start; closestPt.properties.index = i; } if(stop.properties.dist < closestPt.properties.dist) { closestPt = stop; closestPt.properties.index = i; } if(intersectPt && intersectPt.properties.dist < closestPt.properties.dist){ closestPt = intersectPt; closestPt.properties.index = i; } } return closestPt; } // modified from http://jsfiddle.net/justin_c_rounds/Gd2S2/light/ function lineIntersects(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY) { // if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point var denominator, a, b, numerator1, numerator2, result = { x: null, y: null, onLine1: false, onLine2: false }; denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY)); if (denominator == 0) { if(result.x != null && result.y != null) { return result; } else { return false; } } a = line1StartY - line2StartY; b = line1StartX - line2StartX; numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b); numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b); a = numerator1 / denominator; b = numerator2 / denominator; // if we cast these lines infinitely in both directions, they intersect here: result.x = line1StartX + (a * (line1EndX - line1StartX)); result.y = line1StartY + (a * (line1EndY - line1StartY)); // if line1 is a segment and line2 is infinite, they intersect if: if (a > 0 && a < 1) { result.onLine1 = true; } // if line2 is a segment and line1 is infinite, they intersect if: if (b > 0 && b < 1) { result.onLine2 = true; } // if line1 and line2 are segments, they intersect if both of the above are true if(result.onLine1 && result.onLine2){ return [result.x, result.y]; } else { return false; } } },{"turf-bearing":13,"turf-destination":57,"turf-distance":60,"turf-linestring":90,"turf-point":102}],101:[function(require,module,exports){ var featureCollection = require('turf-featurecollection'); var centroid = require('turf-center'); var distance = require('turf-distance'); var inside = require('turf-inside'); var explode = require('turf-explode'); /** * Finds a {@link Point} guaranteed to be on the surface of * {@link GeoJSON} object. * * * Given a {@link Polygon}, the point will be in the area of the polygon * * Given a {@link LineString}, the point will be along the string * * Given a {@link Point}, the point will the same as the input * * @module turf/point-on-surface * @category measurement * @param {GeoJSON} input any GeoJSON object * @returns {Feature} a point on the surface of `input` * @example * // create a random polygon * var polygon = turf.random('polygon'); * * //=polygon * * var pointOnPolygon = turf.pointOnSurface(polygon); * * var resultFeatures = polygon.features.concat(pointOnPolygon); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ module.exports = function(fc) { // normalize if(fc.type != 'FeatureCollection') { if(fc.type != 'Feature') { fc = { type: 'Feature', geometry: fc, properties: {} }; } fc = featureCollection([fc]); } //get centroid var cent = centroid(fc); // check to see if centroid is on surface var onSurface = false; var i = 0; while(!onSurface && i < fc.features.length) { var geom = fc.features[i].geometry; if (geom.type === 'Point') { if (cent.geometry.coordinates[0] === geom.coordinates[0] && cent.geometry.coordinates[1] === geom.coordinates[1]) { onSurface = true; } } else if(geom.type === 'MultiPoint') { var onMultiPoint = false; var k = 0; while(!onMultiPoint && k < geom.coordinates.length) { if (cent.geometry.coordinates[0] === geom.coordinates[k][0] && cent.geometry.coordinates[1] === geom.coordinates[k][1]) { onSurface = true; onMultiPoint = true; } k++; } } else if(geom.type === 'LineString') { var onLine = false; var k = 0; while(!onLine && k < geom.coordinates.length - 1) { var x = cent.geometry.coordinates[0]; var y = cent.geometry.coordinates[1]; var x1 = geom.coordinates[k][0]; var y1 = geom.coordinates[k][1]; var x2 = geom.coordinates[k+1][0]; var y2 = geom.coordinates[k+1][1]; if(pointOnSegment(x, y, x1, y1, x2, y2)) { onLine = true; onSurface = true; } k++; } } else if(geom.type === 'MultiLineString') { var onMultiLine = false; var j = 0; while(!onMultiLine && j < geom.coordinates.length) { var onLine = false; var k = 0; var line = geom.coordinates[j]; while(!onLine && k < line.length - 1) { var x = cent.geometry.coordinates[0]; var y = cent.geometry.coordinates[1]; var x1 = line[k][0]; var y1 = line[k][1]; var x2 = line[k+1][0]; var y2 = line[k+1][1]; if(pointOnSegment(x, y, x1, y1, x2, y2)) { onLine = true; onSurface = true; } k++; } j++; } } else if(geom.type === 'Polygon' || geom.type === 'MultiPolygon') { var f = { type: 'Feature', geometry: geom, properties: {} }; if(inside(cent, f)) { onSurface = true; } } i++; } if(onSurface) { return cent; } else { var vertices = featureCollection([]); for(var i = 0; i < fc.features.length; i++) { vertices.features = vertices.features.concat(explode(fc.features[i]).features); } var closestVertex; var closestDistance = Infinity; for(var i = 0; i < vertices.features.length; i++) { var dist = distance(cent, vertices.features[i], 'miles'); if(dist < closestDistance) { closestDistance = dist; closestVertex = vertices.features[i]; } } return closestVertex; } }; function pointOnSegment (x, y, x1, y1, x2, y2) { var ab = Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); var ap = Math.sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1)); var pb = Math.sqrt((x2-x)*(x2-x)+(y2-y)*(y2-y)); if(ab === ap + pb) { return true; } } },{"turf-center":21,"turf-distance":60,"turf-explode":68,"turf-featurecollection":72,"turf-inside":76}],102:[function(require,module,exports){ /** * Takes coordinates and properties (optional) and returns a new {@link Point} feature. * * @module turf/point * @category helper * @param {number} longitude position west to east in decimal degrees * @param {number} latitude position south to north in decimal degrees * @param {Object} properties an Object that is used as the {@link Feature}'s * properties * @return {Point} a Point feature * @example * var pt1 = turf.point([-75.343, 39.984]); * * //=pt1 */ var isArray = Array.isArray || function(arg) { return Object.prototype.toString.call(arg) === '[object Array]'; }; module.exports = function(coordinates, properties) { if (!isArray(coordinates)) throw new Error('Coordinates must be an array'); if (coordinates.length < 2) throw new Error('Coordinates must be at least 2 numbers long'); return { type: "Feature", geometry: { type: "Point", coordinates: coordinates }, properties: properties || {} }; }; },{}],103:[function(require,module,exports){ /** * Takes an array of LinearRings and optionally an {@link Object} with properties and returns a GeoJSON {@link Polygon} feature. * * @module turf/polygon * @category helper * @param {Array>} rings an array of LinearRings * @param {Object} properties an optional properties object * @return {Polygon} a Polygon feature * @throws {Error} throw an error if a LinearRing of the polygon has too few positions * or if a LinearRing of the Polygon does not have matching Positions at the * beginning & end. * @example * var polygon = turf.polygon([[ * [-2.275543, 53.464547], * [-2.275543, 53.489271], * [-2.215118, 53.489271], * [-2.215118, 53.464547], * [-2.275543, 53.464547] * ]], { name: 'poly1', population: 400}); * * //=polygon */ module.exports = function(coordinates, properties){ if (coordinates === null) throw new Error('No coordinates passed'); for (var i = 0; i < coordinates.length; i++) { var ring = coordinates[i]; for (var j = 0; j < ring[ring.length - 1].length; j++) { if (ring.length < 4) { throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.'); } if (ring[ring.length - 1][j] !== ring[0][j]) { throw new Error('First and last Position are not equivalent.'); } } } var polygon = { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": coordinates }, "properties": properties }; if (!polygon.properties) { polygon.properties = {}; } return polygon; }; },{}],104:[function(require,module,exports){ var ss = require('simple-statistics'); /** * Takes a {@link FeatureCollection}, a property name, and a set of percentiles and returns a quantile array. * @module turf/quantile * @category classification * @param {FeatureCollection} input a FeatureCollection of any type * @param {String} field the property in `input` from which to retrieve quantile values * @param {Array} percentiles an Array of percentiles on which to calculate quantile values * @return {Array} an array of the break values * @example * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "population": 5 * }, * "geometry": { * "type": "Point", * "coordinates": [5, 5] * } * }, { * "type": "Feature", * "properties": { * "population": 40 * }, * "geometry": { * "type": "Point", * "coordinates": [1, 3] * } * }, { * "type": "Feature", * "properties": { * "population": 80 * }, * "geometry": { * "type": "Point", * "coordinates": [14, 2] * } * }, { * "type": "Feature", * "properties": { * "population": 90 * }, * "geometry": { * "type": "Point", * "coordinates": [13, 1] * } * }, { * "type": "Feature", * "properties": { * "population": 100 * }, * "geometry": { * "type": "Point", * "coordinates": [19, 7] * } * } * ] * }; * * var breaks = turf.quantile( * points, 'population', [25, 50, 75, 99]); * * //=breaks */ module.exports = function(fc, field, percentiles){ var vals = []; var quantiles = []; fc.features.forEach(function(feature){ vals.push(feature.properties[field]); }); percentiles.forEach(function(percentile){ quantiles.push(ss.quantile(vals, percentile * 0.01)); }); return quantiles; }; },{"simple-statistics":105}],105:[function(require,module,exports){ arguments[4][59][0].apply(exports,arguments) },{"dup":59}],106:[function(require,module,exports){ var random = require('geojson-random'); /** * Generates random {@link GeoJSON} data, including {@link Point|Points} and {@link Polygon|Polygons}, for testing * and experimentation. * * @module turf/random * @category data * @param {String} [type='point'] type of features desired: 'points' or 'polygons' * @param {Number} [count=1] how many geometries should be generated. * @param {Object} options options relevant to the feature desired. Can include: * @param {Array} options.bbox a bounding box inside of which geometries * are placed. In the case of {@link Point} features, they are guaranteed to be within this bounds, * while {@link Polygon} features have their centroid within the bounds. * @param {Number} [options.num_vertices=10] options.vertices the number of vertices added * to polygon features. * @param {Number} [options.max_radial_length=10] the total number of decimal * degrees longitude or latitude that a polygon can extent outwards to * from its center. * @return {FeatureCollection} generated random features * @example * var points = turf.random('points', 100, { * bbox: [-70, 40, -60, 60] * }); * * //=points * * var polygons = turf.random('polygons', 4, { * bbox: [-70, 40, -60, 60] * }); * * //=polygons */ module.exports = function(type, count, options) { options = options || {}; count = count || 1; switch (type) { case 'point': case 'points': case undefined: return random.point(count, options.bbox); case 'polygon': case 'polygons': return random.polygon( count, options.num_vertices, options.max_radial_length, options.bbox); default: throw new Error('Unknown type given: valid options are points and polygons'); } }; },{"geojson-random":107}],107:[function(require,module,exports){ module.exports = function() { throw new Error('call .point() or .polygon() instead'); }; function position(bbox) { if (bbox) return coordInBBBOX(bbox); else return [lon(), lat()]; } module.exports.position = position; module.exports.point = function(count, bbox) { var features = []; for (i = 0; i < count; i++) { features.push(feature(bbox ? point(position(bbox)) : point())); } return collection(features); }; module.exports.polygon = function(count, num_vertices, max_radial_length, bbox) { if (typeof num_vertices !== 'number') num_vertices = 10; if (typeof max_radial_length !== 'number') max_radial_length = 10; var features = []; for (i = 0; i < count; i++) { var vertices = [], circle_offsets = Array.apply(null, new Array(num_vertices + 1)).map(Math.random); circle_offsets.forEach(sumOffsets); circle_offsets.forEach(scaleOffsets); vertices[vertices.length - 1] = vertices[0]; // close the ring // center the polygon around something vertices = vertices.map(vertexToCoordinate(position(bbox))); features.push(feature(polygon([vertices]))); } function sumOffsets(cur, index, arr) { arr[index] = (index > 0) ? cur + arr[index - 1] : cur; } function scaleOffsets(cur, index) { cur = cur * 2 * Math.PI / circle_offsets[circle_offsets.length - 1]; var radial_scaler = Math.random(); vertices.push([ radial_scaler * max_radial_length * Math.sin(cur), radial_scaler * max_radial_length * Math.cos(cur) ]); } return collection(features); }; function vertexToCoordinate(hub) { return function(cur, index) { return [cur[0] + hub[0], cur[1] + hub[1]]; }; } function rnd() { return Math.random() - 0.5; } function lon() { return rnd() * 360; } function lat() { return rnd() * 180; } function point(coordinates) { return { type: 'Point', coordinates: coordinates || [lon(), lat()] }; } function coordInBBBOX(bbox) { return [ (Math.random() * (bbox[2] - bbox[0])) + bbox[0], (Math.random() * (bbox[3] - bbox[1])) + bbox[1]]; } function pointInBBBOX() { return { type: 'Point', coordinates: [lon(), lat()] }; } function polygon(coordinates) { return { type: 'Polygon', coordinates: coordinates }; } function feature(geom) { return { type: 'Feature', geometry: geom, properties: {} }; } function collection(f) { return { type: 'FeatureCollection', features: f }; } },{}],108:[function(require,module,exports){ var featurecollection = require('turf-featurecollection'); var reclass = require('./index.js'); /** * Takes a {@link FeatureCollection}, an input field, an output field, and * an array of translations and outputs an identical FeatureCollection with * the output field property populated. * @module turf/reclass * @category classification * @param {FeatureCollection} input a FeatureCollection of any type * @param {string} inField the field to translate * @param {string} outField the field in which to store translated results * @param {Array} translations an array of translations * @return {FeatureCollection} a FeatureCollection with identical geometries to `input` but with `outField` populated. * @example * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [13.170547, 32.888669] * } * }, { * "type": "Feature", * "properties": { * "population": 600 * }, * "geometry": { * "type": "Point", * "coordinates": [13.182048, 32.889533] * } * }, { * "type": "Feature", * "properties": { * "population": 100 * }, * "geometry": { * "type": "Point", * "coordinates": [13.17398, 32.882182] * } * }, { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [13.174324, 32.895011] * } * }, { * "type": "Feature", * "properties": { * "population": 300 * }, * "geometry": { * "type": "Point", * "coordinates": [13.185825, 32.884344] * } * } * ] * }; * // 0 to 200 will map to "small", 200 to 400 will map to "medium", 400 to 600 will map to "large" * var translations = [ * [0, 200, "small"], * [200, 400, "medium"], * [400, 600, "large"] * ]; * * var reclassed = turf.reclass( * points, 'population', 'size', translations); * * //=reclassed * */ module.exports = function(fc, inField, outField, translations, done){ var reclassed = featurecollection([]); fc.features.forEach(function(feature){ var reclassedFeature; var found = false; for(var i = 0; i < translations.length; i++){ if(feature.properties[inField] >= translations[i][0] && feature.properties[inField] <= translations[i][1]) { feature.properties[outField] = translations[i][2]; } } reclassed.features.push(feature); }); return reclassed; }; },{"./index.js":108,"turf-featurecollection":72}],109:[function(require,module,exports){ var featureCollection = require('turf-featurecollection'); /** * Takes a {@link FeatureCollection} of any type, a property, and a value and * returns a FeatureCollection with features matching that * property-value pair removed. * * @module turf/remove * @category data * @param {FeatureCollection} features a FeatureCollection of any type * @param {String} property the property to filter * @param {String} value the value to filter * @return {FeatureCollection} the resulting FeatureCollection without features that match the property-value pair * @example * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * 'marker-color': '#00f' * }, * "geometry": { * "type": "Point", * "coordinates": [-0.235004, 5.551918] * } * }, { * "type": "Feature", * "properties": { * 'marker-color': '#f00' * }, * "geometry": { * "type": "Point", * "coordinates": [-0.209598, 5.56439] * } * }, { * "type": "Feature", * "properties": { * 'marker-color': '#00f' * }, * "geometry": { * "type": "Point", * "coordinates": [-0.197753, 5.556018] * } * }, { * "type": "Feature", * "properties": { * 'marker-color': '#000' * }, * "geometry": { * "type": "Point", * "coordinates": [-0.217323, 5.549526] * } * }, { * "type": "Feature", * "properties": { * 'marker-color': '#0f0' * }, * "geometry": { * "type": "Point", * "coordinates": [-0.211315, 5.543887] * } * }, { * "type": "Feature", * "properties": { * 'marker-color': '#00f' * }, * "geometry": { * "type": "Point", * "coordinates": [-0.202217, 5.547134] * } * }, { * "type": "Feature", * "properties": { * 'marker-color': '#0f0' * }, * "geometry": { * "type": "Point", * "coordinates": [-0.231227, 5.56644] * } * } * ] * }; * * //=points * * var filtered = turf.remove(points, 'marker-color', '#00f'); * * //=filtered */ module.exports = function(collection, key, val) { var newFC = featureCollection([]); for(var i = 0; i < collection.features.length; i++) { if(collection.features[i].properties[key] != val) { newFC.features.push(collection.features[i]); } } return newFC; }; },{"turf-featurecollection":72}],110:[function(require,module,exports){ // http://stackoverflow.com/questions/11935175/sampling-a-random-subset-from-an-array var featureCollection = require('turf-featurecollection'); /** * Takes a {@link FeatureCollection} and returns a FeatureCollection with given number of {@link Feature|features} at random. * * @module turf/sample * @category data * @param {FeatureCollection} features a FeatureCollection of any type * @param {number} n number of features to select * @return {FeatureCollection} a FeatureCollection with `n` features * @example * var points = turf.random('points', 1000); * * //=points * * var sample = turf.sample(points, 10); * * //=sample */ module.exports = function(fc, num){ var outFC = featureCollection(getRandomSubarray(fc.features, num)); return outFC; }; function getRandomSubarray(arr, size) { var shuffled = arr.slice(0), i = arr.length, min = i - size, temp, index; while (i-- > min) { index = Math.floor((i + 1) * Math.random()); temp = shuffled[index]; shuffled[index] = shuffled[i]; shuffled[i] = temp; } return shuffled.slice(min); } },{"turf-featurecollection":72}],111:[function(require,module,exports){ var simplify = require('simplify-js'); /** * Takes a {@link LineString} or {@link Polygon} feature and returns a simplified version. Internally uses [simplify-js](http://mourner.github.io/simplify-js/) to perform simplification. * * @module turf/simplify * @category transformation * @param {Feature} feature a {@link LineString} or {@link Polygon} feature to be simplified * @param {number} tolerance simplification tolerance * @param {boolean} highQuality whether or not to spend more time to create * a higher-quality simplification with a different algorithm * @return {Feature} a simplified feature * @example * var feature = { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-70.603637, -33.399918], * [-70.614624, -33.395332], * [-70.639343, -33.392466], * [-70.659942, -33.394759], * [-70.683975, -33.404504], * [-70.697021, -33.419406], * [-70.701141, -33.434306], * [-70.700454, -33.446339], * [-70.694274, -33.458369], * [-70.682601, -33.465816], * [-70.668869, -33.472117], * [-70.646209, -33.473835], * [-70.624923, -33.472117], * [-70.609817, -33.468107], * [-70.595397, -33.458369], * [-70.587158, -33.442901], * [-70.587158, -33.426283], * [-70.590591, -33.414248], * [-70.594711, -33.406224], * [-70.603637, -33.399918] * ]] * } * }; * var tolerance = 0.01; * * var simplified = turf.simplify( * feature, tolerance, false); * * //=feature * * //=simplified */ module.exports = function(feature, tolerance, highQuality){ if(feature.geometry.type === 'LineString') { var line = { type: 'LineString', coordinates: [] }; var pts = feature.geometry.coordinates.map(function(coord) { return {x: coord[0], y: coord[1]}; }); line.coordinates = simplify(pts, tolerance, highQuality).map(function(coords){ return [coords.x, coords.y]; }); return simpleFeature(line, feature.properties); } else if(feature.geometry.type === 'Polygon') { var poly = { type: 'Polygon', coordinates: [] }; feature.geometry.coordinates.forEach(function(ring){ var pts = ring.map(function(coord) { return {x: coord[0], y: coord[1]}; }); var simpleRing = simplify(pts, tolerance, highQuality).map(function(coords){ return [coords.x, coords.y]; }); poly.coordinates.push(simpleRing); }); return simpleFeature(poly, feature.properties) } } function simpleFeature (geom, properties) { return { type: 'Feature', geometry: geom, properties: properties }; } },{"simplify-js":112}],112:[function(require,module,exports){ /* (c) 2013, Vladimir Agafonkin Simplify.js, a high-performance JS polyline simplification library mourner.github.io/simplify-js */ (function () { 'use strict'; // to suit your point format, run search/replace for '.x' and '.y'; // for 3D version, see 3d branch (configurability would draw significant performance overhead) // square distance between 2 points function getSqDist(p1, p2) { var dx = p1.x - p2.x, dy = p1.y - p2.y; return dx * dx + dy * dy; } // square distance from a point to a segment function getSqSegDist(p, p1, p2) { var x = p1.x, y = p1.y, dx = p2.x - x, dy = p2.y - y; if (dx !== 0 || dy !== 0) { var t = ((p.x - x) * dx + (p.y - y) * dy) / (dx * dx + dy * dy); if (t > 1) { x = p2.x; y = p2.y; } else if (t > 0) { x += dx * t; y += dy * t; } } dx = p.x - x; dy = p.y - y; return dx * dx + dy * dy; } // rest of the code doesn't care about point format // basic distance-based simplification function simplifyRadialDist(points, sqTolerance) { var prevPoint = points[0], newPoints = [prevPoint], point; for (var i = 1, len = points.length; i < len; i++) { point = points[i]; if (getSqDist(point, prevPoint) > sqTolerance) { newPoints.push(point); prevPoint = point; } } if (prevPoint !== point) newPoints.push(point); return newPoints; } // simplification using optimized Douglas-Peucker algorithm with recursion elimination function simplifyDouglasPeucker(points, sqTolerance) { var len = points.length, MarkerArray = typeof Uint8Array !== 'undefined' ? Uint8Array : Array, markers = new MarkerArray(len), first = 0, last = len - 1, stack = [], newPoints = [], i, maxSqDist, sqDist, index; markers[first] = markers[last] = 1; while (last) { maxSqDist = 0; for (i = first + 1; i < last; i++) { sqDist = getSqSegDist(points[i], points[first], points[last]); if (sqDist > maxSqDist) { index = i; maxSqDist = sqDist; } } if (maxSqDist > sqTolerance) { markers[index] = 1; stack.push(first, index, index, last); } last = stack.pop(); first = stack.pop(); } for (i = 0; i < len; i++) { if (markers[i]) newPoints.push(points[i]); } return newPoints; } // both algorithms combined for awesome performance function simplify(points, tolerance, highestQuality) { var sqTolerance = tolerance !== undefined ? tolerance * tolerance : 1; points = highestQuality ? points : simplifyRadialDist(points, sqTolerance); points = simplifyDouglasPeucker(points, sqTolerance); return points; } // export as AMD module / Node module / browser or worker variable if (typeof define === 'function' && define.amd) define(function() { return simplify; }); else if (typeof module !== 'undefined') module.exports = simplify; else if (typeof self !== 'undefined') self.simplify = simplify; else window.simplify = simplify; })(); },{}],113:[function(require,module,exports){ /** * Takes a bounding box and returns a new bounding box with a size expanded or contracted * by a factor of X. * * @module turf/size * @category measurement * @param {Array} bbox a bounding box * @param {number} factor the ratio of the new bbox to the input bbox * @return {Array} the resized bbox * @example * var bbox = [0, 0, 10, 10] * * var resized = turf.size(bbox, 2); * * var features = { * "type": "FeatureCollection", * "features": [ * turf.bboxPolygon(bbox), * turf.bboxPolygon(resized) * ] * }; * * //=features */ module.exports = function(bbox, factor){ var currentXDistance = (bbox[2] - bbox[0]); var currentYDistance = (bbox[3] - bbox[1]); var newXDistance = currentXDistance * factor; var newYDistance = currentYDistance * factor; var xChange = newXDistance - currentXDistance; var yChange = newYDistance - currentYDistance; var lowX = bbox[0] - (xChange / 2); var lowY = bbox[1] - (yChange / 2); var highX = (xChange / 2) + bbox[2]; var highY = (yChange / 2) + bbox[3]; var sized = [lowX, lowY, highX, highY]; return sized; } },{}],114:[function(require,module,exports){ var featurecollection = require('turf-featurecollection'); var point = require('turf-point'); var polygon = require('turf-polygon'); var distance = require('turf-distance'); /** * Takes a bounding box and a cell depth and returns a {@link FeatureCollection} of {@link Point} features in a grid. * * @module turf/square-grid * @category interpolation * @param {Array} extent extent in [minX, minY, maxX, maxY] order * @param {Number} cellWidth width of each cell * @param {String} units units to use for cellWidth * @return {FeatureCollection} grid as FeatureCollection with {@link Polygon} features * @example * var extent = [-77.3876953125,38.71980474264239,-76.9482421875,39.027718840211605]; * var cellWidth = 10; * var units = 'miles'; * * var squareGrid = turf.squareGrid(extent, cellWidth, units); * * //=squareGrid */ module.exports = function (bbox, cell, units) { var fc = featurecollection([]); var xFraction = cell / (distance(point([bbox[0], bbox[1]]), point([bbox[2], bbox[1]]), units)); var cellWidth = xFraction * (bbox[2] - bbox[0]); var yFraction = cell / (distance(point([bbox[0], bbox[1]]), point([bbox[0], bbox[3]]), units)); var cellHeight = yFraction * (bbox[3] - bbox[1]); var currentX = bbox[0]; while (currentX <= bbox[2]) { var currentY = bbox[1]; while (currentY <= bbox[3]) { var cellPoly = polygon([[ [currentX, currentY], [currentX, currentY+cellHeight], [currentX+cellWidth, currentY+cellHeight], [currentX+cellWidth, currentY], [currentX, currentY] ]]); fc.features.push(cellPoly); currentY += cellHeight; } currentX += cellWidth; } return fc; } },{"turf-distance":60,"turf-featurecollection":72,"turf-point":102,"turf-polygon":103}],115:[function(require,module,exports){ var midpoint = require('turf-midpoint'); var point = require('turf-point'); var distance = require('turf-distance'); /** * Takes a bounding box and calculates the minimum square bounding box that would contain the input. * * @module turf/square * @category measurement * @param {Array} bbox a bounding box * @return {Array} a square surrounding `bbox` * @example * var bbox = [-20,-20,-15,0]; * * var squared = turf.square(bbox); * * var features = { * "type": "FeatureCollection", * "features": [ * turf.bboxPolygon(bbox), * turf.bboxPolygon(squared) * ] * }; * * //=features */ module.exports = function(bbox){ var squareBbox = [0,0,0,0]; var lowLeft = point([bbox[0], bbox[1]]); var topLeft = point([bbox[0], bbox[3]]); var topRight = point([bbox[2], bbox[3]]); var lowRight = point([bbox[2], bbox[1]]); var horizontalDistance = distance(lowLeft, lowRight, 'miles'); var verticalDistance = distance(lowLeft, topLeft, 'miles'); if(horizontalDistance >= verticalDistance){ squareBbox[0] = bbox[0]; squareBbox[2] = bbox[2]; var verticalMidpoint = midpoint(lowLeft, topLeft); squareBbox[1] = verticalMidpoint.geometry.coordinates[1] - ((bbox[2] - bbox[0]) / 2); squareBbox[3] = verticalMidpoint.geometry.coordinates[1] + ((bbox[2] - bbox[0]) / 2); return squareBbox; } else { squareBbox[1] = bbox[1]; squareBbox[3] = bbox[3]; var horzontalMidpoint = midpoint(lowLeft, lowRight); squareBbox[0] = horzontalMidpoint.geometry.coordinates[0] - ((bbox[3] - bbox[1]) / 2); squareBbox[2] = horzontalMidpoint.geometry.coordinates[0] + ((bbox[3] - bbox[1]) / 2); return squareBbox; } } },{"turf-distance":60,"turf-midpoint":95,"turf-point":102}],116:[function(require,module,exports){ var inside = require('turf-inside'); /** * Calculates the sum of a field for {@link Point} features within a set of {@link Polygon} features. * * @module turf/sum * @category aggregation * @param {FeatureCollection} polygons a FeatureCollection of {@link Polygon} features * @param {FeatureCollection} points a FeatureCollection of {@link Point} features * @param {String} inField the field in input data to analyze * @param {String} outField the field in which to store results * @return {FeatureCollection} a FeatureCollection of {@link Polygon} features * with properties listed as `outField` * @example * var polygons = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-87.990188, 43.026486], * [-87.990188, 43.062115], * [-87.913284, 43.062115], * [-87.913284, 43.026486], * [-87.990188, 43.026486] * ]] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-87.973709, 42.962452], * [-87.973709, 43.014689], * [-87.904014, 43.014689], * [-87.904014, 42.962452], * [-87.973709, 42.962452] * ]] * } * } * ] * }; * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [-87.974052, 43.049321] * } * }, { * "type": "Feature", * "properties": { * "population": 600 * }, * "geometry": { * "type": "Point", * "coordinates": [-87.957229, 43.037277] * } * }, { * "type": "Feature", * "properties": { * "population": 100 * }, * "geometry": { * "type": "Point", * "coordinates": [-87.931137, 43.048568] * } * }, { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [-87.963409, 42.99611] * } * }, { * "type": "Feature", * "properties": { * "population": 300 * }, * "geometry": { * "type": "Point", * "coordinates": [-87.94178, 42.974762] * } * } * ] * }; * * var aggregated = turf.sum( * polygons, points, 'population', 'sum'); * * var resultFeatures = points.features.concat( * aggregated.features); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ module.exports = function(polyFC, ptFC, inField, outField){ polyFC.features.forEach(function(poly){ if(!poly.properties){ poly.properties = {}; } var values = []; ptFC.features.forEach(function(pt){ if (inside(pt, poly)) { values.push(pt.properties[inField]); } }); poly.properties[outField] = sum(values); }); return polyFC; }; function sum(x) { var value = 0; for (var i = 0; i < x.length; i++) { value += x[i]; } return value; } },{"turf-inside":76}],117:[function(require,module,exports){ var inside = require('turf-inside'); /** * Takes a {@link FeatureCollection} of {@link Point} features and a FeatureCollection of {@link Polygon} features and performs a spatial join. * * @module turf/tag * @category joins * @param {FeatureCollection} points a FeatureCollection of {@link Point} features * @param {FeatureCollection} polygons a FeatureCollection of {@link Polygon} features * @param {String} polyId property in `polygons` to add to joined Point features * @param {String} containingPolyId property in `points` in which to store joined property from `polygons * @return {FeatureCollection} a FeatureCollection of point features * @example * var bbox = [0, 0, 50, 50]; * // create a triangular grid of polygons * var triangleGrid = turf.tin(turf.grid(bbox, 10)); * triangleGrid.features.forEach(function(f) { * f.properties.fill = '#' + * (~~(Math.random() * 16)).toString(16) + * (~~(Math.random() * 16)).toString(16) + * (~~(Math.random() * 16)).toString(16); * f.properties.stroke = 0; * f.properties['fill-opacity'] = 1; * }); * var randomPoints = turf.random('point', 30, { * bbox: bbox * }); * var both = turf.featurecollection( * triangleGrid.features.concat(randomPoints.features)); * * //=both * * var tagged = turf.tag(randomPoints, triangleGrid, * 'fill', 'marker-color'); * * //=tagged */ module.exports = function(points, polygons, field, outField){ // prevent mutations points = JSON.parse(JSON.stringify(points)); polygons = JSON.parse(JSON.stringify(polygons)); points.features.forEach(function(pt) { if (!pt.properties) { pt.properties = {}; } polygons.features.forEach(function(poly) { if (pt.properties[outField] === undefined) { var isInside = inside(pt, poly); if (isInside) { pt.properties[outField] = poly.properties[field]; } } }); }); return points; }; },{"turf-inside":76}],118:[function(require,module,exports){ //http://en.wikipedia.org/wiki/Delaunay_triangulation //https://github.com/ironwallaby/delaunay var polygon = require('turf-polygon'); var featurecollection = require('turf-featurecollection'); /** * Takes a set of points and the name of a z-value property and * creates a [Triangulated Irregular Network](http://en.wikipedia.org/wiki/Triangulated_irregular_network), * or a TIN for short, returned as a collection of Polygons. These are often used * for developing elevation contour maps or stepped heat visualizations. * * This triangulates the points, as well as adds properties called `a`, `b`, * and `c` representing the value of the given `propertyName` at each of * the points that represent the corners of the triangle. * * @module turf/tin * @category interpolation * @param {FeatureCollection} points - a GeoJSON FeatureCollection containing * Features with {@link Point} geometries * @param {string=} propertyName - name of the property from which to pull z values. * This is optional: if not given, then there will be no extra data added to the derived triangles. * @return {FeatureCollection} TIN output * @example * // generate some random point data * var points = turf.random('points', 30, { * bbox: [50, 30, 70, 50] * }); * //=points * // add a random property to each point between 0 and 9 * for (var i = 0; i < points.features.length; i++) { * points.features[i].properties.z = ~~(Math.random() * 9); * } * var tin = turf.tin(points, 'z') * for (var i = 0; i < tin.features.length; i++) { * var properties = tin.features[i].properties; * // roughly turn the properties of each * // triangle into a fill color * // so we can visualize the result * properties.fill = '#' + properties.a + * properties.b + properties.c; * } * //=tin */ module.exports = function(points, z) { //break down points return featurecollection(triangulate(points.features.map(function(p) { var point = { x: p.geometry.coordinates[0], y: p.geometry.coordinates[1] }; if (z) point.z = p.properties[z]; return point; })).map(function(triangle) { return polygon([[ [triangle.a.x, triangle.a.y], [triangle.b.x, triangle.b.y], [triangle.c.x, triangle.c.y], [triangle.a.x, triangle.a.y] ]], { a: triangle.a.z, b: triangle.b.z, c: triangle.c.z }); })); }; function Triangle(a, b, c) { this.a = a; this.b = b; this.c = c; var A = b.x - a.x, B = b.y - a.y, C = c.x - a.x, D = c.y - a.y, E = A * (a.x + b.x) + B * (a.y + b.y), F = C * (a.x + c.x) + D * (a.y + c.y), G = 2 * (A * (c.y - b.y) - B * (c.x - b.x)), minx, miny, dx, dy; // If the points of the triangle are collinear, then just find the // extremes and use the midpoint as the center of the circumcircle. if (Math.abs(G) < 0.000001) { minx = Math.min(a.x, b.x, c.x); miny = Math.min(a.y, b.y, c.y); dx = (Math.max(a.x, b.x, c.x) - minx) * 0.5; dy = (Math.max(a.y, b.y, c.y) - miny) * 0.5; this.x = minx + dx; this.y = miny + dy; this.r = dx * dx + dy * dy; } else { this.x = (D * E - B * F) / G; this.y = (A * F - C * E) / G; dx = this.x - a.x; dy = this.y - a.y; this.r = dx * dx + dy * dy; } } function byX(a, b) { return b.x - a.x; } function dedup(edges) { var j = edges.length, a, b, i, m, n; outer: while (j) { b = edges[--j]; a = edges[--j]; i = j; while (i) { n = edges[--i]; m = edges[--i]; if ((a === m && b === n) || (a === n && b === m)) { edges.splice(j, 2); edges.splice(i, 2); j -= 2; continue outer; } } } } function triangulate(vertices) { // Bail if there aren't enough vertices to form any triangles. if (vertices.length < 3) return []; // Ensure the vertex array is in order of descending X coordinate // (which is needed to ensure a subquadratic runtime), and then find // the bounding box around the points. vertices.sort(byX); var i = vertices.length - 1, xmin = vertices[i].x, xmax = vertices[0].x, ymin = vertices[i].y, ymax = ymin; while (i--) { if (vertices[i].y < ymin) ymin = vertices[i].y; if (vertices[i].y > ymax) ymax = vertices[i].y; } //Find a supertriangle, which is a triangle that surrounds all the //vertices. This is used like something of a sentinel value to remove //cases in the main algorithm, and is removed before we return any // results. // Once found, put it in the "open" list. (The "open" list is for // triangles who may still need to be considered; the "closed" list is // for triangles which do not.) var dx = xmax - xmin, dy = ymax - ymin, dmax = (dx > dy) ? dx : dy, xmid = (xmax + xmin) * 0.5, ymid = (ymax + ymin) * 0.5, open = [ new Triangle({ x: xmid - 20 * dmax, y: ymid - dmax, __sentinel: true }, { x: xmid, y: ymid + 20 * dmax, __sentinel: true }, { x: xmid + 20 * dmax, y: ymid - dmax, __sentinel: true } )], closed = [], edges = [], j, a, b; // Incrementally add each vertex to the mesh. i = vertices.length; while (i--) { // For each open triangle, check to see if the current point is // inside it's circumcircle. If it is, remove the triangle and add // it's edges to an edge list. edges.length = 0; j = open.length; while (j--) { // If this point is to the right of this triangle's circumcircle, // then this triangle should never get checked again. Remove it // from the open list, add it to the closed list, and skip. dx = vertices[i].x - open[j].x; if (dx > 0 && dx * dx > open[j].r) { closed.push(open[j]); open.splice(j, 1); continue; } // If not, skip this triangle. dy = vertices[i].y - open[j].y; if (dx * dx + dy * dy > open[j].r) continue; // Remove the triangle and add it's edges to the edge list. edges.push( open[j].a, open[j].b, open[j].b, open[j].c, open[j].c, open[j].a ); open.splice(j, 1); } // Remove any doubled edges. dedup(edges); // Add a new triangle for each edge. j = edges.length; while (j) { b = edges[--j]; a = edges[--j]; open.push(new Triangle(a, b, vertices[i])); } } // Copy any remaining open triangles to the closed list, and then // remove any triangles that share a vertex with the supertriangle. Array.prototype.push.apply(closed, open); i = closed.length; while (i--) if (closed[i].a.__sentinel || closed[i].b.__sentinel || closed[i].c.__sentinel) closed.splice(i, 1); return closed; } },{"turf-featurecollection":72,"turf-polygon":103}],119:[function(require,module,exports){ var featurecollection = require('turf-featurecollection'); var point = require('turf-point'); var polygon = require('turf-polygon'); var distance = require('turf-distance'); /** * Takes a bounding box and a cell depth and returns a {@link FeatureCollection} of {@link Point} features in a grid. * * @module turf/triangle-grid * @category interpolation * @param {Array} extent extent in [minX, minY, maxX, maxY] order * @param {Number} cellWidth width of each cell * @param {String} units units to use for cellWidth * @return {FeatureCollection} grid as FeatureCollection with {@link Polygon} features * @example * var extent = [-77.3876953125,38.71980474264239,-76.9482421875,39.027718840211605]; * var cellWidth = 10; * var units = 'miles'; * * var triangleGrid = turf.triangleGrid(extent, cellWidth, units); * * //=triangleGrid */ module.exports = function (bbox, cell, units) { var fc = featurecollection([]); var xFraction = cell / (distance(point([bbox[0], bbox[1]]), point([bbox[2], bbox[1]]), units)); var cellWidth = xFraction * (bbox[2] - bbox[0]); var yFraction = cell / (distance(point([bbox[0], bbox[1]]), point([bbox[0], bbox[3]]), units)); var cellHeight = yFraction * (bbox[3] - bbox[1]); var xi = 0; var currentX = bbox[0]; while (currentX <= bbox[2]) { var yi = 0; var currentY = bbox[1]; while (currentY <= bbox[3]) { if(xi%2===0 && yi%2===0) { var cell1 = polygon([[ [currentX, currentY], [currentX, currentY+cellHeight], [currentX+cellWidth, currentY], [currentX, currentY] ]]); fc.features.push(cell1); var cell2 = polygon([[ [currentX, currentY+cellHeight], [currentX+cellWidth, currentY+cellHeight], [currentX+cellWidth, currentY], [currentX, currentY+cellHeight] ]]); fc.features.push(cell2); } else if(xi%2===0 && yi%2===1) { var cell1 = polygon([[ [currentX, currentY], [currentX+cellWidth, currentY+cellHeight], [currentX+cellWidth, currentY], [currentX, currentY] ]]); fc.features.push(cell1); var cell2 = polygon([[ [currentX, currentY], [currentX, currentY+cellHeight], [currentX+cellWidth, currentY+cellHeight], [currentX, currentY] ]]); fc.features.push(cell2); } else if(yi%2===0 && xi%2===1) { var cell1 = polygon([[ [currentX, currentY], [currentX, currentY+cellHeight], [currentX+cellWidth, currentY+cellHeight], [currentX, currentY] ]]); fc.features.push(cell1); var cell2 = polygon([[ [currentX, currentY], [currentX+cellWidth, currentY+cellHeight], [currentX+cellWidth, currentY], [currentX, currentY] ]]); fc.features.push(cell2); } else if(yi%2===1 && xi%2===1) { var cell1 = polygon([[ [currentX, currentY], [currentX, currentY+cellHeight], [currentX+cellWidth, currentY], [currentX, currentY] ]]); fc.features.push(cell1); var cell2 = polygon([[ [currentX, currentY+cellHeight], [currentX+cellWidth, currentY+cellHeight], [currentX+cellWidth, currentY], [currentX, currentY+cellHeight] ]]); fc.features.push(cell2); } currentY += cellHeight; yi++; } xi++; currentX += cellWidth; } return fc; }; },{"turf-distance":60,"turf-featurecollection":72,"turf-point":102,"turf-polygon":103}],120:[function(require,module,exports){ // look here for help http://svn.osgeo.org/grass/grass/branches/releasebranch_6_4/vector/v.overlay/main.c //must be array of polygons // depend on jsts for now https://github.com/bjornharrtell/jsts/blob/master/examples/overlay.html var jsts = require('jsts'); /** * Takes two {@link Polygon} features and returnes a combined {@link Polygon} feature. If the input Polygon features are not contiguous, this function returns a {@link MultiPolygon} feature. * * @module turf/union * @category transformation * @param {Polygon} poly1 an input Polygon * @param {Polygon} poly2 another input Polygon * @return {Feature} a combined {@link Polygon} or {@link MultiPolygon} feature * @example * var poly1 = { * "type": "Feature", * "properties": { * "fill": "#0f0" * }, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-82.574787, 35.594087], * [-82.574787, 35.615581], * [-82.545261, 35.615581], * [-82.545261, 35.594087], * [-82.574787, 35.594087] * ]] * } * }; * var poly2 = { * "type": "Feature", * "properties": { * "fill": "#00f" * }, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-82.560024, 35.585153], * [-82.560024, 35.602602], * [-82.52964, 35.602602], * [-82.52964, 35.585153], * [-82.560024, 35.585153] * ]] * } * }; * var polygons = { * "type": "FeatureCollection", * "features": [poly1, poly2] * }; * * var union = turf.union(poly1, poly2); * * //=polygons * * //=union */ module.exports = function(poly1, poly2){ var reader = new jsts.io.GeoJSONReader(); var a = reader.read(JSON.stringify(poly1.geometry)); var b = reader.read(JSON.stringify(poly2.geometry)); var union = a.union(b); var parser = new jsts.io.GeoJSONParser(); union = parser.write(union); return { type: 'Feature', geometry: union, properties: poly1.properties }; } },{"jsts":121}],121:[function(require,module,exports){ arguments[4][17][0].apply(exports,arguments) },{"./lib/jsts":122,"dup":17,"javascript.util":124}],122:[function(require,module,exports){ arguments[4][18][0].apply(exports,arguments) },{"dup":18}],123:[function(require,module,exports){ arguments[4][19][0].apply(exports,arguments) },{"dup":19}],124:[function(require,module,exports){ arguments[4][20][0].apply(exports,arguments) },{"./dist/javascript.util-node.min.js":123,"dup":20}],125:[function(require,module,exports){ var ss = require('simple-statistics'); var inside = require('turf-inside'); /** * Calculates the variance value of a field for {@link Point} features within a set of {@link Polygon} features. * * @module turf/variance * @category aggregation * @param {FeatureCollection} polygons a FeatureCollection of {@link Polygon} features * @param {FeatureCollection} points a FeatureCollection of {@link Point} features * @param {string} inField the field in input data to analyze * @param {string} outField the field in which to store results * @return {FeatureCollection} a FeatureCollection of {@link Polygon} features * with properties listed as `outField` * @example * var polygons = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-97.414398, 37.684092], * [-97.414398, 37.731353], * [-97.332344, 37.731353], * [-97.332344, 37.684092], * [-97.414398, 37.684092] * ]] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-97.333717, 37.606072], * [-97.333717, 37.675397], * [-97.237586, 37.675397], * [-97.237586, 37.606072], * [-97.333717, 37.606072] * ]] * } * } * ] * }; * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [-97.401351, 37.719676] * } * }, { * "type": "Feature", * "properties": { * "population": 600 * }, * "geometry": { * "type": "Point", * "coordinates": [-97.355346, 37.706639] * } * }, { * "type": "Feature", * "properties": { * "population": 100 * }, * "geometry": { * "type": "Point", * "coordinates": [-97.387962, 37.70012] * } * }, { * "type": "Feature", * "properties": { * "population": 200 * }, * "geometry": { * "type": "Point", * "coordinates": [-97.301788, 37.66507] * } * }, { * "type": "Feature", * "properties": { * "population": 300 * }, * "geometry": { * "type": "Point", * "coordinates": [-97.265052, 37.643325] * } * } * ] * }; * * var aggregated = turf.variance( * polygons, points, 'population', 'variance'); * * var resultFeatures = points.features.concat( * aggregated.features); * var result = { * "type": "FeatureCollection", * "features": resultFeatures * }; * * //=result */ module.exports = function (polyFC, ptFC, inField, outField) { polyFC.features.forEach(function(poly){ if(!poly.properties){ poly.properties = {}; } var values = []; ptFC.features.forEach(function(pt){ if (inside(pt, poly)) { values.push(pt.properties[inField]); } }); poly.properties[outField] = ss.variance(values); }); return polyFC; }; },{"simple-statistics":126,"turf-inside":76}],126:[function(require,module,exports){ arguments[4][59][0].apply(exports,arguments) },{"dup":59}],127:[function(require,module,exports){ var inside = require('turf-inside'); var featureCollection = require('turf-featurecollection'); /** * Takes a {@link FeatureCollection} of {@link Point} features and a FeatureCollection of {@link Polygon} features and returns a FeatureCollection of Point features representing all points that fall within a collection of polygons. * * @module turf/within * @category joins * @param {FeatureCollection} points a FeatureCollection of {@link Point} features * @param {FeatureCollection} polygons a FeatureCollection of {@link Polygon} features * @return {FeatureCollection} a collection of all points that land * within at least one polygon * @example * var searchWithin = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Polygon", * "coordinates": [[ * [-46.653,-23.543], * [-46.634,-23.5346], * [-46.613,-23.543], * [-46.614,-23.559], * [-46.631,-23.567], * [-46.653,-23.560], * [-46.653,-23.543] * ]] * } * } * ] * }; * var points = { * "type": "FeatureCollection", * "features": [ * { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-46.6318, -23.5523] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-46.6246, -23.5325] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-46.6062, -23.5513] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-46.663, -23.554] * } * }, { * "type": "Feature", * "properties": {}, * "geometry": { * "type": "Point", * "coordinates": [-46.643, -23.557] * } * } * ] * }; * * var ptsWithin = turf.within(points, searchWithin); * * //=points * * //=searchWithin * * //=ptsWithin */ module.exports = function(ptFC, polyFC){ var pointsWithin = featureCollection([]); for (var i = 0; i < polyFC.features.length; i++) { for (var j = 0; j < ptFC.features.length; j++) { var isInside = inside(ptFC.features[j], polyFC.features[i]); if(isInside){ pointsWithin.features.push(ptFC.features[j]); } } } return pointsWithin; }; },{"turf-featurecollection":72,"turf-inside":76}]},{},[1])(1) });