// Copyright (C) 2004-2006 Autodesk, Inc. // // This library is free software; you can redistribute it and/or // modify it under the terms of version 2.1 of the GNU Lesser // General Public License as published by the Free Software Foundation. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA using System; using System.Diagnostics; using OSGeo.FDO.Geometry; using OSGeo.FDO.Spatial; using OSGeo.FDO.Common; namespace Fdo_Test { /// /// Summary description for CommonFuntion. /// public class Common { public const int Dimensionality_XY = 0; public const int Dimensionality_Z = 1; public const int Dimensionality_M = 2; ////////////////////////////////////////////////////////////////////// // Dump... ////////////////////////////////////////////////////////////////////// public static void DumpPosition(string context, IDirectPosition p) { #if DUMPTESTCONTENT if (p.Dimensionality == Dimensionality_XY) Console.WriteLine(" {0} XY=({1}, {2})", context, p.X, p.Y); else if (p.Dimensionality == (Dimensionality_XY|Dimensionality_Z)) Console.WriteLine(" {0} XYZ=({1}, {2}, {3})", context, p.X, p.Y, p.Z); else if (p.Dimensionality == (Dimensionality_XY|Dimensionality_M)) Console.WriteLine(" {0} XYM=({1}, {2}, {3})", context, p.X, p.Y, p.M); else if (p.Dimensionality == (Dimensionality_XY|Dimensionality_Z|Dimensionality_M)) Console.WriteLine(" {0} XYZM=({1}, {2}, {3}, {4})", context, p.X, p.Y, p.Z, p.M); else Debug.Assert(false, "DumpPosition::UNKNOWN_DIMENSION_TYPE!"); #endif } public static void DumpEnvelope(IEnvelope env) { #if DUMPTESTCONTENT Console.WriteLine(" Envelope=min({0}, {1}, {2}) max({3}, {4}, {5})", env.MinX, env.MinY, env.MinZ, env.MaxX, env.MaxY, env.MaxZ); #endif } // Dump FGFT public static void DumpFGFT(IGeometry p) { #if DUMPTESTCONTENT Console.WriteLine("FGFT = {0}", p.Text); #endif } public static void DumpLineString(ILineString line) { #if DUMPTESTCONTENT Console.WriteLine("{0}:count({1}) dimtype({2}) derivedtype({3}) closed({4})", "LINESTRING", line.Count, line.Dimensionality, line.DerivedType, line.IsClosed); #endif IDirectPosition pStart = line.StartPosition; DumpPosition("", pStart); IDirectPosition pEnd = line.EndPosition; DumpPosition("", pEnd); IEnvelope envl = line.Envelope; DumpEnvelope(envl); for (int i = 0; i < line.Count; i++) { IDirectPosition pos = line[i]; DumpPosition("", pos); } DumpFGFT(line); } public static void DumpLinearRing(ILinearRing lRing) { #if DUMPTESTCONTENT Console.WriteLine("{0}:count({1}) dimtype({2})", "(LINEARRING)", lRing.Count, lRing.Dimensionality); #endif IEnvelope envl = lRing.Envelope; DumpEnvelope(envl); for (int i = 0; i < lRing.Count; i++) { IDirectPosition pos = lRing[i]; DumpPosition("", pos); } } public static void DumpLineStringSegment(ILineStringSegment lSeg) { #if DUMPTESTCONTENT Console.WriteLine("{0}:count({1}) dimtype({2}) derivedtype({3}) closed({4})", "(LINESTRINGSEGMENT)", lSeg.Count, lSeg.Dimensionality, lSeg.DerivedType, lSeg.IsClosed); #endif IDirectPosition pStart = lSeg.StartPosition; DumpPosition("", pStart); IDirectPosition pEnd = lSeg.EndPosition; DumpPosition("", pEnd); IEnvelope envl = lSeg.Envelope; DumpEnvelope(envl); for (int i = 0; i < lSeg.Count; i++) { IDirectPosition pos = lSeg[i]; DumpPosition("", pos); } } public static void DumpPolygon(IPolygon polygon) { #if DUMPTESTCONTENT Console.WriteLine("{0}:interiorRingCount({1}) dimtype({2}) derivedtype({3})", "POLYGON", polygon.InteriorRingCount, polygon.Dimensionality, polygon.DerivedType); #endif ILinearRing extRing = polygon.ExteriorRing; DumpLinearRing(extRing); for (int i = 0; i < polygon.InteriorRingCount; i++) { ILinearRing intRing = polygon.GetInteriorRing(i); DumpLinearRing(intRing); } IEnvelope envl = polygon.Envelope; DumpEnvelope(envl); DumpFGFT(polygon); } public static void DumpGeometry(IGeometry geometry) { #if DUMPTESTCONTENT Console.WriteLine("{0}: dimtype({1}) derivedtype({2})", "GEOMETRY", geometry.Dimensionality, geometry.DerivedType); #endif DumpFGFT(geometry); } public static void DumpPoint(IPoint pnt) { #if DUMPTESTCONTENT Console.WriteLine("{0}:dimtype({1}) derivedtype({2})", "POINT", pnt.Dimensionality, pnt.DerivedType); #endif IEnvelope envl = pnt.Envelope; DumpEnvelope(envl); IDirectPosition pos = pnt.Position; DumpPosition("", pos); DumpFGFT(pnt); } public static void DumpMultiPoint(IMultiPoint multiPnt) { #if DUMPTESTCONTENT Console.WriteLine("{0}:count({1}) dimtype({2}) derivedtype({3})", "MULTIPOINT", multiPnt.Count, multiPnt.Dimensionality, multiPnt.DerivedType); #endif IEnvelope envl = multiPnt.Envelope; DumpEnvelope(envl); for (int i = 0; i < multiPnt.Count; i++) { IPoint pnt = multiPnt[i]; DumpPoint(pnt); } DumpFGFT(multiPnt); } public static void DumpMultiLineString(IMultiLineString multiLine) { #if DUMPTESTCONTENT Console.WriteLine("{0}:count({1}) dimtype({2}) derivedtype({3})", "MULTILINESTRING", multiLine.Count, multiLine.Dimensionality, multiLine.DerivedType); #endif IEnvelope envl = multiLine.Envelope; DumpEnvelope(envl); for (int i = 0; i < multiLine.Count; i++) { ILineString lineString = multiLine[i]; DumpLineString(lineString); } DumpFGFT(multiLine); } public static void DumpMultiPolygon(IMultiPolygon multiPoly) { #if DUMPTESTCONTENT Console.WriteLine("{0}:count({1}) dimtype({2}) derivedtype({3})", "MULTIPOLYGON", multiPoly.Count, multiPoly.Dimensionality, multiPoly.DerivedType); #endif IEnvelope envl = multiPoly.Envelope; DumpEnvelope(envl); for (int i = 0; i < multiPoly.Count; i++) { IPolygon polygon = multiPoly[i]; DumpPolygon(polygon); } DumpFGFT(multiPoly); } public static void DumpCircularArcSegment(ICircularArcSegment arcSeg) { #if DUMPTESTCONTENT Console.WriteLine("{0}:dimtype({1}) derivedtype({2}) closed({3})", "(CIRCULARARCSEGMENT)", arcSeg.Dimensionality, arcSeg.DerivedType, arcSeg.IsClosed); #endif IEnvelope envl = arcSeg.Envelope; DumpEnvelope(envl); IDirectPosition startPos = arcSeg.StartPosition; DumpPosition("", startPos); IDirectPosition midPos = arcSeg.MidPoint; DumpPosition("", midPos); IDirectPosition endPos = arcSeg.EndPosition; DumpPosition("", endPos); } public static void DumpCurveString(ICurveString curveString) { #if DUMPTESTCONTENT Console.WriteLine("{0}:count({1}) dimtype({2}) derivedtype({3}) closed({4})", "CURVESTRING", curveString.Count, curveString.Dimensionality, curveString.DerivedType, curveString.IsClosed); #endif IDirectPosition startPos = curveString.StartPosition; DumpPosition("StartPoint", startPos); IDirectPosition endPos = curveString.EndPosition; DumpPosition("EndPoint", endPos); IEnvelope envl = curveString.Envelope; DumpEnvelope(envl); for (int i = 0; i < curveString.Count; i++) { ICurveSegmentAbstract seg = curveString[i]; switch (seg.DerivedType) { case GeometryComponentType.GeometryComponentType_LineStringSegment: { DumpLineStringSegment((ILineStringSegment)(seg)); break; } case GeometryComponentType.GeometryComponentType_CircularArcSegment: { DumpCircularArcSegment((ICircularArcSegment)(seg)); break; } default: Debug.Assert(false); break; } } DumpFGFT(curveString); } public static void DumpRing(IRing ring) { #if DUMPTESTCONTENT Console.WriteLine("{0}:count({1}) dimtype({2})", "(RING)", ring.Count, ring.Dimensionality); #endif IEnvelope envl = ring.Envelope; DumpEnvelope(envl); for (int i = 0; i < ring.Count; i++) { ICurveSegmentAbstract seg = ring[i]; switch (seg.DerivedType) { case GeometryComponentType.GeometryComponentType_LineStringSegment: { DumpLineStringSegment((ILineStringSegment)seg); break; } case GeometryComponentType.GeometryComponentType_CircularArcSegment: { DumpCircularArcSegment((ICircularArcSegment)seg); break; } } } } public static void DumpCurvePolygon(ICurvePolygon curvePoly) { #if DUMPTESTCONTENT Console.WriteLine("{0}:interiorRingCount({1}) dimtype({2}) derivedtype({3})", "CURVEPOLYGON", curvePoly.InteriorRingCount, curvePoly.Dimensionality, curvePoly.DerivedType); #endif IRing extRing = curvePoly.ExteriorRing; DumpRing(extRing); for (int i = 0; i < curvePoly.InteriorRingCount; i++) { IRing ring = curvePoly.get_InteriorRing(i); DumpRing(ring); } IEnvelope envl = curvePoly.Envelope; DumpEnvelope(envl); DumpFGFT(curvePoly); } public static void DumpMultiCurvePolygon(IMultiCurvePolygon multiCurvePoly) { #if DUMPTESTCONTENT Console.WriteLine("{0}:count({1}) dimtype({2}) derivedtype({3})", "MULTICURVEPOLYGON", multiCurvePoly.Count, multiCurvePoly.Dimensionality, multiCurvePoly.DerivedType); #endif for (int i = 0; i < multiCurvePoly.Count; i++) { ICurvePolygon curvePoly = multiCurvePoly[i]; DumpCurvePolygon(curvePoly); } IEnvelope envl = multiCurvePoly.Envelope; DumpEnvelope(envl); DumpFGFT(multiCurvePoly); } public static void DumpMultiCurveString(IMultiCurveString multiCurveString) { #if DUMPTESTCONTENT Console.WriteLine("{0}:count({1}) dimtype({2}) derivedtype({3})", "MULTICURVESTRING", multiCurveString.Count, multiCurveString.Dimensionality, multiCurveString.DerivedType); #endif for (int i = 0; i < multiCurveString.Count; i++) { ICurveString curveString = multiCurveString[i]; DumpCurveString(curveString); } IEnvelope envl = multiCurveString.Envelope; DumpEnvelope(envl); DumpFGFT(multiCurveString); } public static void DumpMultiGeometry(IMultiGeometry multiGeometry) { #if DUMPTESTCONTENT Console.WriteLine("{0}:count({1}) dimtype({2}) derivedtype({3}))", "MULTIGEOMETRY", multiGeometry.Count, multiGeometry.Dimensionality, multiGeometry.DerivedType); #endif IEnvelope envl = multiGeometry.Envelope; DumpEnvelope(envl); for (int i = 0; i < multiGeometry.Count; i++) { IGeometry geometry = multiGeometry[i]; switch (geometry.DerivedType) { case GeometryType.GeometryType_LineString: DumpLineString((ILineString)geometry); break; case GeometryType.GeometryType_Point: DumpPoint((IPoint)geometry); break; case GeometryType.GeometryType_Polygon: DumpPolygon((IPolygon)geometry); break; case GeometryType.GeometryType_CurveString: DumpCurveString((ICurveString)geometry); break; case GeometryType.GeometryType_CurvePolygon: DumpCurvePolygon((ICurvePolygon)geometry); break; default: Debug.Assert(false, string.Format("MultiGeometry test does not support item type of {0}.", geometry.DerivedType)); break; } } DumpFGFT(multiGeometry); } ////////////////////////////////////////////////////////////////////// // Checkers... ////////////////////////////////////////////////////////////////////// public static void CheckPositionXY(IDirectPosition pos, double x, double y) { Debug.Assert(pos.X == x, "X value mismatch!"); Debug.Assert(pos.Y == y, "Y value mismatch!"); } public static void CheckPositionXYM(IDirectPosition pos, double x, double y, double m) { CheckPositionXY(pos, x, y); Debug.Assert(pos.M == m, "M value mismatch!"); } public static void CheckPositionXYZ(IDirectPosition pos, double x, double y, double z) { CheckPositionXY(pos, x, y); Debug.Assert(pos.Z == z, "Z value mismatch!"); } public static void CheckPositionXYZM(IDirectPosition pos, double x, double y, double z, double m) { CheckPositionXYZ(pos, x, y, z); Debug.Assert(pos.M == m, "M value mismatch!"); } public static void CheckEnvelope(IEnvelope envl, double[] ordsXY) { Debug.Assert(envl.MinX == ordsXY[0], "MinX mismatch!"); Debug.Assert(envl.MinY == ordsXY[1], "MinY mismatch!"); Debug.Assert(envl.MaxX == ordsXY[2], "MaxX mismatch!"); Debug.Assert(envl.MaxY == ordsXY[3], "MaxY mismatch!"); } public static void CheckEnvelope(IEnvelope envl, IDirectPosition pos1, IDirectPosition pos2) { Debug.Assert(envl.MinX == pos1.X, "MinX mismatch!"); Debug.Assert(envl.MinY == pos1.Y, "MinY mismatch!"); Debug.Assert((pos1.Dimensionality & Dimensionality_Z) == 0 || envl.MinZ == pos1.Z, "MinZ mismatch!"); Debug.Assert(envl.MaxX == pos2.X, "MaxX mismatch!"); Debug.Assert(envl.MaxY == pos2.Y, "MaxY mismatch!"); Debug.Assert((pos2.Dimensionality & Dimensionality_Z) == 0 || envl.MaxZ == pos2.Z, "MaxZ mismatch!"); } public static void CheckEnvelopeXY(IEnvelope envl, double minx, double miny, double maxx, double maxy) { Debug.Assert(envl.MinX == minx, "MinX mismatch!"); Debug.Assert(envl.MinY == miny, "MinY mismatch!"); Debug.Assert(envl.MaxX == maxx, "MaxX mismatch!"); Debug.Assert(envl.MaxY == maxy, "MaxY mismatch!"); } public static void CheckEnvelopeXYZ(IEnvelope envl, double minx, double miny, double minz, double maxx, double maxy, double maxz) { CheckEnvelopeXY(envl, minx, miny, maxx, maxy); Debug.Assert(envl.MinZ == minz, "MinZ mismatch!"); Debug.Assert(envl.MaxZ == maxz, "MaxZ mismatch!"); } public static void CheckEqualEnvelopes(IEnvelope envl1, IEnvelope envl2) { Debug.Assert(envl1.MinX == envl2.MinX, "Envelope MinX mismatch!"); Debug.Assert(envl1.MinY == envl2.MinY, "Envelope MinY mismatch!"); Debug.Assert(envl1.MinZ == envl2.MinZ, "Envelope MinZ mismatch!"); Debug.Assert(envl1.MaxX == envl2.MaxX, "Envelope MaxX mismatch!"); Debug.Assert(envl1.MaxY == envl2.MaxY, "Envelope MaxY mismatch!"); Debug.Assert(envl1.MaxZ == envl2.MaxZ, "Envelope MaxZ mismatch!"); } //TODO: use parens in FGFT formatter public static void CheckFGFT(IGeometry geom, string fgft) { DumpFGFT(geom); if (geom.Text != fgft) { mgUnitTestUtil.PrintException(geom.Text, @"c:\1.txt"); mgUnitTestUtil.PrintException(fgft, @"c:\2.txt"); } Debug.Assert(!(geom.Text != fgft), string.Format("FGFT mismatch! <{0}> should be <{1}>", geom.Text, fgft)); } public static void CheckGeometryValidity(SpatialGeometryValidity validity1, SpatialGeometryValidity validity2) { Debug.Assert(validity1 == validity2, "Geometry Validity mismatch."); } ////////////////////////////////////////////////////////////////////// // Helpers to create repetitive geometries public static ICurveString CreateCurveString(double offset) { FgfGeometryFactory gf = new FgfGeometryFactory(); IDirectPosition startPos = gf.CreatePositionXY(offset + 0.0, offset + 0.0); IDirectPosition midPos = gf.CreatePositionXY(offset + 0.0, offset + 1.0); IDirectPosition endPos = gf.CreatePositionXY(offset + 1.0, offset + 2.0); ICircularArcSegment arcSeg = gf.CreateCircularArcSegment(startPos, midPos, endPos); DirectPositionCollection points = new DirectPositionCollection(); IDirectPosition pt1 = gf.CreatePositionXY(offset + 1.0, offset + 2.0); IDirectPosition pt2 = gf.CreatePositionXY(offset + 3.0, offset + 0.0); IDirectPosition pt3 = gf.CreatePositionXY(offset + 3.0, offset + 2.0); points.Add(pt1); points.Add(pt2); points.Add(pt3); ILineStringSegment lineSeg = gf.CreateLineStringSegment(points); CurveSegmentCollection curveSegs = new CurveSegmentCollection(); curveSegs.Add(arcSeg); curveSegs.Add(lineSeg); return gf.CreateCurveString(curveSegs); } public static IRing CreateRing(double offset) { FgfGeometryFactory gf = new FgfGeometryFactory(); IDirectPosition startPos = gf.CreatePositionXY(offset + 0.0, offset + 0.0); IDirectPosition midPos = gf.CreatePositionXY(offset + 0.0, offset + 1.0); IDirectPosition endPos = gf.CreatePositionXY(offset + 1.0, offset + 2.0); ICircularArcSegment arcSeg = gf.CreateCircularArcSegment(startPos, midPos, endPos); DirectPositionCollection points = new DirectPositionCollection(); IDirectPosition fromPt = gf.CreatePositionXY(offset + 1.0, offset + 2.0); IDirectPosition toPt = gf.CreatePositionXY(offset + 0.0, offset + 0.0); points.Add(fromPt); points.Add(toPt); ILineStringSegment lineSeg = gf.CreateLineStringSegment(points); CurveSegmentCollection curveSegs = new CurveSegmentCollection(); curveSegs.Add(arcSeg); curveSegs.Add(lineSeg); return gf.CreateRing(curveSegs); } public static ICurvePolygon CreateCurvePolygon(double offset) { IRing extRing = CreateRing(offset + 100); RingCollection intRings = new RingCollection(); IRing ring1 = CreateRing(offset + 200); IRing ring2 = CreateRing(offset + 300); intRings.Add(ring1); intRings.Add(ring2); FgfGeometryFactory gf = new FgfGeometryFactory(); return gf.CreateCurvePolygon(extRing, intRings); } public static IMultiCurvePolygon CreateMultiCurvePolygon(int numCurvePolys, double offset) { CurvePolygonCollection curvePolys = new CurvePolygonCollection(); for (int i = 0; i < numCurvePolys; i++) { ICurvePolygon curvePoly = CreateCurvePolygon(i + offset); curvePolys.Add(curvePoly); } FgfGeometryFactory gf = new FgfGeometryFactory(); return gf.CreateMultiCurvePolygon(curvePolys); } public static IMultiGeometry CreateMultiGeometry() { GeometryCollection geometries = new GeometryCollection(); FgfGeometryFactory gf = new FgfGeometryFactory(); IGeometry geometry; // CurvePolygon geometry = CreateCurvePolygon(0); geometries.Add(geometry); // CurveString // Not doing CurveString because of some unfixed defect. // It may be the same one that sometimes affects MultiPolygon. geometry = CreateCurveString(100); geometries.Add(geometry); // LineString double[] ordsXY = new double[6]; ordsXY[0] = 0.0; ordsXY[1] = 1.0; ordsXY[2] = 2.0; ordsXY[3] = 3.0; ordsXY[4] = 4.0; ordsXY[5] = 5.0; geometry = gf.CreateLineString(Dimensionality_XY, 6, ordsXY); geometries.Add(geometry); // Point double[] ordsXYZ = new double[3]; ordsXYZ[0] = 5.0; ordsXYZ[1] = 3.0; ordsXYZ[2] = 2.0; geometry = gf.CreatePoint(Dimensionality_XY | Dimensionality_Z, ordsXYZ); geometries.Add(geometry); // Polygon // Not doing Polygon because of some unfixed defect. // It may be the same one that sometimes affects MultiPolygon. double[] ordsXYExt = new double[10]; ordsXYExt[0] = 0.0; ordsXYExt[1] = 0.0; ordsXYExt[2] = 5.0; ordsXYExt[3] = 0.0; ordsXYExt[4] = 5.0; ordsXYExt[5] = 5.0; ordsXYExt[6] = 0.0; ordsXYExt[7] = 5.0; ordsXYExt[8] = 0.0; ordsXYExt[9] = 0.0; double[] ordsXYInt1 = new double[8]; ordsXYInt1[0] = 1.0; ordsXYInt1[1] = 1.0; ordsXYInt1[2] = 2.0; ordsXYInt1[3] = 1.0; ordsXYInt1[4] = 2.0; ordsXYInt1[5] = 2.0; ordsXYInt1[6] = 1.0; ordsXYInt1[7] = 1.0; double[] ordsXYInt2 = new double[8]; ordsXYInt2[0] = 3.0; ordsXYInt2[1] = 3.0; ordsXYInt2[2] = 4.0; ordsXYInt2[3] = 3.0; ordsXYInt2[4] = 4.0; ordsXYInt2[5] = 4.0; ordsXYInt2[6] = 3.0; ordsXYInt2[7] = 3.0; ILinearRing extRing = gf.CreateLinearRing(Dimensionality_XY, 10, ordsXYExt); ILinearRing intRing1 = gf.CreateLinearRing(Dimensionality_XY, 8, ordsXYInt1); ILinearRing intRing2 = gf.CreateLinearRing(Dimensionality_XY, 8, ordsXYInt2); LinearRingCollection intRings = new LinearRingCollection(); intRings.Add(intRing1); intRings.Add(intRing2); geometry = gf.CreatePolygon(extRing, intRings); geometries.Add(geometry); // Make MultiGeometry from the many geometries collected above. return gf.CreateMultiGeometry(geometries); } } }