public MultiPatchConstruction StartInnerRing(IPoint p)
        {
            StartRing(p);
            _currentRingType = esriMultiPatchRingType.esriMultiPatchInnerRing;

            return(this);
        }
Esempio n. 2
0
        private static IEnumerable <List <IRing> > GetPolygons([NotNull] IMultiPatch multipatch,
                                                               [NotNull] GeometryPart part)
        {
            var result = new Dictionary <IRing, List <IRing> >();

            foreach (IRing ring in part.LowLevelGeometries.Cast <IRing>())
            {
                bool beginning = false;
                esriMultiPatchRingType type = multipatch.GetRingType(ring, ref beginning);

                if (type != esriMultiPatchRingType.esriMultiPatchInnerRing)
                {
                    result.Add(ring, new List <IRing>());
                }
                else
                {
                    IRing outerRing = multipatch.FindBeginningRing(ring);

                    Assert.True(result.ContainsKey(outerRing),
                                "No outer ring found for inner ring.");

                    result[outerRing].Add(ring);
                }
            }

            foreach (KeyValuePair <IRing, List <IRing> > keyValuePair in result)
            {
                List <IRing> polygonRings = keyValuePair.Value;

                polygonRings.Insert(0, keyValuePair.Key);

                yield return(polygonRings);
            }
        }
Esempio n. 3
0
        private static int GetInteriorRingCount([NotNull] IMultiPatch multiPatch)
        {
            Assert.ArgumentNotNull(multiPatch, nameof(multiPatch));

            var count = 0;

            foreach (IGeometry part in GeometryUtils.GetParts((IGeometryCollection)multiPatch)
                     )
            {
                var ring = part as IRing;
                if (ring == null)
                {
                    continue;
                }

                var isBeginningRing         = false;
                esriMultiPatchRingType type = multiPatch.GetRingType(ring, ref isBeginningRing);

                if ((type & esriMultiPatchRingType.esriMultiPatchInnerRing) != 0)
                {
                    count++;
                }
            }

            return(count);
        }
    //----------------------------------------------------------------------------------

    public static void SchrijfRingenMP(IFeature pFeat)
    {
        IMultiPatch         pMultiPatch = (IMultiPatch)pFeat.ShapeCopy;
        IGeometryCollection GeoColl     = (IGeometryCollection)pMultiPatch;

        //Schrijf TrianglesVlag = false
        Boolean TrianglesVlag = false;

        WriteBoolean(TrianglesVlag);

        //Schrijf aantalringen
        int aantalringen = GeoColl.GeometryCount;

        Naar3dsMax.binWriter.Write(aantalringen);

        //Loop door de ringencollectie
        for (int i = 0; i < aantalringen; i++)
        {
            IRing   pRing                   = (IRing)GeoColl.get_Geometry(i);
            Boolean isbeginning             = true;
            esriMultiPatchRingType ringtype = pMultiPatch.GetRingType(pRing, ref isbeginning);

            //Schrijf Buitenringvlag
            Boolean Buitenringvlag = (ringtype == esriMultiPatchRingType.esriMultiPatchOuterRing);
            WriteBoolean(Buitenringvlag);
            SchrijfRing(pRing);
        }
    }
        public MultiPatchConstruction StartRing(IPoint p)
        {
            EndPatch();
            _currentPatch    = new RingClass();
            _currentRingType = esriMultiPatchRingType.esriMultiPatchRing;

            var    newRing = (IPointCollection)_currentPatch;
            object missing = Type.Missing;

            newRing.AddPoint(p, ref missing, ref missing);

            return(this);
        }
        private static void AddRing(IMultiPatch result, Linestring closedLinestring,
                                    IRing ringTemplate, esriMultiPatchRingType ringType,
                                    int?pointId)
        {
            IRing ring = CreateRing(closedLinestring, ringTemplate);

            if (pointId != null)
            {
                GeometryUtils.AssignConstantPointID((IPointCollection)ring,
                                                    pointId.Value);
            }

            ((IGeometryCollection)result).AddGeometry(ring);

            result.PutRingType(ring, ringType);
        }
