コード例 #1
0
        public static void AddPaths([NotNull] IList <Linestring> linestringsToAdd,
                                    [NotNull] IPolyline toResult)
        {
            Func <Pnt3D, WKSPointZ> createPoint;

            if (GeometryUtils.IsZAware(toResult))
            {
                createPoint = p => WKSPointZUtils.CreatePoint(p.X, p.Y, p.Z);
            }
            else
            {
                createPoint = p => WKSPointZUtils.CreatePoint(p.X, p.Y, double.NaN);
            }

            IPath pathTemplate = GeometryFactory.CreateEmptyPath(toResult);

            foreach (Linestring resultLinestring in linestringsToAdd)
            {
                var pathPoints = new WKSPointZ[resultLinestring.SegmentCount + 1];

                var i = 0;
                foreach (Line3D line3D in resultLinestring)
                {
                    pathPoints[i++] = createPoint(line3D.StartPoint);
                }

                Pnt3D last = resultLinestring[resultLinestring.SegmentCount - 1].EndPoint;
                pathPoints[i] = createPoint(last);

                IPath path = GeometryFactory.Clone(pathTemplate);
                GeometryUtils.AddWKSPointZs((IPointCollection4)path, pathPoints);
                ((IGeometryCollection)toResult).AddGeometry(path);
            }
        }
コード例 #2
0
        /// <summary>
        /// Determines whether the two geometries have the same set of vertices.
        /// Duplicate vertices are ignored.
        /// </summary>
        /// <returns></returns>
        public bool HaveSameVertices(bool ignoreDuplicateVertices = true)
        {
            WKSPointZ[] baseCoords    = GeometryUtils.GetWKSPointZs(_baseGeometry, true);
            WKSPointZ[] compareCoords = GeometryUtils.GetWKSPointZs(_compareGeometry, true);

            return(WKSPointZUtils.HaveSameVertices(baseCoords, compareCoords, _xyTolerance,
                                                   _zTolerance,
                                                   ignoreDuplicateVertices));
        }
コード例 #3
0
        /// <summary>
        /// Advances the vertex index of coordsToAdvance starting at currentIndex until
        /// the point at the index matches coordinateToMatch. All intermediate points are
        /// added to changedCoords.
        /// </summary>
        /// <param name="coordsToAdvance">The list of coordinates (sorted) to go through
        /// until a coordinate matches <paramref name="coordinateToMatch"/>.</param>
        /// <param name="index">The index to start at which shall be incremented unit the coordinates match.</param>
        /// <param name="coordinateToMatch">The target coordinate.</param>
        /// <param name="comparer">The comparer.</param>
        /// <param name="changedCoords">The list of coordinates that do not match.</param>
        /// <param name="addChangesToResult">Whether the changed points should be added to changedCoords</param>
        /// <param name="reportDuplicateVertices">Whether duplicate vertices in the coordsToAdvance should be reported or not.</param>
        /// <returns>Whether a match was found or not.</returns>
        private bool AdvanceIndexUntilMatch(
            [NotNull] WKSPointZ[] coordsToAdvance,
            ref int index,
            WKSPointZ coordinateToMatch,
            [NotNull] IComparer <WKSPointZ> comparer,
            [NotNull] ICollection <WKSPointZ> changedCoords,
            bool addChangesToResult,
            bool reportDuplicateVertices)
        {
            WKSPointZ currentCoord = coordsToAdvance[index];

            while (comparer.Compare(coordinateToMatch, currentCoord) >= 0 &&
                   index < coordsToAdvance.Length)
            {
                // check if within the tolerance - performance could be improved if comparer could directly handle
                // the tolerance.
                bool useTolerance = Math.Abs(_xyTolerance) > double.Epsilon ||
                                    (!double.IsNaN(_zTolerance) &&
                                     Math.Abs(_zTolerance) > double.Epsilon);

                if (useTolerance &&
                    GeometryUtils.IsSamePoint(currentCoord, coordinateToMatch,
                                              _xyTolerance, _zTolerance))
                {
                    return(true);
                }

                if (addChangesToResult)
                {
                    // except if it's a duplicate that should not be reported
                    bool sameAsPrevious = WKSPointZUtils.ArePointsEqual(
                        coordsToAdvance, index, index - 1,
                        _xyTolerance, _zTolerance);

                    if (!sameAsPrevious || reportDuplicateVertices)
                    {
                        changedCoords.Add(currentCoord);
                    }
                }

                ++index;

                if (index < coordsToAdvance.Length)
                {
                    currentCoord = coordsToAdvance[index];
                }
            }

            return(false);
        }
