Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions src/RTree/Envelope.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Enyim.Collections
{
public class Envelope
{
internal Envelope() { }

public Envelope(int x1, int y1, int x2, int y2)
public Envelope(double x1, double y1, double x2, double y2)
{
X1 = x1;
Y1 = y1;
X2 = x2;
Y2 = y2;
}

public int X1 { get; private set; } // 0
public int Y1 { get; private set; } // 1
public int X2 { get; private set; } // 2
public int Y2 { get; private set; } // 3
public double X1 { get; private set; } // 0
public double Y1 { get; private set; } // 1
public double X2 { get; private set; } // 2
public double Y2 { get; private set; } // 3

internal int Area { get { return (X2 - X1) * (Y2 - Y1); } }
internal int Margin { get { return (X2 - X1) + (Y2 - Y1); } }
internal double Area { get { return (X2 - X1) * (Y2 - Y1); } }
internal double Margin { get { return (X2 - X1) + (Y2 - Y1); } }

internal void Extend(Envelope by)
{
Expand Down
60 changes: 27 additions & 33 deletions src/RTree/RTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace Enyim.Collections
{
Expand All @@ -16,13 +13,13 @@ public class RTree<T>
// per-bucket
private readonly int maxEntries;
private readonly int minEntries;

private RTreeNode<T> root;

public RTree(int maxEntries = 9)
{
this.maxEntries = Math.Max(4, maxEntries);
this.minEntries = (int)Math.Max(2, Math.Ceiling((double)this.maxEntries * 0.4));
this.minEntries = (int)Math.Max(2, Math.Ceiling(this.maxEntries * 0.4));

Clear();
}
Expand Down Expand Up @@ -87,7 +84,7 @@ private RTreeNode<T> BuildOneLevel(List<RTreeNode<T>> items, int level, int heig
height = (int)Math.Ceiling(Math.Log(N) / Math.Log(M));

// target number of root entries to maximize storage utilization
M = (int)Math.Ceiling((double)N / Math.Pow(M, height - 1));
M = (int)Math.Ceiling(N / Math.Pow(M, height - 1));

items.Sort(CompareNodesByMinX);
}
Expand Down Expand Up @@ -132,23 +129,21 @@ public IEnumerable<RTreeNode<T>> Search(Envelope envelope)

while (node != null)
{
for (var i = 0; i < node.Children.Count; i++)
{
var child = node.Children[i];
var childEnvelope = child.Envelope;
foreach (var child in node.Children)
{
var childEnvelope = child.Envelope;

if (envelope.Intersects(childEnvelope))
{
if (node.IsLeaf) retval.Add(child);
else if (envelope.Contains(childEnvelope)) Collect(child, retval);
else nodesToSearch.Push(child);
}
}
if (!envelope.Intersects(childEnvelope)) continue;

node = nodesToSearch.TryPop();
if (node.IsLeaf) retval.Add(child);
else if (envelope.Contains(childEnvelope)) Collect(child, retval);
else nodesToSearch.Push(child);
}

node = nodesToSearch.TryPop();
}

return retval;
return retval;
}

private static void Collect(RTreeNode<T> node, List<RTreeNode<T>> result)
Expand Down Expand Up @@ -207,7 +202,7 @@ private void Insert(RTreeNode<T> item, int level)
AdjutsParentBounds(envelope, insertPath, level);
}

private static int CombinedArea(Envelope what, Envelope with)
private static double CombinedArea(Envelope what, Envelope with)
{
var minX1 = Math.Max(what.X1, with.X1);
var minY1 = Math.Max(what.Y1, with.Y1);
Expand All @@ -217,7 +212,7 @@ private static int CombinedArea(Envelope what, Envelope with)
return (maxX2 - minX1) * (maxY2 - minY1);
}

private static int IntersectionArea(Envelope what, Envelope with)
private static double IntersectionArea(Envelope what, Envelope with)
{
var minX = Math.Max(what.X1, with.X1);
var minY = Math.Max(what.Y1, with.Y1);
Expand All @@ -235,8 +230,8 @@ private RTreeNode<T> ChooseSubtree(Envelope bbox, RTreeNode<T> node, int level,

if (node.IsLeaf || path.Count - 1 == level) break;

var minArea = Int32.MaxValue;
var minEnlargement = Int32.MaxValue;
var minArea = Double.MaxValue;
var minEnlargement = Double.MaxValue;

RTreeNode<T> targetNode = null;

Expand Down Expand Up @@ -309,9 +304,9 @@ private void SplitRoot(RTreeNode<T> node, RTreeNode<T> newNode)

private int ChooseSplitIndex(RTreeNode<T> node, int minEntries, int totalCount)
{
var minOverlap = Int32.MaxValue;
var minArea = Int32.MaxValue;
int index = 0;
var minOverlap = Double.MaxValue;
var minArea = Double.MaxValue;
var index = 0;

for (var i = minEntries; i <= totalCount - minEntries; i++)
{
Expand All @@ -332,11 +327,10 @@ private int ChooseSplitIndex(RTreeNode<T> node, int minEntries, int totalCount)
else if (overlap == minOverlap)
{
// otherwise choose distribution with minimum area
if (area < minArea)
{
minArea = area;
index = i;
}
if (!(area < minArea)) continue;

minArea = area;
index = i;
}
}

Expand Down Expand Up @@ -456,7 +450,7 @@ private static Envelope SumChildBounds(RTreeNode<T> node, int startIndex, int en
return retval;
}

private static void AdjutsParentBounds(Envelope bbox, List<RTreeNode<T>> path, int level)
private static void AdjutsParentBounds(Envelope bbox, IReadOnlyList<RTreeNode<T>> path, int level)
{
// adjust bboxes along the given tree path
for (var i = level; i >= 0; i--)
Expand All @@ -479,7 +473,7 @@ private static void ChooseSplitAxis(RTreeNode<T> node, int m, int M)
private static int CompareNodesByMinX(RTreeNode<T> a, RTreeNode<T> b) { return a.Envelope.X1.CompareTo(b.Envelope.X1); }
private static int CompareNodesByMinY(RTreeNode<T> a, RTreeNode<T> b) { return a.Envelope.Y1.CompareTo(b.Envelope.Y1); }

private static int AllDistMargin(RTreeNode<T> node, int m, int M, Comparison<RTreeNode<T>> compare)
private static double AllDistMargin(RTreeNode<T> node, int m, int M, Comparison<RTreeNode<T>> compare)
{
node.Children.Sort(compare);

Expand Down
5 changes: 0 additions & 5 deletions src/RTree/RTree.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Envelope.cs" />
Expand Down
3 changes: 0 additions & 3 deletions src/RTree/RTreeNode.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Enyim.Collections
{
Expand Down
5 changes: 0 additions & 5 deletions src/RTree/StackExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace Enyim.Collections
{
Expand Down