Esempio n. 7
0
        /// <summary>
        /// Removes gaps in the vertex id values.
        /// </summary>
        /// <param name="geometry"></param>
        private static void CompressVertexIds(IGeometry geometry)
        {
            var geometryCollection = (IGeometryCollection)geometry;

            int processingId = -1;
            int currentId    = -1;

            for (var i = 0; i < geometryCollection.GeometryCount; i++)
            {
                IGeometry part = geometryCollection.Geometry[i];
                int       vertexId;
                if (GeometryUtils.HasUniqueVertexId(part, out vertexId))
                {
                    // NOTE: part id values are not necessarily ordered along geometry indexes
                    // This assumption is not only violated when holes are created in the non-0 part, but
                    // also occurs when extracting several parts from an existing geometry.
                    esriMultiPatchRingType ringType =
                        GetMultipatchRingType(geometry, part);

                    if (vertexId == 0 &&
                        ringType == esriMultiPatchRingType.esriMultiPatchInnerRing)
                    {
                        // The TEFA create hole tool always assigns 0 to the holes - leave them alone.
                        continue;
                    }

                    if (processingId != vertexId)
                    {
                        // different part -> increment current id
                        currentId++;
                        processingId = vertexId;
                    }

                    if (vertexId != currentId)
                    {
                        GeometryUtils.AssignConstantPointID(
                            (IGeometryCollection)geometry, i, currentId);
                    }
                }
            }
        }
Esempio n. 8
0
        private static void AssertEqual(IMultiPatch multipatch1, IMultiPatch multipatch2)
        {
            var originalCollection = ((IGeometryCollection)multipatch1);

            Assert.AreEqual(originalCollection.GeometryCount,
                            ((IGeometryCollection)multipatch2).GeometryCount);

            for (int i = 0; i < originalCollection.GeometryCount; i++)
            {
                IRing originalRing   = (IRing)originalCollection.Geometry[i];
                IRing rehydratedRing = (IRing)((IGeometryCollection)multipatch2).Geometry[i];

                // This does not compare point IDs
                GeometryUtils.AreEqual(originalRing, rehydratedRing);

                bool isBeginning = false;
                esriMultiPatchRingType origType =
                    multipatch1.GetRingType(originalRing, ref isBeginning);
                esriMultiPatchRingType rehydratedType =
                    multipatch2.GetRingType(rehydratedRing, ref isBeginning);

                if (origType == esriMultiPatchRingType.esriMultiPatchInnerRing)
                {
                    Assert.AreEqual(origType, rehydratedType);
                }
                else if (origType == esriMultiPatchRingType.esriMultiPatchOuterRing ||
                         origType == esriMultiPatchRingType.esriMultiPatchFirstRing)
                {
                    Assert.IsTrue(
                        rehydratedType == esriMultiPatchRingType.esriMultiPatchOuterRing ||
                        rehydratedType == esriMultiPatchRingType.esriMultiPatchFirstRing);
                }
                else
                {
                    Assert.AreEqual(origType, rehydratedType);
                }
            }
        }
