public void CanMoveOrCreateJunctionsForMovedEdgeEndpoint() { ISpatialReference sr = SpatialReferenceUtils.CreateSpatialReference( WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95); FeatureClassMock edgeClass, junctionClass; LinearNetworkDef networkDef = CreateSimpleNetworkDef(out edgeClass, out junctionClass); var networkFeatureFinder = new NetworkFeatureFinderMock(); LinearNetworkEditAgent observer = new LinearNetworkEditAgent( networkDef, networkFeatureFinder) { NoCaching = true }; // Existing feature: IPolyline edge1Polyline = GeometryFactory.CreatePolyline( GeometryFactory.CreatePoint(2600000, 1200000, 450, double.NaN, sr), GeometryFactory.CreatePoint(2600020, 1200010, 452, double.NaN, sr)); IFeature existingFeature = CreateInOperation( () => CreateFeature(edgeClass, edge1Polyline), observer); Assert.AreEqual(1, observer.GetCreatedInLastOperation().Count()); // New features get added to the feature finder's cache: 1 edge + 2 junctions Assert.AreEqual(3, networkFeatureFinder.TargetFeatureCandidates.Count); IFeature fromJunction = networkFeatureFinder.TargetFeatureCandidates.First( f => f.Shape.GeometryType == esriGeometryType .esriGeometryPoint); IFeature toJunction = networkFeatureFinder.TargetFeatureCandidates.Last( f => f.Shape.GeometryType == esriGeometryType.esriGeometryPoint); Assert.IsTrue(GeometryUtils.AreEqual(edge1Polyline.FromPoint, fromJunction.Shape)); Assert.IsTrue(GeometryUtils.AreEqual(edge1Polyline.ToPoint, toJunction.Shape)); // Move end point --> the orphan junction is moved IPoint newEnd = edge1Polyline.ToPoint; newEnd.X += 4; UpdateInOperation(() => MoveEndPoint(existingFeature, newEnd), observer); Assert.AreEqual(0, observer.GetCreatedInLastOperation().Count()); Assert.AreEqual(1, observer.GetUpdatedInLastOperation().Count()); // The 3 original features + 0 new junctions (the original was moved to the right place) Assert.AreEqual(3, networkFeatureFinder.TargetFeatureCandidates.Count); IList <IFeature> movedJunction = networkFeatureFinder.FindJunctionFeaturesAt(newEnd); Assert.AreEqual(1, movedJunction.Count); Assert.IsTrue(GeometryUtils.AreEqual(newEnd, movedJunction[0].Shape)); Assert.AreEqual(toJunction, movedJunction[0]); // 'Protect' the junction with a new polyline feature // Add another adjacent feature connected to the first: IPolyline edge2Polyline = GeometryFactory.CreatePolyline( newEnd, GeometryFactory.CreatePoint(2600030, 1200000, 451, double.NaN, sr)); CreateInOperation(() => CreateFeature(edgeClass, edge2Polyline), observer); Assert.AreEqual(1, observer.GetCreatedInLastOperation().Count()); // The 3 previous features + the new edge + 1 new junction Assert.AreEqual(5, networkFeatureFinder.TargetFeatureCandidates.Count); // Now move the end at the 'connected' edge end / junction -> they should be moved along IPoint newEnd2 = GeometryFactory.Clone(newEnd); newEnd2.Y += 4; UpdateInOperation(() => MoveEndPoint(existingFeature, newEnd2), observer); // At the original location, no junction and no edge should be left: IList <IFeature> junctionsAtOrig = networkFeatureFinder.FindJunctionFeaturesAt(newEnd); Assert.AreEqual(0, junctionsAtOrig.Count); IList <IFeature> edgesAtOrig = networkFeatureFinder.FindEdgeFeaturesAt(newEnd); Assert.AreEqual(0, edgesAtOrig.Count); // But at the newEnd2 of the original polyline they should be now: IList <IFeature> newJunction2 = networkFeatureFinder.FindJunctionFeaturesAt(newEnd2); Assert.AreEqual(1, newJunction2.Count); Assert.IsTrue(GeometryUtils.AreEqual(newEnd2, newJunction2[0].Shape)); // in fact, it should be the original junction Assert.AreEqual(toJunction, newJunction2[0]); // And both the explicitly and the implicitly updated edges: IList <IFeature> newEdge2 = networkFeatureFinder.FindEdgeFeaturesAt(newEnd2); Assert.AreEqual(2, newEdge2.Count); // TOP-5262: End points moved in Z only should still result in "vertical drag-along" // Now move the end at the 'connected' edge end / junction -> they should be moved along IPoint newEnd2z = GeometryFactory.Clone(newEnd2); newEnd2z.Z += 2.5; UpdateInOperation(() => MoveEndPoint(existingFeature, newEnd2z), observer); // At the original location, the updated junction and edge should be found junctionsAtOrig = networkFeatureFinder.FindJunctionFeaturesAt(newEnd2); Assert.AreEqual(1, junctionsAtOrig.Count); Assert.AreEqual(newEnd2z.Z, ((Point)junctionsAtOrig[0].Shape).Z); edgesAtOrig = networkFeatureFinder.FindEdgeFeaturesAt(newEnd2); Assert.AreEqual(2, edgesAtOrig.Count); foreach (IFeature edge in edgesAtOrig) { IPoint endPoint = GetLineEndPointAt(newEnd2, (IPolyline)edge.Shape); Assert.AreEqual(newEnd2z.Z, endPoint.Z); } }
private static void SnapToExistingJunction(double notQuiteSnapDistance) { // * new end point == line1.FromPoint // / // / line1 // / // / // /\old end point // / \ // line 2/ \update-geometry // line 1 and2 are connected var line1Geometry = TestUtils.ReadGeometryFromXml( TestUtils.GetGeometryTestDataPath("line1.xml")); IFeature line1Feature = TestUtils.CreateMockFeature(line1Geometry); var lineClass = (FeatureClassMock)line1Feature.Class; ISpatialReference sr = DatasetUtils.GetSpatialReference(lineClass); Assert.NotNull(sr); var pointClass = new FeatureClassMock(2345, "Junctions", esriGeometryType.esriGeometryPoint, esriFeatureType.esriFTSimple, sr); var line2Geometry = TestUtils.ReadGeometryFromXml( TestUtils.GetGeometryTestDataPath("line2.xml")); IFeature line2Feature = lineClass.CreateFeature(line2Geometry); // line 3 joins the others in their connection point (building a junction) var updatedGeometry = TestUtils.ReadGeometryFromXml( TestUtils.GetGeometryTestDataPath("line3.xml")); IFeature featureToReshape = lineClass.CreateFeature(updatedGeometry); IPoint junction = ((IPolyline)updatedGeometry).FromPoint; IFeature junctionFeature = pointClass.CreateFeature(junction); IPoint line1FromJunction = ((IPolyline)line1Geometry).FromPoint; IFeature line1FromJunctionFeature = pointClass.CreateFeature(line1FromJunction); ILinearNetworkFeatureFinder featureFinder = new NetworkFeatureFinderMock(line1Feature, line2Feature, featureToReshape, junctionFeature, line1FromJunctionFeature) { SearchTolerance = 0.01 }; // Single junction feature at line1.FromJunction: Assert.AreEqual(1, featureFinder.FindJunctionFeaturesAt(line1FromJunction).Count); IPolyline newPolyline = GeometryFactory.Clone((IPolyline)updatedGeometry); IPoint oldEndPoint = newPolyline.FromPoint; IPoint newEndPoint = GeometryFactory.Clone(line1FromJunction); newEndPoint.X += notQuiteSnapDistance; newPolyline.FromPoint = newEndPoint; double origLengthLine1 = GetLineFeatureLength(line1Feature); double origLengthLine2 = GetLineFeatureLength(line2Feature); var networkUpdater = new LinearNetworkNodeUpdater(featureFinder); networkUpdater.BarrierGeometryOriginal = (IPolycurve)featureToReshape.Shape; networkUpdater.BarrierGeometryChanged = newPolyline; networkUpdater.UpdateFeatureEndpoint(featureToReshape, newPolyline, null); IEnvelope refreshEnvelope = networkUpdater.RefreshEnvelope; Assert.NotNull(refreshEnvelope); // Still just 1 junction, the original junction is not dragged along Assert.AreEqual(1, featureFinder.FindJunctionFeaturesAt(line1FromJunction).Count); Assert.True(GeometryUtils.Intersects(refreshEnvelope, oldEndPoint)); Assert.True(GeometryUtils.Intersects(refreshEnvelope, newEndPoint)); double lengthLine1 = GetLineFeatureLength(line1Feature); double lengthLine2 = GetLineFeatureLength(line2Feature); Assert.AreEqual(origLengthLine1, lengthLine1); Assert.AreEqual(origLengthLine2, lengthLine2); Assert.IsTrue(GeometryUtils.Touches(line1Feature.Shape, line2Feature.Shape)); Assert.IsTrue(GeometryUtils.Touches(line1Feature.Shape, featureToReshape.Shape)); Assert.IsFalse(GeometryUtils.Intersects(line2Feature.Shape, featureToReshape.Shape)); Assert.IsTrue(GeometryUtils.AreEqual(newEndPoint, line1FromJunctionFeature.Shape)); IPolyline savedPolyline = (IPolyline)featureToReshape.Shape; // Must be exactly snapped, even if the junction was not quite hit: Assert.IsTrue(GeometryUtils.IsSamePoint(savedPolyline.FromPoint, (IPoint)line1FromJunctionFeature.Shape, 0.001, 0.001)); }