ekylibre-cartography 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +3 -0
  3. data/Rakefile +10 -0
  4. data/app/assets/javascripts/cartography.coffee +535 -0
  5. data/app/assets/javascripts/cartography/base.coffee +11 -0
  6. data/app/assets/javascripts/cartography/controls.coffee +463 -0
  7. data/app/assets/javascripts/cartography/events.coffee +36 -0
  8. data/app/assets/javascripts/cartography/layers.coffee +127 -0
  9. data/app/assets/javascripts/cartography/layers/simple.coffee +37 -0
  10. data/app/assets/javascripts/cartography/leaflet/controls.coffee +420 -0
  11. data/app/assets/javascripts/cartography/leaflet/handlers.coffee +461 -0
  12. data/app/assets/javascripts/cartography/leaflet/i18n.coffee +31 -0
  13. data/app/assets/javascripts/cartography/leaflet/layers.coffee +60 -0
  14. data/app/assets/javascripts/cartography/leaflet/toolbars.coffee +450 -0
  15. data/app/assets/javascripts/cartography/patches.js +8 -0
  16. data/app/assets/javascripts/cartography/util.coffee +18 -0
  17. data/app/assets/javascripts/main.js +18 -0
  18. data/app/assets/stylesheets/cartography.css +86 -0
  19. data/app/helpers/cartography_helper.rb +55 -0
  20. data/lib/cartography.rb +1 -0
  21. data/lib/cartography/engine.rb +11 -0
  22. data/lib/cartography/version.rb +3 -0
  23. data/vendor/assets/components/d3-array/dist/d3-array.js +590 -0
  24. data/vendor/assets/components/d3-array/dist/d3-array.min.js +2 -0
  25. data/vendor/assets/components/geojson-equality/dist/geojson-equality.js +295 -0
  26. data/vendor/assets/components/geojson-equality/dist/geojson-equality.js.map +21 -0
  27. data/vendor/assets/components/geojson-equality/dist/geojson-equality.min.js +1 -0
  28. data/vendor/assets/components/leaflet-controlpanel/dist/leaflet.controlpanel.css +29 -0
  29. data/vendor/assets/components/leaflet-controlpanel/dist/leaflet.controlpanel.js +269 -0
  30. data/vendor/assets/components/leaflet-draw-cut/dist/leaflet.draw.cut.css +1 -0
  31. data/vendor/assets/components/leaflet-draw-cut/dist/leaflet.draw.cut.js +8 -0
  32. data/vendor/assets/components/leaflet-draw-merge/dist/leaflet.draw.merge.css +0 -0
  33. data/vendor/assets/components/leaflet-draw-merge/dist/leaflet.draw.merge.js +48026 -0
  34. data/vendor/assets/components/leaflet-draw/dist/leaflet.draw-src.css +326 -0
  35. data/vendor/assets/components/leaflet-draw/dist/leaflet.draw-src.js +4653 -0
  36. data/vendor/assets/components/leaflet-draw/dist/leaflet.draw-src.map +1 -0
  37. data/vendor/assets/components/leaflet-draw/dist/leaflet.draw.css +10 -0
  38. data/vendor/assets/components/leaflet-draw/dist/leaflet.draw.js +10 -0
  39. data/vendor/assets/components/leaflet-geographicutil/dist/leaflet.geographicutil.js +3220 -0
  40. data/vendor/assets/components/leaflet-reactive_measure/dist/reactive_measure.css +30 -0
  41. data/vendor/assets/components/leaflet-reactive_measure/dist/reactive_measure.js +3764 -0
  42. data/vendor/assets/components/leaflet/dist/leaflet-src.js +13609 -0
  43. data/vendor/assets/components/leaflet/dist/leaflet-src.js.map +1 -0
  44. data/vendor/assets/components/leaflet/dist/leaflet-src.map +1 -0
  45. data/vendor/assets/components/leaflet/dist/leaflet.css +632 -0
  46. data/vendor/assets/components/leaflet/dist/leaflet.js +5 -0
  47. data/vendor/assets/components/leaflet/dist/leaflet.js.map +1 -0
  48. data/vendor/assets/components/martinez-polygon-clipping/dist/martinez.min.js +9 -0
  49. data/vendor/assets/components/martinez-polygon-clipping/dist/martinez.umd.js +1716 -0
  50. data/vendor/assets/components/martinez-polygon-clipping/dist/martinez.umd.js.map +1 -0
  51. data/vendor/assets/components/polygon-clipping/dist/polygon-clipping.js +279 -0
  52. data/vendor/assets/components/polygon-clipping/dist/polygon-clipping.min.js +1 -0
  53. data/vendor/assets/components/rtree/dist/rtree.js +911 -0
  54. data/vendor/assets/components/rtree/dist/rtree.min.js +1 -0
  55. data/vendor/assets/components/splaytree/dist/splay.es6.js +765 -0
  56. data/vendor/assets/components/splaytree/dist/splay.es6.js.map +1 -0
  57. data/vendor/assets/components/splaytree/dist/splay.js +797 -0
  58. data/vendor/assets/components/splaytree/dist/splay.js.map +1 -0
  59. metadata +156 -0
