ekylibre-cartography 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +3 -0
- data/Rakefile +10 -0
- data/app/assets/javascripts/cartography.coffee +535 -0
- data/app/assets/javascripts/cartography/base.coffee +11 -0
- data/app/assets/javascripts/cartography/controls.coffee +463 -0
- data/app/assets/javascripts/cartography/events.coffee +36 -0
- data/app/assets/javascripts/cartography/layers.coffee +127 -0
- data/app/assets/javascripts/cartography/layers/simple.coffee +37 -0
- data/app/assets/javascripts/cartography/leaflet/controls.coffee +420 -0
- data/app/assets/javascripts/cartography/leaflet/handlers.coffee +461 -0
- data/app/assets/javascripts/cartography/leaflet/i18n.coffee +31 -0
- data/app/assets/javascripts/cartography/leaflet/layers.coffee +60 -0
- data/app/assets/javascripts/cartography/leaflet/toolbars.coffee +450 -0
- data/app/assets/javascripts/cartography/patches.js +8 -0
- data/app/assets/javascripts/cartography/util.coffee +18 -0
- data/app/assets/javascripts/main.js +18 -0
- data/app/assets/stylesheets/cartography.css +86 -0
- data/app/helpers/cartography_helper.rb +55 -0
- data/lib/cartography.rb +1 -0
- data/lib/cartography/engine.rb +11 -0
- data/lib/cartography/version.rb +3 -0
- data/vendor/assets/components/d3-array/dist/d3-array.js +590 -0
- data/vendor/assets/components/d3-array/dist/d3-array.min.js +2 -0
- data/vendor/assets/components/geojson-equality/dist/geojson-equality.js +295 -0
- data/vendor/assets/components/geojson-equality/dist/geojson-equality.js.map +21 -0
- data/vendor/assets/components/geojson-equality/dist/geojson-equality.min.js +1 -0
- data/vendor/assets/components/leaflet-controlpanel/dist/leaflet.controlpanel.css +29 -0
- data/vendor/assets/components/leaflet-controlpanel/dist/leaflet.controlpanel.js +269 -0
- data/vendor/assets/components/leaflet-draw-cut/dist/leaflet.draw.cut.css +1 -0
- data/vendor/assets/components/leaflet-draw-cut/dist/leaflet.draw.cut.js +8 -0
- data/vendor/assets/components/leaflet-draw-merge/dist/leaflet.draw.merge.css +0 -0
- data/vendor/assets/components/leaflet-draw-merge/dist/leaflet.draw.merge.js +48026 -0
- data/vendor/assets/components/leaflet-draw/dist/leaflet.draw-src.css +326 -0
- data/vendor/assets/components/leaflet-draw/dist/leaflet.draw-src.js +4653 -0
- data/vendor/assets/components/leaflet-draw/dist/leaflet.draw-src.map +1 -0
- data/vendor/assets/components/leaflet-draw/dist/leaflet.draw.css +10 -0
- data/vendor/assets/components/leaflet-draw/dist/leaflet.draw.js +10 -0
- data/vendor/assets/components/leaflet-geographicutil/dist/leaflet.geographicutil.js +3220 -0
- data/vendor/assets/components/leaflet-reactive_measure/dist/reactive_measure.css +30 -0
- data/vendor/assets/components/leaflet-reactive_measure/dist/reactive_measure.js +3764 -0
- data/vendor/assets/components/leaflet/dist/leaflet-src.js +13609 -0
- data/vendor/assets/components/leaflet/dist/leaflet-src.js.map +1 -0
- data/vendor/assets/components/leaflet/dist/leaflet-src.map +1 -0
- data/vendor/assets/components/leaflet/dist/leaflet.css +632 -0
- data/vendor/assets/components/leaflet/dist/leaflet.js +5 -0
- data/vendor/assets/components/leaflet/dist/leaflet.js.map +1 -0
- data/vendor/assets/components/martinez-polygon-clipping/dist/martinez.min.js +9 -0
- data/vendor/assets/components/martinez-polygon-clipping/dist/martinez.umd.js +1716 -0
- data/vendor/assets/components/martinez-polygon-clipping/dist/martinez.umd.js.map +1 -0
- data/vendor/assets/components/polygon-clipping/dist/polygon-clipping.js +279 -0
- data/vendor/assets/components/polygon-clipping/dist/polygon-clipping.min.js +1 -0
- data/vendor/assets/components/rtree/dist/rtree.js +911 -0
- data/vendor/assets/components/rtree/dist/rtree.min.js +1 -0
- data/vendor/assets/components/splaytree/dist/splay.es6.js +765 -0
- data/vendor/assets/components/splaytree/dist/splay.es6.js.map +1 -0
- data/vendor/assets/components/splaytree/dist/splay.js +797 -0
- data/vendor/assets/components/splaytree/dist/splay.js.map +1 -0
- metadata +156 -0
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"martinez.umd.js","sources":["../node_modules/splaytree/index.js","../src/edge_type.js","../src/operation.js","../src/compute_fields.js","../src/sweep_event.js","../src/equals.js","../src/signed_area.js","../src/compare_events.js","../src/divide_segment.js","../src/segment_intersection.js","../src/possible_intersection.js","../src/compare_segments.js","../src/subdivide_segments.js","../src/connect_edges.js","../node_modules/tinyqueue/index.js","../src/fill_queue.js","../src/index.js","../index.js"],"sourcesContent":["function DEFAULT_COMPARE (a, b) { return a > b ? 1 : a < b ? -1 : 0; }\n\nexport default class SplayTree {\n\n constructor(compare = DEFAULT_COMPARE, noDuplicates = false) {\n this._compare = compare;\n this._root = null;\n this._size = 0;\n this._noDuplicates = !!noDuplicates;\n }\n\n\n rotateLeft(x) {\n var y = x.right;\n if (y) {\n x.right = y.left;\n if (y.left) y.left.parent = x;\n y.parent = x.parent;\n }\n\n if (!x.parent) this._root = y;\n else if (x === x.parent.left) x.parent.left = y;\n else x.parent.right = y;\n if (y) y.left = x;\n x.parent = y;\n }\n\n\n rotateRight(x) {\n var y = x.left;\n if (y) {\n x.left = y.right;\n if (y.right) y.right.parent = x;\n y.parent = x.parent;\n }\n\n if (!x.parent) this._root = y;\n else if(x === x.parent.left) x.parent.left = y;\n else x.parent.right = y;\n if (y) y.right = x;\n x.parent = y;\n }\n\n\n _splay(x) {\n while (x.parent) {\n var p = x.parent;\n if (!p.parent) {\n if (p.left === x) this.rotateRight(p);\n else this.rotateLeft(p);\n } else if (p.left === x && p.parent.left === p) {\n this.rotateRight(p.parent);\n this.rotateRight(p);\n } else if (p.right === x && p.parent.right === p) {\n this.rotateLeft(p.parent);\n this.rotateLeft(p);\n } else if (p.left === x && p.parent.right === p) {\n this.rotateRight(p);\n this.rotateLeft(p);\n } else {\n this.rotateLeft(p);\n this.rotateRight(p);\n }\n }\n }\n\n\n splay(x) {\n var p, gp, ggp, l, r;\n\n while (x.parent) {\n p = x.parent;\n gp = p.parent;\n\n if (gp && gp.parent) {\n ggp = gp.parent;\n if (ggp.left === gp) ggp.left = x;\n else ggp.right = x;\n x.parent = ggp;\n } else {\n x.parent = null;\n this._root = x;\n }\n\n l = x.left; r = x.right;\n\n if (x === p.left) { // left\n if (gp) {\n if (gp.left === p) {\n /* zig-zig */\n if (p.right) {\n gp.left = p.right;\n gp.left.parent = gp;\n } else gp.left = null;\n\n p.right = gp;\n gp.parent = p;\n } else {\n /* zig-zag */\n if (l) {\n gp.right = l;\n l.parent = gp;\n } else gp.right = null;\n\n x.left = gp;\n gp.parent = x;\n }\n }\n if (r) {\n p.left = r;\n r.parent = p;\n } else p.left = null;\n\n x.right = p;\n p.parent = x;\n } else { // right\n if (gp) {\n if (gp.right === p) {\n /* zig-zig */\n if (p.left) {\n gp.right = p.left;\n gp.right.parent = gp;\n } else gp.right = null;\n\n p.left = gp;\n gp.parent = p;\n } else {\n /* zig-zag */\n if (r) {\n gp.left = r;\n r.parent = gp;\n } else gp.left = null;\n\n x.right = gp;\n gp.parent = x;\n }\n }\n if (l) {\n p.right = l;\n l.parent = p;\n } else p.right = null;\n\n x.left = p;\n p.parent = x;\n }\n }\n }\n\n\n replace(u, v) {\n if (!u.parent) this._root = v;\n else if (u === u.parent.left) u.parent.left = v;\n else u.parent.right = v;\n if (v) v.parent = u.parent;\n }\n\n\n minNode(u = this._root) {\n if (u) while (u.left) u = u.left;\n return u;\n }\n\n\n maxNode(u = this._root) {\n if (u) while (u.right) u = u.right;\n return u;\n }\n\n\n insert(key, data) {\n var z = this._root;\n var p = null;\n var comp = this._compare;\n var cmp;\n\n if (this._noDuplicates) {\n while (z) {\n p = z;\n cmp = comp(z.key, key);\n if (cmp === 0) return;\n else if (comp(z.key, key) < 0) z = z.right;\n else z = z.left;\n }\n } else {\n while (z) {\n p = z;\n if (comp(z.key, key) < 0) z = z.right;\n else z = z.left;\n }\n }\n\n z = { key, data, left: null, right: null, parent: p };\n\n if (!p) this._root = z;\n else if (comp(p.key, z.key) < 0) p.right = z;\n else p.left = z;\n\n this.splay(z);\n this._size++;\n return z;\n }\n\n\n find (key) {\n var z = this._root;\n var comp = this._compare;\n while (z) {\n var cmp = comp(z.key, key);\n if (cmp < 0) z = z.right;\n else if (cmp > 0) z = z.left;\n else return z;\n }\n return null;\n }\n\n /**\n * Whether the tree contains a node with the given key\n * @param {Key} key\n * @return {boolean} true/false\n */\n contains (key) {\n var node = this._root;\n var comparator = this._compare;\n while (node) {\n var cmp = comparator(key, node.key);\n if (cmp === 0) return true;\n else if (cmp < 0) node = node.left;\n else node = node.right;\n }\n\n return false;\n }\n\n\n remove (key) {\n var z = this.find(key);\n\n if (!z) return false;\n\n this.splay(z);\n\n if (!z.left) this.replace(z, z.right);\n else if (!z.right) this.replace(z, z.left);\n else {\n var y = this.minNode(z.right);\n if (y.parent !== z) {\n this.replace(y, y.right);\n y.right = z.right;\n y.right.parent = y;\n }\n this.replace(z, y);\n y.left = z.left;\n y.left.parent = y;\n }\n\n this._size--;\n return true;\n }\n\n\n removeNode(z) {\n if (!z) return false;\n\n this.splay(z);\n\n if (!z.left) this.replace(z, z.right);\n else if (!z.right) this.replace(z, z.left);\n else {\n var y = this.minNode(z.right);\n if (y.parent !== z) {\n this.replace(y, y.right);\n y.right = z.right;\n y.right.parent = y;\n }\n this.replace(z, y);\n y.left = z.left;\n y.left.parent = y;\n }\n\n this._size--;\n return true;\n }\n\n\n erase (key) {\n var z = this.find(key);\n if (!z) return;\n\n this.splay(z);\n\n var s = z.left;\n var t = z.right;\n\n var sMax = null;\n if (s) {\n s.parent = null;\n sMax = this.maxNode(s);\n this.splay(sMax);\n this._root = sMax;\n }\n if (t) {\n if (s) sMax.right = t;\n else this._root = t;\n t.parent = sMax;\n }\n\n this._size--;\n }\n\n /**\n * Removes and returns the node with smallest key\n * @return {?Node}\n */\n pop () {\n var node = this._root, returnValue = null;\n if (node) {\n while (node.left) node = node.left;\n returnValue = { key: node.key, data: node.data };\n this.remove(node.key);\n }\n return returnValue;\n }\n\n\n /* eslint-disable class-methods-use-this */\n\n /**\n * Successor node\n * @param {Node} node\n * @return {?Node}\n */\n next (node) {\n var successor = node;\n if (successor) {\n if (successor.right) {\n successor = successor.right;\n while (successor && successor.left) successor = successor.left;\n } else {\n successor = node.parent;\n while (successor && successor.right === node) {\n node = successor; successor = successor.parent;\n }\n }\n }\n return successor;\n }\n\n\n /**\n * Predecessor node\n * @param {Node} node\n * @return {?Node}\n */\n prev (node) {\n var predecessor = node;\n if (predecessor) {\n if (predecessor.left) {\n predecessor = predecessor.left;\n while (predecessor && predecessor.right) predecessor = predecessor.right;\n } else {\n predecessor = node.parent;\n while (predecessor && predecessor.left === node) {\n node = predecessor;\n predecessor = predecessor.parent;\n }\n }\n }\n return predecessor;\n }\n /* eslint-enable class-methods-use-this */\n\n\n /**\n * @param {forEachCallback} callback\n * @return {SplayTree}\n */\n forEach(callback) {\n var current = this._root;\n var s = [], done = false, i = 0;\n\n while (!done) {\n // Reach the left most Node of the current Node\n if (current) {\n // Place pointer to a tree node on the stack\n // before traversing the node's left subtree\n s.push(current);\n current = current.left;\n } else {\n // BackTrack from the empty subtree and visit the Node\n // at the top of the stack; however, if the stack is\n // empty you are done\n if (s.length > 0) {\n current = s.pop();\n callback(current, i++);\n\n // We have visited the node and its left\n // subtree. Now, it's right subtree's turn\n current = current.right;\n } else done = true;\n }\n }\n return this;\n }\n\n\n /**\n * Walk key range from `low` to `high`. Stops if `fn` returns a value.\n * @param {Key} low\n * @param {Key} high\n * @param {Function} fn\n * @param {*?} ctx\n * @return {SplayTree}\n */\n range(low, high, fn, ctx) {\n const Q = [];\n const compare = this._compare;\n let node = this._root, cmp;\n\n while (Q.length !== 0 || node) {\n if (node) {\n Q.push(node);\n node = node.left;\n } else {\n node = Q.pop();\n cmp = compare(node.key, high);\n if (cmp > 0) {\n break;\n } else if (compare(node.key, low) >= 0) {\n if (fn.call(ctx, node)) return this; // stop if smth is returned\n }\n node = node.right;\n }\n }\n return this;\n }\n\n /**\n * Returns all keys in order\n * @return {Array<Key>}\n */\n keys () {\n var current = this._root;\n var s = [], r = [], done = false;\n\n while (!done) {\n if (current) {\n s.push(current);\n current = current.left;\n } else {\n if (s.length > 0) {\n current = s.pop();\n r.push(current.key);\n current = current.right;\n } else done = true;\n }\n }\n return r;\n }\n\n\n /**\n * Returns `data` fields of all nodes in order.\n * @return {Array<Value>}\n */\n values () {\n var current = this._root;\n var s = [], r = [], done = false;\n\n while (!done) {\n if (current) {\n s.push(current);\n current = current.left;\n } else {\n if (s.length > 0) {\n current = s.pop();\n r.push(current.data);\n current = current.right;\n } else done = true;\n }\n }\n return r;\n }\n\n\n /**\n * Returns node at given index\n * @param {number} index\n * @return {?Node}\n */\n at (index) {\n // removed after a consideration, more misleading than useful\n // index = index % this.size;\n // if (index < 0) index = this.size - index;\n\n var current = this._root;\n var s = [], done = false, i = 0;\n\n while (!done) {\n if (current) {\n s.push(current);\n current = current.left;\n } else {\n if (s.length > 0) {\n current = s.pop();\n if (i === index) return current;\n i++;\n current = current.right;\n } else done = true;\n }\n }\n return null;\n }\n\n /**\n * Bulk-load items. Both array have to be same size\n * @param {Array<Key>} keys\n * @param {Array<Value>} [values]\n * @param {Boolean} [presort=false] Pre-sort keys and values, using\n * tree's comparator. Sorting is done\n * in-place\n * @return {AVLTree}\n */\n load(keys = [], values = [], presort = false) {\n if (this._size !== 0) throw new Error('bulk-load: tree is not empty');\n const size = keys.length;\n if (presort) sort(keys, values, 0, size - 1, this._compare);\n this._root = loadRecursive(null, keys, values, 0, size);\n this._size = size;\n return this;\n }\n\n\n min() {\n var node = this.minNode(this._root);\n if (node) return node.key;\n else return null;\n }\n\n\n max() {\n var node = this.maxNode(this._root);\n if (node) return node.key;\n else return null;\n }\n\n isEmpty() { return this._root === null; }\n get size() { return this._size; }\n\n\n /**\n * Create a tree and load it with items\n * @param {Array<Key>} keys\n * @param {Array<Value>?} [values]\n\n * @param {Function?} [comparator]\n * @param {Boolean?} [presort=false] Pre-sort keys and values, using\n * tree's comparator. Sorting is done\n * in-place\n * @param {Boolean?} [noDuplicates=false] Allow duplicates\n * @return {SplayTree}\n */\n static createTree(keys, values, comparator, presort, noDuplicates) {\n return new SplayTree(comparator, noDuplicates).load(keys, values, presort);\n }\n}\n\n\nfunction loadRecursive (parent, keys, values, start, end) {\n const size = end - start;\n if (size > 0) {\n const middle = start + Math.floor(size / 2);\n const key = keys[middle];\n const data = values[middle];\n const node = { key, data, parent };\n node.left = loadRecursive(node, keys, values, start, middle);\n node.right = loadRecursive(node, keys, values, middle + 1, end);\n return node;\n }\n return null;\n}\n\n\nfunction sort(keys, values, left, right, compare) {\n if (left >= right) return;\n\n const pivot = keys[(left + right) >> 1];\n let i = left - 1;\n let j = right + 1;\n\n while (true) {\n do i++; while (compare(keys[i], pivot) < 0);\n do j--; while (compare(keys[j], pivot) > 0);\n if (i >= j) break;\n\n let tmp = keys[i];\n keys[i] = keys[j];\n keys[j] = tmp;\n\n tmp = values[i];\n values[i] = values[j];\n values[j] = tmp;\n }\n\n sort(keys, values, left, j, compare);\n sort(keys, values, j + 1, right, compare);\n}\n","export const NORMAL = 0;\nexport const NON_CONTRIBUTING = 1;\nexport const SAME_TRANSITION = 2;\nexport const DIFFERENT_TRANSITION = 3;\n","export const INTERSECTION = 0;\nexport const UNION = 1;\nexport const DIFFERENCE = 2;\nexport const XOR = 3;\n","import {\n NORMAL,\n SAME_TRANSITION,\n DIFFERENT_TRANSITION,\n NON_CONTRIBUTING\n} from './edge_type';\nimport {\n INTERSECTION,\n UNION,\n DIFFERENCE,\n XOR\n} from './operation';\n\n/**\n * @param {SweepEvent} event\n * @param {SweepEvent} prev\n * @param {Operation} operation\n */\nexport default function computeFields (event, prev, operation) {\n // compute inOut and otherInOut fields\n if (prev === null) {\n event.inOut = false;\n event.otherInOut = true;\n\n // previous line segment in sweepline belongs to the same polygon\n } else {\n if (event.isSubject === prev.isSubject) {\n event.inOut = !prev.inOut;\n event.otherInOut = prev.otherInOut;\n\n // previous line segment in sweepline belongs to the clipping polygon\n } else {\n event.inOut = !prev.otherInOut;\n event.otherInOut = prev.isVertical() ? !prev.inOut : prev.inOut;\n }\n\n // compute prevInResult field\n if (prev) {\n event.prevInResult = (!inResult(prev, operation) || prev.isVertical())\n ? prev.prevInResult : prev;\n }\n }\n\n // check if the line segment belongs to the Boolean operation\n event.inResult = inResult(event, operation);\n}\n\n\n/* eslint-disable indent */\nfunction inResult(event, operation) {\n switch (event.type) {\n case NORMAL:\n switch (operation) {\n case INTERSECTION:\n return !event.otherInOut;\n case UNION:\n return event.otherInOut;\n case DIFFERENCE:\n // return (event.isSubject && !event.otherInOut) ||\n // (!event.isSubject && event.otherInOut);\n return (event.isSubject && event.otherInOut) ||\n (!event.isSubject && !event.otherInOut);\n case XOR:\n return true;\n }\n break;\n case SAME_TRANSITION:\n return operation === INTERSECTION || operation === UNION;\n case DIFFERENT_TRANSITION:\n return operation === DIFFERENCE;\n case NON_CONTRIBUTING:\n return false;\n }\n return false;\n}\n/* eslint-enable indent */\n","import { NORMAL } from './edge_type';\n\n\nexport default class SweepEvent {\n\n\n /**\n * Sweepline event\n *\n * @class {SweepEvent}\n * @param {Array.<Number>} point\n * @param {Boolean} left\n * @param {SweepEvent=} otherEvent\n * @param {Boolean} isSubject\n * @param {Number} edgeType\n */\n constructor (point, left, otherEvent, isSubject, edgeType) {\n\n /**\n * Is left endpoint?\n * @type {Boolean}\n */\n this.left = left;\n\n /**\n * @type {Array.<Number>}\n */\n this.point = point;\n\n /**\n * Other edge reference\n * @type {SweepEvent}\n */\n this.otherEvent = otherEvent;\n\n /**\n * Belongs to source or clipping polygon\n * @type {Boolean}\n */\n this.isSubject = isSubject;\n\n /**\n * Edge contribution type\n * @type {Number}\n */\n this.type = edgeType || NORMAL;\n\n\n /**\n * In-out transition for the sweepline crossing polygon\n * @type {Boolean}\n */\n this.inOut = false;\n\n\n /**\n * @type {Boolean}\n */\n this.otherInOut = false;\n\n /**\n * Previous event in result?\n * @type {SweepEvent}\n */\n this.prevInResult = null;\n\n /**\n * Does event belong to result?\n * @type {Boolean}\n */\n this.inResult = false;\n\n\n // connection step\n\n /**\n * @type {Boolean}\n */\n this.resultInOut = false;\n\n this.isExteriorRing = true;\n }\n\n\n /**\n * @param {Array.<Number>} p\n * @return {Boolean}\n */\n isBelow (p) {\n const p0 = this.point, p1 = this.otherEvent.point;\n return this.left\n ? (p0[0] - p[0]) * (p1[1] - p[1]) - (p1[0] - p[0]) * (p0[1] - p[1]) > 0\n // signedArea(this.point, this.otherEvent.point, p) > 0 :\n : (p1[0] - p[0]) * (p0[1] - p[1]) - (p0[0] - p[0]) * (p1[1] - p[1]) > 0;\n //signedArea(this.otherEvent.point, this.point, p) > 0;\n }\n\n\n /**\n * @param {Array.<Number>} p\n * @return {Boolean}\n */\n isAbove (p) {\n return !this.isBelow(p);\n }\n\n\n /**\n * @return {Boolean}\n */\n isVertical () {\n return this.point[0] === this.otherEvent.point[0];\n }\n\n\n clone () {\n const copy = new SweepEvent(\n this.point, this.left, this.otherEvent, this.isSubject, this.type);\n\n copy.inResult = this.inResult;\n copy.prevInResult = this.prevInResult;\n copy.isExteriorRing = this.isExteriorRing;\n copy.inOut = this.inOut;\n copy.otherInOut = this.otherInOut;\n\n return copy;\n }\n}\n","export default function equals(p1, p2) {\n if (p1[0] === p2[0]) {\n if (p1[1] === p2[1]) {\n return true;\n } else {\n return false;\n }\n }\n return false;\n}\n\n// const EPSILON = 1e-9;\n// const abs = Math.abs;\n// TODO https://github.com/w8r/martinez/issues/6#issuecomment-262847164\n// Precision problem.\n//\n// module.exports = function equals(p1, p2) {\n// return abs(p1[0] - p2[0]) <= EPSILON && abs(p1[1] - p2[1]) <= EPSILON;\n// };\n","/**\n * Signed area of the triangle (p0, p1, p2)\n * @param {Array.<Number>} p0\n * @param {Array.<Number>} p1\n * @param {Array.<Number>} p2\n * @return {Number}\n */\nexport default function signedArea(p0, p1, p2) {\n return (p0[0] - p2[0]) * (p1[1] - p2[1]) - (p1[0] - p2[0]) * (p0[1] - p2[1]);\n}\n","import signedArea from './signed_area';\n\n/**\n * @param {SweepEvent} e1\n * @param {SweepEvent} e2\n * @return {Number}\n */\nexport default function compareEvents(e1, e2) {\n const p1 = e1.point;\n const p2 = e2.point;\n\n // Different x-coordinate\n if (p1[0] > p2[0]) return 1;\n if (p1[0] < p2[0]) return -1;\n\n // Different points, but same x-coordinate\n // Event with lower y-coordinate is processed first\n if (p1[1] !== p2[1]) return p1[1] > p2[1] ? 1 : -1;\n\n return specialCases(e1, e2, p1, p2);\n}\n\n\n/* eslint-disable no-unused-vars */\nfunction specialCases(e1, e2, p1, p2) {\n // Same coordinates, but one is a left endpoint and the other is\n // a right endpoint. The right endpoint is processed first\n if (e1.left !== e2.left)\n return e1.left ? 1 : -1;\n\n // const p2 = e1.otherEvent.point, p3 = e2.otherEvent.point;\n // const sa = (p1[0] - p3[0]) * (p2[1] - p3[1]) - (p2[0] - p3[0]) * (p1[1] - p3[1])\n // Same coordinates, both events\n // are left endpoints or right endpoints.\n // not collinear\n if (signedArea(p1, e1.otherEvent.point, e2.otherEvent.point) !== 0) {\n // the event associate to the bottom segment is processed first\n return (!e1.isBelow(e2.otherEvent.point)) ? 1 : -1;\n }\n\n return (!e1.isSubject && e2.isSubject) ? 1 : -1;\n}\n/* eslint-enable no-unused-vars */\n","import SweepEvent from './sweep_event';\nimport equals from './equals';\nimport compareEvents from './compare_events';\n\n/**\n * @param {SweepEvent} se\n * @param {Array.<Number>} p\n * @param {Queue} queue\n * @return {Queue}\n */\nexport default function divideSegment(se, p, queue) {\n const r = new SweepEvent(p, false, se, se.isSubject);\n const l = new SweepEvent(p, true, se.otherEvent, se.isSubject);\n\n /* eslint-disable no-console */\n if (equals(se.point, se.otherEvent.point)) {\n\n console.warn('what is that, a collapsed segment?', se);\n }\n /* eslint-enable no-console */\n\n r.contourId = l.contourId = se.contourId;\n\n // avoid a rounding error. The left event would be processed after the right event\n if (compareEvents(l, se.otherEvent) > 0) {\n se.otherEvent.left = true;\n l.left = false;\n }\n\n // avoid a rounding error. The left event would be processed after the right event\n // if (compareEvents(se, r) > 0) {}\n\n se.otherEvent.otherEvent = l;\n se.otherEvent = r;\n\n queue.push(l);\n queue.push(r);\n\n return queue;\n}\n","//const EPS = 1e-9;\n\n/**\n * Finds the magnitude of the cross product of two vectors (if we pretend\n * they're in three dimensions)\n *\n * @param {Object} a First vector\n * @param {Object} b Second vector\n * @private\n * @returns {Number} The magnitude of the cross product\n */\nfunction crossProduct(a, b) {\n return (a[0] * b[1]) - (a[1] * b[0]);\n}\n\n/**\n * Finds the dot product of two vectors.\n *\n * @param {Object} a First vector\n * @param {Object} b Second vector\n * @private\n * @returns {Number} The dot product\n */\nfunction dotProduct(a, b) {\n return (a[0] * b[0]) + (a[1] * b[1]);\n}\n\n/**\n * Finds the intersection (if any) between two line segments a and b, given the\n * line segments' end points a1, a2 and b1, b2.\n *\n * This algorithm is based on Schneider and Eberly.\n * http://www.cimec.org.ar/~ncalvo/Schneider_Eberly.pdf\n * Page 244.\n *\n * @param {Array.<Number>} a1 point of first line\n * @param {Array.<Number>} a2 point of first line\n * @param {Array.<Number>} b1 point of second line\n * @param {Array.<Number>} b2 point of second line\n * @param {Boolean=} noEndpointTouch whether to skip single touchpoints\n * (meaning connected segments) as\n * intersections\n * @returns {Array.<Array.<Number>>|Null} If the lines intersect, the point of\n * intersection. If they overlap, the two end points of the overlapping segment.\n * Otherwise, null.\n */\nexport default function (a1, a2, b1, b2, noEndpointTouch) {\n // The algorithm expects our lines in the form P + sd, where P is a point,\n // s is on the interval [0, 1], and d is a vector.\n // We are passed two points. P can be the first point of each pair. The\n // vector, then, could be thought of as the distance (in x and y components)\n // from the first point to the second point.\n // So first, let's make our vectors:\n const va = [a2[0] - a1[0], a2[1] - a1[1]];\n const vb = [b2[0] - b1[0], b2[1] - b1[1]];\n // We also define a function to convert back to regular point form:\n\n /* eslint-disable arrow-body-style */\n\n function toPoint(p, s, d) {\n return [\n p[0] + s * d[0],\n p[1] + s * d[1]\n ];\n }\n\n /* eslint-enable arrow-body-style */\n\n // The rest is pretty much a straight port of the algorithm.\n const e = [b1[0] - a1[0], b1[1] - a1[1]];\n let kross = crossProduct(va, vb);\n let sqrKross = kross * kross;\n const sqrLenA = dotProduct(va, va);\n //const sqrLenB = dotProduct(vb, vb);\n\n // Check for line intersection. This works because of the properties of the\n // cross product -- specifically, two vectors are parallel if and only if the\n // cross product is the 0 vector. The full calculation involves relative error\n // to account for possible very small line segments. See Schneider & Eberly\n // for details.\n if (sqrKross > 0/* EPS * sqrLenB * sqLenA */) {\n // If they're not parallel, then (because these are line segments) they\n // still might not actually intersect. This code checks that the\n // intersection point of the lines is actually on both line segments.\n const s = crossProduct(e, vb) / kross;\n if (s < 0 || s > 1) {\n // not on line segment a\n return null;\n }\n const t = crossProduct(e, va) / kross;\n if (t < 0 || t > 1) {\n // not on line segment b\n return null;\n }\n if (s === 0 || s === 1) {\n // on an endpoint of line segment a\n return noEndpointTouch ? null : [toPoint(a1, s, va)];\n }\n if (t === 0 || t === 1) {\n // on an endpoint of line segment b\n return noEndpointTouch ? null : [toPoint(b1, t, vb)];\n }\n return [toPoint(a1, s, va)];\n }\n\n // If we've reached this point, then the lines are either parallel or the\n // same, but the segments could overlap partially or fully, or not at all.\n // So we need to find the overlap, if any. To do that, we can use e, which is\n // the (vector) difference between the two initial points. If this is parallel\n // with the line itself, then the two lines are the same line, and there will\n // be overlap.\n //const sqrLenE = dotProduct(e, e);\n kross = crossProduct(e, va);\n sqrKross = kross * kross;\n\n if (sqrKross > 0 /* EPS * sqLenB * sqLenE */) {\n // Lines are just parallel, not the same. No overlap.\n return null;\n }\n\n const sa = dotProduct(va, e) / sqrLenA;\n const sb = sa + dotProduct(va, vb) / sqrLenA;\n const smin = Math.min(sa, sb);\n const smax = Math.max(sa, sb);\n\n // this is, essentially, the FindIntersection acting on floats from\n // Schneider & Eberly, just inlined into this function.\n if (smin <= 1 && smax >= 0) {\n\n // overlap on an end point\n if (smin === 1) {\n return noEndpointTouch ? null : [toPoint(a1, smin > 0 ? smin : 0, va)];\n }\n\n if (smax === 0) {\n return noEndpointTouch ? null : [toPoint(a1, smax < 1 ? smax : 1, va)];\n }\n\n if (noEndpointTouch && smin === 0 && smax === 1) return null;\n\n // There's overlap on a segment -- two points of intersection. Return both.\n return [\n toPoint(a1, smin > 0 ? smin : 0, va),\n toPoint(a1, smax < 1 ? smax : 1, va)\n ];\n }\n\n return null;\n}\n","import divideSegment from './divide_segment';\nimport intersection from './segment_intersection';\nimport equals from './equals';\nimport compareEvents from './compare_events';\nimport {\n NON_CONTRIBUTING,\n SAME_TRANSITION,\n DIFFERENT_TRANSITION\n} from './edge_type';\n\n/**\n * @param {SweepEvent} se1\n * @param {SweepEvent} se2\n * @param {Queue} queue\n * @return {Number}\n */\nexport default function possibleIntersection (se1, se2, queue) {\n // that disallows self-intersecting polygons,\n // did cost us half a day, so I'll leave it\n // out of respect\n // if (se1.isSubject === se2.isSubject) return;\n const inter = intersection(\n se1.point, se1.otherEvent.point,\n se2.point, se2.otherEvent.point\n );\n\n const nintersections = inter ? inter.length : 0;\n if (nintersections === 0) return 0; // no intersection\n\n // the line segments intersect at an endpoint of both line segments\n if ((nintersections === 1) &&\n (equals(se1.point, se2.point) ||\n equals(se1.otherEvent.point, se2.otherEvent.point))) {\n return 0;\n }\n\n if (nintersections === 2 && se1.isSubject === se2.isSubject) {\n // if(se1.contourId === se2.contourId){\n // console.warn('Edges of the same polygon overlap',\n // se1.point, se1.otherEvent.point, se2.point, se2.otherEvent.point);\n // }\n //throw new Error('Edges of the same polygon overlap');\n return 0;\n }\n\n // The line segments associated to se1 and se2 intersect\n if (nintersections === 1) {\n\n // if the intersection point is not an endpoint of se1\n if (!equals(se1.point, inter[0]) && !equals(se1.otherEvent.point, inter[0])) {\n divideSegment(se1, inter[0], queue);\n }\n\n // if the intersection point is not an endpoint of se2\n if (!equals(se2.point, inter[0]) && !equals(se2.otherEvent.point, inter[0])) {\n divideSegment(se2, inter[0], queue);\n }\n return 1;\n }\n\n // The line segments associated to se1 and se2 overlap\n const events = [];\n let leftCoincide = false;\n let rightCoincide = false;\n\n if (equals(se1.point, se2.point)) {\n leftCoincide = true; // linked\n } else if (compareEvents(se1, se2) === 1) {\n events.push(se2, se1);\n } else {\n events.push(se1, se2);\n }\n\n if (equals(se1.otherEvent.point, se2.otherEvent.point)) {\n rightCoincide = true;\n } else if (compareEvents(se1.otherEvent, se2.otherEvent) === 1) {\n events.push(se2.otherEvent, se1.otherEvent);\n } else {\n events.push(se1.otherEvent, se2.otherEvent);\n }\n\n if ((leftCoincide && rightCoincide) || leftCoincide) {\n // both line segments are equal or share the left endpoint\n se2.type = NON_CONTRIBUTING;\n se1.type = (se2.inOut === se1.inOut)\n ? SAME_TRANSITION : DIFFERENT_TRANSITION;\n\n if (leftCoincide && !rightCoincide) {\n // honestly no idea, but changing events selection from [2, 1]\n // to [0, 1] fixes the overlapping self-intersecting polygons issue\n divideSegment(events[1].otherEvent, events[0].point, queue);\n }\n return 2;\n }\n\n // the line segments share the right endpoint\n if (rightCoincide) {\n divideSegment(events[0], events[1].point, queue);\n return 3;\n }\n\n // no line segment includes totally the other one\n if (events[0] !== events[3].otherEvent) {\n divideSegment(events[0], events[1].point, queue);\n divideSegment(events[1], events[2].point, queue);\n return 3;\n }\n\n // one line segment includes the other one\n divideSegment(events[0], events[1].point, queue);\n divideSegment(events[3].otherEvent, events[2].point, queue);\n\n return 3;\n}\n","import signedArea from './signed_area';\nimport compareEvents from './compare_events';\nimport equals from './equals';\n\n\n/**\n * @param {SweepEvent} le1\n * @param {SweepEvent} le2\n * @return {Number}\n */\nexport default function compareSegments(le1, le2) {\n if (le1 === le2) return 0;\n\n // Segments are not collinear\n if (signedArea(le1.point, le1.otherEvent.point, le2.point) !== 0 ||\n signedArea(le1.point, le1.otherEvent.point, le2.otherEvent.point) !== 0) {\n\n // If they share their left endpoint use the right endpoint to sort\n if (equals(le1.point, le2.point)) return le1.isBelow(le2.otherEvent.point) ? -1 : 1;\n\n // Different left endpoint: use the left endpoint to sort\n if (le1.point[0] === le2.point[0]) return le1.point[1] < le2.point[1] ? -1 : 1;\n\n // has the line segment associated to e1 been inserted\n // into S after the line segment associated to e2 ?\n if (compareEvents(le1, le2) === 1) return le2.isAbove(le1.point) ? -1 : 1;\n\n // The line segment associated to e2 has been inserted\n // into S after the line segment associated to e1\n return le1.isBelow(le2.point) ? -1 : 1;\n }\n\n if (le1.isSubject === le2.isSubject) { // same polygon\n let p1 = le1.point, p2 = le2.point;\n if (p1[0] === p2[0] && p1[1] === p2[1]/*equals(le1.point, le2.point)*/) {\n p1 = le1.otherEvent.point; p2 = le2.otherEvent.point;\n if (p1[0] === p2[0] && p1[1] === p2[1]) return 0;\n else return le1.contourId > le2.contourId ? 1 : -1;\n }\n } else { // Segments are collinear, but belong to separate polygons\n return le1.isSubject ? -1 : 1;\n }\n\n return compareEvents(le1, le2) === 1 ? 1 : -1;\n}\n","import Tree from 'splaytree';\nimport computeFields from './compute_fields';\nimport possibleIntersection from './possible_intersection';\nimport compareSegments from './compare_segments';\nimport {\n INTERSECTION,\n DIFFERENCE\n} from './operation';\n\n\nexport default function subdivide(eventQueue, subject, clipping, sbbox, cbbox, operation) {\n const sweepLine = new Tree(compareSegments);\n const sortedEvents = [];\n\n const rightbound = Math.min(sbbox[2], cbbox[2]);\n\n let prev, next, begin;\n\n while (eventQueue.length !== 0) {\n let event = eventQueue.pop();\n sortedEvents.push(event);\n\n // optimization by bboxes for intersection and difference goes here\n if ((operation === INTERSECTION && event.point[0] > rightbound) ||\n (operation === DIFFERENCE && event.point[0] > sbbox[2])) {\n break;\n }\n\n if (event.left) {\n next = prev = sweepLine.insert(event);\n begin = sweepLine.minNode();\n\n if (prev !== begin) prev = sweepLine.prev(prev);\n else prev = null;\n\n next = sweepLine.next(next);\n\n const prevEvent = prev ? prev.key : null;\n let prevprevEvent;\n computeFields(event, prevEvent, operation);\n if (next) {\n if (possibleIntersection(event, next.key, eventQueue) === 2) {\n computeFields(event, prevEvent, operation);\n computeFields(event, next.key, operation);\n }\n }\n\n if (prev) {\n if (possibleIntersection(prev.key, event, eventQueue) === 2) {\n let prevprev = prev;\n if (prevprev !== begin) prevprev = sweepLine.prev(prevprev);\n else prevprev = null;\n\n prevprevEvent = prevprev ? prevprev.key : null;\n computeFields(prevEvent, prevprevEvent, operation);\n computeFields(event, prevEvent, operation);\n }\n }\n } else {\n event = event.otherEvent;\n next = prev = sweepLine.find(event);\n\n if (prev && next) {\n\n if (prev !== begin) prev = sweepLine.prev(prev);\n else prev = null;\n\n next = sweepLine.next(next);\n sweepLine.remove(event);\n\n if (next && prev) {\n possibleIntersection(prev.key, next.key, eventQueue);\n }\n }\n }\n }\n return sortedEvents;\n}\n","import compareEvents from './compare_events';\nimport { DIFFERENCE } from './operation';\n\n/**\n * @param {Array.<SweepEvent>} sortedEvents\n * @return {Array.<SweepEvent>}\n */\nfunction orderEvents(sortedEvents) {\n let event, i, len, tmp;\n const resultEvents = [];\n for (i = 0, len = sortedEvents.length; i < len; i++) {\n event = sortedEvents[i];\n if ((event.left && event.inResult) ||\n (!event.left && event.otherEvent.inResult)) {\n resultEvents.push(event);\n }\n }\n // Due to overlapping edges the resultEvents array can be not wholly sorted\n let sorted = false;\n while (!sorted) {\n sorted = true;\n for (i = 0, len = resultEvents.length; i < len; i++) {\n if ((i + 1) < len &&\n compareEvents(resultEvents[i], resultEvents[i + 1]) === 1) {\n tmp = resultEvents[i];\n resultEvents[i] = resultEvents[i + 1];\n resultEvents[i + 1] = tmp;\n sorted = false;\n }\n }\n }\n\n\n for (i = 0, len = resultEvents.length; i < len; i++) {\n event = resultEvents[i];\n event.pos = i;\n }\n\n // imagine, the right event is found in the beginning of the queue,\n // when his left counterpart is not marked yet\n for (i = 0, len = resultEvents.length; i < len; i++) {\n event = resultEvents[i];\n if (!event.left) {\n tmp = event.pos;\n event.pos = event.otherEvent.pos;\n event.otherEvent.pos = tmp;\n }\n }\n\n return resultEvents;\n}\n\n\n/**\n * @param {Number} pos\n * @param {Array.<SweepEvent>} resultEvents\n * @param {Object>} processed\n * @return {Number}\n */\nfunction nextPos(pos, resultEvents, processed, origIndex) {\n let newPos = pos + 1;\n const length = resultEvents.length;\n if (newPos > length - 1) return pos - 1;\n let p = resultEvents[pos].point;\n let p1 = resultEvents[newPos].point;\n\n\n // while in range and not the current one by value\n while (newPos < length && p1[0] === p[0] && p1[1] === p[1]) {\n if (!processed[newPos]) {\n return newPos;\n } else {\n newPos++;\n }\n p1 = resultEvents[newPos].point;\n }\n\n newPos = pos - 1;\n\n while (processed[newPos] && newPos >= origIndex) {\n newPos--;\n }\n return newPos;\n}\n\n\n/**\n * @param {Array.<SweepEvent>} sortedEvents\n * @return {Array.<*>} polygons\n */\nexport default function connectEdges(sortedEvents, operation) {\n let i, len;\n const resultEvents = orderEvents(sortedEvents);\n\n // \"false\"-filled array\n const processed = {};\n const result = [];\n let event;\n\n for (i = 0, len = resultEvents.length; i < len; i++) {\n if (processed[i]) continue;\n const contour = [[]];\n\n if (!resultEvents[i].isExteriorRing) {\n if (operation === DIFFERENCE && !resultEvents[i].isSubject && result.length === 0) {\n result.push(contour);\n } else if (result.length === 0) {\n result.push([[contour]]);\n } else {\n result[result.length - 1].push(contour[0]);\n }\n } else if (operation === DIFFERENCE && !resultEvents[i].isSubject && result.length > 1) {\n result[result.length - 1].push(contour[0]);\n } else {\n result.push(contour);\n }\n\n const ringId = result.length - 1;\n let pos = i;\n\n const initial = resultEvents[i].point;\n contour[0].push(initial);\n\n while (pos >= i) {\n event = resultEvents[pos];\n processed[pos] = true;\n\n if (event.left) {\n event.resultInOut = false;\n event.contourId = ringId;\n } else {\n event.otherEvent.resultInOut = true;\n event.otherEvent.contourId = ringId;\n }\n\n pos = event.pos;\n processed[pos] = true;\n contour[0].push(resultEvents[pos].point);\n pos = nextPos(pos, resultEvents, processed, i);\n }\n\n pos = pos === -1 ? i : pos;\n\n event = resultEvents[pos];\n processed[pos] = processed[event.pos] = true;\n event.otherEvent.resultInOut = true;\n event.otherEvent.contourId = ringId;\n }\n\n // Handle if the result is a polygon (eg not multipoly)\n // Commented it again, let's see what do we mean by that\n // if (result.length === 1) result = result[0];\n return result;\n}\n","'use strict';\n\nmodule.exports = TinyQueue;\nmodule.exports.default = TinyQueue;\n\nfunction TinyQueue(data, compare) {\n if (!(this instanceof TinyQueue)) return new TinyQueue(data, compare);\n\n this.data = data || [];\n this.length = this.data.length;\n this.compare = compare || defaultCompare;\n\n if (this.length > 0) {\n for (var i = (this.length >> 1) - 1; i >= 0; i--) this._down(i);\n }\n}\n\nfunction defaultCompare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\nTinyQueue.prototype = {\n\n push: function (item) {\n this.data.push(item);\n this.length++;\n this._up(this.length - 1);\n },\n\n pop: function () {\n if (this.length === 0) return undefined;\n\n var top = this.data[0];\n this.length--;\n\n if (this.length > 0) {\n this.data[0] = this.data[this.length];\n this._down(0);\n }\n this.data.pop();\n\n return top;\n },\n\n peek: function () {\n return this.data[0];\n },\n\n _up: function (pos) {\n var data = this.data;\n var compare = this.compare;\n var item = data[pos];\n\n while (pos > 0) {\n var parent = (pos - 1) >> 1;\n var current = data[parent];\n if (compare(item, current) >= 0) break;\n data[pos] = current;\n pos = parent;\n }\n\n data[pos] = item;\n },\n\n _down: function (pos) {\n var data = this.data;\n var compare = this.compare;\n var halfLength = this.length >> 1;\n var item = data[pos];\n\n while (pos < halfLength) {\n var left = (pos << 1) + 1;\n var right = left + 1;\n var best = data[left];\n\n if (right < this.length && compare(data[right], best) < 0) {\n left = right;\n best = data[right];\n }\n if (compare(best, item) >= 0) break;\n\n data[pos] = best;\n pos = left;\n }\n\n data[pos] = item;\n }\n};\n","import Queue from 'tinyqueue';\nimport SweepEvent from './sweep_event';\nimport compareEvents from './compare_events';\nimport { DIFFERENCE } from './operation';\n\nconst max = Math.max;\nconst min = Math.min;\n\nlet contourId = 0;\n\n\nfunction processPolygon(contourOrHole, isSubject, depth, Q, bbox, isExteriorRing) {\n let i, len, s1, s2, e1, e2;\n for (i = 0, len = contourOrHole.length - 1; i < len; i++) {\n s1 = contourOrHole[i];\n s2 = contourOrHole[i + 1];\n e1 = new SweepEvent(s1, false, undefined, isSubject);\n e2 = new SweepEvent(s2, false, e1, isSubject);\n e1.otherEvent = e2;\n\n if (s1[0] === s2[0] && s1[1] === s2[1]) {\n continue; // skip collapsed edges, or it breaks\n }\n\n e1.contourId = e2.contourId = depth;\n if (!isExteriorRing) {\n e1.isExteriorRing = false;\n e2.isExteriorRing = false;\n }\n if (compareEvents(e1, e2) > 0) {\n e2.left = true;\n } else {\n e1.left = true;\n }\n\n const x = s1[0], y = s1[1];\n bbox[0] = min(bbox[0], x);\n bbox[1] = min(bbox[1], y);\n bbox[2] = max(bbox[2], x);\n bbox[3] = max(bbox[3], y);\n\n // Pushing it so the queue is sorted from left to right,\n // with object on the left having the highest priority.\n Q.push(e1);\n Q.push(e2);\n }\n}\n\n\nexport default function fillQueue(subject, clipping, sbbox, cbbox, operation) {\n const eventQueue = new Queue(null, compareEvents);\n let polygonSet, isExteriorRing, i, ii, j, jj; //, k, kk;\n\n for (i = 0, ii = subject.length; i < ii; i++) {\n polygonSet = subject[i];\n for (j = 0, jj = polygonSet.length; j < jj; j++) {\n isExteriorRing = j === 0;\n if (isExteriorRing) contourId++;\n processPolygon(polygonSet[j], true, contourId, eventQueue, sbbox, isExteriorRing);\n }\n }\n\n for (i = 0, ii = clipping.length; i < ii; i++) {\n polygonSet = clipping[i];\n for (j = 0, jj = polygonSet.length; j < jj; j++) {\n isExteriorRing = j === 0;\n if (operation === DIFFERENCE) isExteriorRing = false;\n if (isExteriorRing) contourId++;\n processPolygon(polygonSet[j], false, contourId, eventQueue, cbbox, isExteriorRing);\n }\n }\n\n return eventQueue;\n}\n","import subdivideSegments from './subdivide_segments';\nimport connectEdges from './connect_edges';\nimport fillQueue from './fill_queue';\nimport {\n INTERSECTION,\n DIFFERENCE,\n UNION,\n XOR\n} from './operation';\n\nconst EMPTY = [];\n\n\nfunction trivialOperation(subject, clipping, operation) {\n let result = null;\n if (subject.length * clipping.length === 0) {\n if (operation === INTERSECTION) {\n result = EMPTY;\n } else if (operation === DIFFERENCE) {\n result = subject;\n } else if (operation === UNION ||\n operation === XOR) {\n result = (subject.length === 0) ? clipping : subject;\n }\n }\n return result;\n}\n\n\nfunction compareBBoxes(subject, clipping, sbbox, cbbox, operation) {\n let result = null;\n if (sbbox[0] > cbbox[2] ||\n cbbox[0] > sbbox[2] ||\n sbbox[1] > cbbox[3] ||\n cbbox[1] > sbbox[3]) {\n if (operation === INTERSECTION) {\n result = EMPTY;\n } else if (operation === DIFFERENCE) {\n result = subject;\n } else if (operation === UNION ||\n operation === XOR) {\n result = subject.concat(clipping);\n }\n }\n return result;\n}\n\n\nexport default function boolean(subject, clipping, operation) {\n if (typeof subject[0][0][0] === 'number') {\n subject = [subject];\n }\n if (typeof clipping[0][0][0] === 'number') {\n clipping = [clipping];\n }\n let trivial = trivialOperation(subject, clipping, operation);\n if (trivial) {\n return trivial === EMPTY ? null : trivial;\n }\n const sbbox = [Infinity, Infinity, -Infinity, -Infinity];\n const cbbox = [Infinity, Infinity, -Infinity, -Infinity];\n\n //console.time('fill queue');\n const eventQueue = fillQueue(subject, clipping, sbbox, cbbox, operation);\n //console.timeEnd('fill queue');\n\n trivial = compareBBoxes(subject, clipping, sbbox, cbbox, operation);\n if (trivial) {\n return trivial === EMPTY ? null : trivial;\n }\n //console.time('subdivide edges');\n const sortedEvents = subdivideSegments(eventQueue, subject, clipping, sbbox, cbbox, operation);\n //console.timeEnd('subdivide edges');\n\n //console.time('connect vertices');\n const result = connectEdges(sortedEvents, operation);\n //console.timeEnd('connect vertices');\n return result;\n}\n","import boolean from './src/';\nimport {\n INTERSECTION,\n DIFFERENCE,\n UNION,\n XOR\n} from './src/operation';\n\nexport function union (subject, clipping) {\n return boolean(subject, clipping, UNION);\n}\n\nexport function diff (subject, clipping) {\n return boolean(subject, clipping, DIFFERENCE);\n}\n\nexport function xor (subject, clipping){\n return boolean(subject, clipping, XOR);\n}\n\nexport function intersection (subject, clipping) {\n return boolean(subject, clipping, INTERSECTION);\n}\n\n/**\n * @enum {Number}\n */\nexport const operations = { UNION, DIFFERENCE, INTERSECTION, XOR };\n"],"names":["this","const","let","Tree","Queue","subdivideSegments","intersection"],"mappings":"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"}
|
@@ -0,0 +1,279 @@
|
|
1
|
+
(function webpackUniversalModuleDefinition(root, factory) {
|
2
|
+
if(typeof exports === 'object' && typeof module === 'object')
|
3
|
+
module.exports = factory();
|
4
|
+
else if(typeof define === 'function' && define.amd)
|
5
|
+
define([], factory);
|
6
|
+
else if(typeof exports === 'object')
|
7
|
+
exports["polygon-clipping"] = factory();
|
8
|
+
else
|
9
|
+
root["polygon-clipping"] = factory();
|
10
|
+
})(typeof self !== 'undefined' ? self : this, function() {
|
11
|
+
return /******/ (function(modules) { // webpackBootstrap
|
12
|
+
/******/ // The module cache
|
13
|
+
/******/ var installedModules = {};
|
14
|
+
/******/
|
15
|
+
/******/ // The require function
|
16
|
+
/******/ function __webpack_require__(moduleId) {
|
17
|
+
/******/
|
18
|
+
/******/ // Check if module is in cache
|
19
|
+
/******/ if(installedModules[moduleId]) {
|
20
|
+
/******/ return installedModules[moduleId].exports;
|
21
|
+
/******/ }
|
22
|
+
/******/ // Create a new module (and put it into the cache)
|
23
|
+
/******/ var module = installedModules[moduleId] = {
|
24
|
+
/******/ i: moduleId,
|
25
|
+
/******/ l: false,
|
26
|
+
/******/ exports: {}
|
27
|
+
/******/ };
|
28
|
+
/******/
|
29
|
+
/******/ // Execute the module function
|
30
|
+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
31
|
+
/******/
|
32
|
+
/******/ // Flag the module as loaded
|
33
|
+
/******/ module.l = true;
|
34
|
+
/******/
|
35
|
+
/******/ // Return the exports of the module
|
36
|
+
/******/ return module.exports;
|
37
|
+
/******/ }
|
38
|
+
/******/
|
39
|
+
/******/
|
40
|
+
/******/ // expose the modules object (__webpack_modules__)
|
41
|
+
/******/ __webpack_require__.m = modules;
|
42
|
+
/******/
|
43
|
+
/******/ // expose the module cache
|
44
|
+
/******/ __webpack_require__.c = installedModules;
|
45
|
+
/******/
|
46
|
+
/******/ // define getter function for harmony exports
|
47
|
+
/******/ __webpack_require__.d = function(exports, name, getter) {
|
48
|
+
/******/ if(!__webpack_require__.o(exports, name)) {
|
49
|
+
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
50
|
+
/******/ }
|
51
|
+
/******/ };
|
52
|
+
/******/
|
53
|
+
/******/ // define __esModule on exports
|
54
|
+
/******/ __webpack_require__.r = function(exports) {
|
55
|
+
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
56
|
+
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
57
|
+
/******/ }
|
58
|
+
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
59
|
+
/******/ };
|
60
|
+
/******/
|
61
|
+
/******/ // create a fake namespace object
|
62
|
+
/******/ // mode & 1: value is a module id, require it
|
63
|
+
/******/ // mode & 2: merge all properties of value into the ns
|
64
|
+
/******/ // mode & 4: return value when already ns object
|
65
|
+
/******/ // mode & 8|1: behave like require
|
66
|
+
/******/ __webpack_require__.t = function(value, mode) {
|
67
|
+
/******/ if(mode & 1) value = __webpack_require__(value);
|
68
|
+
/******/ if(mode & 8) return value;
|
69
|
+
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
70
|
+
/******/ var ns = Object.create(null);
|
71
|
+
/******/ __webpack_require__.r(ns);
|
72
|
+
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
73
|
+
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
74
|
+
/******/ return ns;
|
75
|
+
/******/ };
|
76
|
+
/******/
|
77
|
+
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
78
|
+
/******/ __webpack_require__.n = function(module) {
|
79
|
+
/******/ var getter = module && module.__esModule ?
|
80
|
+
/******/ function getDefault() { return module['default']; } :
|
81
|
+
/******/ function getModuleExports() { return module; };
|
82
|
+
/******/ __webpack_require__.d(getter, 'a', getter);
|
83
|
+
/******/ return getter;
|
84
|
+
/******/ };
|
85
|
+
/******/
|
86
|
+
/******/ // Object.prototype.hasOwnProperty.call
|
87
|
+
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
88
|
+
/******/
|
89
|
+
/******/ // __webpack_public_path__
|
90
|
+
/******/ __webpack_require__.p = "";
|
91
|
+
/******/
|
92
|
+
/******/
|
93
|
+
/******/ // Load entry module and return exports
|
94
|
+
/******/ return __webpack_require__(__webpack_require__.s = "./main.js");
|
95
|
+
/******/ })
|
96
|
+
/************************************************************************/
|
97
|
+
/******/ ({
|
98
|
+
|
99
|
+
/***/ "./main.js":
|
100
|
+
/*!*****************!*\
|
101
|
+
!*** ./main.js ***!
|
102
|
+
\*****************/
|
103
|
+
/*! no static exports found */
|
104
|
+
/***/ (function(module, exports, __webpack_require__) {
|
105
|
+
|
106
|
+
"use strict";
|
107
|
+
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.difference = exports.xor = exports.intersection = exports.union = undefined;\n\nvar _src = __webpack_require__(/*! ./src */ \"./src/index.js\");\n\nvar _src2 = _interopRequireDefault(_src);\n\nvar _operation = __webpack_require__(/*! ./src/operation */ \"./src/operation.js\");\n\nvar _operation2 = _interopRequireDefault(_operation);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar union = exports.union = function union(geom) {\n for (var _len = arguments.length, moreGeoms = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n moreGeoms[_key - 1] = arguments[_key];\n }\n\n return (0, _src2.default)(_operation2.default.types.UNION, geom, moreGeoms);\n};\n\nvar intersection = exports.intersection = function intersection(geom) {\n for (var _len2 = arguments.length, moreGeoms = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n moreGeoms[_key2 - 1] = arguments[_key2];\n }\n\n return (0, _src2.default)(_operation2.default.types.INTERSECTION, geom, moreGeoms);\n};\n\nvar xor = exports.xor = function xor(geom) {\n for (var _len3 = arguments.length, moreGeoms = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {\n moreGeoms[_key3 - 1] = arguments[_key3];\n }\n\n return (0, _src2.default)(_operation2.default.types.XOR, geom, moreGeoms);\n};\n\nvar difference = exports.difference = function difference(subjectGeom) {\n for (var _len4 = arguments.length, clippingGeoms = Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {\n clippingGeoms[_key4 - 1] = arguments[_key4];\n }\n\n return (0, _src2.default)(_operation2.default.types.DIFFERENCE, subjectGeom, clippingGeoms);\n};\n\n//# sourceURL=webpack://polygon-clipping/./main.js?");
|
108
|
+
|
109
|
+
/***/ }),
|
110
|
+
|
111
|
+
/***/ "./node_modules/qheap/index.js":
|
112
|
+
/*!*************************************!*\
|
113
|
+
!*** ./node_modules/qheap/index.js ***!
|
114
|
+
\*************************************/
|
115
|
+
/*! no static exports found */
|
116
|
+
/***/ (function(module, exports, __webpack_require__) {
|
117
|
+
|
118
|
+
eval("module.exports = __webpack_require__(/*! ./lib/qheap.js */ \"./node_modules/qheap/lib/qheap.js\");\n\n\n//# sourceURL=webpack://polygon-clipping/./node_modules/qheap/index.js?");
|
119
|
+
|
120
|
+
/***/ }),
|
121
|
+
|
122
|
+
/***/ "./node_modules/qheap/lib/qheap.js":
|
123
|
+
/*!*****************************************!*\
|
124
|
+
!*** ./node_modules/qheap/lib/qheap.js ***!
|
125
|
+
\*****************************************/
|
126
|
+
/*! no static exports found */
|
127
|
+
/***/ (function(module, exports, __webpack_require__) {
|
128
|
+
|
129
|
+
"use strict";
|
130
|
+
eval("/**\n * nodejs heap, classic array implementation\n *\n * Items are stored in a balanced binary tree packed into an array where\n * node is at [i], left child is at [2*i], right at [2*i+1]. Root is at [1].\n *\n * Copyright (C) 2014-2017 Andras Radics\n * Licensed under the Apache License, Version 2.0\n */\n\n\n\nmodule.exports = Heap;\n\nfunction isBeforeDefault( a, b ) { return a < b; }\n\nfunction Heap( opts ) {\n opts = opts || {};\n if (typeof opts === 'function') opts = {compar: opts};\n\n if (opts.compar) {\n this._isBefore = function(a, b) { return opts.compar(a,b) < 0 };\n } else if (opts.comparBefore) {\n this._isBefore = opts.comparBefore;\n } else {\n this._isBefore = isBeforeDefault;\n }\n this.length = 0;\n this._freeSpace = opts.freeSpace ? this._trimArraySize : false;\n this._list = new Array(opts.size || 100);\n}\n\nHeap.prototype._list = null;\nHeap.prototype._compar = null;\nHeap.prototype._isBefore = null;\nHeap.prototype._freeSpace = null;\nHeap.prototype.length = 0;\n\n/*\n * insert new item at end, and bubble up\n */\nHeap.prototype.insert = function Heap_insert( item ) {\n var idx = ++this.length;\n var list = this._list;\n list[idx] = item;\n\n while (idx > 1) {\n var parentidx = idx >> 1;\n var parentval = list[parentidx];\n if (!(this._isBefore(item, parentval))) break;\n list[idx] = parentval;\n idx = parentidx;\n }\n list[idx] = item;\n};\nHeap.prototype.append = Heap.prototype.insert;\nHeap.prototype.push = Heap.prototype.insert;\nHeap.prototype.unshift = Heap.prototype.insert;\nHeap.prototype.enqueue = Heap.prototype.insert;\n\nHeap.prototype.peek = function Heap_peek( ) {\n return this.length > 0 ? this._list[1] : undefined;\n};\n\nHeap.prototype.size = function Heap_size( ) {\n return this.length;\n};\n\n/*\n * return the root, and bubble down last item from top root position\n * when bubbling down, r: root idx, c: child sub-tree root idx, cv: child root value\n * Note that the child at (c == this.length) does not have to be tested in the loop,\n * since its value is the one being bubbled down, so can loop `while (c < len)`.\n *\n * Note that a redundant (c < len &&) test before the c vs c+1 compar lets node v0.10\n * run 4x faster; v4, v5 and v6 run faster without it if using _isBefore and not\n * raw _compar.\n *\n * Note that this version runs faster than the two-pass pull-up-new-root then\n * bubble-up-last-value-from-hole approach (except when inserting pre-sorted data).\n */\nHeap.prototype.remove = function Heap_remove( ) {\n if (this.length < 1) return undefined;\n var ret = this._list[1];\n var itm = this._list[this.length];\n\n var r = 1, c = 2, cv;\n var len = this.length;\n while (c < len) {\n cv = this._list[c];\n if (this._isBefore(this._list[c+1], cv)) { cv = this._list[c+1] ; c = c+1 }\n if (!(this._isBefore(cv, itm))) break;\n this._list[r] = cv;\n r = c;\n c = c << 1;\n }\n this._list[len] = 0;\n this.length = --len;\n if (len) this._list[r] = itm;\n if (this._freeSpace) this._freeSpace(this._list, len);\n\n return ret;\n};\nHeap.prototype.shift = Heap.prototype.remove;\nHeap.prototype.pop = Heap.prototype.remove;\nHeap.prototype.dequeue = Heap.prototype.remove;\n\n/*\n * Free unused storage slots in the _list.\n * The default is to unconditionally gc, use the options to omit when not useful.\n */\nHeap.prototype.gc = function Heap_gc( options ) {\n if (!options) options = {};\n\n var minListLength = options.minLength; // smallest list that will be gc-d\n if (minListLength === undefined) minListLength = 0;\n\n var minListFull = options.minFull; // list utilization below which to gc\n if (minListFull === undefined) minListFull = 1.00;\n\n if (this._list.length >= minListLength && (this.length < this._list.length * minListFull)) {\n // gc reallocates the array to free the unused storage slots at the end\n // use splice to actually free memory; 7% slower than setting .length\n // note: list.slice makes the array slower to insert to?? splice is better\n this._list.splice(this.length+1, this._list.length);\n }\n}\n\nHeap.prototype._trimArraySize = function Heap__trimArraySize( list, len ) {\n if (len > 10000 && list.length > 4 * len) {\n // use slice to actually free memory; 7% slower than setting .length\n // note: list.slice makes the array slower to insert to?? splice is better\n list.splice(len+1, list.length);\n }\n}\n\nHeap.prototype._check = function Heap__check( ) {\n var isBefore = this._isBefore;\n var _compar = function(a, b) { return isBefore(a, b) ? -1 : 1 };\n\n var i, p, fail = 0;\n for (i=this.length; i>1; i--) {\n // error if parent should go after child, but not if don`t care\n p = i >>> 1;\n // swapping the values must change their ordering, otherwise the\n // comparison is a tie. (Ie, consider the ordering func (a <= b)\n // that for some values reports both that a < b and b < a.)\n if (_compar(this._list[p], this._list[i]) > 0 &&\n _compar(this._list[i], this._list[p]) < 0)\n {\n fail = i;\n }\n }\n if (fail) console.log(\"failed at\", (fail >>> 1), fail);\n return !fail;\n}\n\n// optimize access\nHeap.prototype = Heap.prototype;\n\n\n//# sourceURL=webpack://polygon-clipping/./node_modules/qheap/lib/qheap.js?");
|
131
|
+
|
132
|
+
/***/ }),
|
133
|
+
|
134
|
+
/***/ "./node_modules/splaytree/index.js":
|
135
|
+
/*!*****************************************!*\
|
136
|
+
!*** ./node_modules/splaytree/index.js ***!
|
137
|
+
\*****************************************/
|
138
|
+
/*! exports provided: default */
|
139
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
140
|
+
|
141
|
+
"use strict";
|
142
|
+
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Tree; });\n/* follows \"An implementation of top-down splaying\"\n * by D. Sleator <sleator@cs.cmu.edu> March 1992\n */\n\n/**\n * @typedef {*} Key\n */\n\n\n/**\n * @typedef {*} Value\n */\n\n\n/**\n * @typedef {function(node:Node):void} Visitor\n */\n\n\n/**\n * @typedef {function(a:Key, b:Key):number} Comparator\n */\n\n\n/**\n * @param {function(node:Node):string} NodePrinter\n */\n\n\n/**\n * @typedef {Object} Node\n * @property {Key} Key\n * @property {Value=} data\n * @property {Node} left\n * @property {Node} right\n */\n\nclass Node {\n\n constructor (key, data) {\n this.key = key;\n this.data = data;\n this.left = null;\n this.right = null;\n }\n}\n\nfunction DEFAULT_COMPARE (a, b) { return a > b ? 1 : a < b ? -1 : 0; }\n\n\n/**\n * Simple top down splay, not requiring i to be in the tree t.\n * @param {Key} i\n * @param {Node?} t\n * @param {Comparator} comparator\n */\nfunction splay (i, t, comparator) {\n if (t === null) return t;\n let l, r, y;\n const N = new Node();\n l = r = N;\n\n while (true) {\n const cmp = comparator(i, t.key);\n //if (i < t.key) {\n if (cmp < 0) {\n if (t.left === null) break;\n //if (i < t.left.key) {\n if (comparator(i, t.left.key) < 0) {\n y = t.left; /* rotate right */\n t.left = y.right;\n y.right = t;\n t = y;\n if (t.left === null) break;\n }\n r.left = t; /* link right */\n r = t;\n t = t.left;\n //} else if (i > t.key) {\n } else if (cmp > 0) {\n if (t.right === null) break;\n //if (i > t.right.key) {\n if (comparator(i, t.right.key) > 0) {\n y = t.right; /* rotate left */\n t.right = y.left;\n y.left = t;\n t = y;\n if (t.right === null) break;\n }\n l.right = t; /* link left */\n l = t;\n t = t.right;\n } else {\n break;\n }\n }\n /* assemble */\n l.right = t.left;\n r.left = t.right;\n t.left = N.right;\n t.right = N.left;\n return t;\n}\n\n\n/**\n * @param {Key} i\n * @param {Value} data\n * @param {Comparator} comparator\n * @param {Tree} tree\n * @return {Node} root\n */\nfunction insert (i, data, t, comparator, tree) {\n const node = new Node(i, data);\n\n tree._size++;\n\n if (t === null) {\n node.left = node.right = null;\n return node;\n }\n\n t = splay(i, t, comparator);\n const cmp = comparator(i, t.key);\n if (cmp < 0) {\n node.left = t.left;\n node.right = t;\n t.left = null;\n } else if (cmp >= 0) {\n node.right = t.right;\n node.left = t;\n t.right = null;\n }\n return node;\n}\n\n\n/**\n * Insert i into the tree t, unless it's already there.\n * @param {Key} i\n * @param {Value} data\n * @param {Comparator} comparator\n * @param {Tree} tree\n * @return {Node} root\n */\nfunction add (i, data, t, comparator, tree) {\n const node = new Node(i, data);\n\n if (t === null) {\n node.left = node.right = null;\n tree._size++;\n return node;\n }\n\n t = splay(i, t, comparator);\n const cmp = comparator(i, t.key);\n if (cmp === 0) return t;\n else {\n if (cmp < 0) {\n node.left = t.left;\n node.right = t;\n t.left = null;\n } else if (cmp > 0) {\n node.right = t.right;\n node.left = t;\n t.right = null;\n }\n tree._size++;\n return node;\n }\n}\n\n\n/**\n * Deletes i from the tree if it's there\n * @param {Key} i\n * @param {Tree} tree\n * @param {Comparator} comparator\n * @param {Tree} tree\n * @return {Node} new root\n */\nfunction remove (i, t, comparator, tree) {\n let x;\n if (t === null) return null;\n t = splay(i, t, comparator);\n if (i === t.key) { /* found it */\n if (t.left === null) {\n x = t.right;\n } else {\n x = splay(i, t.left, comparator);\n x.right = t.right;\n }\n tree._size--;\n return x;\n }\n return t; /* It wasn't there */\n}\n\n\nfunction split (key, v, comparator) {\n let left, right;\n if (v === null) {\n left = right = null;\n } else {\n v = splay(key, v, comparator);\n\n const cmp = comparator(v.key, key);\n if (cmp === 0) {\n left = v.left;\n right = v.right;\n } else if (cmp < 0) {\n right = v.right;\n v.right = null;\n left = v;\n } else {\n left = v.left;\n v.left = null;\n right = v;\n }\n }\n return { left, right };\n}\n\n\nfunction merge (left, right, comparator) {\n if (right === null) return left;\n if (left === null) return right;\n\n right = splay(left.key, right, comparator);\n right.left = left;\n return right;\n}\n\n\n/**\n * Prints level of the tree\n * @param {Node} root\n * @param {String} prefix\n * @param {Boolean} isTail\n * @param {Array<string>} out\n * @param {Function(node:Node):String} printNode\n */\nfunction printRow (root, prefix, isTail, out, printNode) {\n if (root) {\n out(`${ prefix }${ isTail ? '└── ' : '├── ' }${ printNode(root) }\\n`);\n const indent = prefix + (isTail ? ' ' : '│ ');\n if (root.left) printRow(root.left, indent, false, out, printNode);\n if (root.right) printRow(root.right, indent, true, out, printNode);\n }\n}\n\n\nclass Tree {\n\n constructor (comparator = DEFAULT_COMPARE) {\n this._comparator = comparator;\n this._root = null;\n this._size = 0;\n }\n\n\n /**\n * Inserts a key, allows duplicates\n * @param {Key} key\n * @param {Value=} data\n * @return {Node|null}\n */\n insert (key, data) {\n return this._root = insert(key, data, this._root, this._comparator, this);\n }\n\n\n /**\n * Adds a key, if it is not present in the tree\n * @param {Key} key\n * @param {Value=} data\n * @return {Node|null}\n */\n add (key, data) {\n return this._root = add(key, data, this._root, this._comparator, this);\n }\n\n\n /**\n * @param {Key} key\n * @return {Node|null}\n */\n remove (key) {\n this._root = remove(key, this._root, this._comparator, this);\n }\n\n\n /**\n * Removes and returns the node with smallest key\n * @return {?Node}\n */\n pop () {\n let node = this._root;\n if (node) {\n while (node.left) node = node.left;\n this._root = splay(node.key, this._root, this._comparator);\n this._root = remove(node.key, this._root, this._comparator, this);\n return { key: node.key, data: node.data };\n }\n return null;\n }\n\n\n /**\n * @param {Key} key\n * @return {Node|null}\n */\n findStatic (key) {\n let current = this._root;\n const compare = this._comparator;\n while (current) {\n const cmp = compare(key, current.key);\n if (cmp === 0) return current;\n else if (cmp < 0) current = current.left;\n else current = current.right;\n }\n return null;\n }\n\n\n /**\n * @param {Key} key\n * @return {Node|null}\n */\n find (key) {\n if (this._root) {\n this._root = splay(key, this._root, this._comparator);\n if (this._comparator(key, this._root.key) !== 0) return null;\n }\n return this._root;\n }\n\n\n /**\n * @param {Key} key\n * @return {Boolean}\n */\n contains (key) {\n let current = this._root;\n const compare = this._comparator;\n while (current) {\n const cmp = compare(key, current.key);\n if (cmp === 0) return true;\n else if (cmp < 0) current = current.left;\n else current = current.right;\n }\n return false;\n }\n\n\n /**\n * @param {Visitor} visitor\n * @param {*=} ctx\n * @return {SplayTree}\n */\n forEach (visitor, ctx) {\n let current = this._root;\n const Q = []; /* Initialize stack s */\n let done = false;\n\n while (!done) {\n if (current !== null) {\n Q.push(current);\n current = current.left;\n } else {\n if (Q.length !== 0) {\n current = Q.pop();\n visitor.call(ctx, current);\n\n current = current.right;\n } else done = true;\n }\n }\n return this;\n }\n\n\n /**\n * Walk key range from `low` to `high`. Stops if `fn` returns a value.\n * @param {Key} low\n * @param {Key} high\n * @param {Function} fn\n * @param {*?} ctx\n * @return {SplayTree}\n */\n range (low, high, fn, ctx) {\n const Q = [];\n const compare = this._comparator;\n let node = this._root, cmp;\n\n while (Q.length !== 0 || node) {\n if (node) {\n Q.push(node);\n node = node.left;\n } else {\n node = Q.pop();\n cmp = compare(node.key, high);\n if (cmp > 0) {\n break;\n } else if (compare(node.key, low) >= 0) {\n if (fn.call(ctx, node)) return this; // stop if smth is returned\n }\n node = node.right;\n }\n }\n return this;\n }\n\n\n /**\n * Returns array of keys\n * @return {Array<Key>}\n */\n keys () {\n const keys = [];\n this.forEach(({ key }) => keys.push(key));\n return keys;\n }\n\n\n /**\n * Returns array of all the data in the nodes\n * @return {Array<Value>}\n */\n values () {\n const values = [];\n this.forEach(({ data }) => values.push(data));\n return values;\n }\n\n\n /**\n * @return {Key|null}\n */\n min() {\n if (this._root) return this.minNode(this._root).key;\n return null;\n }\n\n\n /**\n * @return {Key|null}\n */\n max() {\n if (this._root) return this.maxNode(this._root).key;\n return null;\n }\n\n\n /**\n * @return {Node|null}\n */\n minNode(t = this._root) {\n if (t) while (t.left) t = t.left;\n return t;\n }\n\n\n /**\n * @return {Node|null}\n */\n maxNode(t = this._root) {\n if (t) while (t.right) t = t.right;\n return t;\n }\n\n\n /**\n * Returns node at given index\n * @param {number} index\n * @return {?Node}\n */\n at (index) {\n let current = this._root, done = false, i = 0;\n const Q = [];\n\n while (!done) {\n if (current) {\n Q.push(current);\n current = current.left;\n } else {\n if (Q.length > 0) {\n current = Q.pop();\n if (i === index) return current;\n i++;\n current = current.right;\n } else done = true;\n }\n }\n return null;\n }\n\n\n /**\n * @param {Node} d\n * @return {Node|null}\n */\n next (d) {\n let root = this._root;\n let successor = null;\n\n if (d.right) {\n successor = d.right;\n while (successor.left) successor = successor.left;\n return successor;\n }\n\n const comparator = this._comparator;\n while (root) {\n const cmp = comparator(d.key, root.key);\n if (cmp === 0) break;\n else if (cmp < 0) {\n successor = root;\n root = root.left;\n } else root = root.right;\n }\n\n return successor;\n }\n\n\n /**\n * @param {Node} d\n * @return {Node|null}\n */\n prev (d) {\n let root = this._root;\n let predecessor = null;\n\n if (d.left !== null) {\n predecessor = d.left;\n while (predecessor.right) predecessor = predecessor.right;\n return predecessor;\n }\n\n const comparator = this._comparator;\n while (root) {\n const cmp = comparator(d.key, root.key);\n if (cmp === 0) break;\n else if (cmp < 0) root = root.left;\n else {\n predecessor = root;\n root = root.right;\n }\n }\n return predecessor;\n }\n\n\n /**\n * @return {SplayTree}\n */\n clear() {\n this._root = null;\n this._size = 0;\n return this;\n }\n\n\n /**\n * @return {NodeList}\n */\n toList() {\n return toList(this._root);\n }\n\n\n /**\n * Bulk-load items. Both array have to be same size\n * @param {Array<Key>} keys\n * @param {Array<Value>} [values]\n * @param {Boolean} [presort=false] Pre-sort keys and values, using\n * tree's comparator. Sorting is done\n * in-place\n * @return {AVLTree}\n */\n load (keys = [], values = [], presort = false) {\n let size = keys.length;\n const comparator = this._comparator;\n\n // sort if needed\n if (presort) sort(keys, values, 0, size - 1, comparator);\n\n if (this._root === null) { // empty tree\n this._root = loadRecursive(this._root, keys, values, 0, size);\n this._size = size;\n } else { // that re-builds the whole tree from two in-order traversals\n const mergedList = mergeLists(this.toList(), createList(keys, values), comparator);\n size = this._size + size;\n this._root = sortedListToBST({ head: mergedList }, 0, size);\n }\n return this;\n }\n\n\n /**\n * @return {Boolean}\n */\n isEmpty() { return this._root === null; }\n\n get size () { return this._size; }\n\n\n /**\n * @param {NodePrinter=} printNode\n * @return {String}\n */\n toString (printNode = (n) => n.key) {\n const out = [];\n printRow(this._root, '', true, (v) => out.push(v), printNode);\n return out.join('');\n }\n\n\n update (key, newKey, newData) {\n const comparator = this._comparator;\n let { left, right } = split(key, this._root, comparator);\n this._size--;\n if (comparator(key, newKey) < 0) {\n right = insert(newKey, newData, right, comparator, this);\n } else {\n left = insert(newKey, newData, left, comparator, this);\n }\n this._root = merge(left, right, comparator);\n }\n\n\n split(key) {\n return split(key, this._root, this._comparator);\n }\n}\n\n\nfunction loadRecursive (parent, keys, values, start, end) {\n const size = end - start;\n if (size > 0) {\n const middle = start + Math.floor(size / 2);\n const key = keys[middle];\n const data = values[middle];\n const node = { key, data, parent };\n node.left = loadRecursive(node, keys, values, start, middle);\n node.right = loadRecursive(node, keys, values, middle + 1, end);\n return node;\n }\n return null;\n}\n\n\nfunction createList(keys, values) {\n const head = { next: null };\n let p = head;\n for (let i = 0; i < keys.length; i++) {\n p = p.next = { key: keys[i], data: values[i] };\n }\n p.next = null;\n return head.next;\n}\n\n\nfunction toList (root) {\n var current = root;\n var Q = [], done = false;\n\n const head = { next: null };\n let p = head;\n\n while (!done) {\n if (current) {\n Q.push(current);\n current = current.left;\n } else {\n if (Q.length > 0) {\n current = p = p.next = Q.pop();\n current = current.right;\n } else done = true;\n }\n }\n p.next = null; // that'll work even if the tree was empty\n return head.next;\n}\n\n\nfunction sortedListToBST(list, start, end) {\n const size = end - start;\n if (size > 0) {\n const middle = start + Math.floor(size / 2);\n const left = sortedListToBST(list, start, middle);\n\n const root = list.head;\n root.left = left;\n\n list.head = list.head.next;\n\n root.right = sortedListToBST(list, middle + 1, end);\n return root;\n }\n return null;\n}\n\n\nfunction mergeLists (l1, l2, compare = (a, b) => a - b) {\n const head = {}; // dummy\n let p = head;\n\n let p1 = l1;\n let p2 = l2;\n\n while (p1 !== null && p2 !== null) {\n if (compare(p1.key, p2.key) < 0) {\n p.next = p1;\n p1 = p1.next;\n } else {\n p.next = p2;\n p2 = p2.next;\n }\n p = p.next;\n }\n\n if (p1 !== null) p.next = p1;\n else if (p2 !== null) p.next = p2;\n\n return head.next;\n}\n\n\nfunction sort(keys, values, left, right, compare) {\n if (left >= right) return;\n\n const pivot = keys[(left + right) >> 1];\n let i = left - 1;\n let j = right + 1;\n\n while (true) {\n do i++; while (compare(keys[i], pivot) < 0);\n do j--; while (compare(keys[j], pivot) > 0);\n if (i >= j) break;\n\n let tmp = keys[i];\n keys[i] = keys[j];\n keys[j] = tmp;\n\n tmp = values[i];\n values[i] = values[j];\n values[j] = tmp;\n }\n\n sort(keys, values, left, j, compare);\n sort(keys, values, j + 1, right, compare);\n}\n\n\n//# sourceURL=webpack://polygon-clipping/./node_modules/splaytree/index.js?");
|
143
|
+
|
144
|
+
/***/ }),
|
145
|
+
|
146
|
+
/***/ "./src/bbox.js":
|
147
|
+
/*!*********************!*\
|
148
|
+
!*** ./src/bbox.js ***!
|
149
|
+
\*********************/
|
150
|
+
/*! no static exports found */
|
151
|
+
/***/ (function(module, exports, __webpack_require__) {
|
152
|
+
|
153
|
+
"use strict";
|
154
|
+
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.getUniqueCorners = exports.getBboxOverlap = exports.doBboxesOverlap = exports.isInBbox = undefined;\n\nvar _flp = __webpack_require__(/*! ./flp */ \"./src/flp.js\");\n\n/**\n * A bounding box has the format:\n *\n * { ll: { x: xmin, y: ymin }, ur: { x: xmax, y: ymax } }\n *\n */\n\nvar isInBbox = exports.isInBbox = function isInBbox(bbox, point) {\n var xmin = bbox.ll.x;\n var ymin = bbox.ll.y;\n var xmax = bbox.ur.x;\n var ymax = bbox.ur.y;\n var xpt = point.x;\n var ypt = point.y;\n return (0, _flp.cmp)(xmin, xpt) <= 0 && (0, _flp.cmp)(xpt, xmax) <= 0 && (0, _flp.cmp)(ymin, ypt) <= 0 && (0, _flp.cmp)(ypt, ymax) <= 0;\n};\n\nvar doBboxesOverlap = exports.doBboxesOverlap = function doBboxesOverlap(b1, b2) {\n return !((0, _flp.cmp)(b2.ur.x, b1.ll.x) < 0 || (0, _flp.cmp)(b1.ur.x, b2.ll.x) < 0 || (0, _flp.cmp)(b2.ur.y, b1.ll.y) < 0 || (0, _flp.cmp)(b1.ur.y, b2.ll.y) < 0);\n};\n\n/* Returns either null, or a bbox (aka an ordered pair of points)\n * If there is only one point of overlap, a bbox with identical points\n * will be returned */\nvar getBboxOverlap = exports.getBboxOverlap = function getBboxOverlap(b1, b2) {\n if (!doBboxesOverlap(b1, b2)) return null;\n\n // find the middle two X values\n var lowerX = b1.ll.x < b2.ll.x ? b2.ll.x : b1.ll.x;\n var upperX = b1.ur.x < b2.ur.x ? b1.ur.x : b2.ur.x;\n\n // find the middle two Y values\n var lowerY = b1.ll.y < b2.ll.y ? b2.ll.y : b1.ll.y;\n var upperY = b1.ur.y < b2.ur.y ? b1.ur.y : b2.ur.y;\n\n // put those middle values together to get the overlap\n return { ll: { x: lowerX, y: lowerY }, ur: { x: upperX, y: upperY } };\n};\n\n/* Returns a list of unique corners.\n * Will contain one, two or four points */\nvar getUniqueCorners = exports.getUniqueCorners = function getUniqueCorners(bbox) {\n var xmin = bbox.ll.x;\n var ymin = bbox.ll.y;\n var xmax = bbox.ur.x;\n var ymax = bbox.ur.y;\n var xEq = (0, _flp.cmp)(xmin, xmax) === 0;\n var yEq = (0, _flp.cmp)(ymin, ymax) === 0;\n if (xEq && yEq) return [{ x: xmin, y: ymin }];\n if (xEq) return [{ x: xmin, y: ymin }, { x: xmin, y: ymax }];\n if (yEq) return [{ x: xmin, y: ymin }, { x: xmax, y: ymin }];\n return [{ x: xmin, y: ymin }, { x: xmin, y: ymax }, { x: xmax, y: ymin }, { x: xmax, y: ymax }];\n};\n\n//# sourceURL=webpack://polygon-clipping/./src/bbox.js?");
|
155
|
+
|
156
|
+
/***/ }),
|
157
|
+
|
158
|
+
/***/ "./src/clean-input.js":
|
159
|
+
/*!****************************!*\
|
160
|
+
!*** ./src/clean-input.js ***!
|
161
|
+
\****************************/
|
162
|
+
/*! no static exports found */
|
163
|
+
/***/ (function(module, exports, __webpack_require__) {
|
164
|
+
|
165
|
+
"use strict";
|
166
|
+
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.errorOnSelfIntersectingRings = exports.cleanRing = exports.cleanMultiPoly = exports.forceMultiPoly = exports.pointsAsObjects = undefined;\n\nvar _flp = __webpack_require__(/*! ./flp */ \"./src/flp.js\");\n\nvar _vector = __webpack_require__(/*! ./vector */ \"./src/vector.js\");\n\n/* Given input geometry as a standard array-of-arrays geojson-style\n * geometry, return one that uses objects as points, for better perf */\nvar pointsAsObjects = exports.pointsAsObjects = function pointsAsObjects(geom) {\n // we can handle well-formed multipolys and polys\n var output = [];\n if (!Array.isArray(geom)) {\n throw new Error('Input is not a Polygon or MultiPolygon');\n }\n for (var i = 0, iMax = geom.length; i < iMax; i++) {\n if (!Array.isArray(geom[i])) {\n throw new Error('Input is not a Polygon or MultiPolygon');\n }\n output.push([]);\n for (var j = 0, jMax = geom[i].length; j < jMax; j++) {\n if (!Array.isArray(geom[i][j])) {\n throw new Error('Input is not a Polygon or MultiPolygon');\n }\n if (geom[i][j].length === 2) {\n output[i].push({ x: geom[i][j][0], y: geom[i][j][1] });\n continue;\n }\n output[i].push([]);\n for (var k = 0, kMax = geom[i][j].length; k < kMax; k++) {\n if (!Array.isArray(geom[i][j][k]) || geom[i][j][k].length !== 2) {\n throw new Error('Input is not a Polygon or MultiPolygon');\n }\n output[i][j].push({ x: geom[i][j][k][0], y: geom[i][j][k][1] });\n }\n }\n }\n return output;\n};\n\n/* WARN: input modified directly */\nvar forceMultiPoly = exports.forceMultiPoly = function forceMultiPoly(geom) {\n if (Array.isArray(geom)) {\n if (geom.length === 0) return; // allow empty multipolys\n\n if (Array.isArray(geom[0])) {\n if (Array.isArray(geom[0][0])) {\n if (typeof geom[0][0][0].x === 'number' && typeof geom[0][0][0].y === 'number') {\n // multipolygon\n return;\n }\n }\n if (typeof geom[0][0].x === 'number' && typeof geom[0][0].y === 'number') {\n // polygon\n geom.unshift(geom.splice(0));\n return;\n }\n }\n }\n throw new Error('Unrecognized input - not a polygon nor multipolygon');\n};\n\n/* WARN: input modified directly */\nvar cleanMultiPoly = exports.cleanMultiPoly = function cleanMultiPoly(multipoly) {\n var i = 0;\n while (i < multipoly.length) {\n var poly = multipoly[i];\n if (poly.length === 0) {\n multipoly.splice(i, 1);\n continue;\n }\n\n var exteriorRing = poly[0];\n cleanRing(exteriorRing);\n // poly is dropped if exteriorRing is degenerate\n if (exteriorRing.length === 0) {\n multipoly.splice(i, 1);\n continue;\n }\n\n var j = 1;\n while (j < poly.length) {\n var interiorRing = poly[j];\n cleanRing(interiorRing);\n if (interiorRing.length === 0) poly.splice(j, 1);else j++;\n }\n\n i++;\n }\n};\n\n/* Clean ring:\n * - remove duplicate points\n * - remove colinear points\n * - remove rings with no area (less than 3 distinct points)\n * - close rings (last point should equal first)\n *\n * WARN: input modified directly */\nvar cleanRing = exports.cleanRing = function cleanRing(ring) {\n if (ring.length === 0) return;\n if ((0, _flp.cmpPoints)(ring[0], ring[ring.length - 1]) !== 0) {\n ring.push({ x: ring[0].x, y: ring[0].y }); // copy by value\n }\n\n var isPointUncessary = function isPointUncessary(prevPt, pt, nextPt) {\n return (0, _flp.cmpPoints)(prevPt, pt) === 0 || (0, _flp.cmpPoints)(pt, nextPt) === 0 || (0, _vector.compareVectorAngles)(pt, prevPt, nextPt) === 0;\n };\n\n var i = 1;\n while (i < ring.length - 1) {\n if (isPointUncessary(ring[i - 1], ring[i], ring[i + 1])) ring.splice(i, 1);else i++;\n }\n\n // check the first/last point as well\n while (ring.length > 2) {\n if (!isPointUncessary(ring[ring.length - 2], ring[0], ring[1])) break;\n ring.splice(0, 1);\n ring.splice(ring.length - 1, 1);\n ring.push(ring[0]);\n }\n\n // if our ring has less than 3 distinct points now (so is degenerate)\n // shrink it down to the empty array to communicate to our caller to\n // drop it\n while (ring.length < 4 && ring.length > 0) {\n ring.pop();\n }\n};\n\n/* Scan the already-linked events of the segments for any\n * self-intersecting input rings (which are not supported) */\nvar errorOnSelfIntersectingRings = exports.errorOnSelfIntersectingRings = function errorOnSelfIntersectingRings(segments) {\n var _loop = function _loop(i, iMax) {\n var seg = segments[i];\n\n var evt = seg.flowIntoSE;\n\n if (evt.linkedEvents.length > 2) {\n var evtsThisRing = evt.linkedEvents.filter(function (other) {\n return other.segment.ringIn === seg.ringIn;\n });\n if (evtsThisRing.length > 2) {\n evtsThisRing.sort(evt.getLeftmostComparator(evt.otherSE));\n var leftMostEvt = evtsThisRing[1]; // skip ourself\n var rightMostEvt = evtsThisRing[evtsThisRing.length - 1];\n\n // both the segment on our immediate left and right will flow\n // 'out' in intersection point was a touch and not a crossing\n if (leftMostEvt.segment.flowIntoSE === leftMostEvt || rightMostEvt.segment.flowIntoSE === rightMostEvt) {\n throw new Error('Self-intersecting, crossing input ring found at ' + ('[' + evt.point.x + ', ' + evt.point.y + ']'));\n }\n }\n }\n };\n\n for (var i = 0, iMax = segments.length; i < iMax; i++) {\n _loop(i, iMax);\n }\n};\n\n//# sourceURL=webpack://polygon-clipping/./src/clean-input.js?");
|
167
|
+
|
168
|
+
/***/ }),
|
169
|
+
|
170
|
+
/***/ "./src/flp.js":
|
171
|
+
/*!********************!*\
|
172
|
+
!*** ./src/flp.js ***!
|
173
|
+
\********************/
|
174
|
+
/*! no static exports found */
|
175
|
+
/***/ (function(module, exports, __webpack_require__) {
|
176
|
+
|
177
|
+
"use strict";
|
178
|
+
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n/* Javascript doesn't do integer math. Everything is\n * floating point with percision Number.EPSILON.\n *\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON\n */\n\n// IE Polyfill\nif (Number.EPSILON === undefined) Number.EPSILON = Math.pow(2, -52);\n\nvar EPSILON_SQ = Number.EPSILON * Number.EPSILON;\n\n/* FLP comparator */\nvar cmp = exports.cmp = function cmp(a, b) {\n // check if they're both 0\n if (-Number.EPSILON < a && a < Number.EPSILON) {\n if (-Number.EPSILON < b && b < Number.EPSILON) {\n return 0;\n }\n }\n\n // check if they're flp equal\n if ((a - b) * (a - b) < EPSILON_SQ * a * b) {\n return 0;\n }\n\n // normal comparison\n return a < b ? -1 : 1;\n};\n\n/* FLP point comparator, favors point encountered first by sweep line */\nvar cmpPoints = exports.cmpPoints = function cmpPoints(aPt, bPt) {\n // fist compare X, then compare Y\n\n var a = aPt.x;\n var b = bPt.x;\n\n // inlined version of cmp() for performance boost\n if (a <= -Number.EPSILON || Number.EPSILON <= a || b <= -Number.EPSILON || Number.EPSILON <= b) {\n var diff = a - b;\n if (diff * diff >= EPSILON_SQ * a * b) {\n return a < b ? -1 : 1;\n }\n }\n\n a = aPt.y;\n b = bPt.y;\n\n // inlined version of cmp() for performance boost\n if (a <= -Number.EPSILON || Number.EPSILON <= a || b <= -Number.EPSILON || Number.EPSILON <= b) {\n var _diff = a - b;\n if (_diff * _diff >= EPSILON_SQ * a * b) {\n return a < b ? -1 : 1;\n }\n }\n\n // they're the same\n return 0;\n};\n\n//# sourceURL=webpack://polygon-clipping/./src/flp.js?");
|
179
|
+
|
180
|
+
/***/ }),
|
181
|
+
|
182
|
+
/***/ "./src/geom-in.js":
|
183
|
+
/*!************************!*\
|
184
|
+
!*** ./src/geom-in.js ***!
|
185
|
+
\************************/
|
186
|
+
/*! no static exports found */
|
187
|
+
/***/ (function(module, exports, __webpack_require__) {
|
188
|
+
|
189
|
+
"use strict";
|
190
|
+
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.MultiPoly = exports.Poly = exports.Ring = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _segment = __webpack_require__(/*! ./segment */ \"./src/segment.js\");\n\nvar _segment2 = _interopRequireDefault(_segment);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n// Give rings unique ID's to get consistent sorting of segments\n// and sweep events when all else is identical\nvar ringId = 0;\n\nvar Ring = exports.Ring = function () {\n function Ring(geomRing, poly) {\n _classCallCheck(this, Ring);\n\n this.id = ringId++;\n this.poly = poly;\n this.segments = [];\n\n for (var i = 1, iMax = geomRing.length; i < iMax; i++) {\n this.segments.push(new _segment2.default(geomRing[i - 1], geomRing[i], this));\n }\n }\n\n _createClass(Ring, [{\n key: 'getSweepEvents',\n value: function getSweepEvents() {\n var sweepEvents = [];\n for (var i = 0, iMax = this.segments.length; i < iMax; i++) {\n var segment = this.segments[i];\n sweepEvents.push(segment.leftSE);\n sweepEvents.push(segment.rightSE);\n }\n return sweepEvents;\n }\n }, {\n key: 'isValid',\n\n\n /* Given a segment on this rings with these relationships to other rings,\n * is it a valid segment of the ring's poly? */\n value: function isValid(ringsSameSLER, ringsDiffSLER, ringsInsideOf) {\n var exterior = this.poly.exteriorRing;\n var interiors = this.poly.interiorRings;\n\n if (this === exterior) {\n // exterior segments inside or interior, nope\n for (var i = 0, iMax = ringsInsideOf.length; i < iMax; i++) {\n if (interiors.includes(ringsInsideOf[i])) return false;\n }\n\n // overlap with an interior of same SWL orientatio, nope\n for (var _i = 0, _iMax = ringsSameSLER.length; _i < _iMax; _i++) {\n if (interiors.includes(ringsSameSLER[_i])) return false;\n }\n\n return true;\n }\n\n // interior rings that aren't inside the exterior nor\n // overlapping with different SWE\n if (!ringsInsideOf.includes(exterior)) {\n if (!ringsDiffSLER.includes(exterior)) return false;\n }\n\n // interior rings inside another interior, nope\n for (var _i2 = 0, _iMax2 = ringsInsideOf.length; _i2 < _iMax2; _i2++) {\n if (interiors.includes(ringsInsideOf[_i2])) return false;\n }\n\n // overlapping interiors with different sweep line orientation, nope\n for (var _i3 = 0, _iMax3 = ringsDiffSLER.length; _i3 < _iMax3; _i3++) {\n if (interiors.includes(ringsDiffSLER[_i3])) return false;\n }\n\n return true;\n }\n }, {\n key: 'isExterior',\n get: function get() {\n return this.poly.exteriorRing === this;\n }\n }, {\n key: 'isInterior',\n get: function get() {\n return this.poly.exteriorRing !== this;\n }\n }]);\n\n return Ring;\n}();\n\nvar Poly = exports.Poly = function () {\n function Poly(geomPoly, multiPoly) {\n _classCallCheck(this, Poly);\n\n this.exteriorRing = new Ring(geomPoly[0], this);\n this.interiorRings = [];\n for (var i = 1, iMax = geomPoly.length; i < iMax; i++) {\n this.interiorRings.push(new Ring(geomPoly[i], this));\n }\n this.multiPoly = multiPoly;\n }\n\n _createClass(Poly, [{\n key: 'getSweepEvents',\n value: function getSweepEvents() {\n var sweepEvents = this.exteriorRing.getSweepEvents();\n for (var i = 0, iMax = this.interiorRings.length; i < iMax; i++) {\n var ringSweepEvents = this.interiorRings[i].getSweepEvents();\n for (var j = 0, jMax = ringSweepEvents.length; j < jMax; j++) {\n sweepEvents.push(ringSweepEvents[j]);\n }\n }\n return sweepEvents;\n }\n\n /* Given a segment with these rings, is that segment inside this polygon? */\n\n }, {\n key: 'isInside',\n value: function isInside(ringsOnEdgeOf, ringsInsideOf) {\n // if we're on an edge, we can't be inside\n for (var i = 0, iMax = ringsOnEdgeOf.length; i < iMax; i++) {\n if (ringsOnEdgeOf[i].poly === this) return false;\n }\n\n // we need to be inside the exterior, and nothing else\n var isInsideExterior = false;\n for (var _i4 = 0, _iMax4 = ringsInsideOf.length; _i4 < _iMax4; _i4++) {\n var ring = ringsInsideOf[_i4];\n if (ring.poly !== this) continue;\n if (ring.isInterior) return false;\n isInsideExterior = true;\n }\n return isInsideExterior;\n }\n }]);\n\n return Poly;\n}();\n\nvar MultiPoly = exports.MultiPoly = function () {\n function MultiPoly(geomMultiPoly) {\n _classCallCheck(this, MultiPoly);\n\n this.polys = [];\n for (var i = 0, iMax = geomMultiPoly.length; i < iMax; i++) {\n this.polys.push(new Poly(geomMultiPoly[i], this));\n }\n this.isSubject = false;\n }\n\n _createClass(MultiPoly, [{\n key: 'markAsSubject',\n value: function markAsSubject() {\n this.isSubject = true;\n }\n }, {\n key: 'getSweepEvents',\n value: function getSweepEvents() {\n var sweepEvents = [];\n for (var i = 0, iMax = this.polys.length; i < iMax; i++) {\n var polySweepEvents = this.polys[i].getSweepEvents();\n for (var j = 0, jMax = polySweepEvents.length; j < jMax; j++) {\n sweepEvents.push(polySweepEvents[j]);\n }\n }\n return sweepEvents;\n }\n }]);\n\n return MultiPoly;\n}();\n\n//# sourceURL=webpack://polygon-clipping/./src/geom-in.js?");
|
191
|
+
|
192
|
+
/***/ }),
|
193
|
+
|
194
|
+
/***/ "./src/geom-out.js":
|
195
|
+
/*!*************************!*\
|
196
|
+
!*** ./src/geom-out.js ***!
|
197
|
+
\*************************/
|
198
|
+
/*! no static exports found */
|
199
|
+
/***/ (function(module, exports, __webpack_require__) {
|
200
|
+
|
201
|
+
"use strict";
|
202
|
+
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.MultiPoly = exports.Poly = exports.Ring = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _vector = __webpack_require__(/*! ./vector */ \"./src/vector.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar Ring = exports.Ring = function () {\n _createClass(Ring, null, [{\n key: 'factory',\n\n /* Given the segments from the sweep line pass, compute & return a series\n * of closed rings from all the segments marked to be part of the result */\n value: function factory(allSegments) {\n var ringsOut = [];\n\n for (var i = 0, iMax = allSegments.length; i < iMax; i++) {\n var segment = allSegments[i];\n if (!segment.isInResult || segment.ringOut) continue;\n\n var prevEvent = null;\n var event = segment.leftSE;\n var nextEvent = segment.rightSE;\n var events = [event];\n\n var startingLE = event.linkedEvents;\n var intersectionLEs = [];\n\n /* Walk the chain of linked events to form a closed ring */\n while (true) {\n prevEvent = event;\n event = nextEvent;\n events.push(event);\n\n /* Is the ring complete? */\n if (event.linkedEvents === startingLE) break;\n\n while (true) {\n var availableLEs = event.getAvailableLinkedEvents();\n\n /* Did we hit a dead end? This shouldn't happen. Indicates some earlier\n * part of the algorithm malfunctioned... please file a bug report. */\n if (availableLEs.length === 0) {\n var firstPt = events[0].point;\n var lastPt = events[events.length - 1].point;\n throw new Error('Unable to complete output ring starting at [' + firstPt.x + ',' + (' ' + firstPt.y + ']. Last matching segment found ends at ') + (' [' + lastPt.x + ', ' + lastPt.y + '].'));\n }\n\n /* Only one way to go, so cotinue on the path */\n if (availableLEs.length === 1) {\n nextEvent = availableLEs[0].otherSE;\n break;\n }\n\n /* We must have an intersection. Check for a completed loop */\n var indexLE = null;\n for (var j = 0, jMax = intersectionLEs.length; j < jMax; j++) {\n if (intersectionLEs[j].linkedEvents === event.linkedEvents) {\n indexLE = j;\n break;\n }\n }\n /* Found a completed loop. Cut that off and make a ring */\n if (indexLE !== null) {\n var intersectionLE = intersectionLEs.splice(indexLE)[0];\n var ringEvents = events.splice(intersectionLE.index);\n ringEvents.unshift(ringEvents[0].otherSE);\n ringsOut.push(new Ring(ringEvents.reverse()));\n continue;\n }\n /* register the intersection */\n intersectionLEs.push({\n index: events.length,\n linkedEvents: event.linkedEvents\n });\n /* Choose the left-most option to continue the walk */\n var comparator = event.getLeftmostComparator(prevEvent);\n nextEvent = availableLEs.sort(comparator)[0].otherSE;\n break;\n }\n }\n\n ringsOut.push(new Ring(events));\n }\n return ringsOut;\n }\n }]);\n\n function Ring(events) {\n _classCallCheck(this, Ring);\n\n this.events = events;\n for (var i = 0, iMax = events.length; i < iMax; i++) {\n events[i].segment.registerRingOut(this);\n }\n this.poly = null;\n this._clearCache();\n }\n\n _createClass(Ring, [{\n key: 'registerPoly',\n value: function registerPoly(poly) {\n this.poly = poly;\n }\n }, {\n key: 'getGeom',\n value: function getGeom() {\n // Remove superfluous points (ie extra points along a straight line),\n var points = [[this.events[0].point.x, this.events[0].point.y]];\n for (var i = 1, iMax = this.events.length - 1; i < iMax; i++) {\n var _prevPt = this.events[i - 1].point;\n var _pt = this.events[i].point;\n var _nextPt = this.events[i + 1].point;\n if ((0, _vector.compareVectorAngles)(_pt, _prevPt, _nextPt) === 0) continue;\n points.push([_pt.x, _pt.y]);\n }\n\n // check if the starting point is necessary\n var prevPt = this.events[this.events.length - 2].point;\n var pt = this.events[0].point;\n var nextPt = this.events[1].point;\n if ((0, _vector.compareVectorAngles)(pt, prevPt, nextPt) === 0) points.shift();\n\n // ring was all (within rounding error of angle calc) colinear points\n if (points.length === 0) return null;\n\n points.push(points[0]);\n return this.isExteriorRing ? points : points.reverse();\n }\n }, {\n key: '_clearCache',\n value: function _clearCache() {\n this._cache = {};\n }\n }, {\n key: '_getCached',\n value: function _getCached(propName, calcMethod) {\n // if this._cache[something] isn't set, fill it with this._something()\n if (this._cache[propName] === undefined) {\n this._cache[propName] = this['_' + propName].bind(this)();\n }\n return this._cache[propName];\n }\n }, {\n key: '_isExteriorRing',\n value: function _isExteriorRing() {\n if (!this.enclosingRing) return true;\n if (!this.enclosingRing.enclosingRing) return false;\n // an island in hole is a whole new polygon\n return this.enclosingRing.enclosingRing.isExteriorRing;\n }\n\n /* Returns the ring that encloses this one, if any */\n\n }, {\n key: '_enclosingRing',\n value: function _enclosingRing() {\n var prevSeg = this.events[0].segment.prevInResult;\n while (prevSeg && prevSeg.ringOut === this) {\n prevSeg = prevSeg.prevInResult;\n }var prevPrevSeg = prevSeg ? prevSeg.prevInResult : null;\n\n while (true) {\n // no segment found, thus no ring can enclose us\n if (!prevSeg) return null;\n\n // no segments below prev segment found, thus the ring of the prev\n // segment must loop back around and enclose us\n if (!prevPrevSeg) return prevSeg.ringOut;\n\n // if the two segments are of different rings, the ring of the prev\n // segment must either loop around us or the ring of the prev prev\n // seg, which would make us and the ring of the prev peers\n if (prevPrevSeg.ringOut !== prevSeg.ringOut) {\n if (prevPrevSeg.ringOut.enclosingRing !== prevSeg.ringOut) {\n return prevSeg.ringOut;\n } else return prevSeg.ringOut.enclosingRing;\n }\n\n // two segments are from the same ring, so this was a penisula\n // of that ring. iterate downward, keep searching\n prevSeg = prevPrevSeg.prevInResult;\n prevPrevSeg = prevSeg ? prevSeg.prevInResult : null;\n }\n }\n }, {\n key: 'enclosingRing',\n get: function get() {\n return this._getCached('enclosingRing');\n }\n }, {\n key: 'isExteriorRing',\n get: function get() {\n return this._getCached('isExteriorRing');\n }\n }]);\n\n return Ring;\n}();\n\nvar Poly = exports.Poly = function () {\n function Poly(exteriorRing) {\n _classCallCheck(this, Poly);\n\n this.exteriorRing = exteriorRing;\n exteriorRing.registerPoly(this);\n this.interiorRings = [];\n }\n\n _createClass(Poly, [{\n key: 'addInterior',\n value: function addInterior(ring) {\n this.interiorRings.push(ring);\n ring.registerPoly(this);\n }\n }, {\n key: 'getGeom',\n value: function getGeom() {\n var geom = [this.exteriorRing.getGeom()];\n // exterior ring was all (within rounding error of angle calc) colinear points\n if (geom[0] === null) return null;\n for (var i = 0, iMax = this.interiorRings.length; i < iMax; i++) {\n var ringGeom = this.interiorRings[i].getGeom();\n // interior ring was all (within rounding error of angle calc) colinear points\n if (ringGeom === null) continue;\n geom.push(ringGeom);\n }\n return geom;\n }\n }]);\n\n return Poly;\n}();\n\nvar MultiPoly = exports.MultiPoly = function () {\n function MultiPoly(rings) {\n _classCallCheck(this, MultiPoly);\n\n this.rings = rings;\n this.polys = this._composePolys(rings);\n }\n\n _createClass(MultiPoly, [{\n key: 'getGeom',\n value: function getGeom() {\n var geom = [];\n for (var i = 0, iMax = this.polys.length; i < iMax; i++) {\n var polyGeom = this.polys[i].getGeom();\n // exterior ring was all (within rounding error of angle calc) colinear points\n if (polyGeom === null) continue;\n geom.push(polyGeom);\n }\n return geom;\n }\n }, {\n key: '_composePolys',\n value: function _composePolys(rings) {\n var polys = [];\n for (var i = 0, iMax = rings.length; i < iMax; i++) {\n var ring = rings[i];\n if (ring.poly) continue;\n if (ring.isExteriorRing) polys.push(new Poly(ring));else {\n if (!ring.enclosingRing.poly) polys.push(new Poly(ring.enclosingRing));\n ring.enclosingRing.poly.addInterior(ring);\n }\n }\n return polys;\n }\n }]);\n\n return MultiPoly;\n}();\n\n//# sourceURL=webpack://polygon-clipping/./src/geom-out.js?");
|
203
|
+
|
204
|
+
/***/ }),
|
205
|
+
|
206
|
+
/***/ "./src/index.js":
|
207
|
+
/*!**********************!*\
|
208
|
+
!*** ./src/index.js ***!
|
209
|
+
\**********************/
|
210
|
+
/*! no static exports found */
|
211
|
+
/***/ (function(module, exports, __webpack_require__) {
|
212
|
+
|
213
|
+
"use strict";
|
214
|
+
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = doIt;\n\nvar _qheap = __webpack_require__(/*! qheap */ \"./node_modules/qheap/index.js\");\n\nvar _qheap2 = _interopRequireDefault(_qheap);\n\nvar _cleanInput = __webpack_require__(/*! ./clean-input.js */ \"./src/clean-input.js\");\n\nvar cleanInput = _interopRequireWildcard(_cleanInput);\n\nvar _geomIn = __webpack_require__(/*! ./geom-in */ \"./src/geom-in.js\");\n\nvar geomIn = _interopRequireWildcard(_geomIn);\n\nvar _geomOut = __webpack_require__(/*! ./geom-out */ \"./src/geom-out.js\");\n\nvar geomOut = _interopRequireWildcard(_geomOut);\n\nvar _operation = __webpack_require__(/*! ./operation */ \"./src/operation.js\");\n\nvar _operation2 = _interopRequireDefault(_operation);\n\nvar _sweepEvent = __webpack_require__(/*! ./sweep-event */ \"./src/sweep-event.js\");\n\nvar _sweepEvent2 = _interopRequireDefault(_sweepEvent);\n\nvar _sweepLine = __webpack_require__(/*! ./sweep-line */ \"./src/sweep-line.js\");\n\nvar _sweepLine2 = _interopRequireDefault(_sweepLine);\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction doIt(operationType, geom, moreGeoms) {\n /* Make a copy of the input geometry with points as objects, for perf */\n var geoms = [cleanInput.pointsAsObjects(geom)];\n for (var i = 0, iMax = moreGeoms.length; i < iMax; i++) {\n geoms.push(cleanInput.pointsAsObjects(moreGeoms[i]));\n }\n\n /* Clean inputs */\n for (var _i = 0, _iMax = geoms.length; _i < _iMax; _i++) {\n cleanInput.forceMultiPoly(geoms[_i]);\n cleanInput.cleanMultiPoly(geoms[_i]);\n }\n\n /* Convert inputs to MultiPoly objects, mark subject & register operation */\n var multipolys = [];\n for (var _i2 = 0, _iMax2 = geoms.length; _i2 < _iMax2; _i2++) {\n multipolys.push(new geomIn.MultiPoly(geoms[_i2]));\n }\n multipolys[0].markAsSubject();\n _operation2.default.register(operationType, multipolys.length);\n\n /* Put segment endpoints in a priority queue */\n var queue = new _qheap2.default({ comparBefore: _sweepEvent2.default.compareBefore });\n for (var _i3 = 0, _iMax3 = multipolys.length; _i3 < _iMax3; _i3++) {\n var sweepEvents = multipolys[_i3].getSweepEvents();\n for (var j = 0, jMax = sweepEvents.length; j < jMax; j++) {\n queue.insert(sweepEvents[j]);\n }\n }\n\n /* Pass the sweep line over those endpoints */\n var sweepLine = new _sweepLine2.default();\n while (queue.length) {\n var newEvents = sweepLine.process(queue.remove());\n for (var _i4 = 0, _iMax4 = newEvents.length; _i4 < _iMax4; _i4++) {\n queue.insert(newEvents[_i4]);\n }\n }\n\n /* Error on self-crossing input rings */\n cleanInput.errorOnSelfIntersectingRings(sweepLine.segments);\n\n /* Collect and compile segments we're keeping into a multipolygon */\n var ringsOut = geomOut.Ring.factory(sweepLine.segments);\n var result = new geomOut.MultiPoly(ringsOut);\n return result.getGeom();\n}\n\n//# sourceURL=webpack://polygon-clipping/./src/index.js?");
|
215
|
+
|
216
|
+
/***/ }),
|
217
|
+
|
218
|
+
/***/ "./src/operation.js":
|
219
|
+
/*!**************************!*\
|
220
|
+
!*** ./src/operation.js ***!
|
221
|
+
\**************************/
|
222
|
+
/*! no static exports found */
|
223
|
+
/***/ (function(module, exports, __webpack_require__) {
|
224
|
+
|
225
|
+
"use strict";
|
226
|
+
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar Operation = function () {\n function Operation() {\n _classCallCheck(this, Operation);\n\n this.types = {\n INTERSECTION: 0,\n UNION: 1,\n XOR: 2,\n DIFFERENCE: 3\n };\n }\n\n _createClass(Operation, [{\n key: \"register\",\n value: function register(type, numMultiPolys) {\n this.type = type;\n this.numMultiPolys = numMultiPolys;\n }\n }]);\n\n return Operation;\n}();\n\n// global to register details about the operation on\n\n\nvar operation = new Operation();\n\nexports.default = operation;\n\n//# sourceURL=webpack://polygon-clipping/./src/operation.js?");
|
227
|
+
|
228
|
+
/***/ }),
|
229
|
+
|
230
|
+
/***/ "./src/segment.js":
|
231
|
+
/*!************************!*\
|
232
|
+
!*** ./src/segment.js ***!
|
233
|
+
\************************/
|
234
|
+
/*! no static exports found */
|
235
|
+
/***/ (function(module, exports, __webpack_require__) {
|
236
|
+
|
237
|
+
"use strict";
|
238
|
+
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _operation = __webpack_require__(/*! ./operation */ \"./src/operation.js\");\n\nvar _operation2 = _interopRequireDefault(_operation);\n\nvar _sweepEvent = __webpack_require__(/*! ./sweep-event */ \"./src/sweep-event.js\");\n\nvar _sweepEvent2 = _interopRequireDefault(_sweepEvent);\n\nvar _bbox = __webpack_require__(/*! ./bbox */ \"./src/bbox.js\");\n\nvar _flp = __webpack_require__(/*! ./flp */ \"./src/flp.js\");\n\nvar _vector = __webpack_require__(/*! ./vector */ \"./src/vector.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar Segment = function () {\n _createClass(Segment, null, [{\n key: 'compare',\n value: function compare(a, b) {\n if (a === b) return 0;\n\n var alx = a.leftSE.point.x;\n var aly = a.leftSE.point.y;\n var blx = b.leftSE.point.x;\n var bly = b.leftSE.point.y;\n var arx = a.rightSE.point.x;\n var brx = b.rightSE.point.x;\n\n // check if they're even in the same vertical plane\n if ((0, _flp.cmp)(brx, alx) < 0) return 1;\n if ((0, _flp.cmp)(arx, blx) < 0) return -1;\n\n var cmpLeft = a.comparePoint(b.leftSE.point);\n var cmpLX = (0, _flp.cmp)(alx, blx);\n\n // are a and b colinear?\n if (cmpLeft === 0 && a.comparePoint(b.rightSE.point) === 0 && b.comparePoint(a.leftSE.point) === 0 && b.comparePoint(a.rightSE.point) === 0) {\n // colinear segments with non-matching left-endpoints, consider\n // the more-left endpoint to be earlier\n if (cmpLX !== 0) return cmpLX;\n\n // colinear segments with matching left-endpoints, fall back\n // on creation order of segments as a tie-breaker\n // NOTE: we do not use segment length to break a tie here, because\n // when segments are split their length changes\n if (a.ringIn.id !== b.ringIn.id) {\n return a.ringIn.id < b.ringIn.id ? -1 : 1;\n }\n } else {\n // not colinear\n\n // if the our left endpoints are not in the same vertical line,\n // consider a vertical line at the rightmore of the two left endpoints,\n // consider the segment that intersects lower with that line to be earlier\n if (cmpLX < 0) return cmpLeft === 1 ? -1 : 1;\n if (cmpLX > 0) return b.comparePoint(a.leftSE.point) === 1 ? 1 : -1;\n\n // if our left endpoints match, consider the segment\n // that angles more downward to be earlier\n if (cmpLX === 0 && (0, _flp.cmp)(a.leftSE.point.y, b.leftSE.point.y) === 0) {\n return a.comparePoint(b.rightSE.point) > 0 ? -1 : 1;\n }\n\n // left endpoints are in the same vertical line but don't overlap exactly,\n // lower means ealier\n return (0, _flp.cmp)(aly, bly);\n }\n\n throw new Error('Segment comparison (from [' + a.leftSE.point.x + ', ' + a.leftSR.point.y + '])' + (' -> to [' + a.rightSE.point.x + ', ' + a.rightSE.point.y + ']) failed... ') + ' segments equal but not identical?');\n }\n }]);\n\n function Segment(point1, point2, ring) {\n _classCallCheck(this, Segment);\n\n this.ringIn = ring;\n this.ringOut = null;\n\n var ptCmp = (0, _flp.cmpPoints)(point1, point2);\n var lp = void 0;\n var rp = void 0;\n if (ptCmp < 0) {\n lp = point1;\n rp = point2;\n this.flowL2R = true;\n } else if (ptCmp > 0) {\n lp = point2;\n rp = point1;\n this.flowL2R = false;\n } else {\n throw new Error('Tried to create degenerate segment at [' + point1.x + ', ' + point1.y + ']');\n }\n\n this.leftSE = new _sweepEvent2.default(lp, this);\n this.rightSE = new _sweepEvent2.default(rp, this);\n\n // cache of dynamically computed properies\n this._clearCache();\n }\n\n _createClass(Segment, [{\n key: 'clone',\n value: function clone() {\n var seg = new Segment(this.leftSE.point, this.rightSE.point, this.ringIn);\n seg.flowL2R = this.flowL2R;\n return seg;\n }\n }, {\n key: 'getOtherSE',\n value: function getOtherSE(se) {\n if (se === this.leftSE) return this.rightSE;\n if (se === this.rightSE) return this.leftSE;\n throw new Error('may only be called by own sweep events');\n }\n }, {\n key: 'isAnEndpoint',\n value: function isAnEndpoint(point) {\n return (0, _flp.cmpPoints)(point, this.leftSE.point) === 0 || (0, _flp.cmpPoints)(point, this.rightSE.point) === 0;\n }\n }, {\n key: 'isPointOn',\n value: function isPointOn(point) {\n return (0, _bbox.isInBbox)(this.bbox, point) && this.comparePoint(point) === 0;\n }\n\n /* Compare this segment with a point. Return value indicates\n * 1: point is below segment\n * 0: point is colinear to segment\n * -1: point is above segment */\n\n }, {\n key: 'comparePoint',\n value: function comparePoint(point) {\n if (this.isAnEndpoint(point)) return 0;\n return (0, _vector.compareVectorAngles)(point, this.leftSE.point, this.rightSE.point);\n }\n\n /**\n * Given another segment, returns an array of intersection points\n * between the two segments. The returned array can contain:\n * * zero points: no intersection b/t segments\n * * one point: segments intersect once\n * * two points: segments overlap. Endpoints of overlap returned.\n * Will be ordered as sweep line would encounter them.\n */\n\n }, {\n key: 'getIntersections',\n value: function getIntersections(other) {\n // If bboxes don't overlap, there can't be any intersections\n var bboxOverlap = (0, _bbox.getBboxOverlap)(this.bbox, other.bbox);\n if (bboxOverlap === null) return [];\n\n // The general algorithim doesn't handle overlapping colinear segments.\n // Overlapping colinear segments, if present, will have intersections\n // of one pair of opposing corners of the bbox overlap. Thus we just\n // manually check those coordinates.\n //\n // Note this also handles the cases of a collapsed bbox (just one point)\n // and semi-collapsed bbox (a vertical or horizontal line) as well.\n //\n // In addition, in the case of a T-intersection, this ensures that the\n // interseciton returned matches exactly an endpoint - no rounding error.\n var intersections = [];\n var bboxCorners = (0, _bbox.getUniqueCorners)(bboxOverlap);\n for (var i = 0, iMax = bboxCorners.length; i < iMax; i++) {\n var point = bboxCorners[i];\n // test if this point is an intersection\n if (this.isAnEndpoint(point) && other.isPointOn(point) || other.isAnEndpoint(point) && this.isPointOn(point)) {\n intersections.push(point);\n }\n }\n if (intersections.length > 0) return intersections;\n\n // General case for non-overlapping segments.\n // This algorithm is based on Schneider and Eberly.\n // http://www.cimec.org.ar/~ncalvo/Schneider_Eberly.pdf - pg 244\n var al = this.leftSE.point;\n var bl = other.leftSE.point;\n var va = this.vector;\n var vb = other.vector;\n var ve = { x: bl.x - al.x, y: bl.y - al.y };\n var kross = (0, _vector.crossProduct)(va, vb);\n\n // not on line segment a\n var s = (0, _vector.crossProduct)(ve, vb) / kross;\n if ((0, _flp.cmp)(s, 0) < 0 || (0, _flp.cmp)(1, s) < 0) return [];\n\n var t = (0, _vector.crossProduct)(ve, va) / kross;\n if ((0, _flp.cmp)(t, 0) < 0 || (0, _flp.cmp)(1, t) < 0) return [];\n\n // intersection is in a midpoint of both lines, let's average them and\n // bound the result by org bbox (otherwise leftSE and rightSE could swap)\n var x = (al.x + s * va.x + bl.x + t * vb.x) / 2;\n var y = (al.y + s * va.y + bl.y + t * vb.y) / 2;\n if (x < bboxOverlap.ll.x) x = bboxOverlap.ll.x;\n if (x > bboxOverlap.ur.x) x = bboxOverlap.ur.x;\n if (y < bboxOverlap.ll.y) y = bboxOverlap.ll.y;\n if (y > bboxOverlap.ur.y) y = bboxOverlap.ur.y;\n return [{ x: x, y: y }];\n }\n\n /**\n * Split the given segment into multiple segments on the given points.\n * * The existing segment will retain it's leftSE and a new rightSE will be\n * generated for it.\n * * A new segment will be generated which will adopt the original segment's\n * rightSE, and a new leftSE will be generated for it.\n * * If there are more than two points given to split on, new segments\n * in the middle will be generated with new leftSE and rightSE's.\n * * An array of the newly generated SweepEvents will be returned.\n */\n\n }, {\n key: 'split',\n value: function split(points) {\n // sort them and unique-ify them\n points.sort(_flp.cmpPoints);\n points = points.filter(function (pt, i, pts) {\n return i === 0 || (0, _flp.cmpPoints)(pts[i - 1], pt) !== 0;\n });\n\n for (var i = 0, iMax = points.length; i < iMax; i++) {\n var pt = points[i];\n if (this.isAnEndpoint(pt)) {\n throw new Error('Cannot split segment upon endpoint at [' + pt.x + ', ' + pt.y + ']');\n }\n }\n\n var point = points.shift();\n var newSeg = this.clone();\n newSeg.leftSE = new _sweepEvent2.default(point, newSeg);\n newSeg.rightSE = this.rightSE;\n this.rightSE.segment = newSeg;\n this.rightSE = new _sweepEvent2.default(point, this);\n var newEvents = [this.rightSE, newSeg.leftSE];\n\n if (points.length > 0) {\n var moreNewEvents = newSeg.split(points);\n for (var _i = 0, _iMax = moreNewEvents.length; _i < _iMax; _i++) {\n newEvents.push(moreNewEvents[_i]);\n }\n }\n return newEvents;\n }\n }, {\n key: 'registerPrev',\n value: function registerPrev(other) {\n this.prev = other;\n this._clearCache();\n }\n }, {\n key: 'registerRingOut',\n value: function registerRingOut(ring) {\n this.ringOut = ring;\n }\n\n /* The first segment previous segment chain that is in the result */\n\n }, {\n key: '_prevInResult',\n value: function _prevInResult() {\n var prev = this.prev;\n while (prev && !prev.isInResult) {\n prev = prev.prev;\n }return prev;\n }\n\n /* The segments, including ourselves, for which we overlap perfectly */\n\n }, {\n key: '_coincidents',\n value: function _coincidents() {\n // a coincident will have both left and right sweepEvents linked with us\n var coincidents = [];\n var leftLinkedEvents = this.leftSE.linkedEvents;\n var rightLinkedEvents = this.rightSE.linkedEvents;\n for (var i = 0, iMax = leftLinkedEvents.length; i < iMax; i++) {\n var leftSE = leftLinkedEvents[i];\n if (!leftSE.isLeft) continue;\n if (leftSE.segment.rightSE.linkedEvents !== rightLinkedEvents) continue;\n coincidents.push(leftSE.segment);\n }\n\n if (coincidents.length > 0) {\n // put the 'winner' at the front\n // arbitary - winner is the one with lowest ringId\n coincidents.sort(function (a, b) {\n return a.ringIn.id - b.ringIn.id;\n });\n\n // set this in all our coincident's caches so they don't have to calc it\n for (var _i2 = 0, _iMax2 = coincidents.length; _i2 < _iMax2; _i2++) {\n coincidents[_i2]._cache['coincidents'] = coincidents;\n }\n }\n return coincidents;\n }\n }, {\n key: '_prevNotCoincident',\n value: function _prevNotCoincident() {\n // iterating backwards from next to prev\n var next = this;\n var prev = this.prev;\n while (prev && next.coincidents === prev.coincidents) {\n next = prev;\n prev = prev.prev;\n }\n return prev;\n }\n\n /* Does the sweep line, when it intersects this segment, enter the ring? */\n\n }, {\n key: '_sweepLineEntersRing',\n value: function _sweepLineEntersRing() {\n // opposite of previous segment on the same ring\n var prev = this.prevNotCoincident;\n while (prev) {\n for (var i = 0, iMax = prev.coincidents.length; i < iMax; i++) {\n var seg = prev.coincidents[i];\n if (seg.ringIn === this.ringIn) return !seg.sweepLineEntersRing;\n }\n prev = prev.prevNotCoincident;\n }\n return true;\n }\n\n /* Does the sweep line, when it intersects this segment, enter the polygon? */\n\n }, {\n key: '_ringsInsideOf',\n value: function _ringsInsideOf() {\n if (!this.prev) return [];\n\n // coincidents always share the same rings. Return same array to save mem\n if (this.coincidents === this.prev.coincidents) {\n return this.prev.ringsInsideOf;\n }\n\n var rings = [];\n var prevRingsInsideOf = this.prev.ringsInsideOf;\n var prevRingsEntering = this.prev.getRingsEntering();\n var ringsExiting = this.getRingsExiting();\n\n // rings our prev was inside of all count, except those we're exiting\n for (var i = 0, iMax = prevRingsInsideOf.length; i < iMax; i++) {\n var ring = prevRingsInsideOf[i];\n if (!ringsExiting.includes(ring)) rings.push(ring);\n }\n\n // rings our prev was entering of all count, except those we're exiting\n for (var _i3 = 0, _iMax3 = prevRingsEntering.length; _i3 < _iMax3; _i3++) {\n var _ring = prevRingsEntering[_i3];\n if (!ringsExiting.includes(_ring)) rings.push(_ring);\n }\n\n return rings;\n }\n\n /* Array of input rings this segment is on boundary of */\n\n }, {\n key: 'getRingsOnEdgeOf',\n value: function getRingsOnEdgeOf() {\n var rings = [];\n for (var i = 0, iMax = this.coincidents.length; i < iMax; i++) {\n rings.push(this.coincidents[i].ringIn);\n }\n return rings;\n }\n\n /* Array of input rings this segment is on boundary of,\n * and for which the sweep line enters when intersecting there */\n\n }, {\n key: 'getRingsEntering',\n value: function getRingsEntering() {\n var rings = [];\n for (var i = 0, iMax = this.coincidents.length; i < iMax; i++) {\n var segment = this.coincidents[i];\n if (!segment.sweepLineEntersRing) continue;\n rings.push(segment.ringIn);\n }\n return rings;\n }\n\n /* Array of input rings this segment is on boundary of,\n * and for which the sweep line exits when intersecting there */\n\n }, {\n key: 'getRingsExiting',\n value: function getRingsExiting() {\n var rings = [];\n for (var i = 0, iMax = this.coincidents.length; i < iMax; i++) {\n var segment = this.coincidents[i];\n if (segment.sweepLineEntersRing) continue;\n rings.push(segment.ringIn);\n }\n return rings;\n }\n\n /* Is this segment valid on our own polygon? (ie not outside exterior ring) */\n\n }, {\n key: '_isValidEdgeForPoly',\n value: function _isValidEdgeForPoly() {\n // SLER: sweep line entering orientation\n var sameSLER = void 0;\n var diffSLER = void 0;\n if (this.sweepLineEntersRing) {\n sameSLER = this.getRingsEntering();\n diffSLER = this.getRingsExiting();\n } else {\n diffSLER = this.getRingsEntering();\n sameSLER = this.getRingsExiting();\n }\n return this.ringIn.isValid(sameSLER, diffSLER, this.ringsInsideOf);\n }\n\n /* Array of multipolys this segment is inside of */\n\n }, {\n key: 'getMultiPolysInsideOf',\n value: function getMultiPolysInsideOf() {\n var mps = [];\n for (var i = 0, iMax = this.ringsInsideOf.length; i < iMax; i++) {\n var poly = this.ringsInsideOf[i].poly;\n if (mps.includes(poly.multiPoly)) continue;\n if (!poly.isInside(this.getRingsOnEdgeOf(), this.ringsInsideOf)) continue;\n mps.push(poly.multiPoly);\n }\n return mps;\n }\n\n /* The multipolys on one side of us */\n\n }, {\n key: 'getMultiPolysSLPEnters',\n value: function getMultiPolysSLPEnters(multiPolysInsideOf) {\n // start with the multipolys we're fully inside\n var mps = multiPolysInsideOf.slice();\n // add the multipolys we have the sweep line entering\n for (var i = 0, iMax = this.coincidents.length; i < iMax; i++) {\n var seg = this.coincidents[i];\n if (!seg.sweepLineEntersPoly) continue;\n var mp = seg.ringIn.poly.multiPoly;\n if (!mps.includes(mp)) mps.push(mp);\n }\n return mps;\n }\n\n /* The multipolys on the other side of us */\n\n }, {\n key: 'getMultiPolysSLPExits',\n value: function getMultiPolysSLPExits(multiPolysInsideOf) {\n // start with the multipolys we're fully inside\n var mps = multiPolysInsideOf.slice();\n // add the multipolys we have the sweep line entering\n for (var i = 0, iMax = this.coincidents.length; i < iMax; i++) {\n var seg = this.coincidents[i];\n if (!seg.sweepLineExitsPoly) continue;\n var mp = seg.ringIn.poly.multiPoly;\n if (!mps.includes(mp)) mps.push(mp);\n }\n return mps;\n }\n\n /* Is this segment part of the final result? */\n\n }, {\n key: '_isInResult',\n value: function _isInResult() {\n // if it's not the coincidence winner, it's not in the resul\n if (this !== this.coincidents[0]) return false;\n\n var multiPolysInsideOf = this.getMultiPolysInsideOf();\n var multiPolysSLPEnters = this.getMultiPolysSLPEnters(multiPolysInsideOf);\n var multiPolysSLPExits = this.getMultiPolysSLPExits(multiPolysInsideOf);\n\n switch (_operation2.default.type) {\n case _operation2.default.types.UNION:\n // UNION - included iff:\n // * On one side of us there is 0 poly interiors AND\n // * On the other side there is 1 or more.\n var noEnters = multiPolysSLPEnters.length === 0;\n var noExits = multiPolysSLPExits.length === 0;\n return noEnters !== noExits;\n\n case _operation2.default.types.INTERSECTION:\n // INTERSECTION - included iff:\n // * on one side of us all multipolys are rep. with poly interiors AND\n // * on the other side of us, not all multipolys are repsented\n // with poly interiors\n var least = void 0;\n var most = void 0;\n if (multiPolysSLPEnters.length < multiPolysSLPExits.length) {\n least = multiPolysSLPEnters.length;\n most = multiPolysSLPExits.length;\n } else {\n least = multiPolysSLPExits.length;\n most = multiPolysSLPEnters.length;\n }\n return most === _operation2.default.numMultiPolys && least < most;\n\n case _operation2.default.types.XOR:\n // XOR - included iff:\n // * the difference between the number of multipolys represented\n // with poly interiors on our two sides is an odd number\n var diff = Math.abs(multiPolysSLPEnters.length - multiPolysSLPExits.length);\n return diff % 2 === 1;\n\n case _operation2.default.types.DIFFERENCE:\n // DIFFERENCE included iff:\n // * on exactly one side, we have just the subject\n var isJustSubject = function isJustSubject(mps) {\n return mps.length === 1 && mps[0].isSubject;\n };\n return isJustSubject(multiPolysSLPEnters) !== isJustSubject(multiPolysSLPExits);\n\n default:\n throw new Error('Unrecognized operation type found ' + _operation2.default.type);\n }\n }\n }, {\n key: '_clearCache',\n value: function _clearCache() {\n this._cache = {};\n }\n }, {\n key: 'bbox',\n get: function get() {\n var y1 = this.leftSE.point.y;\n var y2 = this.rightSE.point.y;\n return {\n ll: { x: this.leftSE.point.x, y: y1 < y2 ? y1 : y2 },\n ur: { x: this.rightSE.point.x, y: y1 > y2 ? y1 : y2 }\n };\n }\n\n /* A vector from the left point to the right */\n\n }, {\n key: 'vector',\n get: function get() {\n return {\n x: this.rightSE.point.x - this.leftSE.point.x,\n y: this.rightSE.point.y - this.leftSE.point.y\n };\n }\n }, {\n key: 'isVertical',\n get: function get() {\n return (0, _flp.cmp)(this.leftSE.point.x, this.rightSE.point.x) === 0;\n }\n\n /* In the original ringIn, which event came second */\n\n }, {\n key: 'flowIntoSE',\n get: function get() {\n return this.flowL2R ? this.rightSE : this.leftSE;\n }\n }, {\n key: 'prevInResult',\n get: function get() {\n var key = 'prevInResult';\n if (this._cache[key] === undefined) this._cache[key] = this['_' + key]();\n return this._cache[key];\n }\n }, {\n key: 'coincidents',\n get: function get() {\n var key = 'coincidents';\n if (this._cache[key] === undefined) this._cache[key] = this['_' + key]();\n return this._cache[key];\n }\n }, {\n key: 'prevNotCoincident',\n get: function get() {\n var key = 'prevNotCoincident';\n if (this._cache[key] === undefined) this._cache[key] = this['_' + key]();\n return this._cache[key];\n }\n }, {\n key: 'sweepLineEntersRing',\n get: function get() {\n var key = 'sweepLineEntersRing';\n if (this._cache[key] === undefined) this._cache[key] = this['_' + key]();\n return this._cache[key];\n }\n }, {\n key: 'sweepLineEntersPoly',\n get: function get() {\n if (!this.isValidEdgeForPoly) return false;\n return this.ringIn.isExterior === this.sweepLineEntersRing;\n }\n\n /* Does the sweep line, when it intersects this segment, exit the polygon? */\n\n }, {\n key: 'sweepLineExitsPoly',\n get: function get() {\n if (!this.isValidEdgeForPoly) return false;\n return this.ringIn.isExterior !== this.sweepLineEntersRing;\n }\n\n /* Array of input rings this segment is inside of (not on boundary) */\n\n }, {\n key: 'ringsInsideOf',\n get: function get() {\n var key = 'ringsInsideOf';\n if (this._cache[key] === undefined) this._cache[key] = this['_' + key]();\n return this._cache[key];\n }\n }, {\n key: 'isValidEdgeForPoly',\n get: function get() {\n var key = 'isValidEdgeForPoly';\n if (this._cache[key] === undefined) this._cache[key] = this['_' + key]();\n return this._cache[key];\n }\n }, {\n key: 'isInResult',\n get: function get() {\n var key = 'isInResult';\n if (this._cache[key] === undefined) this._cache[key] = this['_' + key]();\n return this._cache[key];\n }\n }]);\n\n return Segment;\n}();\n\nexports.default = Segment;\n\n//# sourceURL=webpack://polygon-clipping/./src/segment.js?");
|
239
|
+
|
240
|
+
/***/ }),
|
241
|
+
|
242
|
+
/***/ "./src/sweep-event.js":
|
243
|
+
/*!****************************!*\
|
244
|
+
!*** ./src/sweep-event.js ***!
|
245
|
+
\****************************/
|
246
|
+
/*! no static exports found */
|
247
|
+
/***/ (function(module, exports, __webpack_require__) {
|
248
|
+
|
249
|
+
"use strict";
|
250
|
+
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _flp = __webpack_require__(/*! ./flp */ \"./src/flp.js\");\n\nvar _vector = __webpack_require__(/*! ./vector */ \"./src/vector.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar SweepEvent = function () {\n _createClass(SweepEvent, null, [{\n key: 'compareBefore',\n value: function compareBefore(a, b) {\n // favor event with a point that the sweep line hits first\n var cmpX = (0, _flp.cmp)(a.point.x, b.point.x);\n if (cmpX !== 0) return cmpX < 0;\n\n var cmpY = (0, _flp.cmp)(a.point.y, b.point.y);\n if (cmpY !== 0) return cmpY < 0;\n\n // favor right events over left\n if (a.isLeft !== b.isLeft) return !a.isLeft;\n\n // favor events where the line segment is lower\n var pointSegCmp = a.segment.comparePoint(b.otherSE.point);\n if (pointSegCmp !== 0) return pointSegCmp > 0;\n\n // as a tie-breaker, favor lower segment creation id\n var aId = a.segment.ringIn.id;\n var bId = b.segment.ringIn.id;\n if (aId !== bId) return aId < bId;\n\n // NOTE: We don't sort on segment length because that changes\n // as segments are divided.\n\n // they appear to be the same point... are they?\n if (a === b) return false;\n\n throw new Error('SweepEvent comparison failed at [' + a.point.x + ', ' + a.point.y + ']... ' + 'equal but not identical?');\n }\n }]);\n\n function SweepEvent(point, segment) {\n _classCallCheck(this, SweepEvent);\n\n this.point = point;\n this.segment = segment;\n this.linkedEvents = [this];\n }\n\n _createClass(SweepEvent, [{\n key: 'link',\n value: function link(other) {\n var otherLE = other.linkedEvents;\n for (var i = 0, iMax = otherLE.length; i < iMax; i++) {\n var evt = otherLE[i];\n this.linkedEvents.push(evt);\n evt.linkedEvents = this.linkedEvents;\n }\n }\n }, {\n key: 'getAvailableLinkedEvents',\n value: function getAvailableLinkedEvents() {\n var events = [];\n for (var i = 0, iMax = this.linkedEvents.length; i < iMax; i++) {\n var evt = this.linkedEvents[i];\n if (evt !== this && !evt.segment.ringOut && evt.segment.isInResult) {\n events.push(evt);\n }\n }\n return events;\n }\n\n /**\n * Returns a comparator function for sorting linked events that will\n * favor the event that will give us the smallest left-side angle.\n * All ring construction starts as low as possible heading to the right,\n * so by always turning left as sharp as possible we'll get polygons\n * without uncessary loops & holes.\n *\n * The comparator function has a compute cache such that it avoids\n * re-computing already-computed values.\n */\n\n }, {\n key: 'getLeftmostComparator',\n value: function getLeftmostComparator(baseEvent) {\n var _this = this;\n\n var cache = new Map();\n\n var fillCache = function fillCache(linkedEvent) {\n var nextEvent = linkedEvent.otherSE;\n cache.set(linkedEvent, {\n sine: (0, _vector.sineOfAngle)(_this.point, baseEvent.point, nextEvent.point),\n cosine: (0, _vector.cosineOfAngle)(_this.point, baseEvent.point, nextEvent.point)\n });\n };\n\n return function (a, b) {\n if (!cache.has(a)) fillCache(a);\n if (!cache.has(b)) fillCache(b);\n\n var _cache$get = cache.get(a),\n asine = _cache$get.sine,\n acosine = _cache$get.cosine;\n\n var _cache$get2 = cache.get(b),\n bsine = _cache$get2.sine,\n bcosine = _cache$get2.cosine;\n\n var cmpZeroASine = (0, _flp.cmp)(asine, 0);\n var cmpZeroBSine = (0, _flp.cmp)(bsine, 0);\n\n if (cmpZeroASine >= 0 && cmpZeroBSine >= 0) return (0, _flp.cmp)(bcosine, acosine);\n if (cmpZeroASine < 0 && cmpZeroBSine < 0) return (0, _flp.cmp)(acosine, bcosine);\n return (0, _flp.cmp)(bsine, asine);\n };\n }\n }, {\n key: 'isLeft',\n get: function get() {\n return this === this.segment.leftSE;\n }\n }, {\n key: 'isRight',\n get: function get() {\n return this === this.segment.rightSE;\n }\n }, {\n key: 'otherSE',\n get: function get() {\n return this.segment.getOtherSE(this);\n }\n }]);\n\n return SweepEvent;\n}();\n\nexports.default = SweepEvent;\n\n//# sourceURL=webpack://polygon-clipping/./src/sweep-event.js?");
|
251
|
+
|
252
|
+
/***/ }),
|
253
|
+
|
254
|
+
/***/ "./src/sweep-line.js":
|
255
|
+
/*!***************************!*\
|
256
|
+
!*** ./src/sweep-line.js ***!
|
257
|
+
\***************************/
|
258
|
+
/*! no static exports found */
|
259
|
+
/***/ (function(module, exports, __webpack_require__) {
|
260
|
+
|
261
|
+
"use strict";
|
262
|
+
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _splaytree = __webpack_require__(/*! splaytree */ \"./node_modules/splaytree/index.js\");\n\nvar _splaytree2 = _interopRequireDefault(_splaytree);\n\nvar _flp = __webpack_require__(/*! ./flp */ \"./src/flp.js\");\n\nvar _segment = __webpack_require__(/*! ./segment */ \"./src/segment.js\");\n\nvar _segment2 = _interopRequireDefault(_segment);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * NOTE: We must be careful not to change any segments while\n * they are in the SplayTree. AFAIK, there's no way to tell\n * the tree to rebalance itself - thus before splitting\n * a segment that's in the tree, we remove it from the tree,\n * do the split, then re-insert it. (Even though splitting a\n * segment *shouldn't* change its correct position in the\n * sweep line tree, the reality is because of rounding errors,\n * it sometimes does.)\n */\n\nvar SweepLine = function () {\n function SweepLine() {\n var comparator = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _segment2.default.compare;\n\n _classCallCheck(this, SweepLine);\n\n this.tree = new _splaytree2.default(comparator);\n this.segments = [];\n this.prevEvent = null;\n }\n\n _createClass(SweepLine, [{\n key: 'process',\n value: function process(event) {\n var segment = event.segment;\n var newEvents = [];\n var node = event.isLeft ? this.tree.insert(segment) : this.tree.find(segment);\n\n var prevNode = this.tree.prev(node);\n var prevSeg = prevNode ? prevNode.key : null;\n\n var nextNode = this.tree.next(node);\n var nextSeg = nextNode ? nextNode.key : null;\n\n if (event.isLeft) {\n var mySplitters = [];\n\n // Check for intersections against the previous segment in the sweep line\n if (prevSeg) {\n var prevInters = prevSeg.getIntersections(segment);\n if (prevInters.length > 0) {\n var newEventsFromSplit = this._possibleSplit(prevSeg, prevInters);\n for (var i = 0, iMax = newEventsFromSplit.length; i < iMax; i++) {\n newEvents.push(newEventsFromSplit[i]);\n }\n for (var _i = 0, _iMax = prevInters.length; _i < _iMax; _i++) {\n var pt = prevInters[_i];\n if (!segment.isAnEndpoint(pt)) mySplitters.push(pt);\n }\n }\n }\n\n // Check for intersections against the next segment in the sweep line\n if (nextSeg) {\n var nextInters = nextSeg.getIntersections(segment);\n if (nextInters.length > 0) {\n var _newEventsFromSplit = this._possibleSplit(nextSeg, nextInters);\n for (var _i2 = 0, _iMax2 = _newEventsFromSplit.length; _i2 < _iMax2; _i2++) {\n newEvents.push(_newEventsFromSplit[_i2]);\n }\n for (var _i3 = 0, _iMax3 = nextInters.length; _i3 < _iMax3; _i3++) {\n var _pt = nextInters[_i3];\n if (!segment.isAnEndpoint(_pt)) mySplitters.push(_pt);\n }\n }\n }\n\n // did we get some intersections?\n if (newEvents.length > 0 || mySplitters.length > 0) {\n this.tree.remove(segment);\n\n if (mySplitters.length > 0) {\n var _newEventsFromSplit2 = segment.split(mySplitters);\n for (var _i4 = 0, _iMax4 = _newEventsFromSplit2.length; _i4 < _iMax4; _i4++) {\n newEvents.push(_newEventsFromSplit2[_i4]);\n }\n }\n\n // Make sure sweep line ordering is totally consistent for later\n // use with the segment 'prev' pointers - re-do the current event.\n newEvents.push(event);\n return newEvents;\n }\n\n this.segments.push(segment);\n segment.registerPrev(prevSeg);\n } else {\n // event.isRight\n\n // since we're about to be removed from the sweep line, check for\n // intersections between our previous and next segments\n if (prevSeg && nextSeg) {\n var inters = prevSeg.getIntersections(nextSeg);\n if (inters.length > 0) {\n var _newEventsFromSplit3 = this._possibleSplit(prevSeg, inters);\n for (var _i5 = 0, _iMax5 = _newEventsFromSplit3.length; _i5 < _iMax5; _i5++) {\n newEvents.push(_newEventsFromSplit3[_i5]);\n }\n _newEventsFromSplit3 = this._possibleSplit(nextSeg, inters);\n for (var _i6 = 0, _iMax6 = _newEventsFromSplit3.length; _i6 < _iMax6; _i6++) {\n newEvents.push(_newEventsFromSplit3[_i6]);\n }\n }\n }\n\n this.tree.remove(segment);\n }\n\n if (this.prevEvent && (0, _flp.cmpPoints)(this.prevEvent.point, event.point) === 0) {\n this.prevEvent.link(event);\n }\n this.prevEvent = event;\n\n return newEvents;\n }\n }, {\n key: '_possibleSplit',\n value: function _possibleSplit(segment, intersections) {\n var splitters = [];\n for (var i = 0, iMax = intersections.length; i < iMax; i++) {\n var pt = intersections[i];\n if (!segment.isAnEndpoint(pt)) splitters.push(pt);\n }\n\n var newEvents = void 0;\n if (splitters.length > 0) {\n this.tree.remove(segment);\n newEvents = segment.split(splitters);\n this.tree.insert(segment);\n } else newEvents = [];\n return newEvents;\n }\n }]);\n\n return SweepLine;\n}();\n\nexports.default = SweepLine;\n\n//# sourceURL=webpack://polygon-clipping/./src/sweep-line.js?");
|
263
|
+
|
264
|
+
/***/ }),
|
265
|
+
|
266
|
+
/***/ "./src/vector.js":
|
267
|
+
/*!***********************!*\
|
268
|
+
!*** ./src/vector.js ***!
|
269
|
+
\***********************/
|
270
|
+
/*! no static exports found */
|
271
|
+
/***/ (function(module, exports, __webpack_require__) {
|
272
|
+
|
273
|
+
"use strict";
|
274
|
+
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.cosineOfAngle = exports.sineOfAngle = exports.compareVectorAngles = exports.dotProduct = exports.crossProduct = undefined;\n\nvar _flp = __webpack_require__(/*! ./flp */ \"./src/flp.js\");\n\n/* Cross Product of two vectors with first point at origin */\nvar crossProduct = exports.crossProduct = function crossProduct(a, b) {\n return a.x * b.y - a.y * b.x;\n};\n\n/* Dot Product of two vectors with first point at origin */\nvar dotProduct = exports.dotProduct = function dotProduct(a, b) {\n return a.x * b.x + a.y * b.y;\n};\n\n/* Comparator for two vectors with same starting point */\nvar compareVectorAngles = exports.compareVectorAngles = function compareVectorAngles(basePt, endPt1, endPt2) {\n var v1 = { x: endPt1.x - basePt.x, y: endPt1.y - basePt.y };\n var v2 = { x: endPt2.x - basePt.x, y: endPt2.y - basePt.y };\n var kross = crossProduct(v1, v2);\n return (0, _flp.cmp)(kross, 0);\n};\n\nvar length = function length(v) {\n return Math.sqrt(dotProduct(v, v));\n};\n\n/* Get the sine of the angle from pShared -> pAngle to pShaed -> pBase */\nvar sineOfAngle = exports.sineOfAngle = function sineOfAngle(pShared, pBase, pAngle) {\n var vBase = { x: pBase.x - pShared.x, y: pBase.y - pShared.y };\n var vAngle = { x: pAngle.x - pShared.x, y: pAngle.y - pShared.y };\n return crossProduct(vAngle, vBase) / length(vAngle) / length(vBase);\n};\n\n/* Get the cosine of the angle from pShared -> pAngle to pShaed -> pBase */\nvar cosineOfAngle = exports.cosineOfAngle = function cosineOfAngle(pShared, pBase, pAngle) {\n var vBase = { x: pBase.x - pShared.x, y: pBase.y - pShared.y };\n var vAngle = { x: pAngle.x - pShared.x, y: pAngle.y - pShared.y };\n return dotProduct(vAngle, vBase) / length(vAngle) / length(vBase);\n};\n\n//# sourceURL=webpack://polygon-clipping/./src/vector.js?");
|
275
|
+
|
276
|
+
/***/ })
|
277
|
+
|
278
|
+
/******/ });
|
279
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports["polygon-clipping"]=e():t["polygon-clipping"]=e()}("undefined"!=typeof self?self:this,function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=14)}([function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),void 0===Number.EPSILON&&(Number.EPSILON=Math.pow(2,-52));var r=Number.EPSILON*Number.EPSILON;e.cmp=function(t,e){return-Number.EPSILON<t&&t<Number.EPSILON&&-Number.EPSILON<e&&e<Number.EPSILON?0:(t-e)*(t-e)<r*t*e?0:t<e?-1:1},e.cmpPoints=function(t,e){var n=t.x,i=e.x;if(n<=-Number.EPSILON||Number.EPSILON<=n||i<=-Number.EPSILON||Number.EPSILON<=i){var o=n-i;if(o*o>=r*n*i)return n<i?-1:1}if(n=t.y,i=e.y,n<=-Number.EPSILON||Number.EPSILON<=n||i<=-Number.EPSILON||Number.EPSILON<=i){var s=n-i;if(s*s>=r*n*i)return n<i?-1:1}return 0}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.cosineOfAngle=e.sineOfAngle=e.compareVectorAngles=e.dotProduct=e.crossProduct=void 0;var r=n(0),i=e.crossProduct=function(t,e){return t.x*e.y-t.y*e.x},o=e.dotProduct=function(t,e){return t.x*e.x+t.y*e.y},s=(e.compareVectorAngles=function(t,e,n){var o={x:e.x-t.x,y:e.y-t.y},s={x:n.x-t.x,y:n.y-t.y},l=i(o,s);return(0,r.cmp)(l,0)},function(t){return Math.sqrt(o(t,t))});e.sineOfAngle=function(t,e,n){var r={x:e.x-t.x,y:e.y-t.y},o={x:n.x-t.x,y:n.y-t.y};return i(o,r)/s(o)/s(r)},e.cosineOfAngle=function(t,e,n){var r={x:e.x-t.x,y:e.y-t.y},i={x:n.x-t.x,y:n.y-t.y};return o(i,r)/s(i)/s(r)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}();var i=new(function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.types={INTERSECTION:0,UNION:1,XOR:2,DIFFERENCE:3}}return r(t,[{key:"register",value:function(t,e){this.type=t,this.numMultiPolys=e}}]),t}());e.default=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),i=n(0),o=n(1);var s=function(){function t(e,n){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.point=e,this.segment=n,this.linkedEvents=[this]}return r(t,null,[{key:"compareBefore",value:function(t,e){var n=(0,i.cmp)(t.point.x,e.point.x);if(0!==n)return n<0;var r=(0,i.cmp)(t.point.y,e.point.y);if(0!==r)return r<0;if(t.isLeft!==e.isLeft)return!t.isLeft;var o=t.segment.comparePoint(e.otherSE.point);if(0!==o)return o>0;var s=t.segment.ringIn.id,l=e.segment.ringIn.id;if(s!==l)return s<l;if(t===e)return!1;throw new Error("SweepEvent comparison failed at ["+t.point.x+", "+t.point.y+"]... equal but not identical?")}}]),r(t,[{key:"link",value:function(t){for(var e=t.linkedEvents,n=0,r=e.length;n<r;n++){var i=e[n];this.linkedEvents.push(i),i.linkedEvents=this.linkedEvents}}},{key:"getAvailableLinkedEvents",value:function(){for(var t=[],e=0,n=this.linkedEvents.length;e<n;e++){var r=this.linkedEvents[e];r!==this&&!r.segment.ringOut&&r.segment.isInResult&&t.push(r)}return t}},{key:"getLeftmostComparator",value:function(t){var e=this,n=new Map,r=function(r){var i=r.otherSE;n.set(r,{sine:(0,o.sineOfAngle)(e.point,t.point,i.point),cosine:(0,o.cosineOfAngle)(e.point,t.point,i.point)})};return function(t,e){n.has(t)||r(t),n.has(e)||r(e);var o=n.get(t),s=o.sine,l=o.cosine,u=n.get(e),h=u.sine,f=u.cosine,c=(0,i.cmp)(s,0),a=(0,i.cmp)(h,0);return c>=0&&a>=0?(0,i.cmp)(f,l):c<0&&a<0?(0,i.cmp)(l,f):(0,i.cmp)(h,s)}}},{key:"isLeft",get:function(){return this===this.segment.leftSE}},{key:"isRight",get:function(){return this===this.segment.rightSE}},{key:"otherSE",get:function(){return this.segment.getOtherSE(this)}}]),t}();e.default=s},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),i=h(n(2)),o=h(n(3)),s=n(8),l=n(0),u=n(1);function h(t){return t&&t.__esModule?t:{default:t}}var f=function(){function t(e,n,r){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.ringIn=r,this.ringOut=null;var i=(0,l.cmpPoints)(e,n),s=void 0,u=void 0;if(i<0)s=e,u=n,this.flowL2R=!0;else{if(!(i>0))throw new Error("Tried to create degenerate segment at ["+e.x+", "+e.y+"]");s=n,u=e,this.flowL2R=!1}this.leftSE=new o.default(s,this),this.rightSE=new o.default(u,this),this._clearCache()}return r(t,null,[{key:"compare",value:function(t,e){if(t===e)return 0;var n=t.leftSE.point.x,r=t.leftSE.point.y,i=e.leftSE.point.x,o=e.leftSE.point.y,s=t.rightSE.point.x,u=e.rightSE.point.x;if((0,l.cmp)(u,n)<0)return 1;if((0,l.cmp)(s,i)<0)return-1;var h=t.comparePoint(e.leftSE.point),f=(0,l.cmp)(n,i);if(0!==h||0!==t.comparePoint(e.rightSE.point)||0!==e.comparePoint(t.leftSE.point)||0!==e.comparePoint(t.rightSE.point))return f<0?1===h?-1:1:f>0?1===e.comparePoint(t.leftSE.point)?1:-1:0===f&&0===(0,l.cmp)(t.leftSE.point.y,e.leftSE.point.y)?t.comparePoint(e.rightSE.point)>0?-1:1:(0,l.cmp)(r,o);if(0!==f)return f;if(t.ringIn.id!==e.ringIn.id)return t.ringIn.id<e.ringIn.id?-1:1;throw new Error("Segment comparison (from ["+t.leftSE.point.x+", "+t.leftSR.point.y+"]) -> to ["+t.rightSE.point.x+", "+t.rightSE.point.y+"]) failed... segments equal but not identical?")}}]),r(t,[{key:"clone",value:function(){var e=new t(this.leftSE.point,this.rightSE.point,this.ringIn);return e.flowL2R=this.flowL2R,e}},{key:"getOtherSE",value:function(t){if(t===this.leftSE)return this.rightSE;if(t===this.rightSE)return this.leftSE;throw new Error("may only be called by own sweep events")}},{key:"isAnEndpoint",value:function(t){return 0===(0,l.cmpPoints)(t,this.leftSE.point)||0===(0,l.cmpPoints)(t,this.rightSE.point)}},{key:"isPointOn",value:function(t){return(0,s.isInBbox)(this.bbox,t)&&0===this.comparePoint(t)}},{key:"comparePoint",value:function(t){return this.isAnEndpoint(t)?0:(0,u.compareVectorAngles)(t,this.leftSE.point,this.rightSE.point)}},{key:"getIntersections",value:function(t){var e=(0,s.getBboxOverlap)(this.bbox,t.bbox);if(null===e)return[];for(var n=[],r=(0,s.getUniqueCorners)(e),i=0,o=r.length;i<o;i++){var h=r[i];(this.isAnEndpoint(h)&&t.isPointOn(h)||t.isAnEndpoint(h)&&this.isPointOn(h))&&n.push(h)}if(n.length>0)return n;var f=this.leftSE.point,c=t.leftSE.point,a=this.vector,g=t.vector,p={x:c.x-f.x,y:c.y-f.y},y=(0,u.crossProduct)(a,g),v=(0,u.crossProduct)(p,g)/y;if((0,l.cmp)(v,0)<0||(0,l.cmp)(1,v)<0)return[];var d=(0,u.crossProduct)(p,a)/y;if((0,l.cmp)(d,0)<0||(0,l.cmp)(1,d)<0)return[];var E=(f.x+v*a.x+c.x+d*g.x)/2,_=(f.y+v*a.y+c.y+d*g.y)/2;return E<e.ll.x&&(E=e.ll.x),E>e.ur.x&&(E=e.ur.x),_<e.ll.y&&(_=e.ll.y),_>e.ur.y&&(_=e.ur.y),[{x:E,y:_}]}},{key:"split",value:function(t){t.sort(l.cmpPoints),t=t.filter(function(t,e,n){return 0===e||0!==(0,l.cmpPoints)(n[e-1],t)});for(var e=0,n=t.length;e<n;e++){var r=t[e];if(this.isAnEndpoint(r))throw new Error("Cannot split segment upon endpoint at ["+r.x+", "+r.y+"]")}var i=t.shift(),s=this.clone();s.leftSE=new o.default(i,s),s.rightSE=this.rightSE,this.rightSE.segment=s,this.rightSE=new o.default(i,this);var u=[this.rightSE,s.leftSE];if(t.length>0)for(var h=s.split(t),f=0,c=h.length;f<c;f++)u.push(h[f]);return u}},{key:"registerPrev",value:function(t){this.prev=t,this._clearCache()}},{key:"registerRingOut",value:function(t){this.ringOut=t}},{key:"_prevInResult",value:function(){for(var t=this.prev;t&&!t.isInResult;)t=t.prev;return t}},{key:"_coincidents",value:function(){for(var t=[],e=this.leftSE.linkedEvents,n=this.rightSE.linkedEvents,r=0,i=e.length;r<i;r++){var o=e[r];o.isLeft&&(o.segment.rightSE.linkedEvents===n&&t.push(o.segment))}if(t.length>0){t.sort(function(t,e){return t.ringIn.id-e.ringIn.id});for(var s=0,l=t.length;s<l;s++)t[s]._cache.coincidents=t}return t}},{key:"_prevNotCoincident",value:function(){for(var t=this,e=this.prev;e&&t.coincidents===e.coincidents;)t=e,e=e.prev;return e}},{key:"_sweepLineEntersRing",value:function(){for(var t=this.prevNotCoincident;t;){for(var e=0,n=t.coincidents.length;e<n;e++){var r=t.coincidents[e];if(r.ringIn===this.ringIn)return!r.sweepLineEntersRing}t=t.prevNotCoincident}return!0}},{key:"_ringsInsideOf",value:function(){if(!this.prev)return[];if(this.coincidents===this.prev.coincidents)return this.prev.ringsInsideOf;for(var t=[],e=this.prev.ringsInsideOf,n=this.prev.getRingsEntering(),r=this.getRingsExiting(),i=0,o=e.length;i<o;i++){var s=e[i];r.includes(s)||t.push(s)}for(var l=0,u=n.length;l<u;l++){var h=n[l];r.includes(h)||t.push(h)}return t}},{key:"getRingsOnEdgeOf",value:function(){for(var t=[],e=0,n=this.coincidents.length;e<n;e++)t.push(this.coincidents[e].ringIn);return t}},{key:"getRingsEntering",value:function(){for(var t=[],e=0,n=this.coincidents.length;e<n;e++){var r=this.coincidents[e];r.sweepLineEntersRing&&t.push(r.ringIn)}return t}},{key:"getRingsExiting",value:function(){for(var t=[],e=0,n=this.coincidents.length;e<n;e++){var r=this.coincidents[e];r.sweepLineEntersRing||t.push(r.ringIn)}return t}},{key:"_isValidEdgeForPoly",value:function(){var t=void 0,e=void 0;return this.sweepLineEntersRing?(t=this.getRingsEntering(),e=this.getRingsExiting()):(e=this.getRingsEntering(),t=this.getRingsExiting()),this.ringIn.isValid(t,e,this.ringsInsideOf)}},{key:"getMultiPolysInsideOf",value:function(){for(var t=[],e=0,n=this.ringsInsideOf.length;e<n;e++){var r=this.ringsInsideOf[e].poly;t.includes(r.multiPoly)||r.isInside(this.getRingsOnEdgeOf(),this.ringsInsideOf)&&t.push(r.multiPoly)}return t}},{key:"getMultiPolysSLPEnters",value:function(t){for(var e=t.slice(),n=0,r=this.coincidents.length;n<r;n++){var i=this.coincidents[n];if(i.sweepLineEntersPoly){var o=i.ringIn.poly.multiPoly;e.includes(o)||e.push(o)}}return e}},{key:"getMultiPolysSLPExits",value:function(t){for(var e=t.slice(),n=0,r=this.coincidents.length;n<r;n++){var i=this.coincidents[n];if(i.sweepLineExitsPoly){var o=i.ringIn.poly.multiPoly;e.includes(o)||e.push(o)}}return e}},{key:"_isInResult",value:function(){if(this!==this.coincidents[0])return!1;var t=this.getMultiPolysInsideOf(),e=this.getMultiPolysSLPEnters(t),n=this.getMultiPolysSLPExits(t);switch(i.default.type){case i.default.types.UNION:return 0===e.length!==(0===n.length);case i.default.types.INTERSECTION:var r=void 0,o=void 0;return e.length<n.length?(r=e.length,o=n.length):(r=n.length,o=e.length),o===i.default.numMultiPolys&&r<o;case i.default.types.XOR:return Math.abs(e.length-n.length)%2==1;case i.default.types.DIFFERENCE:var s=function(t){return 1===t.length&&t[0].isSubject};return s(e)!==s(n);default:throw new Error("Unrecognized operation type found "+i.default.type)}}},{key:"_clearCache",value:function(){this._cache={}}},{key:"bbox",get:function(){var t=this.leftSE.point.y,e=this.rightSE.point.y;return{ll:{x:this.leftSE.point.x,y:t<e?t:e},ur:{x:this.rightSE.point.x,y:t>e?t:e}}}},{key:"vector",get:function(){return{x:this.rightSE.point.x-this.leftSE.point.x,y:this.rightSE.point.y-this.leftSE.point.y}}},{key:"isVertical",get:function(){return 0===(0,l.cmp)(this.leftSE.point.x,this.rightSE.point.x)}},{key:"flowIntoSE",get:function(){return this.flowL2R?this.rightSE:this.leftSE}},{key:"prevInResult",get:function(){var t="prevInResult";return void 0===this._cache[t]&&(this._cache[t]=this["_"+t]()),this._cache[t]}},{key:"coincidents",get:function(){var t="coincidents";return void 0===this._cache[t]&&(this._cache[t]=this["_"+t]()),this._cache[t]}},{key:"prevNotCoincident",get:function(){var t="prevNotCoincident";return void 0===this._cache[t]&&(this._cache[t]=this["_"+t]()),this._cache[t]}},{key:"sweepLineEntersRing",get:function(){var t="sweepLineEntersRing";return void 0===this._cache[t]&&(this._cache[t]=this["_"+t]()),this._cache[t]}},{key:"sweepLineEntersPoly",get:function(){return!!this.isValidEdgeForPoly&&this.ringIn.isExterior===this.sweepLineEntersRing}},{key:"sweepLineExitsPoly",get:function(){return!!this.isValidEdgeForPoly&&this.ringIn.isExterior!==this.sweepLineEntersRing}},{key:"ringsInsideOf",get:function(){var t="ringsInsideOf";return void 0===this._cache[t]&&(this._cache[t]=this["_"+t]()),this._cache[t]}},{key:"isValidEdgeForPoly",get:function(){var t="isValidEdgeForPoly";return void 0===this._cache[t]&&(this._cache[t]=this["_"+t]()),this._cache[t]}},{key:"isInResult",get:function(){var t="isInResult";return void 0===this._cache[t]&&(this._cache[t]=this["_"+t]()),this._cache[t]}}]),t}();e.default=f},function(t,e,n){"use strict";n.r(e),n.d(e,"default",function(){return u});class r{constructor(t,e){this.key=t,this.data=e,this.left=null,this.right=null}}function i(t,e,n){if(null===e)return e;let i,o,s;const l=new r;for(i=o=l;;){const r=n(t,e.key);if(r<0){if(null===e.left)break;if(n(t,e.left.key)<0&&(s=e.left,e.left=s.right,s.right=e,null===(e=s).left))break;o.left=e,o=e,e=e.left}else{if(!(r>0))break;if(null===e.right)break;if(n(t,e.right.key)>0&&(s=e.right,e.right=s.left,s.left=e,null===(e=s).right))break;i.right=e,i=e,e=e.right}}return i.right=e.left,o.left=e.right,e.left=l.right,e.right=l.left,e}function o(t,e,n,o,s){const l=new r(t,e);if(s._size++,null===n)return l.left=l.right=null,l;const u=o(t,(n=i(t,n,o)).key);return u<0?(l.left=n.left,l.right=n,n.left=null):u>=0&&(l.right=n.right,l.left=n,n.right=null),l}function s(t,e,n,r){let o;return null===e?null:t===(e=i(t,e,n)).key?(null===e.left?o=e.right:(o=i(t,e.left,n)).right=e.right,r._size--,o):e}function l(t,e,n){let r,o;if(null===e)r=o=null;else{const s=n((e=i(t,e,n)).key,t);0===s?(r=e.left,o=e.right):s<0?(o=e.right,e.right=null,r=e):(r=e.left,e.left=null,o=e)}return{left:r,right:o}}class u{constructor(t=function(t,e){return t>e?1:t<e?-1:0}){this._comparator=t,this._root=null,this._size=0}insert(t,e){return this._root=o(t,e,this._root,this._comparator,this)}add(t,e){return this._root=function(t,e,n,o,s){const l=new r(t,e);if(null===n)return l.left=l.right=null,s._size++,l;const u=o(t,(n=i(t,n,o)).key);return 0===u?n:(u<0?(l.left=n.left,l.right=n,n.left=null):u>0&&(l.right=n.right,l.left=n,n.right=null),s._size++,l)}(t,e,this._root,this._comparator,this)}remove(t){this._root=s(t,this._root,this._comparator,this)}pop(){let t=this._root;if(t){for(;t.left;)t=t.left;return this._root=i(t.key,this._root,this._comparator),this._root=s(t.key,this._root,this._comparator,this),{key:t.key,data:t.data}}return null}findStatic(t){let e=this._root;const n=this._comparator;for(;e;){const r=n(t,e.key);if(0===r)return e;e=r<0?e.left:e.right}return null}find(t){return this._root&&(this._root=i(t,this._root,this._comparator),0!==this._comparator(t,this._root.key))?null:this._root}contains(t){let e=this._root;const n=this._comparator;for(;e;){const r=n(t,e.key);if(0===r)return!0;e=r<0?e.left:e.right}return!1}forEach(t,e){let n=this._root;const r=[];let i=!1;for(;!i;)null!==n?(r.push(n),n=n.left):0!==r.length?(n=r.pop(),t.call(e,n),n=n.right):i=!0;return this}range(t,e,n,r){const i=[],o=this._comparator;let s,l=this._root;for(;0!==i.length||l;)if(l)i.push(l),l=l.left;else{if((s=o((l=i.pop()).key,e))>0)break;if(o(l.key,t)>=0&&n.call(r,l))return this;l=l.right}return this}keys(){const t=[];return this.forEach(({key:e})=>t.push(e)),t}values(){const t=[];return this.forEach(({data:e})=>t.push(e)),t}min(){return this._root?this.minNode(this._root).key:null}max(){return this._root?this.maxNode(this._root).key:null}minNode(t=this._root){if(t)for(;t.left;)t=t.left;return t}maxNode(t=this._root){if(t)for(;t.right;)t=t.right;return t}at(t){let e=this._root,n=!1,r=0;const i=[];for(;!n;)if(e)i.push(e),e=e.left;else if(i.length>0){if(e=i.pop(),r===t)return e;r++,e=e.right}else n=!0;return null}next(t){let e=this._root,n=null;if(t.right){for(n=t.right;n.left;)n=n.left;return n}const r=this._comparator;for(;e;){const i=r(t.key,e.key);if(0===i)break;i<0?(n=e,e=e.left):e=e.right}return n}prev(t){let e=this._root,n=null;if(null!==t.left){for(n=t.left;n.right;)n=n.right;return n}const r=this._comparator;for(;e;){const i=r(t.key,e.key);if(0===i)break;i<0?e=e.left:(n=e,e=e.right)}return n}clear(){return this._root=null,this._size=0,this}toList(){return function(t){var e=t,n=[],r=!1;const i={next:null};let o=i;for(;!r;)e?(n.push(e),e=e.left):n.length>0?e=(e=o=o.next=n.pop()).right:r=!0;return o.next=null,i.next}(this._root)}load(t=[],e=[],n=!1){let r=t.length;const i=this._comparator;if(n&&function t(e,n,r,i,o){if(r>=i)return;const s=e[r+i>>1];let l=r-1;let u=i+1;for(;;){do{l++}while(o(e[l],s)<0);do{u--}while(o(e[u],s)>0);if(l>=u)break;let t=e[l];e[l]=e[u],e[u]=t,t=n[l],n[l]=n[u],n[u]=t}t(e,n,r,u,o);t(e,n,u+1,i,o)}(t,e,0,r-1,i),null===this._root)this._root=function t(e,n,r,i,o){const s=o-i;if(s>0){const l=i+Math.floor(s/2),u=n[l],h=r[l],f={key:u,data:h,parent:e};return f.left=t(f,n,r,i,l),f.right=t(f,n,r,l+1,o),f}return null}(this._root,t,e,0,r),this._size=r;else{const n=function(t,e,n=((t,e)=>t-e)){const r={};let i=r,o=t,s=e;for(;null!==o&&null!==s;)n(o.key,s.key)<0?(i.next=o,o=o.next):(i.next=s,s=s.next),i=i.next;null!==o?i.next=o:null!==s&&(i.next=s);return r.next}(this.toList(),function(t,e){const n={next:null};let r=n;for(let n=0;n<t.length;n++)r=r.next={key:t[n],data:e[n]};return r.next=null,n.next}(t,e),i);r=this._size+r,this._root=function t(e,n,r){const i=r-n;if(i>0){const o=n+Math.floor(i/2),s=t(e,n,o),l=e.head;return l.left=s,e.head=e.head.next,l.right=t(e,o+1,r),l}return null}({head:n},0,r)}return this}isEmpty(){return null===this._root}get size(){return this._size}toString(t=(t=>t.key)){const e=[];return function t(e,n,r,i,o){if(e){i(`${n}${r?"└── ":"├── "}${o(e)}\n`);const s=n+(r?" ":"│ ");e.left&&t(e.left,s,!1,i,o),e.right&&t(e.right,s,!0,i,o)}}(this._root,"",!0,t=>e.push(t),t),e.join("")}update(t,e,n){const r=this._comparator;let{left:s,right:u}=l(t,this._root,r);this._size--,r(t,e)<0?u=o(e,n,u,r,this):s=o(e,n,s,r,this),this._root=function(t,e,n){return null===e?t:null===t?e:((e=i(t.key,e,n)).left=t,e)}(s,u,r)}split(t){return l(t,this._root,this._comparator)}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),i=l(n(5)),o=n(0),s=l(n(4));function l(t){return t&&t.__esModule?t:{default:t}}var u=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:s.default.compare;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.tree=new i.default(e),this.segments=[],this.prevEvent=null}return r(t,[{key:"process",value:function(t){var e=t.segment,n=[],r=t.isLeft?this.tree.insert(e):this.tree.find(e),i=this.tree.prev(r),s=i?i.key:null,l=this.tree.next(r),u=l?l.key:null;if(t.isLeft){var h=[];if(s){var f=s.getIntersections(e);if(f.length>0){for(var c=this._possibleSplit(s,f),a=0,g=c.length;a<g;a++)n.push(c[a]);for(var p=0,y=f.length;p<y;p++){var v=f[p];e.isAnEndpoint(v)||h.push(v)}}}if(u){var d=u.getIntersections(e);if(d.length>0){for(var E=this._possibleSplit(u,d),_=0,m=E.length;_<m;_++)n.push(E[_]);for(var x=0,k=d.length;x<k;x++){var S=d[x];e.isAnEndpoint(S)||h.push(S)}}}if(n.length>0||h.length>0){if(this.tree.remove(e),h.length>0)for(var b=e.split(h),P=0,w=b.length;P<w;P++)n.push(b[P]);return n.push(t),n}this.segments.push(e),e.registerPrev(s)}else{if(s&&u){var O=s.getIntersections(u);if(O.length>0){for(var I=this._possibleSplit(s,O),R=0,N=I.length;R<N;R++)n.push(I[R]);for(var L=0,M=(I=this._possibleSplit(u,O)).length;L<M;L++)n.push(I[L])}}this.tree.remove(e)}return this.prevEvent&&0===(0,o.cmpPoints)(this.prevEvent.point,t.point)&&this.prevEvent.link(t),this.prevEvent=t,n}},{key:"_possibleSplit",value:function(t,e){for(var n=[],r=0,i=e.length;r<i;r++){var o=e[r];t.isAnEndpoint(o)||n.push(o)}var s=void 0;return n.length>0?(this.tree.remove(t),s=t.split(n),this.tree.insert(t)):s=[],s}}]),t}();e.default=u},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.MultiPoly=e.Poly=e.Ring=void 0;var r=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),i=n(1);function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}e.Ring=function(){function t(e){o(this,t),this.events=e;for(var n=0,r=e.length;n<r;n++)e[n].segment.registerRingOut(this);this.poly=null,this._clearCache()}return r(t,null,[{key:"factory",value:function(e){for(var n=[],r=0,i=e.length;r<i;r++){var o=e[r];if(o.isInResult&&!o.ringOut){for(var s=null,l=o.leftSE,u=o.rightSE,h=[l],f=l.linkedEvents,c=[];s=l,l=u,h.push(l),l.linkedEvents!==f;)for(;;){var a=l.getAvailableLinkedEvents();if(0===a.length){var g=h[0].point,p=h[h.length-1].point;throw new Error("Unable to complete output ring starting at ["+g.x+", "+g.y+"]. Last matching segment found ends at ["+p.x+", "+p.y+"].")}if(1===a.length){u=a[0].otherSE;break}for(var y=null,v=0,d=c.length;v<d;v++)if(c[v].linkedEvents===l.linkedEvents){y=v;break}if(null===y){c.push({index:h.length,linkedEvents:l.linkedEvents});var E=l.getLeftmostComparator(s);u=a.sort(E)[0].otherSE;break}var _=c.splice(y)[0],m=h.splice(_.index);m.unshift(m[0].otherSE),n.push(new t(m.reverse()))}n.push(new t(h))}}return n}}]),r(t,[{key:"registerPoly",value:function(t){this.poly=t}},{key:"getGeom",value:function(){for(var t=[[this.events[0].point.x,this.events[0].point.y]],e=1,n=this.events.length-1;e<n;e++){var r=this.events[e-1].point,o=this.events[e].point,s=this.events[e+1].point;0!==(0,i.compareVectorAngles)(o,r,s)&&t.push([o.x,o.y])}var l=this.events[this.events.length-2].point,u=this.events[0].point,h=this.events[1].point;return 0===(0,i.compareVectorAngles)(u,l,h)&&t.shift(),0===t.length?null:(t.push(t[0]),this.isExteriorRing?t:t.reverse())}},{key:"_clearCache",value:function(){this._cache={}}},{key:"_getCached",value:function(t,e){return void 0===this._cache[t]&&(this._cache[t]=this["_"+t].bind(this)()),this._cache[t]}},{key:"_isExteriorRing",value:function(){return!this.enclosingRing||!!this.enclosingRing.enclosingRing&&this.enclosingRing.enclosingRing.isExteriorRing}},{key:"_enclosingRing",value:function(){for(var t=this.events[0].segment.prevInResult;t&&t.ringOut===this;)t=t.prevInResult;for(var e=t?t.prevInResult:null;;){if(!t)return null;if(!e)return t.ringOut;if(e.ringOut!==t.ringOut)return e.ringOut.enclosingRing!==t.ringOut?t.ringOut:t.ringOut.enclosingRing;e=(t=e.prevInResult)?t.prevInResult:null}}},{key:"enclosingRing",get:function(){return this._getCached("enclosingRing")}},{key:"isExteriorRing",get:function(){return this._getCached("isExteriorRing")}}]),t}();var s=e.Poly=function(){function t(e){o(this,t),this.exteriorRing=e,e.registerPoly(this),this.interiorRings=[]}return r(t,[{key:"addInterior",value:function(t){this.interiorRings.push(t),t.registerPoly(this)}},{key:"getGeom",value:function(){var t=[this.exteriorRing.getGeom()];if(null===t[0])return null;for(var e=0,n=this.interiorRings.length;e<n;e++){var r=this.interiorRings[e].getGeom();null!==r&&t.push(r)}return t}}]),t}();e.MultiPoly=function(){function t(e){o(this,t),this.rings=e,this.polys=this._composePolys(e)}return r(t,[{key:"getGeom",value:function(){for(var t=[],e=0,n=this.polys.length;e<n;e++){var r=this.polys[e].getGeom();null!==r&&t.push(r)}return t}},{key:"_composePolys",value:function(t){for(var e=[],n=0,r=t.length;n<r;n++){var i=t[n];i.poly||(i.isExteriorRing?e.push(new s(i)):(i.enclosingRing.poly||e.push(new s(i.enclosingRing)),i.enclosingRing.poly.addInterior(i)))}return e}}]),t}()},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.getUniqueCorners=e.getBboxOverlap=e.doBboxesOverlap=e.isInBbox=void 0;var r=n(0),i=(e.isInBbox=function(t,e){var n=t.ll.x,i=t.ll.y,o=t.ur.x,s=t.ur.y,l=e.x,u=e.y;return(0,r.cmp)(n,l)<=0&&(0,r.cmp)(l,o)<=0&&(0,r.cmp)(i,u)<=0&&(0,r.cmp)(u,s)<=0},e.doBboxesOverlap=function(t,e){return!((0,r.cmp)(e.ur.x,t.ll.x)<0||(0,r.cmp)(t.ur.x,e.ll.x)<0||(0,r.cmp)(e.ur.y,t.ll.y)<0||(0,r.cmp)(t.ur.y,e.ll.y)<0)});e.getBboxOverlap=function(t,e){if(!i(t,e))return null;var n=t.ll.x<e.ll.x?e.ll.x:t.ll.x,r=t.ur.x<e.ur.x?t.ur.x:e.ur.x;return{ll:{x:n,y:t.ll.y<e.ll.y?e.ll.y:t.ll.y},ur:{x:r,y:t.ur.y<e.ur.y?t.ur.y:e.ur.y}}},e.getUniqueCorners=function(t){var e=t.ll.x,n=t.ll.y,i=t.ur.x,o=t.ur.y,s=0===(0,r.cmp)(e,i),l=0===(0,r.cmp)(n,o);return s&&l?[{x:e,y:n}]:s?[{x:e,y:n},{x:e,y:o}]:l?[{x:e,y:n},{x:i,y:n}]:[{x:e,y:n},{x:e,y:o},{x:i,y:n},{x:i,y:o}]}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.MultiPoly=e.Poly=e.Ring=void 0;var r,i=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),o=n(4),s=(r=o)&&r.__esModule?r:{default:r};function l(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var u=0,h=e.Ring=function(){function t(e,n){l(this,t),this.id=u++,this.poly=n,this.segments=[];for(var r=1,i=e.length;r<i;r++)this.segments.push(new s.default(e[r-1],e[r],this))}return i(t,[{key:"getSweepEvents",value:function(){for(var t=[],e=0,n=this.segments.length;e<n;e++){var r=this.segments[e];t.push(r.leftSE),t.push(r.rightSE)}return t}},{key:"isValid",value:function(t,e,n){var r=this.poly.exteriorRing,i=this.poly.interiorRings;if(this===r){for(var o=0,s=n.length;o<s;o++)if(i.includes(n[o]))return!1;for(var l=0,u=t.length;l<u;l++)if(i.includes(t[l]))return!1;return!0}if(!n.includes(r)&&!e.includes(r))return!1;for(var h=0,f=n.length;h<f;h++)if(i.includes(n[h]))return!1;for(var c=0,a=e.length;c<a;c++)if(i.includes(e[c]))return!1;return!0}},{key:"isExterior",get:function(){return this.poly.exteriorRing===this}},{key:"isInterior",get:function(){return this.poly.exteriorRing!==this}}]),t}(),f=e.Poly=function(){function t(e,n){l(this,t),this.exteriorRing=new h(e[0],this),this.interiorRings=[];for(var r=1,i=e.length;r<i;r++)this.interiorRings.push(new h(e[r],this));this.multiPoly=n}return i(t,[{key:"getSweepEvents",value:function(){for(var t=this.exteriorRing.getSweepEvents(),e=0,n=this.interiorRings.length;e<n;e++)for(var r=this.interiorRings[e].getSweepEvents(),i=0,o=r.length;i<o;i++)t.push(r[i]);return t}},{key:"isInside",value:function(t,e){for(var n=0,r=t.length;n<r;n++)if(t[n].poly===this)return!1;for(var i=!1,o=0,s=e.length;o<s;o++){var l=e[o];if(l.poly===this){if(l.isInterior)return!1;i=!0}}return i}}]),t}();e.MultiPoly=function(){function t(e){l(this,t),this.polys=[];for(var n=0,r=e.length;n<r;n++)this.polys.push(new f(e[n],this));this.isSubject=!1}return i(t,[{key:"markAsSubject",value:function(){this.isSubject=!0}},{key:"getSweepEvents",value:function(){for(var t=[],e=0,n=this.polys.length;e<n;e++)for(var r=this.polys[e].getSweepEvents(),i=0,o=r.length;i<o;i++)t.push(r[i]);return t}}]),t}()},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.errorOnSelfIntersectingRings=e.cleanRing=e.cleanMultiPoly=e.forceMultiPoly=e.pointsAsObjects=void 0;var r=n(0),i=n(1),o=(e.pointsAsObjects=function(t){var e=[];if(!Array.isArray(t))throw new Error("Input is not a Polygon or MultiPolygon");for(var n=0,r=t.length;n<r;n++){if(!Array.isArray(t[n]))throw new Error("Input is not a Polygon or MultiPolygon");e.push([]);for(var i=0,o=t[n].length;i<o;i++){if(!Array.isArray(t[n][i]))throw new Error("Input is not a Polygon or MultiPolygon");if(2!==t[n][i].length){e[n].push([]);for(var s=0,l=t[n][i].length;s<l;s++){if(!Array.isArray(t[n][i][s])||2!==t[n][i][s].length)throw new Error("Input is not a Polygon or MultiPolygon");e[n][i].push({x:t[n][i][s][0],y:t[n][i][s][1]})}}else e[n].push({x:t[n][i][0],y:t[n][i][1]})}}return e},e.forceMultiPoly=function(t){if(Array.isArray(t)){if(0===t.length)return;if(Array.isArray(t[0])){if(Array.isArray(t[0][0])&&"number"==typeof t[0][0][0].x&&"number"==typeof t[0][0][0].y)return;if("number"==typeof t[0][0].x&&"number"==typeof t[0][0].y)return void t.unshift(t.splice(0))}}throw new Error("Unrecognized input - not a polygon nor multipolygon")},e.cleanMultiPoly=function(t){for(var e=0;e<t.length;){var n=t[e];if(0!==n.length){var r=n[0];if(o(r),0!==r.length){for(var i=1;i<n.length;){var s=n[i];o(s),0===s.length?n.splice(i,1):i++}e++}else t.splice(e,1)}else t.splice(e,1)}},e.cleanRing=function(t){if(0!==t.length){0!==(0,r.cmpPoints)(t[0],t[t.length-1])&&t.push({x:t[0].x,y:t[0].y});for(var e=function(t,e,n){return 0===(0,r.cmpPoints)(t,e)||0===(0,r.cmpPoints)(e,n)||0===(0,i.compareVectorAngles)(e,t,n)},n=1;n<t.length-1;)e(t[n-1],t[n],t[n+1])?t.splice(n,1):n++;for(;t.length>2&&e(t[t.length-2],t[0],t[1]);)t.splice(0,1),t.splice(t.length-1,1),t.push(t[0]);for(;t.length<4&&t.length>0;)t.pop()}});e.errorOnSelfIntersectingRings=function(t){for(var e=function(e,n){var r=t[e],i=r.flowIntoSE;if(i.linkedEvents.length>2){var o=i.linkedEvents.filter(function(t){return t.segment.ringIn===r.ringIn});if(o.length>2){o.sort(i.getLeftmostComparator(i.otherSE));var s=o[1],l=o[o.length-1];if(s.segment.flowIntoSE===s||l.segment.flowIntoSE===l)throw new Error("Self-intersecting, crossing input ring found at ["+i.point.x+", "+i.point.y+"]")}}},n=0,r=t.length;n<r;n++)e(n)}},function(t,e,n){"use strict";function r(t,e){return t<e}function i(t){"function"==typeof(t=t||{})&&(t={compar:t}),t.compar?this._isBefore=function(e,n){return t.compar(e,n)<0}:t.comparBefore?this._isBefore=t.comparBefore:this._isBefore=r,this.length=0,this._freeSpace=!!t.freeSpace&&this._trimArraySize,this._list=new Array(t.size||100)}t.exports=i,i.prototype._list=null,i.prototype._compar=null,i.prototype._isBefore=null,i.prototype._freeSpace=null,i.prototype.length=0,i.prototype.insert=function(t){var e=++this.length,n=this._list;for(n[e]=t;e>1;){var r=e>>1,i=n[r];if(!this._isBefore(t,i))break;n[e]=i,e=r}n[e]=t},i.prototype.append=i.prototype.insert,i.prototype.push=i.prototype.insert,i.prototype.unshift=i.prototype.insert,i.prototype.enqueue=i.prototype.insert,i.prototype.peek=function(){return this.length>0?this._list[1]:void 0},i.prototype.size=function(){return this.length},i.prototype.remove=function(){if(!(this.length<1)){for(var t,e=this._list[1],n=this._list[this.length],r=1,i=2,o=this.length;i<o&&(t=this._list[i],this._isBefore(this._list[i+1],t)&&(t=this._list[i+1],i+=1),this._isBefore(t,n));)this._list[r]=t,r=i,i<<=1;return this._list[o]=0,this.length=--o,o&&(this._list[r]=n),this._freeSpace&&this._freeSpace(this._list,o),e}},i.prototype.shift=i.prototype.remove,i.prototype.pop=i.prototype.remove,i.prototype.dequeue=i.prototype.remove,i.prototype.gc=function(t){t||(t={});var e=t.minLength;void 0===e&&(e=0);var n=t.minFull;void 0===n&&(n=1),this._list.length>=e&&this.length<this._list.length*n&&this._list.splice(this.length+1,this._list.length)},i.prototype._trimArraySize=function(t,e){e>1e4&&t.length>4*e&&t.splice(e+1,t.length)},i.prototype._check=function(){var t,e,n=this._isBefore,r=function(t,e){return n(t,e)?-1:1},i=0;for(t=this.length;t>1;t--)e=t>>>1,r(this._list[e],this._list[t])>0&&r(this._list[t],this._list[e])<0&&(i=t);return i&&console.log("failed at",i>>>1,i),!i},i.prototype=i.prototype},function(t,e,n){t.exports=n(11)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t,e,n){for(var f=[i.pointsAsObjects(e)],c=0,a=n.length;c<a;c++)f.push(i.pointsAsObjects(n[c]));for(var g=0,p=f.length;g<p;g++)i.forceMultiPoly(f[g]),i.cleanMultiPoly(f[g]);for(var y=[],v=0,d=f.length;v<d;v++)y.push(new o.MultiPoly(f[v]));y[0].markAsSubject(),l.default.register(t,y.length);for(var E=new r.default({comparBefore:u.default.compareBefore}),_=0,m=y.length;_<m;_++)for(var x=y[_].getSweepEvents(),k=0,S=x.length;k<S;k++)E.insert(x[k]);var b=new h.default;for(;E.length;)for(var P=b.process(E.remove()),w=0,O=P.length;w<O;w++)E.insert(P[w]);i.errorOnSelfIntersectingRings(b.segments);var I=s.Ring.factory(b.segments);return new s.MultiPoly(I).getGeom()};var r=c(n(12)),i=f(n(10)),o=f(n(9)),s=f(n(7)),l=c(n(2)),u=c(n(3)),h=c(n(6));function f(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e.default=t,e}function c(t){return t&&t.__esModule?t:{default:t}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.difference=e.xor=e.intersection=e.union=void 0;var r=o(n(13)),i=o(n(2));function o(t){return t&&t.__esModule?t:{default:t}}e.union=function(t){for(var e=arguments.length,n=Array(e>1?e-1:0),o=1;o<e;o++)n[o-1]=arguments[o];return(0,r.default)(i.default.types.UNION,t,n)},e.intersection=function(t){for(var e=arguments.length,n=Array(e>1?e-1:0),o=1;o<e;o++)n[o-1]=arguments[o];return(0,r.default)(i.default.types.INTERSECTION,t,n)},e.xor=function(t){for(var e=arguments.length,n=Array(e>1?e-1:0),o=1;o<e;o++)n[o-1]=arguments[o];return(0,r.default)(i.default.types.XOR,t,n)},e.difference=function(t){for(var e=arguments.length,n=Array(e>1?e-1:0),o=1;o<e;o++)n[o-1]=arguments[o];return(0,r.default)(i.default.types.DIFFERENCE,t,n)}}])});
|
@@ -0,0 +1,911 @@
|
|
1
|
+
!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.RTree=e()}}(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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
|
2
|
+
'use strict';
|
3
|
+
var rectangle = _dereq_('./rectangle');
|
4
|
+
var bbox = function (ar, obj) {
|
5
|
+
if (obj && obj.bbox) {
|
6
|
+
return {
|
7
|
+
leaf: obj,
|
8
|
+
x: obj.bbox[0],
|
9
|
+
y: obj.bbox[1],
|
10
|
+
w: obj.bbox[2] - obj.bbox[0],
|
11
|
+
h: obj.bbox[3] - obj.bbox[1]
|
12
|
+
};
|
13
|
+
}
|
14
|
+
var len = ar.length;
|
15
|
+
var i = 0;
|
16
|
+
var a = new Array(len);
|
17
|
+
while (i < len) {
|
18
|
+
a[i] = [ar[i][0], ar[i][1]];
|
19
|
+
i++;
|
20
|
+
}
|
21
|
+
var first = a[0];
|
22
|
+
len = a.length;
|
23
|
+
i = 1;
|
24
|
+
var temp = {
|
25
|
+
min: [].concat(first),
|
26
|
+
max: [].concat(first)
|
27
|
+
};
|
28
|
+
while (i < len) {
|
29
|
+
if (a[i][0] < temp.min[0]) {
|
30
|
+
temp.min[0] = a[i][0];
|
31
|
+
}
|
32
|
+
else if (a[i][0] > temp.max[0]) {
|
33
|
+
temp.max[0] = a[i][0];
|
34
|
+
}
|
35
|
+
if (a[i][1] < temp.min[1]) {
|
36
|
+
temp.min[1] = a[i][1];
|
37
|
+
}
|
38
|
+
else if (a[i][1] > temp.max[1]) {
|
39
|
+
temp.max[1] = a[i][1];
|
40
|
+
}
|
41
|
+
i++;
|
42
|
+
}
|
43
|
+
var out = {
|
44
|
+
x: temp.min[0],
|
45
|
+
y: temp.min[1],
|
46
|
+
w: (temp.max[0] - temp.min[0]),
|
47
|
+
h: (temp.max[1] - temp.min[1])
|
48
|
+
};
|
49
|
+
if (obj) {
|
50
|
+
out.leaf = obj;
|
51
|
+
}
|
52
|
+
return out;
|
53
|
+
};
|
54
|
+
var geoJSON = {};
|
55
|
+
geoJSON.point = function (obj, self) {
|
56
|
+
return (self.insertSubtree({
|
57
|
+
x: obj.geometry.coordinates[0],
|
58
|
+
y: obj.geometry.coordinates[1],
|
59
|
+
w: 0,
|
60
|
+
h: 0,
|
61
|
+
leaf: obj
|
62
|
+
}, self.root));
|
63
|
+
};
|
64
|
+
geoJSON.multiPointLineString = function (obj, self) {
|
65
|
+
return (self.insertSubtree(bbox(obj.geometry.coordinates, obj), self.root));
|
66
|
+
};
|
67
|
+
geoJSON.multiLineStringPolygon = function (obj, self) {
|
68
|
+
return (self.insertSubtree(bbox(Array.prototype.concat.apply([], obj.geometry.coordinates), obj), self.root));
|
69
|
+
};
|
70
|
+
geoJSON.multiPolygon = function (obj, self) {
|
71
|
+
return (self.insertSubtree(bbox(Array.prototype.concat.apply([], Array.prototype.concat.apply([], obj.geometry.coordinates)), obj), self.root));
|
72
|
+
};
|
73
|
+
geoJSON.makeRec = function (obj) {
|
74
|
+
return rectangle(obj.x, obj.y, obj.w, obj.h);
|
75
|
+
};
|
76
|
+
geoJSON.geometryCollection = function (obj, self) {
|
77
|
+
if (obj.bbox) {
|
78
|
+
return (self.insertSubtree({
|
79
|
+
leaf: obj,
|
80
|
+
x: obj.bbox[0],
|
81
|
+
y: obj.bbox[1],
|
82
|
+
w: obj.bbox[2] - obj.bbox[0],
|
83
|
+
h: obj.bbox[3] - obj.bbox[1]
|
84
|
+
}, self.root));
|
85
|
+
}
|
86
|
+
var geos = obj.geometry.geometries;
|
87
|
+
var i = 0;
|
88
|
+
var len = geos.length;
|
89
|
+
var temp = [];
|
90
|
+
var g;
|
91
|
+
while (i < len) {
|
92
|
+
g = geos[i];
|
93
|
+
switch (g.type) {
|
94
|
+
case 'Point':
|
95
|
+
temp.push(geoJSON.makeRec({
|
96
|
+
x: g.coordinates[0],
|
97
|
+
y: g.coordinates[1],
|
98
|
+
w: 0,
|
99
|
+
h: 0
|
100
|
+
}));
|
101
|
+
break;
|
102
|
+
case 'MultiPoint':
|
103
|
+
temp.push(geoJSON.makeRec(bbox(g.coordinates)));
|
104
|
+
break;
|
105
|
+
case 'LineString':
|
106
|
+
temp.push(geoJSON.makeRec(bbox(g.coordinates)));
|
107
|
+
break;
|
108
|
+
case 'MultiLineString':
|
109
|
+
temp.push(geoJSON.makeRec(bbox(Array.prototype.concat.apply([], g.coordinates))));
|
110
|
+
break;
|
111
|
+
case 'Polygon':
|
112
|
+
temp.push(geoJSON.makeRec(bbox(Array.prototype.concat.apply([], g.coordinates))));
|
113
|
+
break;
|
114
|
+
case 'MultiPolygon':
|
115
|
+
temp.push(geoJSON.makeRec(bbox(Array.prototype.concat.apply([], Array.prototype.concat.apply([], g.coordinates)))));
|
116
|
+
break;
|
117
|
+
case 'GeometryCollection':
|
118
|
+
geos = geos.concat(g.geometries);
|
119
|
+
len = geos.length;
|
120
|
+
break;
|
121
|
+
}
|
122
|
+
i++;
|
123
|
+
}
|
124
|
+
var first = temp[0];
|
125
|
+
i = 1;
|
126
|
+
len = temp.length;
|
127
|
+
while (i < len) {
|
128
|
+
first.expand(temp[i]);
|
129
|
+
i++;
|
130
|
+
}
|
131
|
+
return self.insertSubtree({
|
132
|
+
leaf: obj,
|
133
|
+
x: first.x(),
|
134
|
+
y: first.y(),
|
135
|
+
h: first.h(),
|
136
|
+
w: first.w()
|
137
|
+
}, self.root);
|
138
|
+
};
|
139
|
+
exports.geoJSON = function (prelim) {
|
140
|
+
var that = this;
|
141
|
+
var features, feature;
|
142
|
+
if (Array.isArray(prelim)) {
|
143
|
+
features = prelim.slice();
|
144
|
+
}
|
145
|
+
else if (prelim.features && Array.isArray(prelim.features)) {
|
146
|
+
features = prelim.features.slice();
|
147
|
+
}
|
148
|
+
else if (prelim instanceof Object) {
|
149
|
+
features = [prelim];
|
150
|
+
} else {
|
151
|
+
throw ('this isn\'t what we\'re looking for');
|
152
|
+
}
|
153
|
+
var len = features.length;
|
154
|
+
var i = 0;
|
155
|
+
while (i < len) {
|
156
|
+
feature = features[i];
|
157
|
+
if (feature.type === 'Feature') {
|
158
|
+
switch (feature.geometry.type) {
|
159
|
+
case 'Point':
|
160
|
+
geoJSON.point(feature, that);
|
161
|
+
break;
|
162
|
+
case 'MultiPoint':
|
163
|
+
geoJSON.multiPointLineString(feature, that);
|
164
|
+
break;
|
165
|
+
case 'LineString':
|
166
|
+
geoJSON.multiPointLineString(feature, that);
|
167
|
+
break;
|
168
|
+
case 'MultiLineString':
|
169
|
+
geoJSON.multiLineStringPolygon(feature, that);
|
170
|
+
break;
|
171
|
+
case 'Polygon':
|
172
|
+
geoJSON.multiLineStringPolygon(feature, that);
|
173
|
+
break;
|
174
|
+
case 'MultiPolygon':
|
175
|
+
geoJSON.multiPolygon(feature, that);
|
176
|
+
break;
|
177
|
+
case 'GeometryCollection':
|
178
|
+
geoJSON.geometryCollection(feature, that);
|
179
|
+
break;
|
180
|
+
}
|
181
|
+
}
|
182
|
+
i++;
|
183
|
+
}
|
184
|
+
};
|
185
|
+
exports.bbox = function () {
|
186
|
+
var x1, y1, x2, y2;
|
187
|
+
switch (arguments.length) {
|
188
|
+
case 1:
|
189
|
+
x1 = arguments[0][0][0];
|
190
|
+
y1 = arguments[0][0][1];
|
191
|
+
x2 = arguments[0][1][0];
|
192
|
+
y2 = arguments[0][1][1];
|
193
|
+
break;
|
194
|
+
case 2:
|
195
|
+
x1 = arguments[0][0];
|
196
|
+
y1 = arguments[0][1];
|
197
|
+
x2 = arguments[1][0];
|
198
|
+
y2 = arguments[1][1];
|
199
|
+
break;
|
200
|
+
case 4:
|
201
|
+
x1 = arguments[0];
|
202
|
+
y1 = arguments[1];
|
203
|
+
x2 = arguments[2];
|
204
|
+
y2 = arguments[3];
|
205
|
+
break;
|
206
|
+
}
|
207
|
+
|
208
|
+
return this.search({
|
209
|
+
x: x1,
|
210
|
+
y: y1,
|
211
|
+
w: x2 - x1,
|
212
|
+
h: y2 - y1
|
213
|
+
});
|
214
|
+
};
|
215
|
+
|
216
|
+
},{"./rectangle":3}],2:[function(_dereq_,module,exports){
|
217
|
+
'use strict';
|
218
|
+
var RTree = _dereq_('./rtree');
|
219
|
+
var geojson = _dereq_('./geojson');
|
220
|
+
RTree.prototype.bbox = geojson.bbox;
|
221
|
+
RTree.prototype.geoJSON = geojson.geoJSON;
|
222
|
+
RTree.Rectangle = _dereq_('./rectangle');
|
223
|
+
module.exports = RTree;
|
224
|
+
},{"./geojson":1,"./rectangle":3,"./rtree":4}],3:[function(_dereq_,module,exports){
|
225
|
+
'use strict';
|
226
|
+
function Rectangle(x, y, w, h) { // new Rectangle(bounds) or new Rectangle(x, y, w, h)
|
227
|
+
if (!(this instanceof Rectangle)) {
|
228
|
+
return new Rectangle(x, y, w, h);
|
229
|
+
}
|
230
|
+
var x2, y2, p;
|
231
|
+
|
232
|
+
if (x.x) {
|
233
|
+
w = x.w;
|
234
|
+
h = x.h;
|
235
|
+
y = x.y;
|
236
|
+
if (x.w !== 0 && !x.w && x.x2) {
|
237
|
+
w = x.x2 - x.x;
|
238
|
+
h = x.y2 - x.y;
|
239
|
+
}
|
240
|
+
else {
|
241
|
+
w = x.w;
|
242
|
+
h = x.h;
|
243
|
+
}
|
244
|
+
x = x.x;
|
245
|
+
// For extra fastitude
|
246
|
+
x2 = x + w;
|
247
|
+
y2 = y + h;
|
248
|
+
p = (h + w) ? false : true;
|
249
|
+
}
|
250
|
+
else {
|
251
|
+
// For extra fastitude
|
252
|
+
x2 = x + w;
|
253
|
+
y2 = y + h;
|
254
|
+
p = (h + w) ? false : true;
|
255
|
+
}
|
256
|
+
|
257
|
+
this.x1 = this.x = function () {
|
258
|
+
return x;
|
259
|
+
};
|
260
|
+
this.y1 = this.y = function () {
|
261
|
+
return y;
|
262
|
+
};
|
263
|
+
this.x2 = function () {
|
264
|
+
return x2;
|
265
|
+
};
|
266
|
+
this.y2 = function () {
|
267
|
+
return y2;
|
268
|
+
};
|
269
|
+
this.w = function () {
|
270
|
+
return w;
|
271
|
+
};
|
272
|
+
this.h = function () {
|
273
|
+
return h;
|
274
|
+
};
|
275
|
+
this.p = function () {
|
276
|
+
return p;
|
277
|
+
};
|
278
|
+
|
279
|
+
this.overlap = function (a) {
|
280
|
+
if (p || a.p()) {
|
281
|
+
return x <= a.x2() && x2 >= a.x() && y <= a.y2() && y2 >= a.y();
|
282
|
+
}
|
283
|
+
return x < a.x2() && x2 > a.x() && y < a.y2() && y2 > a.y();
|
284
|
+
};
|
285
|
+
|
286
|
+
this.expand = function (a) {
|
287
|
+
var nx, ny;
|
288
|
+
var ax = a.x();
|
289
|
+
var ay = a.y();
|
290
|
+
var ax2 = a.x2();
|
291
|
+
var ay2 = a.y2();
|
292
|
+
if (x > ax) {
|
293
|
+
nx = ax;
|
294
|
+
}
|
295
|
+
else {
|
296
|
+
nx = x;
|
297
|
+
}
|
298
|
+
if (y > ay) {
|
299
|
+
ny = ay;
|
300
|
+
}
|
301
|
+
else {
|
302
|
+
ny = y;
|
303
|
+
}
|
304
|
+
if (x2 > ax2) {
|
305
|
+
w = x2 - nx;
|
306
|
+
}
|
307
|
+
else {
|
308
|
+
w = ax2 - nx;
|
309
|
+
}
|
310
|
+
if (y2 > ay2) {
|
311
|
+
h = y2 - ny;
|
312
|
+
}
|
313
|
+
else {
|
314
|
+
h = ay2 - ny;
|
315
|
+
}
|
316
|
+
x = nx;
|
317
|
+
y = ny;
|
318
|
+
return this;
|
319
|
+
};
|
320
|
+
|
321
|
+
//End of RTree.Rectangle
|
322
|
+
}
|
323
|
+
|
324
|
+
|
325
|
+
/* returns true if rectangle 1 overlaps rectangle 2
|
326
|
+
* [ boolean ] = overlapRectangle(rectangle a, rectangle b)
|
327
|
+
* @static function
|
328
|
+
*/
|
329
|
+
Rectangle.overlapRectangle = function (a, b) {
|
330
|
+
//if(!((a.h||a.w)&&(b.h||b.w))){ not faster resist the urge!
|
331
|
+
if ((a.h === 0 && a.w === 0) || (b.h === 0 && b.w === 0)) {
|
332
|
+
return a.x <= (b.x + b.w) && (a.x + a.w) >= b.x && a.y <= (b.y + b.h) && (a.y + a.h) >= b.y;
|
333
|
+
}
|
334
|
+
else {
|
335
|
+
return a.x < (b.x + b.w) && (a.x + a.w) > b.x && a.y < (b.y + b.h) && (a.y + a.h) > b.y;
|
336
|
+
}
|
337
|
+
};
|
338
|
+
|
339
|
+
/* returns true if rectangle a is contained in rectangle b
|
340
|
+
* [ boolean ] = containsRectangle(rectangle a, rectangle b)
|
341
|
+
* @static function
|
342
|
+
*/
|
343
|
+
Rectangle.containsRectangle = function (a, b) {
|
344
|
+
return (a.x + a.w) <= (b.x + b.w) && a.x >= b.x && (a.y + a.h) <= (b.y + b.h) && a.y >= b.y;
|
345
|
+
};
|
346
|
+
|
347
|
+
/* expands rectangle A to include rectangle B, rectangle B is untouched
|
348
|
+
* [ rectangle a ] = expandRectangle(rectangle a, rectangle b)
|
349
|
+
* @static function
|
350
|
+
*/
|
351
|
+
Rectangle.expandRectangle = function (a, b) {
|
352
|
+
var nx, ny;
|
353
|
+
var axw = a.x + a.w;
|
354
|
+
var bxw = b.x + b.w;
|
355
|
+
var ayh = a.y + a.h;
|
356
|
+
var byh = b.y + b.h;
|
357
|
+
if (a.x > b.x) {
|
358
|
+
nx = b.x;
|
359
|
+
}
|
360
|
+
else {
|
361
|
+
nx = a.x;
|
362
|
+
}
|
363
|
+
if (a.y > b.y) {
|
364
|
+
ny = b.y;
|
365
|
+
}
|
366
|
+
else {
|
367
|
+
ny = a.y;
|
368
|
+
}
|
369
|
+
if (axw > bxw) {
|
370
|
+
a.w = axw - nx;
|
371
|
+
}
|
372
|
+
else {
|
373
|
+
a.w = bxw - nx;
|
374
|
+
}
|
375
|
+
if (ayh > byh) {
|
376
|
+
a.h = ayh - ny;
|
377
|
+
}
|
378
|
+
else {
|
379
|
+
a.h = byh - ny;
|
380
|
+
}
|
381
|
+
a.x = nx;
|
382
|
+
a.y = ny;
|
383
|
+
return a;
|
384
|
+
};
|
385
|
+
|
386
|
+
/* generates a minimally bounding rectangle for all rectangles in
|
387
|
+
* array 'nodes'. If rect is set, it is modified into the MBR. Otherwise,
|
388
|
+
* a new rectangle is generated and returned.
|
389
|
+
* [ rectangle a ] = makeMBR(rectangle array nodes, rectangle rect)
|
390
|
+
* @static function
|
391
|
+
*/
|
392
|
+
Rectangle.makeMBR = function (nodes, rect) {
|
393
|
+
if (!nodes.length) {
|
394
|
+
return {
|
395
|
+
x: 0,
|
396
|
+
y: 0,
|
397
|
+
w: 0,
|
398
|
+
h: 0
|
399
|
+
};
|
400
|
+
}
|
401
|
+
rect = rect || {};
|
402
|
+
rect.x = nodes[0].x;
|
403
|
+
rect.y = nodes[0].y;
|
404
|
+
rect.w = nodes[0].w;
|
405
|
+
rect.h = nodes[0].h;
|
406
|
+
|
407
|
+
for (var i = 1, len = nodes.length; i < len; i++) {
|
408
|
+
Rectangle.expandRectangle(rect, nodes[i]);
|
409
|
+
}
|
410
|
+
|
411
|
+
return rect;
|
412
|
+
};
|
413
|
+
Rectangle.squarifiedRatio = function (l, w, fill) {
|
414
|
+
// Area of new enlarged rectangle
|
415
|
+
var lperi = (l + w) / 2.0; // Average size of a side of the new rectangle
|
416
|
+
var larea = l * w; // Area of new rectangle
|
417
|
+
// return the ratio of the perimeter to the area - the closer to 1 we are,
|
418
|
+
// the more 'square' a rectangle is. conversly, when approaching zero the
|
419
|
+
// more elongated a rectangle is
|
420
|
+
var lgeo = larea / (lperi * lperi);
|
421
|
+
return larea * fill / lgeo;
|
422
|
+
};
|
423
|
+
module.exports = Rectangle;
|
424
|
+
},{}],4:[function(_dereq_,module,exports){
|
425
|
+
'use strict';
|
426
|
+
var rectangle = _dereq_('./rectangle');
|
427
|
+
function RTree(width) {
|
428
|
+
if (!(this instanceof RTree)) {
|
429
|
+
return new RTree(width);
|
430
|
+
}
|
431
|
+
// Variables to control tree-dimensions
|
432
|
+
var minWidth = 3; // Minimum width of any node before a merge
|
433
|
+
var maxWidth = 6; // Maximum width of any node before a split
|
434
|
+
if (!isNaN(width)) {
|
435
|
+
minWidth = Math.floor(width / 2.0);
|
436
|
+
maxWidth = width;
|
437
|
+
}
|
438
|
+
// Start with an empty root-tree
|
439
|
+
var rootTree = {x: 0, y: 0, w: 0, h: 0, id: 'root', nodes: [] };
|
440
|
+
this.root = rootTree;
|
441
|
+
|
442
|
+
|
443
|
+
// This is my special addition to the world of r-trees
|
444
|
+
// every other (simple) method I found produced crap trees
|
445
|
+
// this skews insertions to prefering squarer and emptier nodes
|
446
|
+
var flatten = function (tree) {
|
447
|
+
var todo = tree.slice();
|
448
|
+
var done = [];
|
449
|
+
var current;
|
450
|
+
while (todo.length) {
|
451
|
+
current = todo.pop();
|
452
|
+
if (current.nodes) {
|
453
|
+
todo = todo.concat(current.nodes);
|
454
|
+
} else if (current.leaf) {
|
455
|
+
done.push(current);
|
456
|
+
}
|
457
|
+
}
|
458
|
+
return done;
|
459
|
+
};
|
460
|
+
/* find the best specific node(s) for object to be deleted from
|
461
|
+
* [ leaf node parent ] = removeSubtree(rectangle, object, root)
|
462
|
+
* @private
|
463
|
+
*/
|
464
|
+
var removeSubtree = function (rect, obj, root) {
|
465
|
+
var hitStack = []; // Contains the elements that overlap
|
466
|
+
var countStack = []; // Contains the elements that overlap
|
467
|
+
var retArray = [];
|
468
|
+
var currentDepth = 1;
|
469
|
+
var tree, i, ltree;
|
470
|
+
if (!rect || !rectangle.overlapRectangle(rect, root)) {
|
471
|
+
return retArray;
|
472
|
+
}
|
473
|
+
var retObj = {x: rect.x, y: rect.y, w: rect.w, h: rect.h, target: obj};
|
474
|
+
|
475
|
+
countStack.push(root.nodes.length);
|
476
|
+
hitStack.push(root);
|
477
|
+
while (hitStack.length > 0) {
|
478
|
+
tree = hitStack.pop();
|
479
|
+
i = countStack.pop() - 1;
|
480
|
+
if ('target' in retObj) { // will this ever be false?
|
481
|
+
while (i >= 0) {
|
482
|
+
ltree = tree.nodes[i];
|
483
|
+
if (rectangle.overlapRectangle(retObj, ltree)) {
|
484
|
+
if ((retObj.target && 'leaf' in ltree && ltree.leaf === retObj.target) || (!retObj.target && ('leaf' in ltree || rectangle.containsRectangle(ltree, retObj)))) {
|
485
|
+
// A Match !!
|
486
|
+
// Yup we found a match...
|
487
|
+
// we can cancel search and start walking up the list
|
488
|
+
if ('nodes' in ltree) {// If we are deleting a node not a leaf...
|
489
|
+
retArray = flatten(tree.nodes.splice(i, 1));
|
490
|
+
} else {
|
491
|
+
retArray = tree.nodes.splice(i, 1);
|
492
|
+
}
|
493
|
+
// Resize MBR down...
|
494
|
+
rectangle.makeMBR(tree.nodes, tree);
|
495
|
+
delete retObj.target;
|
496
|
+
//if (tree.nodes.length < minWidth) { // Underflow
|
497
|
+
// retObj.nodes = searchSubtree(tree, true, [], tree);
|
498
|
+
//}
|
499
|
+
break;
|
500
|
+
} else if ('nodes' in ltree) { // Not a Leaf
|
501
|
+
currentDepth++;
|
502
|
+
countStack.push(i);
|
503
|
+
hitStack.push(tree);
|
504
|
+
tree = ltree;
|
505
|
+
i = ltree.nodes.length;
|
506
|
+
}
|
507
|
+
}
|
508
|
+
i--;
|
509
|
+
}
|
510
|
+
|
511
|
+
} else if ('nodes' in retObj) { // We are unsplitting
|
512
|
+
|
513
|
+
tree.nodes.splice(i + 1, 1); // Remove unsplit node
|
514
|
+
if (tree.nodes.length > 0) {
|
515
|
+
rectangle.makeMBR(tree.nodes, tree);
|
516
|
+
}
|
517
|
+
for (var t = 0;t < retObj.nodes.length;t++) {
|
518
|
+
insertSubtree(retObj.nodes[t], tree);
|
519
|
+
}
|
520
|
+
retObj.nodes = [];
|
521
|
+
if (hitStack.length === 0 && tree.nodes.length <= 1) { // Underflow..on root!
|
522
|
+
retObj.nodes = searchSubtree(tree, true, retObj.nodes, tree);
|
523
|
+
tree.nodes = [];
|
524
|
+
hitStack.push(tree);
|
525
|
+
countStack.push(1);
|
526
|
+
} else if (hitStack.length > 0 && tree.nodes.length < minWidth) { // Underflow..AGAIN!
|
527
|
+
retObj.nodes = searchSubtree(tree, true, retObj.nodes, tree);
|
528
|
+
tree.nodes = [];
|
529
|
+
} else {
|
530
|
+
delete retObj.nodes; // Just start resizing
|
531
|
+
}
|
532
|
+
} else { // we are just resizing
|
533
|
+
rectangle.makeMBR(tree.nodes, tree);
|
534
|
+
}
|
535
|
+
currentDepth -= 1;
|
536
|
+
}
|
537
|
+
return retArray;
|
538
|
+
};
|
539
|
+
|
540
|
+
/* choose the best damn node for rectangle to be inserted into
|
541
|
+
* [ leaf node parent ] = chooseLeafSubtree(rectangle, root to start search at)
|
542
|
+
* @private
|
543
|
+
*/
|
544
|
+
var chooseLeafSubtree = function (rect, root) {
|
545
|
+
var bestChoiceIndex = -1;
|
546
|
+
var bestChoiceStack = [];
|
547
|
+
var bestChoiceArea;
|
548
|
+
var first = true;
|
549
|
+
bestChoiceStack.push(root);
|
550
|
+
var nodes = root.nodes;
|
551
|
+
|
552
|
+
while (first || bestChoiceIndex !== -1) {
|
553
|
+
if (first) {
|
554
|
+
first = false;
|
555
|
+
} else {
|
556
|
+
bestChoiceStack.push(nodes[bestChoiceIndex]);
|
557
|
+
nodes = nodes[bestChoiceIndex].nodes;
|
558
|
+
bestChoiceIndex = -1;
|
559
|
+
}
|
560
|
+
|
561
|
+
for (var i = nodes.length - 1; i >= 0; i--) {
|
562
|
+
var ltree = nodes[i];
|
563
|
+
if ('leaf' in ltree) {
|
564
|
+
// Bail out of everything and start inserting
|
565
|
+
bestChoiceIndex = -1;
|
566
|
+
break;
|
567
|
+
}
|
568
|
+
// Area of new enlarged rectangle
|
569
|
+
var oldLRatio = rectangle.squarifiedRatio(ltree.w, ltree.h, ltree.nodes.length + 1);
|
570
|
+
|
571
|
+
// Enlarge rectangle to fit new rectangle
|
572
|
+
var nw = Math.max(ltree.x + ltree.w, rect.x + rect.w) - Math.min(ltree.x, rect.x);
|
573
|
+
var nh = Math.max(ltree.y + ltree.h, rect.y + rect.h) - Math.min(ltree.y, rect.y);
|
574
|
+
|
575
|
+
// Area of new enlarged rectangle
|
576
|
+
var lratio = rectangle.squarifiedRatio(nw, nh, ltree.nodes.length + 2);
|
577
|
+
|
578
|
+
if (bestChoiceIndex < 0 || Math.abs(lratio - oldLRatio) < bestChoiceArea) {
|
579
|
+
bestChoiceArea = Math.abs(lratio - oldLRatio);
|
580
|
+
bestChoiceIndex = i;
|
581
|
+
}
|
582
|
+
}
|
583
|
+
}
|
584
|
+
|
585
|
+
return bestChoiceStack;
|
586
|
+
};
|
587
|
+
|
588
|
+
/* split a set of nodes into two roughly equally-filled nodes
|
589
|
+
* [ an array of two new arrays of nodes ] = linearSplit(array of nodes)
|
590
|
+
* @private
|
591
|
+
*/
|
592
|
+
var linearSplit = function (nodes) {
|
593
|
+
var n = pickLinear(nodes);
|
594
|
+
while (nodes.length > 0) {
|
595
|
+
pickNext(nodes, n[0], n[1]);
|
596
|
+
}
|
597
|
+
return n;
|
598
|
+
};
|
599
|
+
|
600
|
+
/* insert the best source rectangle into the best fitting parent node: a or b
|
601
|
+
* [] = pickNext(array of source nodes, target node array a, target node array b)
|
602
|
+
* @private
|
603
|
+
*/
|
604
|
+
var pickNext = function (nodes, a, b) {
|
605
|
+
// Area of new enlarged rectangle
|
606
|
+
var areaA = rectangle.squarifiedRatio(a.w, a.h, a.nodes.length + 1);
|
607
|
+
var areaB = rectangle.squarifiedRatio(b.w, b.h, b.nodes.length + 1);
|
608
|
+
var highAreaDelta;
|
609
|
+
var highAreaNode;
|
610
|
+
var lowestGrowthGroup;
|
611
|
+
|
612
|
+
for (var i = nodes.length - 1; i >= 0;i--) {
|
613
|
+
var l = nodes[i];
|
614
|
+
var newAreaA = {};
|
615
|
+
newAreaA.x = Math.min(a.x, l.x);
|
616
|
+
newAreaA.y = Math.min(a.y, l.y);
|
617
|
+
newAreaA.w = Math.max(a.x + a.w, l.x + l.w) - newAreaA.x;
|
618
|
+
newAreaA.h = Math.max(a.y + a.h, l.y + l.h) - newAreaA.y;
|
619
|
+
var changeNewAreaA = Math.abs(rectangle.squarifiedRatio(newAreaA.w, newAreaA.h, a.nodes.length + 2) - areaA);
|
620
|
+
|
621
|
+
var newAreaB = {};
|
622
|
+
newAreaB.x = Math.min(b.x, l.x);
|
623
|
+
newAreaB.y = Math.min(b.y, l.y);
|
624
|
+
newAreaB.w = Math.max(b.x + b.w, l.x + l.w) - newAreaB.x;
|
625
|
+
newAreaB.h = Math.max(b.y + b.h, l.y + l.h) - newAreaB.y;
|
626
|
+
var changeNewAreaB = Math.abs(rectangle.squarifiedRatio(newAreaB.w, newAreaB.h, b.nodes.length + 2) - areaB);
|
627
|
+
|
628
|
+
if (!highAreaNode || !highAreaDelta || Math.abs(changeNewAreaB - changeNewAreaA) < highAreaDelta) {
|
629
|
+
highAreaNode = i;
|
630
|
+
highAreaDelta = Math.abs(changeNewAreaB - changeNewAreaA);
|
631
|
+
lowestGrowthGroup = changeNewAreaB < changeNewAreaA ? b : a;
|
632
|
+
}
|
633
|
+
}
|
634
|
+
var tempNode = nodes.splice(highAreaNode, 1)[0];
|
635
|
+
if (a.nodes.length + nodes.length + 1 <= minWidth) {
|
636
|
+
a.nodes.push(tempNode);
|
637
|
+
rectangle.expandRectangle(a, tempNode);
|
638
|
+
} else if (b.nodes.length + nodes.length + 1 <= minWidth) {
|
639
|
+
b.nodes.push(tempNode);
|
640
|
+
rectangle.expandRectangle(b, tempNode);
|
641
|
+
}
|
642
|
+
else {
|
643
|
+
lowestGrowthGroup.nodes.push(tempNode);
|
644
|
+
rectangle.expandRectangle(lowestGrowthGroup, tempNode);
|
645
|
+
}
|
646
|
+
};
|
647
|
+
|
648
|
+
/* pick the 'best' two starter nodes to use as seeds using the 'linear' criteria
|
649
|
+
* [ an array of two new arrays of nodes ] = pickLinear(array of source nodes)
|
650
|
+
* @private
|
651
|
+
*/
|
652
|
+
var pickLinear = function (nodes) {
|
653
|
+
var lowestHighX = nodes.length - 1;
|
654
|
+
var highestLowX = 0;
|
655
|
+
var lowestHighY = nodes.length - 1;
|
656
|
+
var highestLowY = 0;
|
657
|
+
var t1, t2;
|
658
|
+
|
659
|
+
for (var i = nodes.length - 2; i >= 0;i--) {
|
660
|
+
var l = nodes[i];
|
661
|
+
if (l.x > nodes[highestLowX].x) {
|
662
|
+
highestLowX = i;
|
663
|
+
} else if (l.x + l.w < nodes[lowestHighX].x + nodes[lowestHighX].w) {
|
664
|
+
lowestHighX = i;
|
665
|
+
}
|
666
|
+
if (l.y > nodes[highestLowY].y) {
|
667
|
+
highestLowY = i;
|
668
|
+
} else if (l.y + l.h < nodes[lowestHighY].y + nodes[lowestHighY].h) {
|
669
|
+
lowestHighY = i;
|
670
|
+
}
|
671
|
+
}
|
672
|
+
var dx = Math.abs((nodes[lowestHighX].x + nodes[lowestHighX].w) - nodes[highestLowX].x);
|
673
|
+
var dy = Math.abs((nodes[lowestHighY].y + nodes[lowestHighY].h) - nodes[highestLowY].y);
|
674
|
+
if (dx > dy) {
|
675
|
+
if (lowestHighX > highestLowX) {
|
676
|
+
t1 = nodes.splice(lowestHighX, 1)[0];
|
677
|
+
t2 = nodes.splice(highestLowX, 1)[0];
|
678
|
+
} else {
|
679
|
+
t2 = nodes.splice(highestLowX, 1)[0];
|
680
|
+
t1 = nodes.splice(lowestHighX, 1)[0];
|
681
|
+
}
|
682
|
+
} else {
|
683
|
+
if (lowestHighY > highestLowY) {
|
684
|
+
t1 = nodes.splice(lowestHighY, 1)[0];
|
685
|
+
t2 = nodes.splice(highestLowY, 1)[0];
|
686
|
+
} else {
|
687
|
+
t2 = nodes.splice(highestLowY, 1)[0];
|
688
|
+
t1 = nodes.splice(lowestHighY, 1)[0];
|
689
|
+
}
|
690
|
+
}
|
691
|
+
return [
|
692
|
+
{x: t1.x, y: t1.y, w: t1.w, h: t1.h, nodes: [t1]},
|
693
|
+
{x: t2.x, y: t2.y, w: t2.w, h: t2.h, nodes: [t2]}
|
694
|
+
];
|
695
|
+
};
|
696
|
+
|
697
|
+
var attachData = function (node, moreTree) {
|
698
|
+
node.nodes = moreTree.nodes;
|
699
|
+
node.x = moreTree.x;
|
700
|
+
node.y = moreTree.y;
|
701
|
+
node.w = moreTree.w;
|
702
|
+
node.h = moreTree.h;
|
703
|
+
return node;
|
704
|
+
};
|
705
|
+
|
706
|
+
/* non-recursive internal search function
|
707
|
+
* [ nodes | objects ] = searchSubtree(rectangle, [return node data], [array to fill], root to begin search at)
|
708
|
+
* @private
|
709
|
+
*/
|
710
|
+
var searchSubtree = function (rect, returnNode, returnArray, root) {
|
711
|
+
var hitStack = []; // Contains the elements that overlap
|
712
|
+
|
713
|
+
if (!rectangle.overlapRectangle(rect, root)) {
|
714
|
+
return returnArray;
|
715
|
+
}
|
716
|
+
|
717
|
+
|
718
|
+
hitStack.push(root.nodes);
|
719
|
+
|
720
|
+
while (hitStack.length > 0) {
|
721
|
+
var nodes = hitStack.pop();
|
722
|
+
|
723
|
+
for (var i = nodes.length - 1; i >= 0; i--) {
|
724
|
+
var ltree = nodes[i];
|
725
|
+
if (rectangle.overlapRectangle(rect, ltree)) {
|
726
|
+
if ('nodes' in ltree) { // Not a Leaf
|
727
|
+
hitStack.push(ltree.nodes);
|
728
|
+
} else if ('leaf' in ltree) { // A Leaf !!
|
729
|
+
if (!returnNode) {
|
730
|
+
returnArray.push(ltree.leaf);
|
731
|
+
} else {
|
732
|
+
returnArray.push(ltree);
|
733
|
+
}
|
734
|
+
}
|
735
|
+
}
|
736
|
+
}
|
737
|
+
}
|
738
|
+
|
739
|
+
return returnArray;
|
740
|
+
};
|
741
|
+
|
742
|
+
/* non-recursive internal insert function
|
743
|
+
* [] = insertSubtree(rectangle, object to insert, root to begin insertion at)
|
744
|
+
* @private
|
745
|
+
*/
|
746
|
+
var insertSubtree = function (node, root) {
|
747
|
+
var bc; // Best Current node
|
748
|
+
// Initial insertion is special because we resize the Tree and we don't
|
749
|
+
// care about any overflow (seriously, how can the first object overflow?)
|
750
|
+
if (root.nodes.length === 0) {
|
751
|
+
root.x = node.x;
|
752
|
+
root.y = node.y;
|
753
|
+
root.w = node.w;
|
754
|
+
root.h = node.h;
|
755
|
+
root.nodes.push(node);
|
756
|
+
return;
|
757
|
+
}
|
758
|
+
|
759
|
+
// Find the best fitting leaf node
|
760
|
+
// chooseLeaf returns an array of all tree levels (including root)
|
761
|
+
// that were traversed while trying to find the leaf
|
762
|
+
var treeStack = chooseLeafSubtree(node, root);
|
763
|
+
var retObj = node;//{x:rect.x,y:rect.y,w:rect.w,h:rect.h, leaf:obj};
|
764
|
+
var pbc;
|
765
|
+
// Walk back up the tree resizing and inserting as needed
|
766
|
+
while (treeStack.length > 0) {
|
767
|
+
//handle the case of an empty node (from a split)
|
768
|
+
if (bc && 'nodes' in bc && bc.nodes.length === 0) {
|
769
|
+
pbc = bc; // Past bc
|
770
|
+
bc = treeStack.pop();
|
771
|
+
for (var t = 0;t < bc.nodes.length;t++) {
|
772
|
+
if (bc.nodes[t] === pbc || bc.nodes[t].nodes.length === 0) {
|
773
|
+
bc.nodes.splice(t, 1);
|
774
|
+
break;
|
775
|
+
}
|
776
|
+
}
|
777
|
+
} else {
|
778
|
+
bc = treeStack.pop();
|
779
|
+
}
|
780
|
+
|
781
|
+
// If there is data attached to this retObj
|
782
|
+
if ('leaf' in retObj || 'nodes' in retObj || Array.isArray(retObj)) {
|
783
|
+
// Do Insert
|
784
|
+
if (Array.isArray(retObj)) {
|
785
|
+
for (var ai = 0; ai < retObj.length; ai++) {
|
786
|
+
rectangle.expandRectangle(bc, retObj[ai]);
|
787
|
+
}
|
788
|
+
bc.nodes = bc.nodes.concat(retObj);
|
789
|
+
} else {
|
790
|
+
rectangle.expandRectangle(bc, retObj);
|
791
|
+
bc.nodes.push(retObj); // Do Insert
|
792
|
+
}
|
793
|
+
|
794
|
+
if (bc.nodes.length <= maxWidth) { // Start Resizeing Up the Tree
|
795
|
+
retObj = {x: bc.x, y: bc.y, w: bc.w, h: bc.h};
|
796
|
+
} else { // Otherwise Split this Node
|
797
|
+
// linearSplit() returns an array containing two new nodes
|
798
|
+
// formed from the split of the previous node's overflow
|
799
|
+
var a = linearSplit(bc.nodes);
|
800
|
+
retObj = a;//[1];
|
801
|
+
|
802
|
+
if (treeStack.length < 1) { // If are splitting the root..
|
803
|
+
bc.nodes.push(a[0]);
|
804
|
+
treeStack.push(bc); // Reconsider the root element
|
805
|
+
retObj = a[1];
|
806
|
+
} /*else {
|
807
|
+
delete bc;
|
808
|
+
}*/
|
809
|
+
}
|
810
|
+
} else { // Otherwise Do Resize
|
811
|
+
//Just keep applying the new bounding rectangle to the parents..
|
812
|
+
rectangle.expandRectangle(bc, retObj);
|
813
|
+
retObj = {x: bc.x, y: bc.y, w: bc.w, h: bc.h};
|
814
|
+
}
|
815
|
+
}
|
816
|
+
};
|
817
|
+
|
818
|
+
this.insertSubtree = insertSubtree;
|
819
|
+
/* quick 'n' dirty function for plugins or manually drawing the tree
|
820
|
+
* [ tree ] = RTree.getTree(): returns the raw tree data. useful for adding
|
821
|
+
* @public
|
822
|
+
* !! DEPRECATED !!
|
823
|
+
*/
|
824
|
+
this.getTree = function () {
|
825
|
+
return rootTree;
|
826
|
+
};
|
827
|
+
|
828
|
+
/* quick 'n' dirty function for plugins or manually loading the tree
|
829
|
+
* [ tree ] = RTree.setTree(sub-tree, where to attach): returns the raw tree data. useful for adding
|
830
|
+
* @public
|
831
|
+
* !! DEPRECATED !!
|
832
|
+
*/
|
833
|
+
this.setTree = function (newTree, where) {
|
834
|
+
if (!where) {
|
835
|
+
where = rootTree;
|
836
|
+
}
|
837
|
+
return attachData(where, newTree);
|
838
|
+
};
|
839
|
+
|
840
|
+
/* non-recursive search function
|
841
|
+
* [ nodes | objects ] = RTree.search(rectangle, [return node data], [array to fill])
|
842
|
+
* @public
|
843
|
+
*/
|
844
|
+
this.search = function (rect, returnNode, returnArray) {
|
845
|
+
returnArray = returnArray || [];
|
846
|
+
return searchSubtree(rect, returnNode, returnArray, rootTree);
|
847
|
+
};
|
848
|
+
|
849
|
+
|
850
|
+
var removeArea = function (rect) {
|
851
|
+
var numberDeleted = 1,
|
852
|
+
retArray = [],
|
853
|
+
deleted;
|
854
|
+
while (numberDeleted > 0) {
|
855
|
+
deleted = removeSubtree(rect, false, rootTree);
|
856
|
+
numberDeleted = deleted.length;
|
857
|
+
retArray = retArray.concat(deleted);
|
858
|
+
}
|
859
|
+
return retArray;
|
860
|
+
};
|
861
|
+
|
862
|
+
var removeObj = function (rect, obj) {
|
863
|
+
var retArray = removeSubtree(rect, obj, rootTree);
|
864
|
+
return retArray;
|
865
|
+
};
|
866
|
+
/* non-recursive delete function
|
867
|
+
* [deleted object] = RTree.remove(rectangle, [object to delete])
|
868
|
+
*/
|
869
|
+
this.remove = function (rect, obj) {
|
870
|
+
if (!obj || typeof obj === 'function') {
|
871
|
+
return removeArea(rect, obj);
|
872
|
+
} else {
|
873
|
+
return removeObj(rect, obj);
|
874
|
+
}
|
875
|
+
};
|
876
|
+
|
877
|
+
/* non-recursive insert function
|
878
|
+
* [] = RTree.insert(rectangle, object to insert)
|
879
|
+
*/
|
880
|
+
this.insert = function (rect, obj) {
|
881
|
+
var retArray = insertSubtree({x: rect.x, y: rect.y, w: rect.w, h: rect.h, leaf: obj}, rootTree);
|
882
|
+
return retArray;
|
883
|
+
};
|
884
|
+
}
|
885
|
+
RTree.prototype.toJSON = function (printing) {
|
886
|
+
return JSON.stringify(this.root, false, printing);
|
887
|
+
};
|
888
|
+
|
889
|
+
RTree.fromJSON = function (json) {
|
890
|
+
var rt = new RTree();
|
891
|
+
rt.setTree(JSON.parse(json));
|
892
|
+
return rt;
|
893
|
+
};
|
894
|
+
|
895
|
+
module.exports = RTree;
|
896
|
+
|
897
|
+
|
898
|
+
/**
|
899
|
+
* Polyfill for the Array.isArray function
|
900
|
+
* todo: Test on IE7 and IE8
|
901
|
+
* Taken from https://github.com/geraintluff/tv4/issues/20
|
902
|
+
*/
|
903
|
+
if (typeof Array.isArray !== 'function') {
|
904
|
+
Array.isArray = function (a) {
|
905
|
+
return typeof a === 'object' && {}.toString.call(a) === '[object Array]';
|
906
|
+
};
|
907
|
+
}
|
908
|
+
|
909
|
+
},{"./rectangle":3}]},{},[2])
|
910
|
+
(2)
|
911
|
+
});
|