コード例 #4
0
        private IList <WKSPointZ> GetPointDifference(bool symmetric)
        {
            var result = new List <WKSPointZ>();

            if (!GeometryUtils.IsSamePoint((IPoint)_baseGeometry,
                                           (IPoint)_compareGeometry,
                                           _xyTolerance, _zTolerance))
            {
                result.Add(WKSPointZUtils.CreatePoint((IPoint)_baseGeometry));

                if (symmetric)
                {
                    result.Add(WKSPointZUtils.CreatePoint((IPoint)_compareGeometry));
                }
            }

            return(result);
        }
コード例 #5
0
        public static void AddPoints(IEnumerable <Pnt3D> points, IMultipoint toResult)
        {
            Func <Pnt3D, WKSPointZ> createPoint;

            if (GeometryUtils.IsZAware(toResult))
            {
                createPoint = p => WKSPointZUtils.CreatePoint(p.X, p.Y, p.Z);
            }
            else
            {
                createPoint =
                    p => WKSPointZUtils.CreatePoint(p.X, p.Y, double.NaN);
            }

            WKSPointZ[] wksPointZs = points.Select(p => createPoint(p)).ToArray();

            GeometryUtils.AddWKSPointZs((IPointCollection4)toResult, wksPointZs);
        }
コード例 #6
0
        private static WKSPointZ[] GetWksPoints(IEnumerable <Pnt3D> pnts, int pointCount)
        {
            WKSPointZ[] wksPointArray = GetWksPointArray(pointCount);

            var count = 0;

            foreach (Pnt3D pnt3D in pnts)
            {
                if (count == pointCount)
                {
                    break;
                }

                wksPointArray[count++] =
                    WKSPointZUtils.CreatePoint(pnt3D.X, pnt3D.Y, pnt3D.Z);
            }

            return(wksPointArray);
        }
コード例 #7
0
        /// <summary>
        /// Adds the remaining points starting from baseIndexStart for baseCoords and from
        /// compareIndexStart for compareCoords.
        /// </summary>
        /// <param name="baseCoords"></param>
        /// <param name="compareCoords"></param>
        /// <param name="baseIndexStart"></param>
        /// <param name="compareIndexStart"></param>
        /// <param name="result"></param>
        /// <param name="reportDuplicateVertices"></param>
        /// <param name="baseInsertsOnly"></param>
        private void AddRemainingPoints(
            WKSPointZ[] baseCoords,
            WKSPointZ[] compareCoords,
            int baseIndexStart,
            int compareIndexStart,
            List <WKSPointZ> result,
            bool reportDuplicateVertices,
            bool baseInsertsOnly)
        {
            // add all remaining points from baseCoords
            for (int i = baseIndexStart; i < baseCoords.Length; i++)
            {
                bool sameAsPrevious = WKSPointZUtils.ArePointsEqual(
                    baseCoords, i, i - 1, _xyTolerance,
                    _zTolerance);

                if (sameAsPrevious && !reportDuplicateVertices)
                {
                    continue;
                }

                result.Add(baseCoords[i]);
            }

            if (!baseInsertsOnly)
            {
                // add all remaining points from baseCoords
                for (int i = compareIndexStart; i < compareCoords.Length; i++)
                {
                    bool sameAsPrevious = WKSPointZUtils.ArePointsEqual(compareCoords, i, i - 1,
                                                                        _xyTolerance,
                                                                        _zTolerance);

                    if (sameAsPrevious && !reportDuplicateVertices)
                    {
                        continue;
                    }

                    result.Add(compareCoords[i]);
                }
            }
        }
コード例 #8
0
        private static bool TryGetPlaneVectors(WKSPointZ normal, WKSPointZ vector,
                                               out WKSPointZ planeVector1,
                                               out WKSPointZ planeVector2)
        {
            planeVector1 = WKSPointZUtils.GetVectorProduct(normal, vector);

            const double e = 0.1;

            if (GetLength2(planeVector1) < e)
            {
                planeVector2 = new WKSPointZ();
                return(false);
            }

            planeVector1 = WKSPointZUtils.GetNormed(planeVector1);

            planeVector2 = WKSPointZUtils.GetVectorProduct(normal, planeVector1);

            return(GetLength2(planeVector2) >= e);
        }
コード例 #9
0
        public void GetPlaneVectors(out WKSPointZ planeVector1, out WKSPointZ planeVector2)
        {
            WKSPointZ normal = GetNormalVector();

            if (TryGetPlaneVectors(normal, WKSPointZUtils.CreatePoint(1, 0, 0),
                                   out planeVector1, out planeVector2))
            {
                return;
            }

            if (TryGetPlaneVectors(normal, WKSPointZUtils.CreatePoint(0, 1, 0),
                                   out planeVector1, out planeVector2))
            {
                return;
            }

            if (TryGetPlaneVectors(normal, WKSPointZUtils.CreatePoint(0, 0, 1),
                                   out planeVector1, out planeVector2))
            {
                return;
            }

            throw new InvalidOperationException("unable to create plane vectors");
        }