@@ -0,0 +1 @@
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){"use strict";var rectangle=_dereq_("./rectangle");var bbox=function(ar,obj){if(obj&&obj.bbox){return{leaf:obj,x:obj.bbox[0],y:obj.bbox[1],w:obj.bbox[2]-obj.bbox[0],h:obj.bbox[3]-obj.bbox[1]}}var len=ar.length;var i=0;var a=new Array(len);while(i<len){a[i]=[ar[i][0],ar[i][1]];i++}var first=a[0];len=a.length;i=1;var temp={min:[].concat(first),max:[].concat(first)};while(i<len){if(a[i][0]<temp.min[0]){temp.min[0]=a[i][0]}else if(a[i][0]>temp.max[0]){temp.max[0]=a[i][0]}if(a[i][1]<temp.min[1]){temp.min[1]=a[i][1]}else if(a[i][1]>temp.max[1]){temp.max[1]=a[i][1]}i++}var out={x:temp.min[0],y:temp.min[1],w:temp.max[0]-temp.min[0],h:temp.max[1]-temp.min[1]};if(obj){out.leaf=obj}return out};var geoJSON={};geoJSON.point=function(obj,self){return self.insertSubtree({x:obj.geometry.coordinates[0],y:obj.geometry.coordinates[1],w:0,h:0,leaf:obj},self.root)};geoJSON.multiPointLineString=function(obj,self){return self.insertSubtree(bbox(obj.geometry.coordinates,obj),self.root)};geoJSON.multiLineStringPolygon=function(obj,self){return self.insertSubtree(bbox(Array.prototype.concat.apply([],obj.geometry.coordinates),obj),self.root)};geoJSON.multiPolygon=function(obj,self){return self.insertSubtree(bbox(Array.prototype.concat.apply([],Array.prototype.concat.apply([],obj.geometry.coordinates)),obj),self.root)};geoJSON.makeRec=function(obj){return rectangle(obj.x,obj.y,obj.w,obj.h)};geoJSON.geometryCollection=function(obj,self){if(obj.bbox){return self.insertSubtree({leaf:obj,x:obj.bbox[0],y:obj.bbox[1],w:obj.bbox[2]-obj.bbox[0],h:obj.bbox[3]-obj.bbox[1]},self.root)}var geos=obj.geometry.geometries;var i=0;var len=geos.length;var temp=[];var g;while(i<len){g=geos[i];switch(g.type){case"Point":temp.push(geoJSON.makeRec({x:g.coordinates[0],y:g.coordinates[1],w:0,h:0}));break;case"MultiPoint":temp.push(geoJSON.makeRec(bbox(g.coordinates)));break;case"LineString":temp.push(geoJSON.makeRec(bbox(g.coordinates)));break;case"MultiLineString":temp.push(geoJSON.makeRec(bbox(Array.prototype.concat.apply([],g.coordinates))));break;case"Polygon":temp.push(geoJSON.makeRec(bbox(Array.prototype.concat.apply([],g.coordinates))));break;case"MultiPolygon":temp.push(geoJSON.makeRec(bbox(Array.prototype.concat.apply([],Array.prototype.concat.apply([],g.coordinates)))));break;case"GeometryCollection":geos=geos.concat(g.geometries);len=geos.length;break}i++}var first=temp[0];i=1;len=temp.length;while(i<len){first.expand(temp[i]);i++}return self.insertSubtree({leaf:obj,x:first.x(),y:first.y(),h:first.h(),w:first.w()},self.root)};exports.geoJSON=function(prelim){var that=this;var features,feature;if(Array.isArray(prelim)){features=prelim.slice()}else if(prelim.features&&Array.isArray(prelim.features)){features=prelim.features.slice()}else if(prelim instanceof Object){features=[prelim]}else{throw"this isn't what we're looking for"}var len=features.length;var i=0;while(i<len){feature=features[i];if(feature.type==="Feature"){switch(feature.geometry.type){case"Point":geoJSON.point(feature,that);break;case"MultiPoint":geoJSON.multiPointLineString(feature,that);break;case"LineString":geoJSON.multiPointLineString(feature,that);break;case"MultiLineString":geoJSON.multiLineStringPolygon(feature,that);break;case"Polygon":geoJSON.multiLineStringPolygon(feature,that);break;case"MultiPolygon":geoJSON.multiPolygon(feature,that);break;case"GeometryCollection":geoJSON.geometryCollection(feature,that);break}}i++}};exports.bbox=function(){var x1,y1,x2,y2;switch(arguments.length){case 1:x1=arguments[0][0][0];y1=arguments[0][0][1];x2=arguments[0][1][0];y2=arguments[0][1][1];break;case 2:x1=arguments[0][0];y1=arguments[0][1];x2=arguments[1][0];y2=arguments[1][1];break;case 4:x1=arguments[0];y1=arguments[1];x2=arguments[2];y2=arguments[3];break}return this.search({x:x1,y:y1,w:x2-x1,h:y2-y1})}},{"./rectangle":3}],2:[function(_dereq_,module,exports){"use strict";var RTree=_dereq_("./rtree");var geojson=_dereq_("./geojson");RTree.prototype.bbox=geojson.bbox;RTree.prototype.geoJSON=geojson.geoJSON;RTree.Rectangle=_dereq_("./rectangle");module.exports=RTree},{"./geojson":1,"./rectangle":3,"./rtree":4}],3:[function(_dereq_,module,exports){"use strict";function Rectangle(x,y,w,h){if(!(this instanceof Rectangle)){return new Rectangle(x,y,w,h)}var x2,y2,p;if(x.x){w=x.w;h=x.h;y=x.y;if(x.w!==0&&!x.w&&x.x2){w=x.x2-x.x;h=x.y2-x.y}else{w=x.w;h=x.h}x=x.x;x2=x+w;y2=y+h;p=h+w?false:true}else{x2=x+w;y2=y+h;p=h+w?false:true}this.x1=this.x=function(){return x};this.y1=this.y=function(){return y};this.x2=function(){return x2};this.y2=function(){return y2};this.w=function(){return w};this.h=function(){return h};this.p=function(){return p};this.overlap=function(a){if(p||a.p()){return x<=a.x2()&&x2>=a.x()&&y<=a.y2()&&y2>=a.y()}return x<a.x2()&&x2>a.x()&&y<a.y2()&&y2>a.y()};this.expand=function(a){var nx,ny;var ax=a.x();var ay=a.y();var ax2=a.x2();var ay2=a.y2();if(x>ax){nx=ax}else{nx=x}if(y>ay){ny=ay}else{ny=y}if(x2>ax2){w=x2-nx}else{w=ax2-nx}if(y2>ay2){h=y2-ny}else{h=ay2-ny}x=nx;y=ny;return this}}Rectangle.overlapRectangle=function(a,b){if(a.h===0&&a.w===0||b.h===0&&b.w===0){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}else{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}};Rectangle.containsRectangle=function(a,b){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};Rectangle.expandRectangle=function(a,b){var nx,ny;var axw=a.x+a.w;var bxw=b.x+b.w;var ayh=a.y+a.h;var byh=b.y+b.h;if(a.x>b.x){nx=b.x}else{nx=a.x}if(a.y>b.y){ny=b.y}else{ny=a.y}if(axw>bxw){a.w=axw-nx}else{a.w=bxw-nx}if(ayh>byh){a.h=ayh-ny}else{a.h=byh-ny}a.x=nx;a.y=ny;return a};Rectangle.makeMBR=function(nodes,rect){if(!nodes.length){return{x:0,y:0,w:0,h:0}}rect=rect||{};rect.x=nodes[0].x;rect.y=nodes[0].y;rect.w=nodes[0].w;rect.h=nodes[0].h;for(var i=1,len=nodes.length;i<len;i++){Rectangle.expandRectangle(rect,nodes[i])}return rect};Rectangle.squarifiedRatio=function(l,w,fill){var lperi=(l+w)/2;var larea=l*w;var lgeo=larea/(lperi*lperi);return larea*fill/lgeo};module.exports=Rectangle},{}],4:[function(_dereq_,module,exports){"use strict";var rectangle=_dereq_("./rectangle");function RTree(width){if(!(this instanceof RTree)){return new RTree(width)}var minWidth=3;var maxWidth=6;if(!isNaN(width)){minWidth=Math.floor(width/2);maxWidth=width}var rootTree={x:0,y:0,w:0,h:0,id:"root",nodes:[]};this.root=rootTree;var flatten=function(tree){var todo=tree.slice();var done=[];var current;while(todo.length){current=todo.pop();if(current.nodes){todo=todo.concat(current.nodes)}else if(current.leaf){done.push(current)}}return done};var removeSubtree=function(rect,obj,root){var hitStack=[];var countStack=[];var retArray=[];var currentDepth=1;var tree,i,ltree;if(!rect||!rectangle.overlapRectangle(rect,root)){return retArray}var retObj={x:rect.x,y:rect.y,w:rect.w,h:rect.h,target:obj};countStack.push(root.nodes.length);hitStack.push(root);while(hitStack.length>0){tree=hitStack.pop();i=countStack.pop()-1;if("target"in retObj){while(i>=0){ltree=tree.nodes[i];if(rectangle.overlapRectangle(retObj,ltree)){if(retObj.target&&"leaf"in ltree&&ltree.leaf===retObj.target||!retObj.target&&("leaf"in ltree||rectangle.containsRectangle(ltree,retObj))){if("nodes"in ltree){retArray=flatten(tree.nodes.splice(i,1))}else{retArray=tree.nodes.splice(i,1)}rectangle.makeMBR(tree.nodes,tree);delete retObj.target;break}else if("nodes"in ltree){currentDepth++;countStack.push(i);hitStack.push(tree);tree=ltree;i=ltree.nodes.length}}i--}}else if("nodes"in retObj){tree.nodes.splice(i+1,1);if(tree.nodes.length>0){rectangle.makeMBR(tree.nodes,tree)}for(var t=0;t<retObj.nodes.length;t++){insertSubtree(retObj.nodes[t],tree)}retObj.nodes=[];if(hitStack.length===0&&tree.nodes.length<=1){retObj.nodes=searchSubtree(tree,true,retObj.nodes,tree);tree.nodes=[];hitStack.push(tree);countStack.push(1)}else if(hitStack.length>0&&tree.nodes.length<minWidth){retObj.nodes=searchSubtree(tree,true,retObj.nodes,tree);tree.nodes=[]}else{delete retObj.nodes}}else{rectangle.makeMBR(tree.nodes,tree)}currentDepth-=1}return retArray};var chooseLeafSubtree=function(rect,root){var bestChoiceIndex=-1;var bestChoiceStack=[];var bestChoiceArea;var first=true;bestChoiceStack.push(root);var nodes=root.nodes;while(first||bestChoiceIndex!==-1){if(first){first=false}else{bestChoiceStack.push(nodes[bestChoiceIndex]);nodes=nodes[bestChoiceIndex].nodes;bestChoiceIndex=-1}for(var i=nodes.length-1;i>=0;i--){var ltree=nodes[i];if("leaf"in ltree){bestChoiceIndex=-1;break}var oldLRatio=rectangle.squarifiedRatio(ltree.w,ltree.h,ltree.nodes.length+1);var nw=Math.max(ltree.x+ltree.w,rect.x+rect.w)-Math.min(ltree.x,rect.x);var nh=Math.max(ltree.y+ltree.h,rect.y+rect.h)-Math.min(ltree.y,rect.y);var lratio=rectangle.squarifiedRatio(nw,nh,ltree.nodes.length+2);if(bestChoiceIndex<0||Math.abs(lratio-oldLRatio)<bestChoiceArea){bestChoiceArea=Math.abs(lratio-oldLRatio);bestChoiceIndex=i}}}return bestChoiceStack};var linearSplit=function(nodes){var n=pickLinear(nodes);while(nodes.length>0){pickNext(nodes,n[0],n[1])}return n};var pickNext=function(nodes,a,b){var areaA=rectangle.squarifiedRatio(a.w,a.h,a.nodes.length+1);var areaB=rectangle.squarifiedRatio(b.w,b.h,b.nodes.length+1);var highAreaDelta;var highAreaNode;var lowestGrowthGroup;for(var i=nodes.length-1;i>=0;i--){var l=nodes[i];var newAreaA={};newAreaA.x=Math.min(a.x,l.x);newAreaA.y=Math.min(a.y,l.y);newAreaA.w=Math.max(a.x+a.w,l.x+l.w)-newAreaA.x;newAreaA.h=Math.max(a.y+a.h,l.y+l.h)-newAreaA.y;var changeNewAreaA=Math.abs(rectangle.squarifiedRatio(newAreaA.w,newAreaA.h,a.nodes.length+2)-areaA);var newAreaB={};newAreaB.x=Math.min(b.x,l.x);newAreaB.y=Math.min(b.y,l.y);newAreaB.w=Math.max(b.x+b.w,l.x+l.w)-newAreaB.x;newAreaB.h=Math.max(b.y+b.h,l.y+l.h)-newAreaB.y;var changeNewAreaB=Math.abs(rectangle.squarifiedRatio(newAreaB.w,newAreaB.h,b.nodes.length+2)-areaB);if(!highAreaNode||!highAreaDelta||Math.abs(changeNewAreaB-changeNewAreaA)<highAreaDelta){highAreaNode=i;highAreaDelta=Math.abs(changeNewAreaB-changeNewAreaA);lowestGrowthGroup=changeNewAreaB<changeNewAreaA?b:a}}var tempNode=nodes.splice(highAreaNode,1)[0];if(a.nodes.length+nodes.length+1<=minWidth){a.nodes.push(tempNode);rectangle.expandRectangle(a,tempNode)}else if(b.nodes.length+nodes.length+1<=minWidth){b.nodes.push(tempNode);rectangle.expandRectangle(b,tempNode)}else{lowestGrowthGroup.nodes.push(tempNode);rectangle.expandRectangle(lowestGrowthGroup,tempNode)}};var pickLinear=function(nodes){var lowestHighX=nodes.length-1;var highestLowX=0;var lowestHighY=nodes.length-1;var highestLowY=0;var t1,t2;for(var i=nodes.length-2;i>=0;i--){var l=nodes[i];if(l.x>nodes[highestLowX].x){highestLowX=i}else if(l.x+l.w<nodes[lowestHighX].x+nodes[lowestHighX].w){lowestHighX=i}if(l.y>nodes[highestLowY].y){highestLowY=i}else if(l.y+l.h<nodes[lowestHighY].y+nodes[lowestHighY].h){lowestHighY=i}}var dx=Math.abs(nodes[lowestHighX].x+nodes[lowestHighX].w-nodes[highestLowX].x);var dy=Math.abs(nodes[lowestHighY].y+nodes[lowestHighY].h-nodes[highestLowY].y);if(dx>dy){if(lowestHighX>highestLowX){t1=nodes.splice(lowestHighX,1)[0];t2=nodes.splice(highestLowX,1)[0]}else{t2=nodes.splice(highestLowX,1)[0];t1=nodes.splice(lowestHighX,1)[0]}}else{if(lowestHighY>highestLowY){t1=nodes.splice(lowestHighY,1)[0];t2=nodes.splice(highestLowY,1)[0]}else{t2=nodes.splice(highestLowY,1)[0];t1=nodes.splice(lowestHighY,1)[0]}}return[{x:t1.x,y:t1.y,w:t1.w,h:t1.h,nodes:[t1]},{x:t2.x,y:t2.y,w:t2.w,h:t2.h,nodes:[t2]}]};var attachData=function(node,moreTree){node.nodes=moreTree.nodes;node.x=moreTree.x;node.y=moreTree.y;node.w=moreTree.w;node.h=moreTree.h;return node};var searchSubtree=function(rect,returnNode,returnArray,root){var hitStack=[];if(!rectangle.overlapRectangle(rect,root)){return returnArray}hitStack.push(root.nodes);while(hitStack.length>0){var nodes=hitStack.pop();for(var i=nodes.length-1;i>=0;i--){var ltree=nodes[i];if(rectangle.overlapRectangle(rect,ltree)){if("nodes"in ltree){hitStack.push(ltree.nodes)}else if("leaf"in ltree){if(!returnNode){returnArray.push(ltree.leaf)}else{returnArray.push(ltree)}}}}}return returnArray};var insertSubtree=function(node,root){var bc;if(root.nodes.length===0){root.x=node.x;root.y=node.y;root.w=node.w;root.h=node.h;root.nodes.push(node);return}var treeStack=chooseLeafSubtree(node,root);var retObj=node;var pbc;while(treeStack.length>0){if(bc&&"nodes"in bc&&bc.nodes.length===0){pbc=bc;bc=treeStack.pop();for(var t=0;t<bc.nodes.length;t++){if(bc.nodes[t]===pbc||bc.nodes[t].nodes.length===0){bc.nodes.splice(t,1);break}}}else{bc=treeStack.pop()}if("leaf"in retObj||"nodes"in retObj||Array.isArray(retObj)){if(Array.isArray(retObj)){for(var ai=0;ai<retObj.length;ai++){rectangle.expandRectangle(bc,retObj[ai])}bc.nodes=bc.nodes.concat(retObj)}else{rectangle.expandRectangle(bc,retObj);bc.nodes.push(retObj)}if(bc.nodes.length<=maxWidth){retObj={x:bc.x,y:bc.y,w:bc.w,h:bc.h}}else{var a=linearSplit(bc.nodes);retObj=a;if(treeStack.length<1){bc.nodes.push(a[0]);treeStack.push(bc);retObj=a[1]}}}else{rectangle.expandRectangle(bc,retObj);retObj={x:bc.x,y:bc.y,w:bc.w,h:bc.h}}}};this.insertSubtree=insertSubtree;this.getTree=function(){return rootTree};this.setTree=function(newTree,where){if(!where){where=rootTree}return attachData(where,newTree)};this.search=function(rect,returnNode,returnArray){returnArray=returnArray||[];return searchSubtree(rect,returnNode,returnArray,rootTree)};var removeArea=function(rect){var numberDeleted=1,retArray=[],deleted;while(numberDeleted>0){deleted=removeSubtree(rect,false,rootTree);numberDeleted=deleted.length;retArray=retArray.concat(deleted)}return retArray};var removeObj=function(rect,obj){var retArray=removeSubtree(rect,obj,rootTree);return retArray};this.remove=function(rect,obj){if(!obj||typeof obj==="function"){return removeArea(rect,obj)}else{return removeObj(rect,obj)}};this.insert=function(rect,obj){var retArray=insertSubtree({x:rect.x,y:rect.y,w:rect.w,h:rect.h,leaf:obj},rootTree);return retArray}}RTree.prototype.toJSON=function(printing){return JSON.stringify(this.root,false,printing)};RTree.fromJSON=function(json){var rt=new RTree;rt.setTree(JSON.parse(json));return rt};module.exports=RTree;if(typeof Array.isArray!=="function"){Array.isArray=function(a){return typeof a==="object"&&{}.toString.call(a)==="[object Array]"}}},{"./rectangle":3}]},{},[2])(2)});
@@ -0,0 +1,765 @@
1
+ /**
2
+ * splaytree v2.0.2
3
+ * Fast Splay tree for Node and browser
4
+ *
5
+ * @author Alexander Milevski <info@w8r.name>
6
+ * @license MIT
7
+ * @preserve
8
+ */
9
+
10
+ /* follows "An implementation of top-down splaying"
11
+ * by D. Sleator <sleator@cs.cmu.edu> March 1992
12
+ */
13
+
14
+ /**
15
+ * @typedef {*} Key
16
+ */
17
+
18
+
19
+ /**
20
+ * @typedef {*} Value
21
+ */
22
+
23
+
24
+ /**
25
+ * @typedef {function(node:Node):void} Visitor
26
+ */
27
+
28
+
29
+ /**
30
+ * @typedef {function(a:Key, b:Key):number} Comparator
31
+ */
32
+
33
+
34
+ /**
35
+ * @param {function(node:Node):string} NodePrinter
36
+ */
37
+
38
+
39
+ /**
40
+ * @typedef {Object} Node
41
+ * @property {Key} Key
42
+ * @property {Value=} data
43
+ * @property {Node} left
44
+ * @property {Node} right
45
+ */
46
+
47
+ class Node {
48
+
49
+ constructor (key, data) {
50
+ this.key = key;
51
+ this.data = data;
52
+ this.left = null;
53
+ this.right = null;
54
+ }
55
+ }
56
+
57
+ function DEFAULT_COMPARE (a, b) { return a > b ? 1 : a < b ? -1 : 0; }
58
+
59
+
60
+ /**
61
+ * Simple top down splay, not requiring i to be in the tree t.
62
+ * @param {Key} i
63
+ * @param {Node?} t
64
+ * @param {Comparator} comparator
65
+ */
66
+ function splay (i, t, comparator) {
67
+ if (t === null) return t;
68
+ let l, r, y;
69
+ const N = new Node();
70
+ l = r = N;
71
+
72
+ while (true) {
73
+ const cmp = comparator(i, t.key);
74
+ //if (i < t.key) {
75
+ if (cmp < 0) {
76
+ if (t.left === null) break;
77
+ //if (i < t.left.key) {
78
+ if (comparator(i, t.left.key) < 0) {
79
+ y = t.left; /* rotate right */
80
+ t.left = y.right;
81
+ y.right = t;
82
+ t = y;
83
+ if (t.left === null) break;
84
+ }
85
+ r.left = t; /* link right */
86
+ r = t;
87
+ t = t.left;
88
+ //} else if (i > t.key) {
89
+ } else if (cmp > 0) {
90
+ if (t.right === null) break;
91
+ //if (i > t.right.key) {
92
+ if (comparator(i, t.right.key) > 0) {
93
+ y = t.right; /* rotate left */
94
+ t.right = y.left;
95
+ y.left = t;
96
+ t = y;
97
+ if (t.right === null) break;
98
+ }
99
+ l.right = t; /* link left */
100
+ l = t;
101
+ t = t.right;
102
+ } else {
103
+ break;
104
+ }
105
+ }
106
+ /* assemble */
107
+ l.right = t.left;
108
+ r.left = t.right;
109
+ t.left = N.right;
110
+ t.right = N.left;
111
+ return t;
112
+ }
113
+
114
+
115
+ /**
116
+ * @param {Key} i
117
+ * @param {Value} data
118
+ * @param {Comparator} comparator
119
+ * @param {Tree} tree
120
+ * @return {Node} root
121
+ */
122
+ function insert (i, data, t, comparator, tree) {
123
+ const node = new Node(i, data);
124
+
125
+ tree._size++;
126
+
127
+ if (t === null) {
128
+ node.left = node.right = null;
129
+ return node;
130
+ }
131
+
132
+ t = splay(i, t, comparator);
133
+ const cmp = comparator(i, t.key);
134
+ if (cmp < 0) {
135
+ node.left = t.left;
136
+ node.right = t;
137
+ t.left = null;
138
+ } else if (cmp >= 0) {
139
+ node.right = t.right;
140
+ node.left = t;
141
+ t.right = null;
142
+ }
143
+ return node;
144
+ }
145
+
146
+
147
+ /**
148
+ * Insert i into the tree t, unless it's already there.
149
+ * @param {Key} i
150
+ * @param {Value} data
151
+ * @param {Comparator} comparator
152
+ * @param {Tree} tree
153
+ * @return {Node} root
154
+ */
155
+ function add (i, data, t, comparator, tree) {
156
+ const node = new Node(i, data);
157
+
158
+ if (t === null) {
159
+ node.left = node.right = null;
160
+ tree._size++;
161
+ return node;
162
+ }
163
+
164
+ t = splay(i, t, comparator);
165
+ const cmp = comparator(i, t.key);
166
+ if (cmp === 0) return t;
167
+ else {
168
+ if (cmp < 0) {
169
+ node.left = t.left;
170
+ node.right = t;
171
+ t.left = null;
172
+ } else if (cmp > 0) {
173
+ node.right = t.right;
174
+ node.left = t;
175
+ t.right = null;
176
+ }
177
+ tree._size++;
178
+ return node;
179
+ }
180
+ }
181
+
182
+
183
+ /**
184
+ * Deletes i from the tree if it's there
185
+ * @param {Key} i
186
+ * @param {Tree} tree
187
+ * @param {Comparator} comparator
188
+ * @param {Tree} tree
189
+ * @return {Node} new root
190
+ */
191
+ function remove (i, t, comparator, tree) {
192
+ let x;
193
+ if (t === null) return null;
194
+ t = splay(i, t, comparator);
195
+ if (i === t.key) { /* found it */
196
+ if (t.left === null) {
197
+ x = t.right;
198
+ } else {
199
+ x = splay(i, t.left, comparator);
200
+ x.right = t.right;
201
+ }
202
+ tree._size--;
203
+ return x;
204
+ }
205
+ return t; /* It wasn't there */
206
+ }
207
+
208
+
209
+ function split (key, v, comparator) {
210
+ let left, right;
211
+ if (v === null) {
212
+ left = right = null;
213
+ } else {
214
+ v = splay(key, v, comparator);
215
+
216
+ const cmp = comparator(v.key, key);
217
+ if (cmp === 0) {
218
+ left = v.left;
219
+ right = v.right;
220
+ } else if (cmp < 0) {
221
+ right = v.right;
222
+ v.right = null;
223
+ left = v;
224
+ } else {
225
+ left = v.left;
226
+ v.left = null;
227
+ right = v;
228
+ }
229
+ }
230
+ return { left, right };
231
+ }
232
+
233
+
234
+ function merge (left, right, comparator) {
235
+ if (right === null) return left;
236
+ if (left === null) return right;
237
+
238
+ right = splay(left.key, right, comparator);
239
+ right.left = left;
240
+ return right;
241
+ }
242
+
243
+
244
+ /**
245
+ * Prints level of the tree
246
+ * @param {Node} root
247
+ * @param {String} prefix
248
+ * @param {Boolean} isTail
249
+ * @param {Array<string>} out
250
+ * @param {Function(node:Node):String} printNode
251
+ */
252
+ function printRow (root, prefix, isTail, out, printNode) {
253
+ if (root) {
254
+ out(`${ prefix }${ isTail ? '└── ' : '├── ' }${ printNode(root) }\n`);
255
+ const indent = prefix + (isTail ? ' ' : '│ ');
256
+ if (root.left) printRow(root.left, indent, false, out, printNode);
257
+ if (root.right) printRow(root.right, indent, true, out, printNode);
258
+ }
259
+ }
260
+
261
+
262
+ class Tree {
263
+
264
+ constructor (comparator = DEFAULT_COMPARE) {
265
+ this._comparator = comparator;
266
+ this._root = null;
267
+ this._size = 0;
268
+ }
269
+
270
+
271
+ /**
272
+ * Inserts a key, allows duplicates
273
+ * @param {Key} key
274
+ * @param {Value=} data
275
+ * @return {Node|null}
276
+ */
277
+ insert (key, data) {
278
+ return this._root = insert(key, data, this._root, this._comparator, this);
279
+ }
280
+
281
+
282
+ /**
283
+ * Adds a key, if it is not present in the tree
284
+ * @param {Key} key
285
+ * @param {Value=} data
286
+ * @return {Node|null}
287
+ */
288
+ add (key, data) {
289
+ return this._root = add(key, data, this._root, this._comparator, this);
290
+ }
291
+
292
+
293
+ /**
294
+ * @param {Key} key
295
+ * @return {Node|null}
296
+ */
297
+ remove (key) {
298
+ this._root = remove(key, this._root, this._comparator, this);
299
+ }
300
+
301
+
302
+ /**
303
+ * Removes and returns the node with smallest key
304
+ * @return {?Node}
305
+ */
306
+ pop () {
307
+ let node = this._root;
308
+ if (node) {
309
+ while (node.left) node = node.left;
310
+ this._root = splay(node.key, this._root, this._comparator);
311
+ this._root = remove(node.key, this._root, this._comparator, this);
312
+ return { key: node.key, data: node.data };
313
+ }
314
+ return null;
315
+ }
316
+
317
+
318
+ /**
319
+ * @param {Key} key
320
+ * @return {Node|null}
321
+ */
322
+ findStatic (key) {
323
+ let current = this._root;
324
+ const compare = this._comparator;
325
+ while (current) {
326
+ const cmp = compare(key, current.key);
327
+ if (cmp === 0) return current;
328
+ else if (cmp < 0) current = current.left;
329
+ else current = current.right;
330
+ }
331
+ return null;
332
+ }
333
+
334
+
335
+ /**
336
+ * @param {Key} key
337
+ * @return {Node|null}
338
+ */
339
+ find (key) {
340
+ if (this._root) {
341
+ this._root = splay(key, this._root, this._comparator);
342
+ if (this._comparator(key, this._root.key) !== 0) return null;
343
+ }
344
+ return this._root;
345
+ }
346
+
347
+
348
+ /**
349
+ * @param {Key} key
350
+ * @return {Boolean}
351
+ */
352
+ contains (key) {
353
+ let current = this._root;
354
+ const compare = this._comparator;
355
+ while (current) {
356
+ const cmp = compare(key, current.key);
357
+ if (cmp === 0) return true;
358
+ else if (cmp < 0) current = current.left;
359
+ else current = current.right;
360
+ }
361
+ return false;
362
+ }
363
+
364
+
365
+ /**
366
+ * @param {Visitor} visitor
367
+ * @param {*=} ctx
368
+ * @return {SplayTree}
369
+ */
370
+ forEach (visitor, ctx) {
371
+ let current = this._root;
372
+ const Q = []; /* Initialize stack s */
373
+ let done = false;
374
+
375
+ while (!done) {
376
+ if (current !== null) {
377
+ Q.push(current);
378
+ current = current.left;
379
+ } else {
380
+ if (Q.length !== 0) {
381
+ current = Q.pop();
382
+ visitor.call(ctx, current);
383
+
384
+ current = current.right;
385
+ } else done = true;
386
+ }
387
+ }
388
+ return this;
389
+ }
390
+
391
+
392
+ /**
393
+ * Walk key range from `low` to `high`. Stops if `fn` returns a value.
394
+ * @param {Key} low
395
+ * @param {Key} high
396
+ * @param {Function} fn
397
+ * @param {*?} ctx
398
+ * @return {SplayTree}
399
+ */
400
+ range (low, high, fn, ctx) {
401
+ const Q = [];
402
+ const compare = this._comparator;
403
+ let node = this._root, cmp;
404
+
405
+ while (Q.length !== 0 || node) {
406
+ if (node) {
407
+ Q.push(node);
408
+ node = node.left;
409
+ } else {
410
+ node = Q.pop();
411
+ cmp = compare(node.key, high);
412
+ if (cmp > 0) {
413
+ break;
414
+ } else if (compare(node.key, low) >= 0) {
415
+ if (fn.call(ctx, node)) return this; // stop if smth is returned
416
+ }
417
+ node = node.right;
418
+ }
419
+ }
420
+ return this;
421
+ }
422
+
423
+
424
+ /**
425
+ * Returns array of keys
426
+ * @return {Array<Key>}
427
+ */
428
+ keys () {
429
+ const keys = [];
430
+ this.forEach(({ key }) => keys.push(key));
431
+ return keys;
432
+ }
433
+
434
+
435
+ /**
436
+ * Returns array of all the data in the nodes
437
+ * @return {Array<Value>}
438
+ */
439
+ values () {
440
+ const values = [];
441
+ this.forEach(({ data }) => values.push(data));
442
+ return values;
443
+ }
444
+
445
+
446
+ /**
447
+ * @return {Key|null}
448
+ */
449
+ min() {
450
+ if (this._root) return this.minNode(this._root).key;
451
+ return null;
452
+ }
453
+
454
+
455
+ /**
456
+ * @return {Key|null}
457
+ */
458
+ max() {
459
+ if (this._root) return this.maxNode(this._root).key;
460
+ return null;
461
+ }
462
+
463
+
464
+ /**
465
+ * @return {Node|null}
466
+ */
467
+ minNode(t = this._root) {
468
+ if (t) while (t.left) t = t.left;
469
+ return t;
470
+ }
471
+
472
+
473
+ /**
474
+ * @return {Node|null}
475
+ */
476
+ maxNode(t = this._root) {
477
+ if (t) while (t.right) t = t.right;
478
+ return t;
479
+ }
480
+
481
+
482
+ /**
483
+ * Returns node at given index
484
+ * @param {number} index
485
+ * @return {?Node}
486
+ */
487
+ at (index) {
488
+ let current = this._root, done = false, i = 0;
489
+ const Q = [];
490
+
491
+ while (!done) {
492
+ if (current) {
493
+ Q.push(current);
494
+ current = current.left;
495
+ } else {
496
+ if (Q.length > 0) {
497
+ current = Q.pop();
498
+ if (i === index) return current;
499
+ i++;
500
+ current = current.right;
501
+ } else done = true;
502
+ }
503
+ }
504
+ return null;
505
+ }
506
+
507
+
508
+ /**
509
+ * @param {Node} d
510
+ * @return {Node|null}
511
+ */
512
+ next (d) {
513
+ let root = this._root;
514
+ let successor = null;
515
+
516
+ if (d.right) {
517
+ successor = d.right;
518
+ while (successor.left) successor = successor.left;
519
+ return successor;
520
+ }
521
+
522
+ const comparator = this._comparator;
523
+ while (root) {
524
+ const cmp = comparator(d.key, root.key);
525
+ if (cmp === 0) break;
526
+ else if (cmp < 0) {
527
+ successor = root;
528
+ root = root.left;
529
+ } else root = root.right;
530
+ }
531
+
532
+ return successor;
533
+ }
534
+
535
+
536
+ /**
537
+ * @param {Node} d
538
+ * @return {Node|null}
539
+ */
540
+ prev (d) {
541
+ let root = this._root;
542
+ let predecessor = null;
543
+
544
+ if (d.left !== null) {
545
+ predecessor = d.left;
546
+ while (predecessor.right) predecessor = predecessor.right;
547
+ return predecessor;
548
+ }
549
+
550
+ const comparator = this._comparator;
551
+ while (root) {
552
+ const cmp = comparator(d.key, root.key);
553
+ if (cmp === 0) break;
554
+ else if (cmp < 0) root = root.left;
555
+ else {
556
+ predecessor = root;
557
+ root = root.right;
558
+ }
559
+ }
560
+ return predecessor;
561
+ }
562
+
563
+
564
+ /**
565
+ * @return {SplayTree}
566
+ */
567
+ clear() {
568
+ this._root = null;
569
+ this._size = 0;
570
+ return this;
571
+ }
572
+
573
+
574
+ /**
575
+ * @return {NodeList}
576
+ */
577
+ toList() {
578
+ return toList(this._root);
579
+ }
580
+
581
+
582
+ /**
583
+ * Bulk-load items. Both array have to be same size
584
+ * @param {Array<Key>} keys
585
+ * @param {Array<Value>} [values]
586
+ * @param {Boolean} [presort=false] Pre-sort keys and values, using
587
+ * tree's comparator. Sorting is done
588
+ * in-place
589
+ * @return {AVLTree}
590
+ */
591
+ load (keys = [], values = [], presort = false) {
592
+ let size = keys.length;
593
+ const comparator = this._comparator;
594
+
595
+ // sort if needed
596
+ if (presort) sort(keys, values, 0, size - 1, comparator);
597
+
598
+ if (this._root === null) { // empty tree
599
+ this._root = loadRecursive(this._root, keys, values, 0, size);
600
+ this._size = size;
601
+ } else { // that re-builds the whole tree from two in-order traversals
602
+ const mergedList = mergeLists(this.toList(), createList(keys, values), comparator);
603
+ size = this._size + size;
604
+ this._root = sortedListToBST({ head: mergedList }, 0, size);
605
+ }
606
+ return this;
607
+ }
608
+
609
+
610
+ /**
611
+ * @return {Boolean}
612
+ */
613
+ isEmpty() { return this._root === null; }
614
+
615
+ get size () { return this._size; }
616
+
617
+
618
+ /**
619
+ * @param {NodePrinter=} printNode
620
+ * @return {String}
621
+ */
622
+ toString (printNode = (n) => n.key) {
623
+ const out = [];
624
+ printRow(this._root, '', true, (v) => out.push(v), printNode);
625
+ return out.join('');
626
+ }
627
+
628
+
629
+ update (key, newKey, newData) {
630
+ const comparator = this._comparator;
631
+ let { left, right } = split(key, this._root, comparator);
632
+ this._size--;
633
+ if (comparator(key, newKey) < 0) {
634
+ right = insert(newKey, newData, right, comparator, this);
635
+ } else {
636
+ left = insert(newKey, newData, left, comparator, this);
637
+ }
638
+ this._root = merge(left, right, comparator);
639
+ }
640
+
641
+
642
+ split(key) {
643
+ return split(key, this._root, this._comparator);
644
+ }
645
+ }
646
+
647
+
648
+ function loadRecursive (parent, keys, values, start, end) {
649
+ const size = end - start;
650
+ if (size > 0) {
651
+ const middle = start + Math.floor(size / 2);
652
+ const key = keys[middle];
653
+ const data = values[middle];
654
+ const node = { key, data, parent };
655
+ node.left = loadRecursive(node, keys, values, start, middle);
656
+ node.right = loadRecursive(node, keys, values, middle + 1, end);
657
+ return node;
658
+ }
659
+ return null;
660
+ }
661
+
662
+
663
+ function createList(keys, values) {
664
+ const head = { next: null };
665
+ let p = head;
666
+ for (let i = 0; i < keys.length; i++) {
667
+ p = p.next = { key: keys[i], data: values[i] };
668
+ }
669
+ p.next = null;
670
+ return head.next;
671
+ }
672
+
673
+
674
+ function toList (root) {
675
+ var current = root;
676
+ var Q = [], done = false;
677
+
678
+ const head = { next: null };
679
+ let p = head;
680
+
681
+ while (!done) {
682
+ if (current) {
683
+ Q.push(current);
684
+ current = current.left;
685
+ } else {
686
+ if (Q.length > 0) {
687
+ current = p = p.next = Q.pop();
688
+ current = current.right;
689
+ } else done = true;
690
+ }
691
+ }
692
+ p.next = null; // that'll work even if the tree was empty
693
+ return head.next;
694
+ }
695
+
696
+
697
+ function sortedListToBST(list, start, end) {
698
+ const size = end - start;
699
+ if (size > 0) {
700
+ const middle = start + Math.floor(size / 2);
701
+ const left = sortedListToBST(list, start, middle);
702
+
703
+ const root = list.head;
704
+ root.left = left;
705
+
706
+ list.head = list.head.next;
707
+
708
+ root.right = sortedListToBST(list, middle + 1, end);
709
+ return root;
710
+ }
711
+ return null;
712
+ }
713
+
714
+
715
+ function mergeLists (l1, l2, compare = (a, b) => a - b) {
716
+ const head = {}; // dummy
717
+ let p = head;
718
+
719
+ let p1 = l1;
720
+ let p2 = l2;
721
+
722
+ while (p1 !== null && p2 !== null) {
723
+ if (compare(p1.key, p2.key) < 0) {
724
+ p.next = p1;
725
+ p1 = p1.next;
726
+ } else {
727
+ p.next = p2;
728
+ p2 = p2.next;
729
+ }
730
+ p = p.next;
731
+ }
732
+
733
+ if (p1 !== null) p.next = p1;
734
+ else if (p2 !== null) p.next = p2;
735
+
736
+ return head.next;
737
+ }
738
+
739
+
740
+ function sort(keys, values, left, right, compare) {
741
+ if (left >= right) return;
742
+
743
+ const pivot = keys[(left + right) >> 1];
744
+ let i = left - 1;
745
+ let j = right + 1;
746
+
747
+ while (true) {
748
+ do i++; while (compare(keys[i], pivot) < 0);
749
+ do j--; while (compare(keys[j], pivot) > 0);
750
+ if (i >= j) break;
751
+
752
+ let tmp = keys[i];
753
+ keys[i] = keys[j];
754
+ keys[j] = tmp;
755
+
756
+ tmp = values[i];
757
+ values[i] = values[j];
758
+ values[j] = tmp;
759
+ }
760
+
761
+ sort(keys, values, left, j, compare);
762
+ sort(keys, values, j + 1, right, compare);
763
+ }
764
+
765
+ export default Tree;