/// <summary> /// Set previous index and point to refs /// </summary> /// <param name="pointColl">The point coll.</param> /// <param name="currentIndex">Index of the current.</param> /// <param name="point">The point.</param> private static void GetPreviousPoint([NotNull] IPointCollection pointColl, int currentIndex, [NotNull] ref IPoint point) { int prevIndex; if (currentIndex == 0) { prevIndex = pointColl.PointCount - 2; } else { prevIndex = currentIndex - 1; } pointColl.QueryPoint(prevIndex, point); }
/// <summary> /// Gets the next point. /// </summary> /// <param name="pointColl">The point coll.</param> /// <param name="currentIndex">Index of the current.</param> /// <param name="point">The point.</param> private static void GetNextPoint([NotNull] IPointCollection pointColl, int currentIndex, [NotNull] ref IPoint point) { int nextIndex; if (currentIndex == pointColl.PointCount - 1) { nextIndex = 0; } else { nextIndex = currentIndex + 1; } pointColl.QueryPoint(nextIndex, point); }
private static void FillIdPointIndexesDictionary( [NotNull] IDictionary <int, List <int> > idPointIndexesDictionary, [NotNull] IPointCollection pointCollection, int baseIndex) { int pointCount = pointCollection.PointCount; for (int pointIndex = 0; pointIndex < pointCount; pointIndex++) { pointCollection.QueryPoint(pointIndex, QueryPoint); int id = QueryPoint.ID; List <int> pointIndexes; if (!idPointIndexesDictionary.TryGetValue(id, out pointIndexes)) { pointIndexes = new List <int>(pointCount); idPointIndexesDictionary.Add(id, pointIndexes); } pointIndexes.Add(pointIndex + baseIndex); } }
public override IEnumerable <AngleInfo> GetAngles() { int partIndex; int vertexIndex; double x2 = 0; double y2 = 0; double z2 = 0; double dx1 = 0; double dy1 = 0; double dz1 = 0; double l12 = 0; var minVertex = 2; if (((ICurve)_points).IsClosed) { var segments = _points as ISegmentCollection; if (segments != null) { int segmentCount = segments.SegmentCount; if (segmentCount == 1) { ISegment segment = segments.Segment[0]; if (IsZeroLength(segment)) { // single zero-length segment forming a closed curve, ignore // NOTE: closed elliptic arcs also report length = 0, unable to calculate tangents --> ignored here yield break; } AngleInfo info = AngleInfo.Create(segment, segment, Settings.Is3D); yield return(info); yield break; } if (segmentCount == 2) { ISegment segment0 = segments.Segment[0]; ISegment segment1 = segments.Segment[1]; if (!(segment0 is ILine) || !(segment1 is ILine)) { // two segment closed curve, at least one of the segments is non-linear // --> calculate using tangent // otherwise, linearized segment angles would always be 0, resulting in errors bool segment0IsZeroLength = IsZeroLength(segment0); bool segment1IsZeroLength = IsZeroLength(segment1); if (!segment0IsZeroLength && !segment1IsZeroLength) { yield return (AngleInfo.Create(segment0, segment1, Settings.Is3D)); yield return (AngleInfo.Create(segment1, segment0, Settings.Is3D)); } else if (segment0IsZeroLength) { yield return (AngleInfo.Create(segment1, segment1, Settings.Is3D)); } else { // segment 1 is zero length yield return (AngleInfo.Create(segment0, segment0, Settings.Is3D)); } yield break; } } } _points.QueryPoint(_points.PointCount - 2, Settings.QueryPoint); Settings.QueryPoint.QueryCoords(out x2, out y2); z2 = Settings.QueryPoint.Z; minVertex = 1; } IEnumVertex vertexEnum = _points.EnumVertices; vertexEnum.QueryNext(Settings.QueryPoint, out partIndex, out vertexIndex); while (partIndex >= 0 && vertexIndex >= 0) { double dx0 = dx1; double dy0 = dy1; double l02 = l12; double x1 = x2; double y1 = y2; double z1 = z2; Settings.QueryPoint.QueryCoords(out x2, out y2); z2 = Settings.QueryPoint.Z; dx1 = x2 - x1; dy1 = y2 - y1; l12 = dx1 * dx1 + dy1 * dy1; double prod = dx0 * dx1 + dy0 * dy1; if (Settings.Is3D) { double dz0 = dz1; dz1 = z2 - z1; l12 += dz1 * dz1; prod += dz0 * dz1; } if (vertexIndex < minVertex) { vertexEnum.QueryNext(Settings.QueryPoint, out partIndex, out vertexIndex); continue; } var angleInfo = new AngleInfo(x1, y1, z1, l02, l12, prod); yield return(angleInfo); vertexEnum.QueryNext(Settings.QueryPoint, out partIndex, out vertexIndex); } }
private void SetPINValue() { //The Theory. //Select polygons that intersect the sketch. //Construct one polyline from the boundaries and intersect with sketch. //Sort resulting intersection locations (multipoint) by distance of the intersect // from the start of the sketch and create new ordered multipoint. //Loop through new ordered multipoint, select underlying parcel and calc pin. IFeatureLayer featLayer = m_editLayers.CurrentLayer; m_curve = m_edSketch.Geometry as IPolyline; //Search parcel polys by graphic to get feature cursor ISpatialFilter spatialFilter = new SpatialFilter(); spatialFilter.Geometry = m_curve; spatialFilter.GeometryField = m_editLayers.CurrentLayer.FeatureClass.ShapeFieldName; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses; IFeatureCursor featCursor = featLayer.Search(spatialFilter, true); IFeature feature = featCursor.NextFeature(); //If we have no intersects then exit if (feature == null) { return; } //Make a GeomBag of the polygons boundaries (polylines) IGeometryCollection geomBag = new GeometryBagClass(); object missing = Type.Missing; while (feature != null) { ITopologicalOperator poly = feature.Shape as ITopologicalOperator; geomBag.AddGeometry(poly.Boundary, ref missing, ref missing); feature = featCursor.NextFeature(); } //Make one polyline from the boundaries IPolyline polyLineU = new PolylineClass(); ITopologicalOperator topoOp = polyLineU as ITopologicalOperator; topoOp.ConstructUnion(geomBag as IEnumGeometry); //Get the intersections of the boundaries and the curve IPointCollection pointCol = topoOp.Intersect(m_curve, esriGeometryDimension.esriGeometry0Dimension) as IPointCollection; //The point collection is not ordered by distance along the curve so //need to create a new collection with this info int[] pointOrder = new int[pointCol.PointCount]; double dac = 0, dfc = 0; bool bRS = false; for (int i = 0; i < pointCol.PointCount; i++) { IPoint queryPoint = new PointClass(); pointCol.QueryPoint(i, queryPoint); m_curve.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, queryPoint, false, null, ref dac, ref dfc, ref bRS); pointOrder[i] = (int)dac; } //use built in bubble sort System.Array.Sort(pointOrder); //Loop through the sorted array and calc midpoint between parcel boundaries IPointCollection midPoints = new MultipointClass(); for (int i = 0; i < pointOrder.Length - 1; i++) { //Get the midpoint distance double midPointDist = (pointOrder[i] + pointOrder[i + 1]) / 2; //create a point at the distance and store in point collection IPoint queryPoint = new PointClass(); m_curve.QueryPoint(esriSegmentExtension.esriNoExtension, midPointDist, false, queryPoint); midPoints.AddPoint(queryPoint, ref missing, ref missing); } //If ends of sketch are included then add them as points if (chkEnds.Checked) { object before = 0 as object; midPoints.AddPoint(m_curve.FromPoint, ref before, ref missing); midPoints.AddPoint(m_curve.ToPoint, ref missing, ref missing); } m_editor.StartOperation(); //Loop through calculated midpoints, select polygon and calc pin for (int i = 0; i < midPoints.PointCount; i++) { IPoint midPoint = midPoints.get_Point(i); spatialFilter = new SpatialFilter(); spatialFilter.Geometry = midPoint; spatialFilter.GeometryField = m_editLayers.CurrentLayer.FeatureClass.ShapeFieldName; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelWithin; featCursor = featLayer.Search(spatialFilter, false); while ((feature = featCursor.NextFeature()) != null) { feature.set_Value(feature.Fields.FindField(cmbPINField.Text), m_lotNum); feature.Store(); m_lotNum += int.Parse(txtlotinc.Text); } } m_editor.StopOperation("ViperPIN"); txtlot.Text = m_lotNum.ToString(); }
public static IList <IPoint> GetPointsToRemove( [NotNull] IGeometry newGeometry, [CanBeNull] IPointCollection testPoints, [NotNull] IGeometry originalGeometry) { if (testPoints == null || testPoints.PointCount == 0) { return(null); } IList <IPoint> pointsToRemove = new List <IPoint>(); IPoint testPoint = new PointClass(); IHitTest orgHitTest = GeometryUtils.GetHitTest(originalGeometry, true); IHitTest newHitTest = GeometryUtils.GetHitTest(newGeometry, true); double searchRadius = GeometryUtils.GetSearchRadius(originalGeometry); ILine line = new LineClass(); IPoint prevPoint = new PointClass(); IPoint nextPoint = new PointClass(); for (var i = 0; i < testPoints.PointCount; i++) { testPoints.QueryPoint(i, testPoint); int hitSegmentIndex; bool isValidBoundaryPoint = IsValidBoundaryPoint(testPoint, orgHitTest, searchRadius, newHitTest, out hitSegmentIndex); if (!isValidBoundaryPoint) { continue; } IGeometry geometryPart; if (newGeometry is IGeometryCollection) { geometryPart = Assert.NotNull(GeometryUtils.GetHitGeometryPart( testPoint, newGeometry, searchRadius)); } else { geometryPart = newGeometry; } int lastIndex = ((IPointCollection)geometryPart).PointCount - 1; // If point is start or end point of a line, can not be removed bool pointValid = !PointIsEndOrStart(newGeometry, lastIndex, hitSegmentIndex); if (!pointValid) { continue; } // If removing point would change the the shape of the geometry, can not be removed bool pointAffectsShape = PointAffectsShape(testPoint, searchRadius, (IPointCollection)geometryPart, prevPoint, nextPoint, line, hitSegmentIndex); if (pointAffectsShape) { continue; } pointsToRemove.Add(GeometryFactory.Clone(testPoint)); } return(pointsToRemove); }
private static IGeometry SimplifyPath2D(IGeometry path, bool bReverse, double simpFactor) { IGeometry oldPath = path; IPointCollection oldPointCollection = oldPath as IPointCollection; IPolyline newPath = new PolylineClass(); IPointCollection newPointCollection = newPath as IPointCollection; ISpatialReference sr = oldPath.SpatialReference; int pointCount; pointCount = oldPointCollection.PointCount; double[] lastCoord = new double[2]; IPoint beginningPoint = new PointClass(); oldPointCollection.QueryPoint(bReverse ? (pointCount - 1) : 0, beginningPoint); beginningPoint.QueryCoords(out lastCoord[0], out lastCoord[1]); bool bKeep = true; IPolyline oldLine = oldPath as IPolyline; double length = oldLine.Length; object Missing = Type.Missing; newPointCollection.AddPoint(beginningPoint, ref Missing, ref Missing); for (int i = 1; i < pointCount - 1; i++) //simplify 2D path { double[] coord = new double[2]; IPoint currentPoint = new PointClass(); oldPointCollection.QueryPoint(bReverse ? (pointCount - i - 1) : i, currentPoint); currentPoint.QueryCoords(out coord[0], out coord[1]); double[] d = new double[2]; d[0] = coord[0] - lastCoord[0]; d[1] = coord[1] - lastCoord[1]; double distance; distance = Math.Sqrt(d[0] * d[0] + d[1] * d[1]); if (distance < (0.25 * simpFactor * length)) { bKeep = false; } else { bKeep = true; } if (bKeep) { newPointCollection.AddPoint(currentPoint, ref Missing, ref Missing); lastCoord[0] = coord[0]; lastCoord[1] = coord[1]; } } IPoint finalPoint = new PointClass(); oldPointCollection.QueryPoint(bReverse ? 0 : (pointCount - 1), finalPoint); newPointCollection.AddPoint(finalPoint, ref Missing, ref Missing); newPath.SpatialReference = sr; return((IGeometry)newPath); }