public void CanSplitEdgeAndKeepConnectedStable() { 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); // Add a connected edge feature: IPolyline edge2Polyline = GeometryFactory.CreatePolyline( GeometryFactory.CreatePoint(2600020, 1200010, 452, double.NaN, sr), GeometryFactory.CreatePoint(2600030, 1200005, 450, double.NaN, sr)); IPolyline edge2PolylineOrig = GeometryFactory.Clone(edge2Polyline); IFeature secondEdge = CreateInOperation( () => CreateFeature(edgeClass, edge2Polyline), observer); Assert.NotNull(secondEdge); Assert.AreEqual(1, observer.GetCreatedInLastOperation().Count()); IPolyline edge3Polyline = GeometryFactory.CreatePolyline( GeometryFactory.CreatePoint(2600020, 1200010, 452, double.NaN, sr), GeometryFactory.CreatePoint(2600030, 1200015, 450, double.NaN, sr)); IFeature thirdEdge = CreateInOperation( () => CreateFeature(edgeClass, edge3Polyline), observer); // Now split by an existing edge (chopper style): IPolyline cuttingPolyline = GeometryFactory.CreatePolyline( new[] { WKSPointZUtils.CreatePoint(2600020, 1200010, 452), WKSPointZUtils.CreatePoint(2600020, 1200000, 452), WKSPointZUtils.CreatePoint(2600015, 1200000, 452), WKSPointZUtils.CreatePoint(2600015, 1200020, 450) }, sr); IFeature cuttingEdge = CreateInOperation( () => CreateFeature(edgeClass, cuttingPolyline), observer); IPoint splitPoint = GeometryFactory.CreatePoint(2600015, 1200007.5, 450, double.NaN, sr); SplitInOperation(existingFeature, splitPoint, observer); Assert.AreEqual(1, observer.GetUpdatedInLastOperation().Count()); // Only the actual update - no dragging along of the connected edge! // 1 original edge + its 2 junctions + 1 second edge + its 1 extra juction // + 1 split-insert edge + 1 split junction //Assert.AreEqual(7, networkFeatureFinder.TargetFeatureCandidates.Count); Assert.IsTrue(GeometryUtils.AreEqual(edge2PolylineOrig, secondEdge.Shape)); }
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; } }