/// <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);
        }
Beispiel #3
0
            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);
                }
            }
Beispiel #4
0
            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);
        }