using Core.Gis.GeoApi.Geometries; namespace Core.GIS.NetTopologySuite.GeometriesGraph { /// /// A Depth object records the topological depth of the sides /// of an Edge for up to two Geometries. /// public class Depth { /// /// /// private const int Null = -1; private readonly int[,] depth = new int[2, 3]; /// /// /// public Depth() { // initialize depth array to a sentinel value for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { depth[i, j] = Null; } } } /// /// Calls GetDepth and SetDepth. /// /// /// /// public int this[int geomIndex, Positions posIndex] { get { return GetDepth(geomIndex, posIndex); } set { SetDepth(geomIndex, posIndex, value); } } /// /// /// /// /// public static int DepthAtLocation(Locations location) { if (location == Locations.Exterior) { return 0; } if (location == Locations.Interior) { return 1; } return Null; } /// /// /// /// /// /// public int GetDepth(int geomIndex, Positions posIndex) { return depth[geomIndex, (int) posIndex]; } /// /// /// /// /// /// public void SetDepth(int geomIndex, Positions posIndex, int depthValue) { depth[geomIndex, (int) posIndex] = depthValue; } /// /// /// /// /// /// public Locations GetLocation(int geomIndex, Positions posIndex) { if (depth[geomIndex, (int) posIndex] <= 0) { return Locations.Exterior; } return Locations.Interior; } /// /// /// /// /// /// public void Add(int geomIndex, Positions posIndex, Locations location) { if (location == Locations.Interior) { depth[geomIndex, (int) posIndex]++; } } /// /// A Depth object is null (has never been initialized) if all depths are null. /// public bool IsNull() { for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { if (depth[i, j] != Null) { return false; } } } return true; } /// /// /// /// /// public bool IsNull(int geomIndex) { return depth[geomIndex, 1] == Null; } /// /// /// /// /// /// public bool IsNull(int geomIndex, Positions posIndex) { return depth[geomIndex, (int) posIndex] == Null; } /// /// /// /// public void Add(Label lbl) { for (int i = 0; i < 2; i++) { for (int j = 1; j < 3; j++) { Locations loc = lbl.GetLocation(i, (Positions) j); if (loc == Locations.Exterior || loc == Locations.Interior) { // initialize depth if it is null, otherwise add this location value if (IsNull(i, (Positions) j)) { depth[i, j] = DepthAtLocation(loc); } else { depth[i, j] += DepthAtLocation(loc); } } } } } /// /// /// /// /// public int GetDelta(int geomIndex) { return depth[geomIndex, (int) Positions.Right] - depth[geomIndex, (int) Positions.Left]; } /// /// Normalize the depths for each point, if they are non-null. /// A normalized depth /// has depth values in the set { 0, 1 }. /// Normalizing the depths /// involves reducing the depths by the same amount so that at least /// one of them is 0. If the remaining value is > 0, it is set to 1. /// public void Normalize() { for (int i = 0; i < 2; i++) { if (!IsNull(i)) { int minDepth = depth[i, 1]; if (depth[i, 2] < minDepth) { minDepth = depth[i, 2]; } if (minDepth < 0) { minDepth = 0; } for (int j = 1; j < 3; j++) { int newValue = 0; if (depth[i, j] > minDepth) { newValue = 1; } depth[i, j] = newValue; } } } } /// /// /// /// public override string ToString() { return "A: " + depth[0, 1] + "," + depth[0, 2] + " B: " + depth[1, 1] + "," + depth[1, 2]; } } }