Skip to content
Merged
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
2 changes: 1 addition & 1 deletion Nsi.Geospatial.Io/SpatialReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public FeatureCollection Read(string path)
{
foreach (var part in ProcessGeometry(geom, wkt))
f.AddPart(part);
f.ComputeMbr();
f.ComputeBoundingBox();
}

fc.AddFeature(f);
Expand Down
10 changes: 5 additions & 5 deletions Nsi.Geospatial/Geometry/BoundingBox.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
namespace Nsi.Geospatial.Geometry;

/// <summary>Axis-aligned 2D bounding box. Replaces the old double[4] MBR arrays.</summary>
public readonly struct BoundingBox
public struct BoundingBox
{
public double MinX { get; }
public double MinY { get; }
public double MaxX { get; }
public double MaxY { get; }
public double MinX { get; set;}
public double MinY { get; set;}
public double MaxX { get; set;}
public double MaxY { get; set;}

public BoundingBox(double minX, double minY, double maxX, double maxY)
{
Expand Down
12 changes: 6 additions & 6 deletions Nsi.Geospatial/Geometry/Feature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public sealed class Feature
public string? Name { get; set; }

public List<Part> Parts { get; } = new();
public BoundingBox Mbr { get; private set; } = BoundingBox.Empty;
public BoundingBox BoundingBox { get; private set; } = BoundingBox.Empty;

/// <summary>This feature's attribute values, keyed by column name. Null-safe.</summary>
public Dictionary<string, object?> Attributes { get; } = new(StringComparer.OrdinalIgnoreCase);
Expand All @@ -26,15 +26,15 @@ public sealed class Feature
public void AddPart(Part part)
{
Parts.Add(part);
Mbr = Mbr.Union(part.Mbr);
BoundingBox = BoundingBox.Union(part.BoundingBox);
}

public BoundingBox ComputeMbr()
public BoundingBox ComputeBoundingBox()
{
Mbr = BoundingBox.Empty;
BoundingBox = BoundingBox.Empty;
foreach (var p in Parts)
Mbr = Mbr.Union(p.Mbr);
return Mbr;
BoundingBox = BoundingBox.Union(p.BoundingBox);
return BoundingBox;
}

public T? GetAttribute<T>(string name)
Expand Down
12 changes: 6 additions & 6 deletions Nsi.Geospatial/Geometry/Part.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Nsi.Geospatial.Geometry;
public sealed class Part
{
public List<Vertex> Vertices { get; } = new();
public BoundingBox Mbr { get; private set; } = BoundingBox.Empty;
public BoundingBox BoundingBox { get; private set; } = BoundingBox.Empty;
public bool IsHole { get; set; }
public bool Direction { get; set; }
public int BeginIndex { get; set; }
Expand All @@ -20,7 +20,7 @@ public sealed class Part

public Part(string? wkt = null) => Wkt = wkt;

public void AddVertex(Vertex vertex, bool updateMbr = true)
public void AddVertex(Vertex vertex, bool updateBoundingBox = true)
{
if (Vertices.Count > 0)
{
Expand All @@ -38,11 +38,11 @@ public void AddVertex(Vertex vertex, bool updateMbr = true)

Vertices.Add(vertex);

if (updateMbr)
if (updateBoundingBox)
{
Mbr = Vertices.Count == 1
BoundingBox = Vertices.Count == 1
? BoundingBox.Point(vertex.X, vertex.Y)
: Mbr.Union(BoundingBox.Point(vertex.X, vertex.Y));
: BoundingBox.Union(BoundingBox.Point(vertex.X, vertex.Y));
}
}

Expand All @@ -52,7 +52,7 @@ public void CloseRing()
if (Vertices.Count > 0)
{
var first = Vertices[0];
AddVertex(new Vertex(first.X, first.Y), updateMbr: false);
AddVertex(new Vertex(first.X, first.Y), updateBoundingBox: false);
(CentroidX, CentroidY) = GeometryMath.Centroid(Vertices.Select(v => (v.X, v.Y)));
Area = GeometryMath.Area(Vertices.Select(v => (v.X, v.Y)));
}
Expand Down
88 changes: 43 additions & 45 deletions Nsi.Geospatial/Spatial/RTreeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,48 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Nsi.Geospatial.Geometry;

namespace Nsi.Geospatial.Spatial
{
public class RTreeManager
{
public RTreeNode _root;
private int _minChildren;
private int _maxChildren;
public RTreeManager(int minChilds = 4, int maxChilds = 10)
{
_minChildren = minChilds;
_maxChildren = maxChilds;
_root = new RTreeNode(this, _maxChildren, _minChildren);
}
namespace Nsi.Geospatial.Spatial;

public void addFeature(int[] featInd, double mbrXmax, double mbrXmin, double mbrYmax, double mbrYmin)
{
RTreeNode featNode = new RTreeNode(this, _maxChildren, _minChildren, featInd);
featNode.MBRXMin = mbrXmin;
featNode.MBRXMax = mbrXmax;
featNode.MBRYMin = mbrYmin;
featNode.MBRYMax = mbrYmax;
_root.addFeatureChildEnforceIntersect(featNode);
}
public List<RTreeNode> findByXY(double x, double y)
{
List<RTreeNode> nodePAth = new List<RTreeNode>();
_root.getCandidateFeatNodesByMBR(x, x, y, y, nodePAth);
return nodePAth;
}
public List<RTreeNode> findByInd(int ind)
{
List<RTreeNode> nodePAth = new List<RTreeNode>();
_root.getChildrenContainingInd(ind, nodePAth);
return nodePAth;
}
public List<RTreeNode> getEndNodes
{
get
{
List<RTreeNode> endNodes = new List<RTreeNode>();
_root.getEndNodes(endNodes);
return endNodes;
}
}
}
}
public class RTreeManager
{
public RTreeNode _root;
private int _minChildren;
private int _maxChildren;
public RTreeManager(int minChilds = 4, int maxChilds = 10)
{
_minChildren = minChilds;
_maxChildren = maxChilds;
_root = new RTreeNode(this, _maxChildren, _minChildren);
}

public void addFeature(int[] featInd, BoundingBox bbox)
{
RTreeNode featNode = new RTreeNode(this, _maxChildren, _minChildren, featInd);
featNode.BoundingBox = bbox;
_root.addFeatureChildEnforceIntersect(featNode);
}
public List<RTreeNode> findByXY(double x, double y)
{
List<RTreeNode> nodePAth = new List<RTreeNode>();
BoundingBox bbox = new BoundingBox(x,y,x,y);
_root.getCandidateFeatNodesByMBR(bbox, nodePAth);
return nodePAth;
}
public List<RTreeNode> findByInd(int ind)
{
List<RTreeNode> nodePAth = new List<RTreeNode>();
_root.getChildrenContainingInd(ind, nodePAth);
return nodePAth;
}
public List<RTreeNode> getEndNodes
{
get
{
List<RTreeNode> endNodes = new List<RTreeNode>();
_root.getEndNodes(endNodes);
return endNodes;
}
}
}
Loading
Loading