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];
}
}
}