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); } }
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); }
private static IEnumerable <IPolygon> GetRingsAsPolygons( [NotNull] IMultiPatch multiPatch) { var parts = (IGeometryCollection)multiPatch; var result = new List <IPolygon>(parts.GeometryCount); foreach (IGeometry part in GeometryUtils.GetParts(parts)) { var ring = part as IRing; if (ring == null) { continue; } var isBeginningRing = false; multiPatch.GetRingType(ring, ref isBeginningRing); if (isBeginningRing) { IPolygon ringPolygon = MultiPatchUtils.GetFace(multiPatch, ring); if (!ringPolygon.IsEmpty) { result.Add(ringPolygon); } } } return(result); }
//---------------------------------------------------------------------------------- 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); } }
protected override IIndexedMultiPatch GetAdaptedMultiPatch() { IMultiPatch multiPatch = GetMultiPatch(_multiPatchFeature); var parts = (IGeometryCollection)multiPatch; var outerRingIndexes = new List <int>(); int partCount = parts.GeometryCount; for (int partIndex = 0; partIndex < partCount; partIndex++) { var ring = parts.Geometry[partIndex] as IRing; if (ring == null) { continue; } bool isBeginning = false; multiPatch.GetRingType(ring, ref isBeginning); if (!isBeginning) { continue; } int followingRings = multiPatch.FollowingRingCount[ring]; if (followingRings <= 0) { continue; } if (!IsHorizontal(ring)) { continue; } outerRingIndexes.Add(partIndex); } if (outerRingIndexes.Count > 0) { IMultiPatch adapted = CopyWithConvertedInnerRings(multiPatch, outerRingIndexes); return(QaGeometryUtils.CreateIndexedMultiPatch(adapted)); } return(GetIndexedMultipatch(_multiPatchFeature)); }
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); } } }
public static List <IPolygon> GetFaces( [NotNull] IIndexedMultiPatch indexedMultiPatch, int patchIndex) { IMultiPatch multiPatch = indexedMultiPatch.BaseGeometry; var patches = (IGeometryCollection)multiPatch; var ring = patches.Geometry[patchIndex] as IRing; if (ring != null) { bool beginning = false; multiPatch.GetRingType(ring, ref beginning); // TODO handle undefined/invalid ring types? return(beginning ? new List <IPolygon> { GetFace(multiPatch, ring) } : new List <IPolygon>()); } List <int> partIndexes = indexedMultiPatch.GetPartIndexes(patchIndex); var result = new List <IPolygon>(partIndexes.Count); foreach (int partIndex in partIndexes) { WKSPointZ[] wksPoints = GetWksPointZs(indexedMultiPatch, partIndex); IPolygon face = GeometryFactory.CreatePolygon(wksPoints, multiPatch .SpatialReference); result.Add(face); } return(result); }
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); }
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); }