コード例 #10
0
        public WKSPointZ GetPlaneVector()
        {
            WKSPointZ normal = GetNormalVector();

            WKSPointZ planeVector;

            if (TryGetNormal(normal, WKSPointZUtils.CreatePoint(1, 0, 0), out planeVector))
            {
            }
            else if (TryGetNormal(normal, WKSPointZUtils.CreatePoint(0, 1, 0), out planeVector))
            {
            }
            else if (TryGetNormal(normal, WKSPointZUtils.CreatePoint(0, 0, 1), out planeVector))
            {
            }
            else
            {
                throw new InvalidOperationException("unable to create plane vector");
            }

            WKSPointZ normedPlaneVector = WKSPointZUtils.GetNormed(planeVector);

            return(normedPlaneVector);
        }
コード例 #11
0
        private IList <WKSPointZ> GetChangedVertices(
            WKSPointZ[] baseCoords, WKSPointZ[] compareCoords,
            bool reportDuplicateVertices, bool baseInsertsOnly)
        {
            Assert.ArgumentNotNull(baseCoords, nameof(baseCoords));
            Assert.ArgumentNotNull(compareCoords, nameof(compareCoords));

            var comparer = new WKSPointZComparer(_xyTolerance, _zTolerance, 0, 0, 0);

            Array.Sort(baseCoords, comparer);
            Array.Sort(compareCoords, comparer);

            var result = new List <WKSPointZ>();

            var i1 = 0;
            var i2 = 0;

            while (i1 < baseCoords.Length && i2 < compareCoords.Length)
            {
                WKSPointZ a = baseCoords[i1];
                WKSPointZ b = compareCoords[i2];

                bool inSync = GeometryUtils.IsSamePoint(a, b, _xyTolerance, _zTolerance);

                if (!inSync)
                {
                    // a is greater than b, advance b until in sync with a
                    bool matchAdvanceCompareCoords = AdvanceIndexUntilMatch(
                        compareCoords, ref i2, a, comparer, result, !baseInsertsOnly,
                        reportDuplicateVertices);

                    // b is greater than a, advance a until in sync with b
                    bool matchAdvanceBaseCoords = AdvanceIndexUntilMatch(
                        baseCoords, ref i1, b, comparer, result, true, reportDuplicateVertices);

                    if (matchAdvanceCompareCoords || matchAdvanceBaseCoords)
                    {
                        inSync = true;
                    }
                }

                // Advance to next set of coordinates only if in sync to make sure no difference points are missed
                if (inSync)
                {
                    ++i1;
                    ++i2;
                }

                // Skip identical points in sequence otherwise From/To points in rotated ring get reported as changes
                // NOTE: SameCoords tolerates index out of bounds!
                while (WKSPointZUtils.ArePointsEqual(baseCoords, i1, i1 - 1, _xyTolerance,
                                                     _zTolerance))
                {
                    bool compareCoordsHasDuplicateToo =
                        inSync &&
                        WKSPointZUtils.ArePointsEqual(compareCoords, i2, i2 - 1, _xyTolerance,
                                                      _zTolerance);

                    if (compareCoordsHasDuplicateToo)
                    {
                        // in sync and both have a duplicate at the same location -> unchanged, do not report
                        // but increment both indexes
                        ++i2;
                    }
                    else
                    {
                        // not in sync or compare geometry has no duplicate -> changed, report on request
                        if (reportDuplicateVertices)
                        {
                            result.Add(baseCoords[i1]);
                        }
                    }

                    // eventually landing at the next non-identical point:
                    ++i1;
                }

                // process remaining duplicates at current location (or at original location if not in sync)
                while (WKSPointZUtils.ArePointsEqual(compareCoords, i2, i2 - 1, _xyTolerance,
                                                     _zTolerance))
                {
                    if (reportDuplicateVertices && !baseInsertsOnly)
                    {
                        result.Add(compareCoords[i2]);
                    }

                    ++i2;
                }
            }

            AddRemainingPoints(baseCoords, compareCoords, i1, i2, result,
                               reportDuplicateVertices, baseInsertsOnly);

            return(result);
        }
コード例 #12
0
        private static bool TryGetNormal(WKSPointZ v0, WKSPointZ v1, out WKSPointZ normal)
        {
            normal = WKSPointZUtils.GetVectorProduct(v0, v1);

            return(GetLength2(normal) > 0.1);
        }