static void SnapPointToClosestPolyline(string shpPath, double x, double y, double tolerance) { string path = Path.GetDirectoryName(shpPath); string name = Path.GetFileNameWithoutExtension(shpPath); _stopWatch.Restart(); IWorkspaceFactory wsf = new ShapefileWorkspaceFactoryClass(); IWorkspace ws = wsf.OpenFromFile(path, 0); IFeatureClass fClass = ((IFeatureWorkspace)ws).OpenFeatureClass(name); _stopWatch.Stop(); DisplayTime(_stopWatch, string.Format("Opening {0}", Path.GetFileName(shpPath))); ISpatialReference sRef = ((IGeoDataset)fClass).SpatialReference; IPoint point = new Point { X = x, Y = y, SpatialReference = sRef }; IFeatureCursor cursor = null; try { IGeometry buffer = ((ITopologicalOperator)point).Buffer(tolerance); ISpatialFilter filter = new SpatialFilter { Geometry = buffer, GeometryField = fClass.ShapeFieldName, SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects }; _stopWatch.Restart(); cursor = fClass.Search(filter, true); _stopWatch.Stop(); DisplayTime(_stopWatch, "Hydrating Cursor"); _stopWatch.Restart(); IFeature feature = cursor.NextFeature(); _stopWatch.Stop(); DisplayTime(_stopWatch, string.Format("...Cursor for 1st record. [Null Row: {0}]", feature == null)); IPoint outPoint = new PointClass(); double distanceAlongurve = 0; double distanceFromCurve = 0; IPolyline6 polyline = (IPolyline6)feature.Shape; bool rightSide = false; polyline.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, point, true, outPoint, ref distanceAlongurve, ref distanceFromCurve, ref rightSide); Marshal.FinalReleaseComObject(outPoint); Marshal.FinalReleaseComObject(polyline); _stopWatch.Restart(); feature = cursor.NextFeature(); _stopWatch.Stop(); DisplayTime(_stopWatch, string.Format("...Cursor for eof. [Null Row: {0}]", feature == null)); } catch (Exception ex) { Console.WriteLine("Exception: {0}", ex.Message); } Marshal.FinalReleaseComObject(cursor); }
static void SnapPointToClosestPolylineUserMod(string shpPath, double x, double y, double tolerance) { string path = Path.GetDirectoryName(shpPath); string name = Path.GetFileNameWithoutExtension(shpPath); const string fmt1 = " Latitude : {0,13}"; const string fmt2 = " Longitude: {0,13}"; const string fmt3 = " ...Open Feature Class: {0:0000} ms"; const string fmt4 = " ...Get Polygon: {0:0000} ms"; const string fmt5 = " ...Search Feature Class: {0:0000} ms"; const string fmt6 = " ...Next Feature: {0:0000} ms [OID: {1,8} | Vertices: {2,10}]"; const string fmt7 = " ...Done."; const int noOID = -1; const string fmt8 = "0000000"; _writer.WriteLine(fmt1, x.ToString("000.0000000")); _writer.WriteLine(fmt2, y.ToString("000.0000000")); _stopWatch.Restart(); Type factoryType = Type.GetTypeFromProgID("esriDataSourcesFile.ShapefileWorkspaceFactory"); IWorkspaceFactory wsf = (IWorkspaceFactory)Activator.CreateInstance(factoryType); IWorkspace ws = wsf.OpenFromFile(path, 0); IFeatureClass fClass = ((IFeatureWorkspace)ws).OpenFeatureClass(name); _stopWatch.Stop(); _writer.WriteLine(fmt3, _stopWatch.ElapsedMilliseconds); ISpatialReference sRef = ((IGeoDataset)fClass).SpatialReference; IPoint point = new Point { X = x, Y = y, SpatialReference = sRef }; IFeatureCursor cursor = null; try { _stopWatch.Restart(); IGeometry buffer = ((ITopologicalOperator)point).Buffer(tolerance); _stopWatch.Stop(); _writer.WriteLine(fmt4, _stopWatch.ElapsedMilliseconds); ISpatialFilter filter = new SpatialFilter { Geometry = buffer, GeometryField = fClass.ShapeFieldName, SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects }; _stopWatch.Restart(); cursor = fClass.Search(filter, true); _stopWatch.Stop(); _writer.WriteLine(fmt5, _stopWatch.ElapsedMilliseconds); _stopWatch.Restart(); IFeature feature = cursor.NextFeature(); _stopWatch.Stop(); _writer.WriteLine(fmt6, _stopWatch.ElapsedMilliseconds, feature != null ? feature.OID.ToString(fmt8) : noOID.ToString(fmt8), feature != null ? _pntCount[feature.OID].ToString(fmt8) : noOID.ToString(fmt8)); while (feature != null) { IPoint outPoint = new PointClass(); double distanceAlongurve = 0; double distanceFromCurve = 0; IPolyline6 polyline = (IPolyline6)feature.Shape; bool rightSide = false; polyline.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, point, true, outPoint, ref distanceAlongurve, ref distanceFromCurve, ref rightSide); Marshal.FinalReleaseComObject(outPoint); Marshal.FinalReleaseComObject(polyline); _stopWatch.Restart(); feature = cursor.NextFeature(); _stopWatch.Stop(); _writer.WriteLine(fmt6, _stopWatch.ElapsedMilliseconds, feature != null ? feature.OID.ToString(fmt8) : noOID.ToString(fmt8), feature != null ? _pntCount[feature.OID].ToString(fmt8) : noOID.ToString(fmt8)); } _writer.WriteLine(fmt7); } catch (Exception ex) { Console.WriteLine("Exception: {0}", ex.Message); } Marshal.FinalReleaseComObject(cursor); }
protected override void OnClick() { IEditor pEd = (IEditor)ArcMap.Editor; IEditor2 pEd2 = (IEditor2)ArcMap.Editor; IEditProperties pEdProps1 = pEd as IEditProperties; IEditProperties2 pEdProps2 = pEd as IEditProperties2; IEditSketch2 pSketch2 = ArcMap.Editor as IEditSketch2; ISegmentCollection pSegColl = pSketch2.Geometry as ISegmentCollection; double dLineDirection = 0; ISketchTool sketchTool = ArcMap.Application.CurrentTool.Command as ISketchTool; if (sketchTool.Constraint == esriSketchConstraint.esriConstraintAngle) { dLineDirection = sketchTool.AngleConstraint; } else { ILine pRubberBandLine = new LineClass(); pRubberBandLine.PutCoords(pSketch2.LastPoint, pEd2.Location); dLineDirection = pRubberBandLine.Angle; } IAngularConverter pAngConv = new AngularConverterClass(); pAngConv.SetAngle(dLineDirection, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); int iSegCnt = pSegColl.SegmentCount; dlgSpiralParameters SpiralEntryDialog = new dlgSpiralParameters(); string sBearing = pAngConv.GetString(pEdProps2.DirectionType, pEdProps2.DirectionUnits, pEdProps2.AngularUnitPrecision); SpiralEntryDialog.txtDirection.Text = sBearing; //Display the dialog DialogResult pDialogResult = SpiralEntryDialog.ShowDialog(); esriCurveDensifyMethod DensifyMethod = esriCurveDensifyMethod.esriCurveDensifyByAngle; //default double dDensifyParameter = 2 * Math.PI / 180; //2 degrees //default if (SpiralEntryDialog.optCustomDensification.Checked) { DensifyMethod = (esriCurveDensifyMethod)SpiralEntryDialog.cboDensificationType.SelectedIndex; if (DensifyMethod == esriCurveDensifyMethod.esriCurveDensifyByAngle) { dDensifyParameter = Convert.ToDouble(SpiralEntryDialog.numAngleDensification.Value) * Math.PI / 180; } else { if (!Double.TryParse(SpiralEntryDialog.txtDensifyValue.Text, out dDensifyParameter)) { dDensifyParameter = 2; } } } if (pDialogResult != DialogResult.OK) { return; } if (SpiralEntryDialog.txtStartRadius.Text.ToLower().Trim() == "infinity" && SpiralEntryDialog.txtEndRadius.Text.ToLower().Trim() == "infinity") { return; } double dSpiralRadius1 = Double.MaxValue; //default to infinity double dFromCurvature = 0; if (SpiralEntryDialog.txtStartRadius.Text.ToLower() != "infinity") { if (Double.TryParse(SpiralEntryDialog.txtStartRadius.Text, out dSpiralRadius1)) { dFromCurvature = 1 / dSpiralRadius1; } else { return; } } double dSpiralRadius2 = Double.MaxValue; //default to infinity double dToCurvature = 0; if (SpiralEntryDialog.txtEndRadius.Text.ToLower() != "infinity") { if (Double.TryParse(SpiralEntryDialog.txtEndRadius.Text, out dSpiralRadius2)) { dToCurvature = 1 / dSpiralRadius2; } else { return; } } bool bIsCCW = (dSpiralRadius1 > dSpiralRadius2) ? SpiralEntryDialog.optRight.Checked : SpiralEntryDialog.optLeft.Checked; bool bSpecialCaseCircularArc = (dSpiralRadius1 == dSpiralRadius2); if (!pAngConv.SetString(SpiralEntryDialog.txtDirection.Text, pEdProps2.DirectionType, pEdProps2.DirectionUnits)) { return; } double dNorthAzimuthRadians = pAngConv.GetAngle(esriDirectionType.esriDTNorthAzimuth, esriDirectionUnits.esriDURadians); IVector3D pVec = new Vector3DClass(); pVec.PolarSet(dNorthAzimuthRadians, 0, 500); IPoint pTangentPoint = new PointClass(); pTangentPoint.PutCoords(pSketch2.LastPoint.X + pVec.XComponent, pSketch2.LastPoint.Y + pVec.YComponent); //double dStreamingTol = pEdProps1.StreamTolerance; //if (dStreamingTol == 0) // dStreamingTol = 0.001 * 5000; //metric //double dSpiralOffsetGeometryPrecision = 0.001 * 250; //metric 0.25 m IPolyline6 theSpiralPolyLine = null; double dExitTangent = 0; if (SpiralEntryDialog.cboPathLengthParameter.SelectedIndex == 0) { double dSpiralArcLength; if (!Double.TryParse(SpiralEntryDialog.txtPathLengthParameter.Text, out dSpiralArcLength)) { return; } if (bSpecialCaseCircularArc) { ILine pInTangentLine = new LineClass(); pInTangentLine.PutCoords(pSketch2.LastPoint, pTangentPoint); ISegment pTangentSegment = (ISegment)pInTangentLine; IConstructCircularArc2 pCircArcConstr = new ESRI.ArcGIS.Geometry.CircularArcClass() as IConstructCircularArc2; pCircArcConstr.ConstructTangentRadiusArc(pTangentSegment, false, bIsCCW, dSpiralRadius1, dSpiralArcLength); ICircularArc pArcSegment = pCircArcConstr as ICircularArc; //Get chord Line from tangent curve constructor ILine pChordLine = new LineClass(); pChordLine.PutCoords(pArcSegment.FromPoint, pArcSegment.ToPoint); double dPolarRadians = pChordLine.Angle; //to get the chord azimuth pCircArcConstr.ConstructBearingRadiusArc(pSketch2.LastPoint, dPolarRadians, bIsCCW, dSpiralRadius1, dSpiralArcLength); dExitTangent = pArcSegment.ToAngle + Math.PI / 2; ISegmentCollection segCollection = new PolylineClass() as ISegmentCollection; object obj = Type.Missing; segCollection.AddSegment((ISegment)pArcSegment, ref obj, ref obj); theSpiralPolyLine = segCollection as IPolyline6; } else { theSpiralPolyLine = ConstructSpiralbyLength(pSketch2.LastPoint, pTangentPoint, dFromCurvature, dToCurvature, bIsCCW, dSpiralArcLength, DensifyMethod, dDensifyParameter, out dExitTangent); } } if (SpiralEntryDialog.cboPathLengthParameter.SelectedIndex == 1) { if (!pAngConv.SetString(SpiralEntryDialog.txtPathLengthParameter.Text, esriDirectionType.esriDTPolar, pEdProps2.DirectionUnits)) { return; } double dSpiralDeltaAngle = pAngConv.GetAngle(esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); if (bSpecialCaseCircularArc) { ILine pInTangentLine = new LineClass(); pInTangentLine.PutCoords(pSketch2.LastPoint, pTangentPoint); ISegment pTangentSegment = (ISegment)pInTangentLine; IConstructCircularArc2 pCircArcConstr = new ESRI.ArcGIS.Geometry.CircularArcClass() as IConstructCircularArc2; pCircArcConstr.ConstructTangentRadiusAngle(pTangentSegment, false, bIsCCW, dSpiralRadius1, dSpiralDeltaAngle); ICircularArc pArcSegment = pCircArcConstr as ICircularArc; //Get chord Line from tangent curve constructor ILine pChordLine = new LineClass(); pChordLine.PutCoords(pArcSegment.FromPoint, pArcSegment.ToPoint); double dPolarRadians = pChordLine.Angle; //to get the chord azimuth pCircArcConstr.ConstructBearingRadiusAngle(pSketch2.LastPoint, dPolarRadians, bIsCCW, dSpiralRadius1, dSpiralDeltaAngle); dExitTangent = pArcSegment.ToAngle + Math.PI / 2; ISegmentCollection segCollection = new PolylineClass() as ISegmentCollection; object obj = Type.Missing; segCollection.AddSegment((ISegment)pArcSegment, ref obj, ref obj); theSpiralPolyLine = segCollection as IPolyline6; } else { theSpiralPolyLine = ConstructSpiralbyDeltaAngle(pSketch2.LastPoint, pTangentPoint, dFromCurvature, dToCurvature, bIsCCW, dSpiralDeltaAngle, DensifyMethod, dDensifyParameter, out dExitTangent); } } if (theSpiralPolyLine == null) { MessageBox.Show("A spiral could not be created with the entered parameters."); return; } ISegmentCollection pSpiralSegCollection = theSpiralPolyLine as ISegmentCollection; //Start a sketch operation and insert the new envelope into the sketch ISketchOperation2 sketchOp = new SketchOperationClass(); sketchOp.Start(ArcMap.Editor); sketchOp.MenuString = "Add Spiral"; pSegColl.AddSegmentCollection(pSpiralSegCollection); IGeometry geom = pSegColl as IGeometry; pSketch2.Geometry = geom; //set the angle constraint to the exit tangent of the spiral sketchTool.Constraint = esriSketchConstraint.esriConstraintAngle; sketchTool.AngleConstraint = dExitTangent; sketchOp.Finish(ArcMap.Document.ActiveView.Extent, esriSketchOperationType.esriSketchOperationGeneral, null); }