Beispiel #1
0
        private static void GetClosePart([NotNull] SegmentProxy neighbor,
                                         [NotNull] IIndexedSegments geom,
                                         [NotNull] SegmentPart segPart,
                                         double searchDistanceSquared, bool is3D,
                                         out double min, out double max)
        {
            SegmentProxy part = geom.GetSegment(segPart.PartIndex, segPart.SegmentIndex);
            IPnt         start = part.GetPointAt(segPart.MinFraction);
            double       minStart, maxStart;

            GetClosePart(neighbor, start, searchDistanceSquared, is3D, out minStart,
                         out maxStart);

            IPnt   end = part.GetPointAt(segPart.MaxFraction);
            double minEnd, maxEnd;

            GetClosePart(neighbor, end, searchDistanceSquared, is3D, out minEnd, out maxEnd);

            min = Math.Min(minStart, minEnd);
            max = Math.Max(maxStart, maxEnd);
        }
            public override IPnt GetNearestEdgePoint(out bool isVertex)
            {
                double fraction = Fraction;

                if (fraction < 0 || fraction > 1)
                {
                    isVertex = true;
                    return(GetNearestVertex());
                }

                isVertex = fraction <= 0 || fraction >= 1;
                IPnt edgePoint = _segmentProxy.GetPointAt(fraction, as3D: true);

                return(edgePoint);
            }
Beispiel #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);
        }
Beispiel #4
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);
            }
        }