/// <summary>
        /// Ensures the connectivity of the specified feature with its previously connected features
        /// according to specific rules:
        /// - Split or merge operations: no action
        /// - Snap to an edge interior of an *adjacent* edge: endpoint relocation (Y-reshape style)
        /// - Snap to an edge interior of a non-adjacent edge: existing junction at previous end
        ///   point gets moved if it has no other previous connection
        /// - Drag along features from original end point if:
        ///    - End point was moved to 'empty field' (no other feature exists at new end point)
        ///    - Z-only update
        ///    - End point moved within search tolerance
        /// </summary>
        /// <param name="reshapedFeature"></param>
        /// <param name="originalPolyline"></param>
        /// <param name="atFromPoint"></param>
        /// <param name="newEndPoint"></param>
        /// <param name="adjacentNonReshapedEdges"></param>
        /// <returns>Whether the specified end point was snapped to adjacent features or not.</returns>
        private bool EnsureConnectivityWithAdjacentFeatures(
            [NotNull] IFeature reshapedFeature,
            [NotNull] IPolyline originalPolyline,
            bool atFromPoint,
            [NotNull] IPoint newEndPoint,
            [NotNull] IList <IFeature> adjacentNonReshapedEdges)
        {
            IList <IFeature> otherHitEdgesAtNewEnd = FindOtherEdgeFeaturesAt(
                reshapedFeature, newEndPoint);

            if (HasInsertAtOldAndNewEnd(adjacentNonReshapedEdges, otherHitEdgesAtNewEnd))
            {
                return(false);                // Split
            }

            if (HasDeleteAtOldAndNewEnd(originalPolyline, atFromPoint, newEndPoint))
            {
                return(false);                // Merge
            }

            bool endPointMovedWithinTolerance =
                ContainSameFeatures(adjacentNonReshapedEdges, otherHitEdgesAtNewEnd);

            bool result = !endPointMovedWithinTolerance &&
                          LinearNetworkEditUtils.SnapPoint(newEndPoint, otherHitEdgesAtNewEnd,
                                                           NetworkFeatureFinder);

            IFeature targetEdge;
            bool     snappedToAdjacentEdgeInterior = IsRelocatedEndSnappedToAdjacentEdge(
                originalPolyline, atFromPoint, newEndPoint, otherHitEdgesAtNewEnd, out targetEdge);

            if (snappedToAdjacentEdgeInterior)
            {
                RelocateEndpointAlongTarget(reshapedFeature, originalPolyline, newEndPoint,
                                            atFromPoint, targetEdge,
                                            adjacentNonReshapedEdges);

                MoveJunctionFeatures(originalPolyline, atFromPoint, newEndPoint);
            }
            else if (endPointMovedWithinTolerance ||
                     otherHitEdgesAtNewEnd.Count == 0 ||
                     IsZOnlyChange(originalPolyline, atFromPoint, newEndPoint))
            {
                // Drag along other edge endpoints if no other edge was hit ('disconnect and reconnect')
                // or the update was within the tolerance / Z-only
                MaintainConnectionWithOtherNetworkEdges(
                    adjacentNonReshapedEdges, originalPolyline, newEndPoint, atFromPoint);

                // And the junction
                MoveJunctionFeatures(originalPolyline, atFromPoint, newEndPoint);
            }
            else if (adjacentNonReshapedEdges.Count == 0)
            {
                // New end point was snapped to other edges - drag the junction only if it is
                // not connected to any other edges at the previous location
                MoveJunctionFeatures(originalPolyline, atFromPoint, newEndPoint);
            }

            return(result);
        }
Пример #2
0
        private void SplitAtJunctions([NotNull] IFeature edgeFeature,
                                      [NotNull] ICollection <IFeature> splittingJunctions)
        {
            _msg.DebugFormat("Splitting {0} by using split junction(s) {1}",
                             GdbObjectUtils.ToString(edgeFeature),
                             StringUtils.Concatenate(splittingJunctions,
                                                     j => GdbObjectUtils.ToString(j), ", "));

            var newEdges =
                LinearNetworkEditUtils.SplitAtJunctions(edgeFeature, splittingJunctions);

            foreach (IFeature newEdge in newEdges)
            {
                NetworkFeatureFinder.TargetFeatureCandidates?.Add(newEdge);
            }
        }
Пример #3
0
        private IFeature InsertRequiredJunction(IFeature forEdgeFeature,
                                                bool atEdgeFromPoint)
        {
            IPolyline edge = (IPolyline)forEdgeFeature.Shape;

            IPoint edgeEndPoint = atEdgeFromPoint ? edge.FromPoint : edge.ToPoint;

            IList <IFeature> foundJunctions =
                NetworkFeatureFinder.FindJunctionFeaturesAt(edgeEndPoint);

            if (foundJunctions.Count == 0)
            {
                IList <IFeature> otherPolylineFeatures = NetworkFeatureFinder.FindEdgeFeaturesAt(
                    edgeEndPoint,
                    f =>
                    !GdbObjectUtils.IsSameObject(f, forEdgeFeature,
                                                 ObjectClassEquality.SameTableSameVersion));

                if (LinearNetworkEditUtils.SnapPoint(edgeEndPoint, otherPolylineFeatures,
                                                     NetworkFeatureFinder))
                {
                    UpdateEdgeEndPoint(forEdgeFeature, edge, atEdgeFromPoint, edgeEndPoint);
                }

                IFeature createdJunction = CreateJunction(edgeEndPoint);

                if (createdJunction != null)
                {
                    return(createdJunction);
                }
            }
            else
            {
                EnsureSnapped(forEdgeFeature, edge, edgeEndPoint, atEdgeFromPoint, foundJunctions);
            }

            return(null);
        }