public HeightSegment(SegmentProxy segment)
            {
                _segment = segment;
                double z0 = segment.GetStart(true)[2];
                double z1 = segment.GetStart(true)[2];

                _height = (z0 + z1) / 2.0;
            }
            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);
            }
Esempio n. 4
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);
        }
Esempio n. 5
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);
            }
Esempio n. 7
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;
            }
        }
Esempio n. 8
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);
            }
        }
Esempio n. 9
0
            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;
                }
            }