protected override bool GetNextSegment(out double length, out double dz,
                                                   out int partIndex, out int segmentIndex)
            {
                if (!_enumSegments.MoveNext())
                {
                    length       = double.NaN;
                    dz           = double.NaN;
                    partIndex    = -1;
                    segmentIndex = -1;
                    return(false);
                }

                SegmentProxy segment = Assert.NotNull(_enumSegments.Current);

                partIndex    = segment.PartIndex;
                segmentIndex = segment.SegmentIndex;

                length = segment.Length;
                double z0 = segment.GetStart(true)[2];
                double z1 = segment.GetEnd(true)[2];

                dz = z1 - z0;

                return(true);
            }
            public override Pnt GetNearestVertex()
            {
                double fraction = Fraction;

                Pnt vertex = fraction < 0.5
                                                     ? _segmentProxy.GetStart(as3D: true)
                                                     : _segmentProxy.GetEnd(as3D: true);

                return(vertex);
            }
示例#3
0
        private static double GetOffset([NotNull] Pnt pnt,
                                        [NotNull] SegmentProxy segmentProxy,
                                        out double fraction,
                                        out bool?onRightSide)
        {
            double?offset;

            fraction = SegmentUtils.GetClosestPointFraction(
                segmentProxy, pnt, out offset, out onRightSide, as3D: false);

            double distance2;

            if (fraction < 0)
            {
                distance2   = pnt.Dist2(segmentProxy.GetStart(as3D: false));
                onRightSide = null;
            }
            else if (fraction > 1)
            {
                distance2   = pnt.Dist2(segmentProxy.GetEnd(as3D: false));
                onRightSide = null;
            }
            else
            {
                if (!offset.HasValue)
                {
                    Pnt    s          = segmentProxy.GetStart(as3D: false);
                    Pnt    e          = segmentProxy.GetEnd(as3D: false);
                    double vectorProd = (pnt - s).VectorProduct(s - e);
                    onRightSide = vectorProd < 0;
                    distance2   = pnt.Dist2(segmentProxy.GetPointAt(fraction, as3D: false));
                }
                else
                {
                    distance2 = 0;                     // offset has value and will be used as distance
                }
            }

            double distance = offset ?? Math.Sqrt(distance2);

            return(distance);
        }
示例#4
0
        private static double GetDistanceToVertices([NotNull] IPoint point,
                                                    [NotNull] IFeature neighbourFeature,
                                                    [NotNull] IPoint nearestPoint,
                                                    double maxNeededDistance)
        {
            double minDistance2 = double.MaxValue;

            SegmentProxy nearestSegment = null;
            var          isEndNearest   = false;
            Pnt          qaPoint        = QaGeometryUtils.CreatePoint3D(point);

            IEnumerable <SegmentProxy> segments = EnumSegments(qaPoint, neighbourFeature,
                                                               maxNeededDistance);

            foreach (SegmentProxy segment in segments)
            {
                if (GetNearest(qaPoint, segment.GetStart(false), ref minDistance2))
                {
                    nearestSegment = segment;
                    isEndNearest   = false;
                }

                if (GetNearest(qaPoint, segment.GetEnd(false), ref minDistance2))
                {
                    nearestSegment = segment;
                    isEndNearest   = true;
                }
            }

            double minDistance;

            if (nearestSegment != null)
            {
                minDistance = Math.Sqrt(minDistance2);

                if (minDistance <= maxNeededDistance)
                {
                    Pnt nearest = !isEndNearest
                                                              ? nearestSegment.GetStart(true)
                                                              : nearestSegment.GetEnd(true);

                    nearestPoint.PutCoords(nearest.X, nearest.Y);
                    nearestPoint.Z = nearest[2];
                }
            }
            else
            {
                minDistance = double.MaxValue;
            }

            return(minDistance);
        }
            private bool IsHorizontal([NotNull] SegmentProxy segment)
            {
                double length = segment.Length;

                if (Math.Abs(length) < double.Epsilon)
                {
                    return(false);
                }

                double z0         = segment.GetStart(true)[2];
                double z1         = segment.GetEnd(true)[2];
                double slopeAngle = Math.Atan2(Math.Abs(z1 - z0), length);

                bool isHorizontal = slopeAngle <= _horizontalToleranceRad;

                return(isHorizontal);
            }
