From d23453b1a64a9c8fb68269d220ea4368f7128e6a Mon Sep 17 00:00:00 2001 From: booo Date: Sun, 24 Jul 2011 12:26:14 +0200 Subject: [PATCH 1/3] rtree.js: removed whitespaces... --- src/rtree.js | 150 +++++++++++++++++++++++++-------------------------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/src/rtree.js b/src/rtree.js index 11fd356..e69900b 100644 --- a/src/rtree.js +++ b/src/rtree.js @@ -1,9 +1,9 @@ -/****************************************************************************** +/****************************************************************************** rtree.js - General-Purpose Non-Recursive Javascript R-Tree Library Version 0.6.2, December 5st 2009 Copyright (c) 2009 Jon-Carlos Rivera - + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including @@ -11,10 +11,10 @@ distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -37,9 +37,9 @@ var RTree = function(width){ if(!isNaN(width)){ _Min_Width = Math.floor(width/2.0); _Max_Width = width;} // Start with an empty root-tree var _T = {x:0, y:0, w:0, h:0, id:"root", nodes:[] }; - + var isArray = function(o) { - return Object.prototype.toString.call(o) === '[object Array]'; + return Object.prototype.toString.call(o) === '[object Array]'; }; /* @function @@ -70,13 +70,13 @@ var RTree = function(width){ // Area of new enlarged rectangle var lperi = (l + w) / 2.0; // Average size of a side of the new rectangle var larea = l * w; // Area of new rectangle - // return the ratio of the perimeter to the area - the closer to 1 we are, - // the more "square" a rectangle is. conversly, when approaching zero the + // return the ratio of the perimeter to the area - the closer to 1 we are, + // the more "square" a rectangle is. conversly, when approaching zero the // more elongated a rectangle is var lgeo = larea / (lperi*lperi); - return(larea * fill / lgeo); + return(larea * fill / lgeo); }; - + /* find the best specific node(s) for object to be deleted from * [ leaf node parent ] = _remove_subtree(rectangle, object, root) * @private @@ -86,19 +86,19 @@ var RTree = function(width){ var count_stack = []; // Contains the elements that overlap var ret_array = []; var current_depth = 1; - + if(!rect || !RTree.Rectangle.overlap_rectangle(rect, root)) return ret_array; var ret_obj = {x:rect.x, y:rect.y, w:rect.w, h:rect.h, target:obj}; - + count_stack.push(root.nodes.length); hit_stack.push(root); do { var tree = hit_stack.pop(); var i = count_stack.pop()-1; - + if("target" in ret_obj) { // We are searching for a target while(i >= 0) { var ltree = tree.nodes[i]; @@ -109,9 +109,9 @@ var RTree = function(width){ // we can cancel search and start walking up the list if("nodes" in ltree) {// If we are deleting a node not a leaf... ret_array = _search_subtree(ltree, true, [], ltree); - tree.nodes.splice(i, 1); + tree.nodes.splice(i, 1); } else { - ret_array = tree.nodes.splice(i, 1); + ret_array = tree.nodes.splice(i, 1); } // Resize MBR down... RTree.Rectangle.make_MBR(tree.nodes, tree); @@ -146,7 +146,7 @@ var RTree = function(width){ count_stack.push(1); } else if(hit_stack.length > 0 && tree.nodes.length < _Min_Width) { // Underflow..AGAIN! ret_obj.nodes = _search_subtree(tree, true, ret_obj.nodes, tree); - tree.nodes.length = 0; + tree.nodes.length = 0; }else { delete ret_obj.nodes; // Just start resizing } @@ -155,7 +155,7 @@ var RTree = function(width){ } current_depth -= 1; }while(hit_stack.length > 0); - + return(ret_array); }; @@ -167,26 +167,26 @@ var RTree = function(width){ var best_choice_index = -1; var best_choice_stack = []; var best_choice_area; - + var load_callback = function(local_tree, local_node){ - return(function(data) { + return(function(data) { local_tree._attach_data(local_node, data); }); }; - + best_choice_stack.push(root); - var nodes = root.nodes; + var nodes = root.nodes; - do { + do { if(best_choice_index != -1) { best_choice_stack.push(nodes[best_choice_index]); nodes = nodes[best_choice_index].nodes; best_choice_index = -1; } - + for(var i = nodes.length-1; i >= 0; i--) { var ltree = nodes[i]; - if("leaf" in ltree) { + if("leaf" in ltree) { // Bail out of everything and start inserting best_choice_index = -1; break; @@ -201,10 +201,10 @@ var RTree = function(width){ // Enlarge rectangle to fit new rectangle 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); - + // Area of new enlarged rectangle var lratio = RTree.Rectangle.squarified_ratio(nw, nh, ltree.nodes.length+2); - + if(best_choice_index < 0 || Math.abs(lratio - old_lratio) < best_choice_area) { best_choice_area = Math.abs(lratio - old_lratio); best_choice_index = i; } @@ -225,7 +225,7 @@ var RTree = function(width){ } return(n); }; - + /* insert the best source rectangle into the best fitting parent node: a or b * [] = pick_next(array of source nodes, target node array a, target node array b) * @private @@ -237,14 +237,14 @@ var RTree = function(width){ var high_area_delta; var high_area_node; var lowest_growth_group; - + for(var i = nodes.length-1; i>=0;i--) { var l = nodes[i]; var new_area_a = {}; new_area_a.x = Math.min(a.x, l.x); new_area_a.y = Math.min(a.y, l.y); new_area_a.w = Math.max(a.x+a.w, l.x+l.w) - new_area_a.x; new_area_a.h = Math.max(a.y+a.h, l.y+l.h) - new_area_a.y; var change_new_area_a = Math.abs(RTree.Rectangle.squarified_ratio(new_area_a.w, new_area_a.h, a.nodes.length+2) - area_a); - + var new_area_b = {}; new_area_b.x = Math.min(b.x, l.x); new_area_b.y = Math.min(b.y, l.y); new_area_b.w = Math.max(b.x+b.w, l.x+l.w) - new_area_b.x; new_area_b.h = Math.max(b.y+b.h, l.y+l.h) - new_area_b.y; @@ -280,7 +280,7 @@ var RTree = function(width){ var lowest_high_y = nodes.length-1; var highest_low_y = 0; var t1, t2; - + for(var i = nodes.length-2; i>=0;i--) { var l = nodes[i]; if(l.x > nodes[highest_low_x].x ) highest_low_x = i; @@ -290,7 +290,7 @@ var RTree = function(width){ } var dx = Math.abs((nodes[lowest_high_x].x+nodes[lowest_high_x].w) - nodes[highest_low_x].x); var dy = Math.abs((nodes[lowest_high_y].y+nodes[lowest_high_y].h) - nodes[highest_low_y].y); - if( dx > dy ) { + if( dx > dy ) { if(lowest_high_x > highest_low_x) { t1 = nodes.splice(lowest_high_x, 1)[0]; t2 = nodes.splice(highest_low_x, 1)[0]; @@ -310,7 +310,7 @@ var RTree = function(width){ 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 _attach_data = function(node, more_tree){ node.nodes = more_tree.nodes; node.x = more_tree.x; node.y = more_tree.y; @@ -318,27 +318,27 @@ var RTree = function(width){ return(node); }; - /* non-recursive internal search function + /* non-recursive internal search function * [ nodes | objects ] = _search_subtree(rectangle, [return node data], [array to fill], root to begin search at) * @private */ var _search_subtree = function(rect, return_node, return_array, root) { var hit_stack = []; // Contains the elements that overlap - + if(!RTree.Rectangle.overlap_rectangle(rect, root)) return(return_array); - + var load_callback = function(local_tree, local_node){ - return(function(data) { + return(function(data) { local_tree._attach_data(local_node, data); }); }; - + hit_stack.push(root.nodes); - + do { var nodes = hit_stack.pop(); - + for(var i = nodes.length-1; i >= 0; i--) { var ltree = nodes[i]; if(RTree.Rectangle.overlap_rectangle(rect, ltree)) { @@ -357,10 +357,10 @@ var RTree = function(width){ } } }while(hit_stack.length > 0); - + return(return_array); }; - + /* non-recursive internal insert function * [] = _insert_subtree(rectangle, object to insert, root to begin insertion at) * @private @@ -375,13 +375,13 @@ var RTree = function(width){ root.nodes.push(node); return; } - + // Find the best fitting leaf node // choose_leaf returns an array of all tree levels (including root) // that were traversed while trying to find the leaf var tree_stack = _choose_leaf_subtree(node, root); var ret_obj = node;//{x:rect.x,y:rect.y,w:rect.w,h:rect.h, leaf:obj}; - + // Walk back up the tree resizing and inserting as needed do { //handle the case of an empty node (from a split) @@ -396,20 +396,20 @@ var RTree = function(width){ } else { bc = tree_stack.pop(); } - + // If there is data attached to this ret_obj - if("leaf" in ret_obj || "nodes" in ret_obj || isArray(ret_obj)) { + if("leaf" in ret_obj || "nodes" in ret_obj || isArray(ret_obj)) { // Do Insert if(isArray(ret_obj)) { for(var ai = 0; ai < ret_obj.length; ai++) { RTree.Rectangle.expand_rectangle(bc, ret_obj[ai]); } - bc.nodes = bc.nodes.concat(ret_obj); + bc.nodes = bc.nodes.concat(ret_obj); } else { RTree.Rectangle.expand_rectangle(bc, ret_obj); bc.nodes.push(ret_obj); // Do Insert } - + if(bc.nodes.length <= _Max_Width) { // Start Resizeing Up the Tree ret_obj = {x:bc.x,y:bc.y,w:bc.w,h:bc.h}; } else { // Otherwise Split this Node @@ -417,7 +417,7 @@ var RTree = function(width){ // formed from the split of the previous node's overflow var a = _linear_split(bc.nodes); ret_obj = a;//[1]; - + if(tree_stack.length < 1) { // If are splitting the root.. bc.nodes.push(a[0]); tree_stack.push(bc); // Reconsider the root element @@ -442,7 +442,7 @@ var RTree = function(width){ this.get_tree = function() { return _T; }; - + /* quick 'n' dirty function for plugins or manually loading the tree * [ tree ] = RTree.set_tree(sub-tree, where to attach): returns the raw tree data. useful for adding * @public @@ -453,8 +453,8 @@ var RTree = function(width){ where = _T; return(_attach_data(where, new_tree)); }; - - /* non-recursive search function + + /* non-recursive search function * [ nodes | objects ] = RTree.search(rectangle, [return node data], [array to fill]) * @public */ @@ -474,7 +474,7 @@ var RTree = function(width){ } return(_search_subtree.apply(this, arguments)); }; - + /* partially-recursive toJSON function * [ string ] = RTree.toJSON([rectangle], [tree]) * @public @@ -486,10 +486,10 @@ var RTree = function(width){ var max_depth = 3; // This triggers recursion and tree-splitting var current_depth = 1; var return_string = ""; - + if(rect && !RTree.Rectangle.overlap_rectangle(rect, _T)) return ""; - + if(!tree) { count_stack.push(_T.nodes.length); hit_stack.push(_T.nodes); @@ -500,14 +500,14 @@ var RTree = function(width){ hit_stack.push(tree.nodes); return_string += "var main_tree = {x:"+tree.x.toFixed()+",y:"+tree.y.toFixed()+",w:"+tree.w.toFixed()+",h:"+tree.h.toFixed()+",nodes:["; } - + do { var nodes = hit_stack.pop(); var i = count_stack.pop()-1; - + if(i >= 0 && i < nodes.length-1) return_string += ","; - + while(i >= 0) { var ltree = nodes[i]; if(!rect || RTree.Rectangle.overlap_rectangle(rect, ltree)) { @@ -544,15 +544,15 @@ var RTree = function(width){ return_string += "]}"; current_depth -= 1; } }while(hit_stack.length > 0); - + return_string+=";"; - + for(var my_key in return_stack) { return_string += "\nvar " + my_key + " = function(){" + return_stack[my_key] + " return(main_tree);};"; } return(return_string); }; - + /* non-recursive function that deletes a specific * [ number ] = RTree.remove(rectangle, obj) */ @@ -571,8 +571,8 @@ var RTree = function(width){ if(arguments[1] === false) { // Do area-wide delete var numberdeleted = 0; var ret_array = []; - do { - numberdeleted=ret_array.length; + do { + numberdeleted=ret_array.length; ret_array = ret_array.concat(_remove_subtree.apply(this, arguments)); }while( numberdeleted != ret_array.length); return ret_array; @@ -581,17 +581,17 @@ var RTree = function(width){ return(_remove_subtree.apply(this, arguments)); } }; - + /* non-recursive insert function * [] = RTree.insert(rectangle, object to insert) */ this.insert = function(rect, obj) { if(arguments.length < 2) throw "Wrong number of arguments. RT.Insert requires at least a bounding rectangle and an object." - + return(_insert_subtree({x:rect.x,y:rect.y,w:rect.w,h:rect.h,leaf:obj}, _T)); }; - + /* non-recursive delete function * [deleted object] = RTree.remove(rectangle, [object to delete]) */ @@ -605,7 +605,7 @@ RTree.Rectangle = function(ix, iy, iw, ih) { // new Rectangle(bounds) or new Rec var x, x2, y, y2, w, h; if(ix.x) { - x = ix.x; y = ix.y; + x = ix.x; y = ix.y; if(ix.w !== 0 && !ix.w && ix.x2){ w = ix.x2-ix.x; h = ix.y2-ix.y; } else { @@ -620,18 +620,18 @@ RTree.Rectangle = function(ix, iy, iw, ih) { // new Rectangle(bounds) or new Rec 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.y2 = function(){return y2;}; this.w = function(){return w;}; this.h = function(){return h;}; - + this.toJSON = function() { return('{"x":'+x.toString()+', "y":'+y.toString()+', "w":'+w.toString()+', "h":'+h.toString()+'}'); }; - + this.overlap = function(a) { return(this.x() < a.x2() && this.x2() > a.x() && this.y() < a.y2() && this.y2() > a.y()); }; - + this.expand = function(a) { var nx = Math.min(this.x(), a.x()); var ny = Math.min(this.y(), a.y()); @@ -640,11 +640,11 @@ RTree.Rectangle = function(ix, iy, iw, ih) { // new Rectangle(bounds) or new Rec x = nx; y = ny; return(this); }; - + this.setRect = function(ix, iy, iw, ih) { var x, x2, y, y2, w, h; if(ix.x) { - x = ix.x; y = ix.y; + x = ix.x; y = ix.y; if(ix.w !== 0 && !ix.w && ix.x2) { w = ix.x2-ix.x; h = ix.y2-ix.y; } else { @@ -703,9 +703,9 @@ RTree.Rectangle.make_MBR = function(nodes, rect) { rect = {x:nodes[0].x, y:nodes[0].y, w:nodes[0].w, h:nodes[0].h}; else rect.x = nodes[0].x; rect.y = nodes[0].y; rect.w = nodes[0].w; rect.h = nodes[0].h; - + for(var i = nodes.length-1; i>0; i--) RTree.Rectangle.expand_rectangle(rect, nodes[i]); - + return(rect); -}; \ No newline at end of file +}; From 0daa557f608170a58265b4a99c293bc635b3f0dd Mon Sep 17 00:00:00 2001 From: booo Date: Sun, 24 Jul 2011 12:56:22 +0200 Subject: [PATCH 2/3] export RTree for use with require() --- src/rtree.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rtree.js b/src/rtree.js index e69900b..12e8033 100644 --- a/src/rtree.js +++ b/src/rtree.js @@ -709,3 +709,7 @@ RTree.Rectangle.make_MBR = function(nodes, rect) { return(rect); }; + +if (typeof module === 'object' && typeof require === 'function') { + exports.RTree = RTree +} From 512809c8cee693d146c0ccdfa116122432bd3959 Mon Sep 17 00:00:00 2001 From: booo Date: Sun, 24 Jul 2011 15:12:15 +0200 Subject: [PATCH 3/3] package.json added --- package.json | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..cb4ab4f --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "rtree", + "version": "0.0.1", + "description": "rtree library for javascript", + "keywords": ["rtree"], + "maintainers": [ + { + "name": "Jon-Carlos Rivera", + "email": "imbcmdth@hotmail.com", + "web": "https://github.com/imbcmdth/RTree" + } + ], + "bugs": { + "web": "https://github.com/imbcmdth/RTree/issues" + }, + "repositories": [ + { + "type": "git", + "url": "https://github.com/imbcmdth/RTree.git" + } + ], + "dependencies": {}, + "main": "./src/rtree.js" + +}