private static GeoAPIMultiPolygon FromMultiPolygon(IMultiPolygon geometry, GeoAPIGeometryFactory factory, bool copyUserData) { var dsPolygons = new GeoAPI.Geometries.IPolygon[geometry.NumGeometries]; for (var i = 0; i < dsPolygons.Length; i++) { dsPolygons[i] = FromPolygon((IPolygon)geometry.GetGeometryN(i), factory, copyUserData); } var result = factory.CreateMultiPolygon(dsPolygons); if (copyUserData) { result.UserData = geometry.UserData; } return(result); }
/// <summary> /// Creates a Polygon or MultiPolygon from this Polygon shape. /// </summary> /// <param name="shape">The shape to convert</param> /// <param name="factory">The geometry factory to use.</param> /// <param name="copyAttributes">A value indicating whether or not to copy the <see cref="Data.Shape.Attributes"/> to <see cref="GeoAPIGeometry.UserData"/></param> /// <returns>The geometry representing the converted shape.</returns> private static GeoAPIGeometry FromPolygonShape(Data.Shape shape, GeoAPIGeometryFactory factory, bool copyAttributes) { var shells = new List<GeoAPILinearRing>(); var holes = new List<GeoAPILinearRing>(); foreach (var part in shape.Range.Parts) { var coords = new List<GeoAPICoordinate>(); var i = part.StartIndex; foreach (var d in part) { var c = new GeoAPICoordinate(d.X, d.Y); //if (shape.HasM()) c.M = M[i]; if (shape.HasZ()) c.Z = shape.Z[i]; i++; coords.Add(c); } var ring = factory.CreateLinearRing(coords.ToArray()); if (shape.Range.Parts.Count == 1) { shells.Add(ring); } else { if (NetTopologySuite.Algorithm.CGAlgorithms.IsCCW(ring.Coordinates)) { holes.Add(ring); } else { shells.Add(ring); } } } //// Now we have a list of all shells and all holes var holesForShells = new List<GeoAPILinearRing>[shells.Count]; for (var i = 0; i < shells.Count; i++) { holesForShells[i] = new List<GeoAPILinearRing>(); } // Find holes foreach (var testRing in holes) { GeoAPILinearRing minShell = null; GeoAPIEnvelope minEnv = null; var testEnv = testRing.EnvelopeInternal; var testPt = testRing.Coordinates[0]; for (int j = 0; j < shells.Count; j++) { var tryRing = shells[j]; var tryEnv = tryRing.EnvelopeInternal; if (minShell != null) minEnv = minShell.EnvelopeInternal; var isContained = tryEnv.Contains(testEnv) && (NetTopologySuite.Algorithm.CGAlgorithms.IsPointInRing(testPt, tryRing.Coordinates) || (PointInList(testPt, tryRing.Coordinates))); // Check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minEnv.Contains(tryEnv)) { minShell = tryRing; } holesForShells[j].Add(testRing); } } } var polygons = new GeoAPIPolygon[shells.Count]; for (var i = 0; i < shells.Count; i++) { polygons[i] = factory.CreatePolygon(shells[i], holesForShells[i].ToArray()); } if (polygons.Length == 1) { if (copyAttributes) polygons[0].UserData = shape.Attributes; return polygons[0]; } // It's a multi part var ret = factory.CreateMultiPolygon(polygons); if (copyAttributes) ret.UserData = shape.Attributes; return ret; }
private static GeoAPIMultiPolygon FromMultiPolygon(IMultiPolygon geometry, GeoAPIGeometryFactory factory, bool copyUserData) { var dsPolygons = new GeoAPI.Geometries.IPolygon[geometry.NumGeometries]; for (var i = 0; i < dsPolygons.Length; i++) dsPolygons[i] = FromPolygon((IPolygon)geometry.GetGeometryN(i), factory, copyUserData); var result = factory.CreateMultiPolygon(dsPolygons); if (copyUserData) result.UserData = geometry.UserData; return result; }
/// <summary> /// Creates a Polygon or MultiPolygon from this Polygon shape. /// </summary> /// <param name="shape">The shape to convert</param> /// <param name="factory">The geometry factory to use.</param> /// <param name="copyAttributes">A value indicating whether or not to copy the <see cref="Data.Shape.Attributes"/> to <see cref="GeoAPIGeometry.UserData"/></param> /// <returns>The geometry representing the converted shape.</returns> private static GeoAPIGeometry FromPolygonShape(Data.Shape shape, GeoAPIGeometryFactory factory, bool copyAttributes) { var shells = new List <GeoAPILinearRing>(); var holes = new List <GeoAPILinearRing>(); foreach (var part in shape.Range.Parts) { var coords = new List <GeoAPICoordinate>(); var i = part.StartIndex; foreach (var d in part) { var c = new GeoAPICoordinate(d.X, d.Y); //if (shape.HasM()) c.M = M[i]; if (shape.HasZ()) { c.Z = shape.Z[i]; } i++; coords.Add(c); } var ring = factory.CreateLinearRing(coords.ToArray()); if (shape.Range.Parts.Count == 1) { shells.Add(ring); } else { if (NetTopologySuite.Algorithm.CGAlgorithms.IsCCW(ring.Coordinates)) { holes.Add(ring); } else { shells.Add(ring); } } } //// Now we have a list of all shells and all holes var holesForShells = new List <GeoAPILinearRing> [shells.Count]; for (var i = 0; i < shells.Count; i++) { holesForShells[i] = new List <GeoAPILinearRing>(); } // Find holes foreach (var testRing in holes) { GeoAPILinearRing minShell = null; GeoAPIEnvelope minEnv = null; var testEnv = testRing.EnvelopeInternal; var testPt = testRing.Coordinates[0]; for (int j = 0; j < shells.Count; j++) { var tryRing = shells[j]; var tryEnv = tryRing.EnvelopeInternal; if (minShell != null) { minEnv = minShell.EnvelopeInternal; } var isContained = tryEnv.Contains(testEnv) && (NetTopologySuite.Algorithm.CGAlgorithms.IsPointInRing(testPt, tryRing.Coordinates) || (PointInList(testPt, tryRing.Coordinates))); // Check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minEnv.Contains(tryEnv)) { minShell = tryRing; } holesForShells[j].Add(testRing); } } } var polygons = new GeoAPIPolygon[shells.Count]; for (var i = 0; i < shells.Count; i++) { polygons[i] = factory.CreatePolygon(shells[i], holesForShells[i].ToArray()); } if (polygons.Length == 1) { if (copyAttributes) { polygons[0].UserData = shape.Attributes; } return(polygons[0]); } // It's a multi part var ret = factory.CreateMultiPolygon(polygons); if (copyAttributes) { ret.UserData = shape.Attributes; } return(ret); }