viceroypenguin / RBush

R-Tree Implementation for C#

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

What we need to change C# 7.2 to C# 6

falkantara opened this issue · comments

Hi, I don't know you still supporting this project. But I need to use this in VS 2015 with some 3rd party libs. Which they don't support using VS 2017 and C# 7.2. Any idea of how to use in VS 2015 this lib.
By the way, thanks to implementing this project and the performance is crazy comparison to the other Rtree solutions out there.

You should look at version 1.0.24 on Nuget; that version was the last that supported C# 6 and VS 2015. I believe most of the functionality is the same between version 1 and 2; the primary reason for the primary number increase was the breaking change in requiring C# 7 on the newer versions.

https://www.nuget.org/packages/RBush/1.0.24

Thanks for your quick answer.
Any idea of how to implement this in 3d solutions which functionalities should we change in the envelope class etc. Cause I tried Rtree https://github.com/yeroo/RTree solutions it's 2.5 times slower at least compared to yours

Best

Yes, obviously, you will need to change Envelope to contain MinZ and MaxZ. You will also need to change Area to Volume as the product of all three dimensions, and Margin as the sum of all three dimensions. Intersection, Contains, Intersects, and the two Bounds properties should be fairly straight forward to update as well.

The other big change needed will be in RBush.SortChildren(), to sort by the third dimension as well for identifying which way to split the child nodes. After that, it should just work. Let me know if you have performance issues with that, and I can try to untangle what I remember about this DS from the cobwebs in my brain.

Hi, I changed almost everything you said in the code. But I'm stuck in two functions to implement
Since I don't know what is going on exactly in these methods I cannot configure on my own.
Best

#region Sort Functions
private static readonly IComparer CompareMinX =
ProjectionComparer3D.Create(d => d.Envelope3D.MinX);
private static readonly IComparer CompareMinY =
ProjectionComparer3D.Create(d => d.Envelope3D.MinY);
private static readonly IComparer CompareMinZ =
ProjectionComparer3D.Create(d => d.Envelope3D.MinZ);

#endregion

private void SortChildren(Node3D node3D)
{
node3D.Children.Sort(CompareMinX);
var splitsByX = GetPotentialSplitMargins(node3D.Children);
node3D.Children.Sort(CompareMinY);
var splitsByY = GetPotentialSplitMargins(node3D.Children);
node3D.Children.Sort(CompareMinZ);
var splitsByZ = GetPotentialSplitMargins(node3D.Children);

**if (splitsByX < splitsByY && splitsByX < splitsByZ)
{
	node3D.Children.Sort(CompareMinX);
}
else if(splitsByY < splitsByX && splitsByY < splitsByZ)
{
	node3D.Children.Sort(CompareMinY);
}
else
{
	node3D.Children.Sort(CompareMinZ);
}**

}

// not sure where we should insert CompareMinZ related code if necessary
private Node3D BuildNodes(List data, int left, int right, int height, int maxEntries)
{
var num = right - left + 1;
if (num <= maxEntries)
{
if (height == 1)
return new Node3D(data.Skip(left).Take(num).ToList(), height);
else
return new Node3D(new List { BuildNodes(data, left, right, height - 1, this.maxEntries) }, height);
}

data.Sort(left, num, **CompareMinX**);

var nodeSize = (num + (maxEntries - 1)) / maxEntries;
var subSortLength = nodeSize * (int)Math.Ceiling(Math.Sqrt(maxEntries));

var children = new List<ISpatialData3D>(maxEntries);
for (int subCounter = left; subCounter <= right; subCounter += subSortLength)
{
	var subRight = Math.Min(subCounter + subSortLength - 1, right);
	data.Sort(subCounter, subRight - subCounter + 1, **CompareMinY**);

	for (int nodeCounter = subCounter; nodeCounter <= subRight; nodeCounter += nodeSize)
	{
	          children.Add(
		     BuildNodes(
				data,
				nodeCounter,
				Math.Min(nodeCounter + nodeSize - 1, subRight),
				height - 1,
				this.maxEntries));
	}
    }

return new Node3D(children, height);

}

SortChildren() looks correct; I don't remember exactly how it should be impacted in BuildNodes(). I think the goal there was to alternate between X and Y dimensions, so theoretically there should be a 3rd for loop for dealing w/ the 3rd dimension. I would try without changing BuildNodes() to start though; it may or may not impact performance significantly.

You should look at version 1.0.24 on Nuget; that version was the last that supported C# 6 and VS 2015. I believe most of the functionality is the same between version 1 and 2; the primary reason for the primary number increase was the breaking change in requiring C# 7 on the newer versions.

https://www.nuget.org/packages/RBush/1.0.24

Hi again,
If you have this nuget full source C# code in your archive can you share, please with me?
Since nuget only provide dll. I need to see the language difference for performance comparison.

Best

According to the build system, version 1.0.24 corresponds to git commit 18aa544