Example #1
0
        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);
        }
Example #2
0
        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));
        }