private static Dictionary <IPolygon, IMultiPatch> BuildResultMultipatches( [NotNull] IMultiPatch prototype, [NotNull] IDictionary <RingGroup, List <RingGroup> > splitResultsByFootprintPart, DegenerateMultipatchFootprintAction nonSimpleBoundaryAction) { var result = new Dictionary <IPolygon, IMultiPatch>(); IRing emptyRing = GeometryFactory.CreateEmptyRing(prototype); foreach (var outerRingsByFootprintPart in splitResultsByFootprintPart) { RingGroup footprintPart = outerRingsByFootprintPart.Key; List <RingGroup> resultPolys = outerRingsByFootprintPart.Value; IMultiPatch resultMultipatch = GeometryFactory.CreateEmptyMultiPatch(prototype); foreach (RingGroup poly in resultPolys) { // TODO: Support vertical ring group with inner rings bool simplify = poly.InteriorRings.Any(); GeometryConversionUtils.AddRingGroup( resultMultipatch, poly, simplify, poly.Id != null); } if (resultPolys.Any(p => p.Id != null)) { GeometryUtils.MakePointIDAware(resultMultipatch); } // Guard against multipatches with wrong footprint. They are so broken (IRelationalOps are wrong) that // it's not worth using them any further... if (IsMultipatchWithDegenerateFootprint(resultMultipatch)) { switch (nonSimpleBoundaryAction) { case DegenerateMultipatchFootprintAction.Throw: throw new DegenerateResultGeometryException( "The multipatch cut operation resulted in a multipatch with degenerate footprint."); case DegenerateMultipatchFootprintAction.Discard: _msg.DebugFormat( "Discarding result multipatch with degenerate boundary: {0}", GeometryUtils.ToString(resultMultipatch)); continue; case DegenerateMultipatchFootprintAction.Keep: _msg.DebugFormat( "Detected result multipatch with degenerate boundary (it will be kept): {0}", GeometryUtils.ToString(resultMultipatch)); break; } } IPolygon footprintPoly = GeometryConversionUtils.CreatePolygon(emptyRing, emptyRing, footprintPart); result.Add(footprintPoly, resultMultipatch); } return(result); }
public void CanConvertMultipatchWithOuterInnerRingSequence() { ISpatialReference sr = SpatialReferenceUtils.CreateSpatialReference( WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95); IRing outerRing0 = GeometryUtils.GetRings( GeometryFactory.CreatePolygon( 2601000, 1200000, 2602000, 1201000, 432)) .Single(); outerRing0.SpatialReference = sr; IRing outerRing1 = GeometryUtils.GetRings( GeometryFactory.CreatePolygon( 2600000, 1200000, 2601000, 1201000, 432)) .Single(); outerRing1.SpatialReference = sr; IRing innerRing = GeometryFactory.CreateRing(new[] { new WKSPointZ() { X = 2600100, Y = 1200100, Z = 432 }, new WKSPointZ() { X = 2600200, Y = 1200100, Z = 432 }, new WKSPointZ() { X = 2600200, Y = 1200200, Z = 432 }, new WKSPointZ() { X = 2600100, Y = 1200200, Z = 432 }, new WKSPointZ() { X = 2600100, Y = 1200100, Z = 432 }, }); innerRing.SpatialReference = sr; IMultiPatch multipatch = GeometryFactory.CreateEmptyMultiPatch(outerRing0); object emptyRef = Type.Missing; ((IGeometryCollection)multipatch).AddGeometry(outerRing0, ref emptyRef, ref emptyRef); multipatch.PutRingType(outerRing0, esriMultiPatchRingType.esriMultiPatchFirstRing); ((IGeometryCollection)multipatch).AddGeometry(outerRing1, ref emptyRef, ref emptyRef); multipatch.PutRingType(outerRing1, esriMultiPatchRingType.esriMultiPatchOuterRing); ((IGeometryCollection)multipatch).AddGeometry(innerRing, ref emptyRef, ref emptyRef); multipatch.PutRingType(innerRing, esriMultiPatchRingType.esriMultiPatchInnerRing); WkbGeometryWriter writer = new WkbGeometryWriter(); byte[] wkb = writer.WriteMultipatch(multipatch); WkbGeometryReader reader = new WkbGeometryReader(); IGeometry rehydrated = reader.ReadGeometry(new MemoryStream(wkb)); Assert.IsTrue(GeometryUtils.AreEqual(multipatch, rehydrated)); }