Esempio n. 9
0
        public static IGeometry GetExample4()
        {
            const double CircleDegrees                   = 360.0;
            const int    CircleDivisions                 = 18;
            const double VectorComponentOffset           = 0.0000001;
            const double InnerBuildingRadius             = 3.0;
            const double OuterBuildingExteriorRingRadius = 9.0;
            const double OuterBuildingInteriorRingRadius = 6.0;
            const double BaseZ          = 0.0;
            const double InnerBuildingZ = 16.0;
            const double OuterBuildingZ = 6.0;

            //Composite: Tall Building Protruding Through Outer Ring-Shaped Building

            IMultiPatch multiPatch = new MultiPatchClass();

            IGeometryCollection multiPatchGeometryCollection = multiPatch as IGeometryCollection;

            IPoint originPoint = GeometryUtilities.ConstructPoint3D(0, 0, 0);

            IVector3D upperAxisVector3D = GeometryUtilities.ConstructVector3D(0, 0, 10);

            IVector3D lowerAxisVector3D = GeometryUtilities.ConstructVector3D(0, 0, -10);

            lowerAxisVector3D.XComponent += VectorComponentOffset;

            IVector3D normalVector3D = upperAxisVector3D.CrossProduct(lowerAxisVector3D) as IVector3D;

            double rotationAngleInRadians = GeometryUtilities.GetRadians(CircleDegrees / CircleDivisions);

            //Inner Building

            IGeometry innerBuildingBaseGeometry = new PolygonClass();

            IPointCollection innerBuildingBasePointCollection = innerBuildingBaseGeometry as IPointCollection;

            //Outer Building

            IGeometry outerBuildingBaseGeometry = new PolygonClass();

            IGeometryCollection outerBuildingBaseGeometryCollection = outerBuildingBaseGeometry as IGeometryCollection;

            IPointCollection outerBuildingBaseExteriorRingPointCollection = new RingClass();

            IPointCollection outerBuildingBaseInteriorRingPointCollection = new RingClass();

            for (int i = 0; i < CircleDivisions; i++)
            {
                normalVector3D.Rotate(-1 * rotationAngleInRadians, upperAxisVector3D);

                //Inner Building

                normalVector3D.Magnitude = InnerBuildingRadius;

                IPoint innerBuildingBaseVertexPoint = GeometryUtilities.ConstructPoint2D(originPoint.X + normalVector3D.XComponent,
                                                                                         originPoint.Y + normalVector3D.YComponent);

                innerBuildingBasePointCollection.AddPoint(innerBuildingBaseVertexPoint, ref _missing, ref _missing);

                //Outer Building

                //Exterior Ring

                normalVector3D.Magnitude = OuterBuildingExteriorRingRadius;

                IPoint outerBuildingBaseExteriorRingVertexPoint = GeometryUtilities.ConstructPoint2D(originPoint.X + normalVector3D.XComponent,
                                                                                                     originPoint.Y + normalVector3D.YComponent);

                outerBuildingBaseExteriorRingPointCollection.AddPoint(outerBuildingBaseExteriorRingVertexPoint, ref _missing, ref _missing);

                //Interior Ring

                normalVector3D.Magnitude = OuterBuildingInteriorRingRadius;

                IPoint outerBuildingBaseInteriorRingVertexPoint = GeometryUtilities.ConstructPoint2D(originPoint.X + normalVector3D.XComponent,
                                                                                                     originPoint.Y + normalVector3D.YComponent);

                outerBuildingBaseInteriorRingPointCollection.AddPoint(outerBuildingBaseInteriorRingVertexPoint, ref _missing, ref _missing);
            }

            IPolygon innerBuildingBasePolygon = innerBuildingBaseGeometry as IPolygon;

            innerBuildingBasePolygon.Close();

            IRing outerBuildingBaseExteriorRing = outerBuildingBaseExteriorRingPointCollection as IRing;

            outerBuildingBaseExteriorRing.Close();

            IRing outerBuildingBaseInteriorRing = outerBuildingBaseInteriorRingPointCollection as IRing;

            outerBuildingBaseInteriorRing.Close();
            outerBuildingBaseInteriorRing.ReverseOrientation();

            outerBuildingBaseGeometryCollection.AddGeometry(outerBuildingBaseExteriorRing as IGeometry, ref _missing, ref _missing);
            outerBuildingBaseGeometryCollection.AddGeometry(outerBuildingBaseInteriorRing as IGeometry, ref _missing, ref _missing);

            ITopologicalOperator topologicalOperator = outerBuildingBaseGeometry as ITopologicalOperator;

            topologicalOperator.Simplify();

            IConstructMultiPatch innerBuildingConstructMultiPatch = new MultiPatchClass();

            innerBuildingConstructMultiPatch.ConstructExtrudeFromTo(BaseZ, InnerBuildingZ, innerBuildingBaseGeometry);

            IGeometryCollection innerBuildingMultiPatchGeometryCollection = innerBuildingConstructMultiPatch as IGeometryCollection;

            for (int i = 0; i < innerBuildingMultiPatchGeometryCollection.GeometryCount; i++)
            {
                multiPatchGeometryCollection.AddGeometry(innerBuildingMultiPatchGeometryCollection.get_Geometry(i), ref _missing, ref _missing);
            }

            IConstructMultiPatch outerBuildingConstructMultiPatch = new MultiPatchClass();

            outerBuildingConstructMultiPatch.ConstructExtrudeFromTo(BaseZ, OuterBuildingZ, outerBuildingBaseGeometry);

            IMultiPatch outerBuildingMultiPatch = outerBuildingConstructMultiPatch as IMultiPatch;

            IGeometryCollection outerBuildingMultiPatchGeometryCollection = outerBuildingConstructMultiPatch as IGeometryCollection;

            for (int i = 0; i < outerBuildingMultiPatchGeometryCollection.GeometryCount; i++)
            {
                IGeometry outerBuildingPatchGeometry = outerBuildingMultiPatchGeometryCollection.get_Geometry(i);

                multiPatchGeometryCollection.AddGeometry(outerBuildingPatchGeometry, ref _missing, ref _missing);

                if (outerBuildingPatchGeometry.GeometryType == esriGeometryType.esriGeometryRing)
                {
                    bool isBeginningRing = false;

                    esriMultiPatchRingType multiPatchRingType = outerBuildingMultiPatch.GetRingType(outerBuildingPatchGeometry as IRing, ref isBeginningRing);

                    multiPatch.PutRingType(outerBuildingPatchGeometry as IRing, multiPatchRingType);
                }
            }

            return(multiPatchGeometryCollection as IGeometry);
        }
