Пример #1
0
        private void QueryCompareGeometryCoordinates(VertexIndex atVertexIndex,
                                                     [NotNull] IPoint result)
        {
            if (_compareGeometry.GeometryType == esriGeometryType.esriGeometryMultipoint)
            {
                ((IPointCollection)_compareGeometry).QueryPoint(atVertexIndex.PartIndex, result);
                return;
            }

            var geometryCollection = _compareGeometry as IGeometryCollection;

            if (geometryCollection == null || atVertexIndex.PartIndex == 0)
            {
                ((IPointCollection)_compareGeometry).QueryPoint(
                    atVertexIndex.VertexIndexInPart, result);
                return;
            }

            if (!(_compareGeometry is ISegmentCollection))
            {
                throw new NotImplementedException(
                          string.Format("Not implemented for geometry type {0}",
                                        _compareGeometry.GeometryType));
            }

            // This makes a big difference for geometries with hundreds of parts (proved by CanCalculateDifferenceInHugeLockergestein())
            int globalIndex = GetGlobalVertexIndex(
                atVertexIndex, GetCompareGeometryPartStartIndex(geometryCollection));

            ((IPointCollection)_compareGeometry).QueryPoint(globalIndex, result);
        }
Пример #2
0
        private ISegment GetBaseSegment(VertexIndex atFromVertexIndex)
        {
            var fromSegments = _baseGeometry as ISegmentCollection;

            if (fromSegments == null)
            {
                throw new NotImplementedException(
                          "Cannot get base segments, no segment collection");
            }

            var geometryCollection = _baseGeometry as IGeometryCollection;

            if (geometryCollection == null || atFromVertexIndex.PartIndex == 0)
            {
                return(fromSegments.Segment[atFromVertexIndex.VertexIndexInPart]);
            }

            if (!(_baseGeometry is ISegmentCollection))
            {
                throw new NotImplementedException(
                          string.Format("Not implemented for geometry type {0}",
                                        _compareGeometry.GeometryType));
            }

            // This makes a big difference for geometries with hundreds of parts (such as the one
            // used in CanCalculateDifferenceInHugeLockergestein())
            int globalSegmentIndex = GetGlobalSegmentIndex(
                atFromVertexIndex, GetBaseGeometryPartStartIndex(geometryCollection));

            ISegment segment = fromSegments.Segment[globalSegmentIndex];

            return(segment);
        }
Пример #3
0
        private static int GetGlobalVertexIndex(VertexIndex atVertexIndex,
                                                IList <int> partStartVertxIndexes)
        {
            int globalIndex = partStartVertxIndexes[atVertexIndex.PartIndex] +
                              atVertexIndex.VertexIndexInPart;

            return(globalIndex);
        }
Пример #4
0
        private static int GetGlobalSegmentIndex(
            VertexIndex fromVertexIndex,
            IList <int> partStartVertxIndexes)
        {
            // each part has one segment less than vertices:
            int globalIndex = partStartVertxIndexes[fromVertexIndex.PartIndex]
                              - fromVertexIndex.PartIndex
                              + fromVertexIndex.VertexIndexInPart;

            return(globalIndex);
        }
