public static void CreateJumps(IApplication app, JumpTypes jumpType, double jumpDistance) { IProgressDialog2 progressDialog = default(IProgressDialog2); IProgressDialogFactory progressDialogFactory = null; ITrackCancel trackCancel = null; IStepProgressor stepProgressor = null; ICursor lineCursor = null; IEditor editor = null; IFeature lineFeature = null; IMxDocument mxdoc = null; IMap map = null; UID geoFeatureLayerID = null; IEnumLayer enumLayer = null; IEditLayers eLayers = null; List<IFeatureLayer> lineLayers = null; ILayer layer = null; IFeatureLayer fLayer = null; IFeatureSelection fSel = null; try { //Get editor editor = Globals.getEditor(app); if (editor.EditState != esriEditState.esriStateEditing) { MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("MustBEditg"), A4LGSharedFunctions.Localizer.GetString("GeometryToolsLbl_6")); return; } //ProgressBar progressDialogFactory = new ProgressDialogFactoryClass(); // Create a CancelTracker trackCancel = new CancelTrackerClass(); // Set the properties of the Step Progressor Int32 int32_hWnd = editor.Parent.hWnd; stepProgressor = progressDialogFactory.Create(trackCancel, int32_hWnd); stepProgressor.MinRange = 0; // stepProgressor.MaxRange = itotal stepProgressor.StepValue = 1; stepProgressor.Message = ""; stepProgressor.Hide(); // Create the ProgressDialog. This automatically displays the dialog progressDialog = (ESRI.ArcGIS.Framework.IProgressDialog2)stepProgressor; // Explict Cast // Set the properties of the ProgressDialog progressDialog.CancelEnabled = false; progressDialog.Description = A4LGSharedFunctions.Localizer.GetString("GeometryToolsProc_12") +"..."; progressDialog.Title = A4LGSharedFunctions.Localizer.GetString("GeometryToolsProc_12"); progressDialog.Animation = ESRI.ArcGIS.Framework.esriProgressAnimationTypes.esriProgressGlobe; mxdoc = (IMxDocument)app.Document; map = editor.Map; //Get enumeration of feature layers geoFeatureLayerID = new UIDClass(); geoFeatureLayerID.Value = "{E156D7E5-22AF-11D3-9F99-00C04F6BC78E}"; enumLayer = map.get_Layers(((ESRI.ArcGIS.esriSystem.UID)geoFeatureLayerID), true); //Get enumeration of editable layers eLayers = (IEditLayers)editor; // Create list of visible line layers with selected feature(s) lineLayers = new List<IFeatureLayer>(); enumLayer.Reset(); layer = enumLayer.Next(); while (layer != null) { fLayer = (IFeatureLayer)layer; stepProgressor.Message = A4LGSharedFunctions.Localizer.GetString("GeometryToolsMess_2") + fLayer.Name; if (fLayer.Valid && (fLayer.FeatureClass.ShapeType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline) && (fLayer.Visible)) { if (eLayers.IsEditable(fLayer)) { fSel = fLayer as IFeatureSelection; if (fSel.SelectionSet.Count > 0) { stepProgressor.Message = A4LGSharedFunctions.Localizer.GetString("GeometryToolsMess_3") + fLayer.Name; lineLayers.Add(fLayer); } } } layer = enumLayer.Next(); } if (lineLayers.Count == 0) { MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("GeometryToolsError_7")); return; } // Create an edit operation enabling undo/redo editor.StartOperation(); IPointCollection linePointCollection = null; ISpatialFilter spatialFilter = null; IFeatureCursor featureCursor = null; IFeature crossFeature = null; ITopologicalOperator topologicalOP = null; ITopologicalOperator topologicalOP2 = null; IPointCollection intersectPointCollection = null; IPoint intersectPoint = null; IPoint outPoint = null; IPoint beginPoint = null; IPoint endPoint = null; IActiveView activeView = null; IInvalidArea invalid = null; IEnvelope ext = null; ISegmentCollection testSegmentColl = null; ISegment testSegment = null; ISegmentCollection segmentColl = null; ISegmentCollection segmentCollNew = null; IConstructCircularArc constructCircArc = null; ISegment curveSegment = null; //IProximityOperator proximityOP = null; IPolycurve3 selCurve = null; IPolycurve3 selCurveB = null; IPolycurve3 crossCurve = null; IPolycurve3 crossCurveB = null; IPolycurve3 testSelCurve = null; IPolycurve3 testSelCurveB = null; object _missing = null; IFeatureSelection lineSel = null; ISelectionSet2 sel = null; IZAware pZAware = null; ISegmentCollection testSegmentColl2 = null; ISegment testSegment2 = null; IGeometryDef pGeometryDefTest = null; IFields pFieldsTest = null; IField pFieldTest = null; IGeoDataset pDS = null; try { activeView = map as IActiveView; invalid = new InvalidAreaClass(); invalid.Display = editor.Display; linePointCollection = (IPointCollection)new PolylineClass(); spatialFilter = new SpatialFilterClass(); intersectPoint = new PointClass(); outPoint = new PointClass(); //used for curve test on cross feature bool testProjectOnto; bool testCreatePart; bool testSplitHappened; int testNewPartIndex; int testNewSegmentIndex; //used for curve test on selected feature bool testProjectOnto2; bool testCreatePart2; bool testSplitHappened2; int testNewPartIndex2; int testNewSegmentIndex2; //ICurve lineCurve; double totalDistance; double distAlongCurve = 0; double distFromCurve = 0; bool boolRightSide = false; //test the amount of needed space for the inserted curve double remainderDistance = 0; double pointDistance = 0; bool projectOnto; bool createPart; bool splitHappenedBefore; bool splitHappenedAfter; int newPartIndexBegin; int newSegmentIndexBegin; int newPartIndexEnd; int newSegmentIndexEnd; _missing = Type.Missing; // Step through all line layers with selection sets foreach (IFeatureLayer lineLayer in lineLayers) { stepProgressor.Message = A4LGSharedFunctions.Localizer.GetString("GeometryToolsMess_4a") + lineLayer.Name; // Get cursor of selected lines lineSel = (IFeatureSelection)lineLayer; sel = lineSel.SelectionSet as ISelectionSet2; sel.Search(null, false, out lineCursor); // Process each selected line int idx = 0; while ((lineFeature = (IFeature)lineCursor.NextRow()) != null) { idx++; stepProgressor.Message = A4LGSharedFunctions.Localizer.GetString("GeometryToolsMess_4b") + idx + A4LGSharedFunctions.Localizer.GetString("GeometryToolsMess_4c") + lineLayer.Name; if (lineFeature.Shape.GeometryType == esriGeometryType.esriGeometryPolyline) { selCurve = (IPolycurve3)lineFeature.ShapeCopy; pZAware = selCurve as IZAware; if (pZAware.ZAware) { pZAware.ZAware = false; } // Get cursor of crossing features spatialFilter.Geometry = selCurve; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses; featureCursor = lineLayer.Search(spatialFilter, false); // Process each crossing feature while ((crossFeature = (IFeature)featureCursor.NextFeature()) != null) { topologicalOP = (ITopologicalOperator)crossFeature.Shape; //topologicalOP2 = (ITopologicalOperator)polylinePointCollection; topologicalOP2 = (ITopologicalOperator)selCurve; topologicalOP2.Simplify(); topologicalOP.Simplify(); intersectPointCollection = (IPointCollection)topologicalOP.Intersect((IGeometry)selCurve, esriGeometryDimension.esriGeometry0Dimension); for (int i = 0; i < intersectPointCollection.PointCount; i++) { intersectPoint = intersectPointCollection.get_Point(i); //Determine if the crossing segement is an arc. //Continue if it is not. testProjectOnto = true; testCreatePart = false; crossCurve = (IPolycurve3)crossFeature.ShapeCopy; crossCurve.SplitAtPoint(intersectPoint, testProjectOnto, testCreatePart, out testSplitHappened, out testNewPartIndex, out testNewSegmentIndex); crossCurveB = (IPolycurve3)crossFeature.ShapeCopy; testSegmentColl = crossCurveB as ISegmentCollection; testSegment = testSegmentColl.get_Segment(testNewSegmentIndex - 1); if (testSegment.GeometryType != esriGeometryType.esriGeometryCircularArc) { //Determine if the current location of the selected line is an arc. //Continue if it is not. testProjectOnto2 = true; testCreatePart2 = false; testSelCurve = (IPolycurve3)lineFeature.ShapeCopy; testSelCurve.SplitAtPoint(intersectPoint, testProjectOnto2, testCreatePart2, out testSplitHappened2, out testNewPartIndex2, out testNewSegmentIndex2); testSelCurveB = (IPolycurve3)lineFeature.ShapeCopy; testSegmentColl2 = testSelCurveB as ISegmentCollection; testSegment2 = testSegmentColl2.get_Segment(testNewSegmentIndex2 - 1); if (testSegment2.GeometryType != esriGeometryType.esriGeometryCircularArc) { //Find distance along the original selected line //focusPolyline = (IPolyline)lineFeature.ShapeCopy; selCurveB = (IPolycurve3)lineFeature.ShapeCopy; selCurveB.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, intersectPoint, false, outPoint, ref distAlongCurve, ref distFromCurve, ref boolRightSide); remainderDistance = selCurveB.Length - distAlongCurve; totalDistance = distAlongCurve + jumpDistance; //Continue if there is enough room if ((selCurveB.Length >= (jumpDistance / 2)) && (remainderDistance >= (jumpDistance / 2))) { //find the points where the curve will begin and end beginPoint = new PointClass(); endPoint = new PointClass(); selCurveB.QueryPoint(esriSegmentExtension.esriNoExtension, (distAlongCurve - (jumpDistance / 2)), false, beginPoint); selCurveB.QueryPoint(esriSegmentExtension.esriNoExtension, (distAlongCurve + (jumpDistance / 2)), false, endPoint); //split the original line at the two points (vertices for begin and end of new curve) projectOnto = true; createPart = false; selCurveB.SplitAtPoint(beginPoint, projectOnto, createPart, out splitHappenedBefore, out newPartIndexBegin, out newSegmentIndexBegin); selCurveB.SplitAtPoint(endPoint, projectOnto, createPart, out splitHappenedAfter, out newPartIndexEnd, out newSegmentIndexEnd); if ((splitHappenedBefore = true) && (splitHappenedAfter = true)) { //Create the curve segment and add it to the polyline constructCircArc = new CircularArcClass(); // proximityOP = (IProximityOperator)intersectPoint; //pointDistance = proximityOP.ReturnDistance(beginPoint); pointDistance = jumpDistance; //check for direction of line to always make the jump on top if (jumpType == JumpTypes.Over) if (endPoint.X > beginPoint.X) { try { constructCircArc.ConstructChordDistance(intersectPoint, beginPoint, false, (pointDistance)); } catch { MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("GeometryToolsError_8")); continue; } } else { try { constructCircArc.ConstructChordDistance(intersectPoint, beginPoint, true, (pointDistance)); } catch { MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("GeometryToolsError_8")); continue; } } else { if (endPoint.X <= beginPoint.X) { try { constructCircArc.ConstructChordDistance(intersectPoint, beginPoint, false, (pointDistance)); } catch { MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("GeometryToolsError_8")); continue; } } else { try { constructCircArc.ConstructChordDistance(intersectPoint, beginPoint, true, (pointDistance)); } catch { MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("GeometryToolsError_8")); continue; } } } curveSegment = constructCircArc as ISegment; if (curveSegment != null & curveSegment.Length > 0) { segmentCollNew = (ISegmentCollection)new PolylineClass(); segmentCollNew.AddSegment(curveSegment, ref _missing, ref _missing); segmentColl = (ISegmentCollection)selCurveB; segmentColl.ReplaceSegmentCollection(newSegmentIndexBegin, 1, segmentCollNew); string sShpName = lineLayer.FeatureClass.ShapeFieldName; pFieldsTest = lineLayer.FeatureClass.Fields; int lGeomIndex = pFieldsTest.FindField(sShpName); pFieldTest = pFieldsTest.get_Field(lGeomIndex); pGeometryDefTest = pFieldTest.GeometryDef; bool bZAware; bool bMAware; //Determine if M or Z aware bZAware = pGeometryDefTest.HasZ; bMAware = pGeometryDefTest.HasM; if (bZAware) { // IGeometry pGeo = new PolylineClass(); pZAware = selCurveB as IZAware; if (pZAware.ZAware) { } else { pZAware.ZAware = true; //pZAware.DropZs(); } // pZAware.DropZs(); IZ pZ = selCurveB as IZ; pZ.SetConstantZ(0); } if (bMAware) { } pDS = lineLayer.FeatureClass as IGeoDataset; selCurveB.SpatialReference = pDS.SpatialReference; lineFeature.Shape = (IGeometry)selCurveB; lineFeature.Store(); //Prepare to redraw area around feature ext = curveSegment.Envelope; ext.Expand(2, 2, true); invalid.Add(ext); } } } else { MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("GeometryToolsError_9")); } } } } } } } } } catch (Exception ex) { editor.AbortOperation(); MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("GeometryToolsLbl_6") + "\n" + ex.Message, ex.Source); } finally { // Refresh if (invalid!= null) invalid.Invalidate((short)esriScreenCache.esriAllScreenCaches); linePointCollection = null; spatialFilter = null; if (featureCursor != null) Marshal.ReleaseComObject(featureCursor); featureCursor = null; crossFeature = null; topologicalOP = null; topologicalOP2 = null; intersectPointCollection = null; intersectPoint = null; outPoint = null; beginPoint = null; endPoint = null; activeView = null; invalid = null; ext = null; testSegmentColl = null; testSegment = null; segmentColl = null; segmentCollNew = null; constructCircArc = null; curveSegment = null; //proximityOP = null; selCurve = null; selCurveB = null; crossCurve = null; crossCurveB = null; testSelCurve = null; testSelCurveB = null; _missing = null; lineSel = null; sel = null; pZAware = null; testSegmentColl2 = null; testSegment2 = null; pGeometryDefTest = null; pFieldsTest = null; pFieldTest = null; pDS = null; } // Stop the edit operation editor.StopOperation(A4LGSharedFunctions.Localizer.GetString("GeometryToolsLbl_6")); } catch (Exception ex) { MessageBox.Show(A4LGSharedFunctions.Localizer.GetString("GeometryToolsLbl_6") + "\n" + ex.Message, ex.Source); return; } finally { if (lineCursor != null) { Marshal.ReleaseComObject(lineCursor); } // Cleanup if (progressDialog != null) { progressDialog.HideDialog(); //progressDialog = null; Marshal.ReleaseComObject(progressDialog); //progressDialogFactory = null; //Marshal.ReleaseComObject(progressDialogFactory); //trackCancel = null; //Marshal.ReleaseComObject(trackCancel); //stepProgressor = null; //Marshal.ReleaseComObject(stepProgressor); //appCursor = null; } progressDialog = null; progressDialogFactory = null; trackCancel = null; stepProgressor = null; lineCursor = null; editor = null; lineFeature = null; mxdoc = null; map = null; geoFeatureLayerID = null; enumLayer = null; eLayers = null; lineLayers = null; layer = null; fLayer = null; fSel = null; } }