/// <summary> /// Returns <c>true</c> if this <see cref="IntersectionMatrix" /> is /// T*T***T** (for two points or two surfaces) /// 1*T***T** (for two curves). /// </summary> /// <param name="dimensionOfGeometryA">The dimension of the first <see cref="IGeometry"/>.</param> /// <param name="dimensionOfGeometryB">The dimension of the second <see cref="IGeometry"/>.</param> /// <returns> /// <c>true</c> if the two <see cref="IGeometry"/> /// s related by this <see cref="IntersectionMatrix" /> overlap. For this /// function to return <c>true</c>, the <see cref="IGeometry"/>s must /// be two points, two curves or two surfaces. /// </returns> public bool IsOverlaps(Dimension dimensionOfGeometryA, Dimension dimensionOfGeometryB) { if ((dimensionOfGeometryA == Dimension.Point && dimensionOfGeometryB == Dimension.Point) || (dimensionOfGeometryA == Dimension.Surface && dimensionOfGeometryB == Dimension.Surface)) return IsTrue(_matrix[(int)Location.Interior, (int)Location.Interior]) && IsTrue(_matrix[(int)Location.Interior, (int)Location.Exterior]) && IsTrue(_matrix[(int)Location.Exterior, (int)Location.Interior]); if (dimensionOfGeometryA == Dimension.Curve && dimensionOfGeometryB == Dimension.Curve) return _matrix[(int)Location.Interior, (int)Location.Interior] == Dimension.Curve && IsTrue(_matrix[(int)Location.Interior, (int)Location.Exterior]) && IsTrue(_matrix[(int)Location.Exterior, (int)Location.Interior]); return false; }
/// <summary> /// Returns <c>true</c> if this <see cref="IntersectionMatrix" /> is /// FT*******, F**T***** or F***T****. /// </summary> /// <param name="dimensionOfGeometryA">The dimension of the first <see cref="IGeometry"/>.</param> /// <param name="dimensionOfGeometryB">The dimension of the second <see cref="IGeometry"/>.</param> /// <returns> /// <c>true</c> if the two <see cref="IGeometry"/> /// s related by this <see cref="IntersectionMatrix" /> touch; Returns false /// if both <see cref="IGeometry"/>s are points. /// </returns> public bool IsTouches(Dimension dimensionOfGeometryA, Dimension dimensionOfGeometryB) { if (dimensionOfGeometryA > dimensionOfGeometryB) //no need to get transpose because pattern matrix is symmetrical return IsTouches(dimensionOfGeometryB, dimensionOfGeometryA); if ((dimensionOfGeometryA == Dimension.Surface && dimensionOfGeometryB == Dimension.Surface) || (dimensionOfGeometryA == Dimension.Curve && dimensionOfGeometryB == Dimension.Curve) || (dimensionOfGeometryA == Dimension.Curve && dimensionOfGeometryB == Dimension.Surface) || (dimensionOfGeometryA == Dimension.Point && dimensionOfGeometryB == Dimension.Surface) || (dimensionOfGeometryA == Dimension.Point && dimensionOfGeometryB == Dimension.Curve)) return _matrix[(int)Location.Interior, (int)Location.Interior] == Dimension.False && (IsTrue(_matrix[(int)Location.Interior, (int)Location.Boundary]) || IsTrue(_matrix[(int)Location.Boundary, (int)Location.Interior]) || IsTrue(_matrix[(int)Location.Boundary, (int)Location.Boundary])); return false; }
/// <summary> /// Tests whether the argument dimensions are equal and /// this <c>IntersectionMatrix</c> matches /// the pattern <tt>T*F**FFF*</tt>. /// <para/> /// <b>Note:</b> This pattern differs from the one stated in /// <i>Simple feature access - Part 1: Common architecture</i>. /// That document states the pattern as <tt>TFFFTFFFT</tt>. This would /// specify that /// two identical <tt>POINT</tt>s are not equal, which is not desirable behaviour. /// The pattern used here has been corrected to compute equality in this situation. /// </summary> /// <param name="dimensionOfGeometryA">The dimension of the first <see cref="IGeometry"/>.</param> /// <param name="dimensionOfGeometryB">The dimension of the second <see cref="IGeometry"/>.</param> /// <returns> /// <c>true</c> if the two <see cref="IGeometry"/>s /// related by this <see cref="IntersectionMatrix" /> are equal; the /// <see cref="IGeometry"/>s must have the same dimension to be equal. /// </returns> public bool IsEquals(Dimension dimensionOfGeometryA, Dimension dimensionOfGeometryB) { if (dimensionOfGeometryA != dimensionOfGeometryB) return false; return IsTrue(_matrix[(int)Location.Interior, (int)Location.Interior]) && _matrix[(int)Location.Interior, (int)Location.Exterior] == Dimension.False && _matrix[(int)Location.Boundary, (int)Location.Exterior] == Dimension.False && _matrix[(int)Location.Exterior, (int)Location.Interior] == Dimension.False && _matrix[(int)Location.Exterior, (int)Location.Boundary] == Dimension.False; }
/// <summary> /// If row >= 0 and column >= 0, changes the specified element to <c>minimumDimensionValue</c> /// if the element is less. Does nothing if row is smaller to 0 or column is smaller to 0. /// </summary> /// <param name="row"></param> /// <param name="column"></param> /// <param name="minimumDimensionValue"></param> public void SetAtLeastIfValid(Location row, Location column, Dimension minimumDimensionValue) { if (row >= Location.Interior && column >= Location.Interior) SetAtLeast(row, column, minimumDimensionValue); }
/// <summary> /// Changes the elements of this <see cref="IntersectionMatrix" /> to <c>dimensionValue</c>. /// </summary> /// <param name="dimensionValue"> /// The dimension value to which to set this <see cref="IntersectionMatrix" /> /// s elements. Possible values <c>True, False, Dontcare, 0, 1, 2}</c>. /// </param> public void SetAll(Dimension dimensionValue) { for (int ai = 0; ai < 3; ai++) for (int bi = 0; bi < 3; bi++) _matrix[ai, bi] = dimensionValue; }
/// <summary> /// Changes the specified element to <c>minimumDimensionValue</c> if the element is less. /// </summary> /// <param name="row"> /// The row of this <see cref="IntersectionMatrix" />, /// indicating the interior, boundary or exterior of the first <see cref="IGeometry"/>. /// </param> /// <param name="column"> /// The column of this <see cref="IntersectionMatrix" />, /// indicating the interior, boundary or exterior of the second <see cref="IGeometry"/>. /// </param> /// <param name="minimumDimensionValue"> /// The dimension value with which to compare the /// element. The order of dimension values from least to greatest is /// <c>True, False, Dontcare, 0, 1, 2</c>. /// </param> public void SetAtLeast(Location row, Location column, Dimension minimumDimensionValue) { if (_matrix[(int)row, (int)column] < minimumDimensionValue) _matrix[(int)row, (int)column] = minimumDimensionValue; }
/// <summary> /// Changes the value of one of this <see cref="IntersectionMatrix" /> elements. /// </summary> /// <param name="row"> /// The row of this <see cref="IntersectionMatrix" />, /// indicating the interior, boundary or exterior of the first <see cref="IGeometry"/> /// </param> /// <param name="column"> /// The column of this <see cref="IntersectionMatrix" />, /// indicating the interior, boundary or exterior of the second <see cref="IGeometry"/> /// </param> /// <param name="dimensionValue">The new value of the element</param> public void Set(Location row, Location column, Dimension dimensionValue) { _matrix[(int)row, (int)column] = dimensionValue; }
/// <summary> /// Tests if the dimension value satisfies the dimension symbol. /// </summary> /// <param name="actualDimensionValue"> /// a number that can be stored in the <c>IntersectionMatrix</c>. /// Possible values are <c>{True, False, Dontcare, 0, 1, 2}</c>. /// </param> /// <param name="requiredDimensionSymbol"> /// A character used in the string /// representation of an <see cref="IntersectionMatrix" />. /// Possible values are <c>T, F, * , 0, 1, 2</c>. /// </param> /// <returns> /// <c>true</c> if the dimension symbol encompasses the dimension value. /// </returns> public static bool Matches(Dimension actualDimensionValue, char requiredDimensionSymbol) { if (requiredDimensionSymbol == DimensionUtility.SymDontcare) return true; if (requiredDimensionSymbol == DimensionUtility.SymTrue && (actualDimensionValue >= Dimension.Point || actualDimensionValue == Dimension.True)) return true; if (requiredDimensionSymbol == DimensionUtility.SymFalse && actualDimensionValue == Dimension.False) return true; if (requiredDimensionSymbol == DimensionUtility.SymP && actualDimensionValue == Dimension.Point) return true; if (requiredDimensionSymbol == DimensionUtility.SymL && actualDimensionValue == Dimension.Curve) return true; if (requiredDimensionSymbol == DimensionUtility.SymA && actualDimensionValue == Dimension.Surface) return true; return false; }
/// <summary> /// Tests if the dimension value matches <tt>TRUE</tt> /// (i.e. has value 0, 1, 2 or TRUE). /// </summary> /// <param name="actualDimensionValue">A number that can be stored in the <c>IntersectionMatrix</c>. /// Possible values are <c>{<see cref="Dimension.True"/>, <see cref="Dimension.False"/>, <see cref="Dimension.Dontcare"/>, <see cref="Dimension.Point"/>, <see cref="Dimension.Curve"/>, <see cref="Dimension.Surface"/>}</c></param> /// <returns><c>true</c> if the dimension value matches <see cref="Dimension.True"/></returns> public static bool IsTrue(Dimension actualDimensionValue) { if (actualDimensionValue >= 0 || actualDimensionValue == Dimension.True) { return true; } return false; }
/// <summary> /// Converts the dimension value to a dimension symbol, /// for example, <c>True => 'T'</c> /// </summary> /// <param name="dimensionValue">Number that can be stored in the <c>IntersectionMatrix</c>. /// Possible values are <c>True, False, Dontcare, 0, 1, 2</c>.</param> /// <returns>Character for use in the string representation of an <c>IntersectionMatrix</c>. /// Possible values are <c>T, F, * , 0, 1, 2</c>.</returns> public static char ToDimensionSymbol(Dimension dimensionValue) { switch (dimensionValue) { case Dimension.False: return SymFalse; case Dimension.True: return SymTrue; case Dimension.Dontcare: return SymDontcare; case Dimension.Point: return SymP; case Dimension.Curve: return SymL; case Dimension.Surface: return SymA; default: throw new ArgumentOutOfRangeException ("Unknown dimension value: " + dimensionValue); } }