Пример #5
0
        private Dictionary <WKSPointZ, VertexIndex> CreateCoordinateDictionary(
            [NotNull] IGeometry geometry,
            bool compare3D,
            out Dictionary <WKSPointZ, List <VertexIndex> > duplicateCoordinates)
        {
            double zTolerance = compare3D
                                                    ? _zTolerance
                                                    : double.NaN;

            var comparer = new WKSPointZComparer(_xyTolerance, zTolerance,
                                                 geometry.SpatialReference);

            var coordinateDictionary =
                new Dictionary <WKSPointZ, VertexIndex>(((IPointCollection)geometry).PointCount,
                                                        comparer);

            WKSPointZ[] pointArray = GeometryUtils.GetWKSPointZs(geometry, true);

            // NOTE: there can be ambiguity if two different segments have the same point (rings, boundary loops)
            //		 or in the 2D case if two points differ only in Z. Hence duplicates must be explicitly managed.
            var currentPartIdx     = 0;
            var currentIndexInPart = 0;
            var geometryCollection = geometry as IGeometryCollection;

            int partCount = geometryCollection?.GeometryCount ?? 1;

            duplicateCoordinates = new Dictionary <WKSPointZ, List <VertexIndex> >(partCount);
            // one duplicate for each ring

            IPointCollection currentPartPoints =
                geometryCollection == null
                                        ? (IPointCollection)geometry
                                        : null;

            foreach (WKSPointZ wksPointZ in pointArray)
            {
                if (currentPartPoints == null && geometryCollection != null)
                {
                    currentPartPoints =
                        geometryCollection.get_Geometry(currentPartIdx) as IPointCollection;
                }

                bool isLastInPart = currentPartPoints != null &&
                                    currentIndexInPart == currentPartPoints.PointCount - 1;

                var currentVertexIndex = new VertexIndex(currentPartIdx, currentIndexInPart,
                                                         isLastInPart);

                if (!coordinateDictionary.ContainsKey(wksPointZ))
                {
                    coordinateDictionary.Add(wksPointZ, currentVertexIndex);
                }
                else if (!compare3D && !double.IsNaN(_zTolerance))
                {
                    VertexIndex alreadyAdded = coordinateDictionary[wksPointZ];

                    List <VertexIndex> duplicateIndices;
                    if (!duplicateCoordinates.TryGetValue(wksPointZ, out duplicateIndices))
                    {
                        duplicateIndices = new List <VertexIndex>(2)
                        {
                            alreadyAdded
                        };
                        duplicateCoordinates.Add(wksPointZ, duplicateIndices);
                    }

                    duplicateIndices.Add(currentVertexIndex);
                }

                if (isLastInPart)
                {
                    currentPartIdx++;
                    currentPartPoints  = null;
                    currentIndexInPart = 0;
                }
                else
                {
                    currentIndexInPart++;
                }
            }

            return(coordinateDictionary);
        }
Пример #6
0
        public IPolyline GetBaseSegmentZDifferences(
            out IDictionary <WKSPointZ, VertexIndex> zDifferentPoints)
        {
            Assert.True(_baseGeometry is IPolyline || _baseGeometry is IPath,
                        "Not implemented for geometries other than lines.");

            Stopwatch watch = _msg.DebugStartTiming("Calculating Z difference on source...");

            // Get the points that are in the base but not in the target:
            zDifferentPoints = GetDifference(true);

            IDictionary <VertexIndex, ISegment> sourceSegmentsToAdd =
                new Dictionary <VertexIndex, ISegment>();

            foreach (
                KeyValuePair <WKSPointZ, VertexIndex> differentPointOnPath in zDifferentPoints)
            {
                bool targetContainsPoint =
                    CompareGeometryContainsPoint3D(differentPointOnPath.Key);

                if (!targetContainsPoint)
                {
                    // Take the respective segment before and after this point as difference
                    VertexIndex vertexIndex = differentPointOnPath.Value;

                    int previousSegmentIdx = vertexIndex.VertexIndexInPart - 1;

                    var previousVertexIdx = new VertexIndex(vertexIndex.PartIndex,
                                                            previousSegmentIdx,
                                                            false);
                    if (previousSegmentIdx >= 0 &&
                        !sourceSegmentsToAdd.ContainsKey(previousVertexIdx))
                    {
                        ISegment segment = GetBaseSegment(previousVertexIdx);

                        sourceSegmentsToAdd.Add(previousVertexIdx, segment);
                    }

                    if (!vertexIndex.IsLastInPart &&
                        !sourceSegmentsToAdd.ContainsKey(vertexIndex))
                    {
                        ISegment segment = GetBaseSegment(vertexIndex);
                        sourceSegmentsToAdd.Add(vertexIndex, segment);
                    }
                }
            }

            IPolyline sourceDifferences =
                GeometryFactory.CreatePolyline(_baseGeometry.SpatialReference, true,
                                               GeometryUtils.IsMAware(_baseGeometry));

            var segmentArray = new ISegment[sourceSegmentsToAdd.Count];

            sourceSegmentsToAdd.Values.CopyTo(segmentArray, 0);

            GeometryUtils.GeometryBridge.SetSegments((ISegmentCollection)sourceDifferences,
                                                     ref segmentArray);

            _msg.DebugStopTiming(watch,
                                 "Calculated Z differences on source and built difference line");

            return(sourceDifferences);
        }