示例#6
0
        public AzimuthSegment([NotNull] SegmentProxy segment, double xyResolution)
        {
            Segment       = segment;
            _xyResolution = xyResolution;
            Pnt start = Segment.GetStart(false);
            Pnt end   = Segment.GetEnd(false);

            double dx = end.X - start.X;
            double dy = end.Y - start.Y;

            Azimuth = Math.Atan2(dx, dy); // Azimuth is the angle to north

            if (Azimuth < 0)              // the orientation must be ignored
            {
                Azimuth += Math.PI;
            }
        }
示例#7
0
        private static double GetDistanceToCurve(
            [NotNull] IPoint point,
            [NotNull] IFeature neighbourFeature,
            [NotNull] IPoint nearestPoint,
            double maxNeededDistance,
            out bool onRightSide)
        {
            var neighborCurve = (ICurve)neighbourFeature.Shape;

            if (UseQueryPointAndDistance)
            {
                const bool asRatio   = false;
                double     along     = 0;
                double     distance  = 0;
                var        rightSide = false;

                // TLMQA-292 (EBG - BB): most time spent here (> 90%)
                neighborCurve.QueryPointAndDistance(esriSegmentExtension.esriNoExtension,
                                                    point, asRatio, nearestPoint,
                                                    ref along, ref distance, ref rightSide);
                onRightSide = rightSide;
                return(distance);
            }

            {
                double       nearestDistance    = maxNeededDistance * 1.01;
                bool?        nearestOnRightSide = null;
                SegmentProxy nearestSegment     = null;
                double       nearestFraction    = 0;

                double x;
                double y;
                point.QueryCoords(out x, out y);
                Pnt qaPoint = new Pnt2D(x, y);
                foreach (SegmentProxy segmentProxy in
                         EnumSegments(qaPoint, neighbourFeature, maxNeededDistance))
                {
                    bool?  onSegmentRightSide;
                    double alongFraction;
                    double offset = GetOffset(qaPoint, segmentProxy,
                                              out alongFraction, out onSegmentRightSide);
                    if (offset <= nearestDistance)
                    {
                        if (!onSegmentRightSide.HasValue && !nearestOnRightSide.HasValue &&
                            nearestSegment != null)
                        {
                            nearestOnRightSide = GetOnRightSide(
                                nearestSegment, nearestFraction, segmentProxy, alongFraction,
                                neighborCurve);
                        }
                        else if (offset < nearestDistance)
                        {
                            nearestOnRightSide = onSegmentRightSide;
                        }

                        nearestDistance = offset;
                        nearestSegment  = segmentProxy;
                        nearestFraction = alongFraction;
                    }
                }

                if (nearestSegment != null)
                {
                    double f = Math.Min(1, Math.Max(0, nearestFraction));
                    IPnt   p = nearestSegment.GetPointAt(f, as3D: true);
                    nearestPoint.PutCoords(p.X, p.Y);
                    nearestPoint.Z = p[2];

                    if (!nearestOnRightSide.HasValue)
                    {
                        // Extend segment lineary to determine right side
                        Pnt s = nearestSegment.GetStart(as3D: false);
                        Pnt e = nearestSegment.GetEnd(as3D: false);

                        if (nearestFraction >= 1)
                        {
                            nearestOnRightSide = (e - s).VectorProduct(e - qaPoint) > 0;
                        }
                        else if (nearestFraction <= 0)
                        {
                            nearestOnRightSide = (e - s).VectorProduct(s - qaPoint) > 0;
                        }
                    }
                }

                onRightSide = nearestOnRightSide ?? false;
                return(nearestDistance);
            }
        }