Esempio n. 10
0
            private void Initialize()
            {
                _indexedMultipatch = GetAdaptedMultiPatch();
                IMultiPatch multiPatch = _indexedMultipatch.BaseGeometry;

                _verticalFaceSegments = new List <SegmentProxy>();

                var patches            = (IGeometryCollection)multiPatch;
                var verticalPatchParts = new Dictionary <int, List <int> >();

                int patchCount = patches.GeometryCount;

                for (int patchIndex = 0; patchIndex < patchCount; patchIndex++)
                {
                    List <int> partIndexes = _indexedMultipatch.GetPartIndexes(patchIndex);

                    foreach (int partIndex in partIndexes)
                    {
                        int partSegmentCount =
                            _indexedMultipatch.GetPartSegmentCount(partIndex);

                        var segments = new List <SegmentProxy>(partSegmentCount);
                        for (int segmentIndex = 0;
                             segmentIndex < partSegmentCount;
                             segmentIndex++)
                        {
                            segments.Add(
                                _indexedMultipatch.GetSegment(partIndex, segmentIndex));
                        }

                        Plane plane =
                            QaGeometryUtils.CreatePlane(
                                (IEnumerable <SegmentProxy>)segments);

                        if (Math.Abs(plane.GetNormalVector().Z) < double.Epsilon)
                        {
                            List <int> verticalParts;
                            if (!verticalPatchParts.TryGetValue(
                                    patchIndex, out verticalParts))
                            {
                                verticalParts = new List <int>();
                                verticalPatchParts.Add(patchIndex, verticalParts);
                            }

                            verticalParts.Add(partIndex);
                            _verticalFaceSegments.AddRange(segments);
                        }
                    }
                }

                if (verticalPatchParts.Count > 0)
                {
                    object      missing = Type.Missing;
                    IMultiPatch nonVerticalMultiPatch =
                        new MultiPatchClass
                    {
                        SpatialReference = multiPatch.SpatialReference
                    };

                    for (int patchIndex = 0; patchIndex < patchCount; patchIndex++)
                    {
                        List <int> verticalParts;
                        IGeometry  patch =
                            ((IGeometryCollection)multiPatch).Geometry[patchIndex];

                        if (!verticalPatchParts.TryGetValue(
                                patchIndex, out verticalParts))
                        {
                            IGeometry clone = GeometryFactory.Clone(patch);
                            ((IGeometryCollection)nonVerticalMultiPatch).AddGeometry(
                                clone,
                                ref missing,
                                ref missing);
                            var ring = patch as IRing;
                            if (ring != null)
                            {
                                bool isBeginning = false;
                                esriMultiPatchRingType ringType =
                                    multiPatch.GetRingType(ring, ref isBeginning);
                                nonVerticalMultiPatch.PutRingType(
                                    (IRing)clone, ringType);
                            }
                        }
                        else
                        {
                            if (patch is IRing)
                            {
                                continue;
                            }

                            List <int> partIndexes =
                                _indexedMultipatch.GetPartIndexes(patchIndex);

                            foreach (int partIndex in partIndexes)
                            {
                                if (verticalParts.Contains(partIndex))
                                {
                                    continue;
                                }

                                int partSegmentCount =
                                    _indexedMultipatch.GetPartSegmentCount(partIndex);

                                var points = new List <WKSPointZ>(3);

                                for (int segmentIndex = 0;
                                     segmentIndex < partSegmentCount;
                                     segmentIndex++)
                                {
                                    SegmentProxy segment =
                                        _indexedMultipatch.GetSegment(
                                            partIndex, segmentIndex);

                                    const bool as3D = true;
                                    Pnt        p    = segment.GetStart(as3D);

                                    points.Add(
                                        WKSPointZUtils.CreatePoint(p.X, p.Y, p[2]));
                                }

                                IRing ring = CreateRing(points);

                                ((IGeometryCollection)nonVerticalMultiPatch).AddGeometry(
                                    ring,
                                    ref missing,
                                    ref missing);
                            }
                        }
                    }

                    _nonVerticalMultipatch = nonVerticalMultiPatch;
                }
                else
                {
                    _nonVerticalMultipatch = multiPatch;
                }
            }
        private IPolygon GetFootprint([NotNull] IMultiPatch multiPatch,
                                      double xyTolerance,
                                      [CanBeNull] out IPolyline tooSmallRings)
        {
            Assert.ArgumentNotNull(multiPatch, nameof(multiPatch));

            var         notLargeEnoughRings        = new List <IRing>();
            IMultiPatch largeEnoughRingsMultiPatch = null;

            object missing = Type.Missing;

            foreach (IGeometry part in GeometryUtils.GetParts(
                         (IGeometryCollection)multiPatch))
            {
                var ring = part as IRing;
                if (ring == null)
                {
                    continue;
                }

                var isBeginning = false;
                esriMultiPatchRingType ringType = multiPatch.GetRingType(ring, ref isBeginning);

                if (IsTooSmall(ring, xyTolerance))
                {
                    if (isBeginning)
                    {
                        // throw away following rings (holes) that are too small
                        notLargeEnoughRings.Add(ring);
                    }
                }
                else
                {
                    if (largeEnoughRingsMultiPatch == null)
                    {
                        largeEnoughRingsMultiPatch = new MultiPatchClass
                        {
                            SpatialReference =
                                multiPatch.SpatialReference
                        };
                        ((IZAware)largeEnoughRingsMultiPatch).ZAware = true;
                    }

                    IRing clone = GeometryFactory.Clone(ring);
                    ((IGeometryCollection)largeEnoughRingsMultiPatch).AddGeometry(clone,
                                                                                  ref missing,
                                                                                  ref missing);

                    largeEnoughRingsMultiPatch.PutRingType(clone, ringType);
                }
            }

            ISpatialReference spatialReference = multiPatch.SpatialReference;

            tooSmallRings = notLargeEnoughRings.Count > 0
                                                ? CreatePolyline(notLargeEnoughRings, spatialReference)
                                                : null;

            return(largeEnoughRingsMultiPatch != null
                                       ? GeometryFactory.CreatePolygon(largeEnoughRingsMultiPatch)
                                       : null);
        }
        private IGeometry GetErrorGeometry([NotNull] IMultiPatch multiPatch,
                                           [NotNull] IPolygon footprintPolygon)
        {
            ISpatialReference spatialReference = multiPatch.SpatialReference;
            var result = new MultiPatchClass
            {
                SpatialReference = spatialReference
            };

            GeometryUtils.AllowIndexing(footprintPolygon);
            footprintPolygon.QueryEnvelope(_envelopeTemplate1);

            object missing = Type.Missing;

            foreach (IGeometry part in GeometryUtils.GetParts(
                         (IGeometryCollection)multiPatch))
            {
                var ring = part as IRing;
                if (ring == null)
                {
                    continue;
                }

                var isBeginningRing             = false;
                esriMultiPatchRingType ringType = multiPatch.GetRingType(ring, ref isBeginningRing);

                if (!isBeginningRing)
                {
                    continue;
                }

                ring.QueryEnvelope(_envelopeTemplate2);

                if (!((IRelationalOperator)_envelopeTemplate1).Contains(_envelopeTemplate2))
                {
                    // the ring envelope is not contained in the footprint envelope
                    continue;
                }

                IPolyline polyline = CreatePolyline(new[] { ring }, spatialReference);

                if (polyline == null)
                {
                    continue;
                }

                if (!((IRelationalOperator2)footprintPolygon).ContainsEx(
                        polyline, esriSpatialRelationExEnum.esriSpatialRelationExBoundary))
                {
                    continue;
                }

                // the beginning ring is inside the footprint

                // add the beginning ring
                IRing clonedRing = GeometryFactory.Clone(ring);
                ((IGeometryCollection)result).AddGeometry(clonedRing, ref missing, ref missing);
                result.PutRingType(clonedRing, ringType);

                int followingRingCount = multiPatch.get_FollowingRingCount(ring);

                if (followingRingCount > 0)
                {
                    // add the following rings

                    var followingRings = new IRing[followingRingCount];
                    GeometryUtils.GeometryBridge.QueryFollowingRings(multiPatch, ring,
                                                                     ref followingRings);

                    foreach (IRing followingRing in followingRings)
                    {
                        var dummy = false;
                        esriMultiPatchRingType followingRingType = multiPatch.GetRingType(
                            followingRing,
                            ref dummy);

                        IRing clonedFollowingRing = GeometryFactory.Clone(followingRing);

                        ((IGeometryCollection)result).AddGeometry(clonedFollowingRing,
                                                                  ref missing, ref missing);

                        result.PutRingType(clonedFollowingRing, followingRingType);
                    }
                }
            }

            if (result.IsEmpty)
            {
                // ((IZ) footprintPolygon).SetConstantZ(multiPatch.Envelope.ZMin);
                return(footprintPolygon);
            }

            return(result);
        }