/// <summary> /// Finds the nearest point to the requested location that is within the tolerance radius. /// </summary> /// <param name="ProjectedRadius">The tolerance radius in projected units used to search for the nearest point that can be snapped to. </param> /// <param name="x">x coordinate in projected map units</param> /// <param name="y">y coordinate in projected map units</param> /// <param name="BestPoint">A PointD class with the location of the nearest point to snap to if there is are any within the tolerance, null if no points are found.</param> /// <returns>Returns true if there is a point to snap to.</returns> public bool CanSnap(double ProjectedRadius, double x, double y, ref System.Collections.ArrayList BestPoints) { PointD BestPoint = null; System.Collections.IDictionaryEnumerator ie = m_lists.GetEnumerator(); while (ie.MoveNext()) { int snaplayeridx = (int)ie.Key; if (((System.Collections.SortedList)m_lists[snaplayeridx]).Count == 0) { continue; } try { double val = (x - ProjectedRadius); int first = FindFirst(((System.Collections.SortedList)m_lists[snaplayeridx]), val); double bestX = x + ProjectedRadius, bestY = y + ProjectedRadius; double curX; if (first == -1) { System.Diagnostics.Debug.WriteLine("Could not find any points to snap to"); return(false); } curX = (double)((System.Collections.SortedList)m_lists[snaplayeridx]).GetKey(first); while (curX < (x + ProjectedRadius)) { if (Math.Abs(curX - x) < Math.Abs(bestX - x)) { // the current x is closer to the x value than the previous best // now we think we have a new best x, try to find a better y value System.Collections.SortedList tList = (System.Collections.SortedList)((System.Collections.SortedList)m_lists[snaplayeridx]).GetByIndex(first); for (int j = 0; j < tList.Count; j++) { double curY = (double)tList.GetKey(j); if (Math.Abs(curY - y) < Math.Abs(bestY - y)) { // the current y is closer to the y value than the previous best BestPoint = new PointD(curX, curY); if (BestPoints == null) { BestPoints = new System.Collections.ArrayList(); } BestPoints.AddRange((System.Collections.ArrayList)tList.GetByIndex(j)); // only reset the bestX and bestY when both are better than the previous. bestX = curX; bestY = curY; } } } first++; if (first < ((System.Collections.SortedList)m_lists[snaplayeridx]).Count) { curX = (double)((System.Collections.SortedList)m_lists[snaplayeridx]).GetKey(first); } else { break; } } } catch (System.Exception ex) { errCnt++; System.Diagnostics.Debug.WriteLine(errCnt + " " + ex.Message); } } if (BestPoints == null) { return(false); } else { return(true); } }
/// <summary> /// Finds the nearest point to the requested location that is within the tolerance radius. /// </summary> /// <param name="ProjectedRadius">The tolerance radius in projected units used to search for the nearest point that can be snapped to.</param> /// <param name="x">x coordinate in projected map units</param> /// <param name="y">y coordinate in projected map units</param> /// <param name="curShape">The shape that is currently being created. Points from this shape are also checked.</param> /// <param name="BestPoint">A PointD class with the location of the nearest point to snap to if there is are any within the tolerance, null if no points are found.</param> /// <returns>Returns true if there is a point to snap to.</returns> public bool CanSnap(double ProjectedRadius, double x, double y, ShapeClass curShape, ref System.Collections.ArrayList BestPoints) { System.Collections.IDictionaryEnumerator ie = m_lists.GetEnumerator(); PointD myBest = null; System.Collections.ArrayList myBestPoints = null; while (ie.MoveNext()) { int snaplayeridx = (int)ie.Key; // find any points that are within the tolerance in curShape. for (int i = 0; i < curShape.NumPoints; i++) { PointD pt = curShape[i]; double d = pt.Dist(x, y); if (d < ProjectedRadius) { if (myBest != null) { if (d < myBest.Dist(x, y)) { myBest = pt; } } else { myBest = pt; } } } if (myBest != null) { SnapData d = new SnapData(-1, -1, myBest); myBestPoints = new System.Collections.ArrayList(); myBestPoints.Add(d); } if (CanSnap(ProjectedRadius, x, y, ref BestPoints)) { // work with that best point. if (myBest != null) { PointD tPoint = ((SnapData)BestPoints[0]).point; if (myBest.Dist(x, y) < tPoint.Dist(x, y)) { if (BestPoints == null) { BestPoints = new System.Collections.ArrayList(); } BestPoints.AddRange(myBestPoints); } } } else { if (myBestPoints != null) { if (BestPoints == null) { BestPoints = new System.Collections.ArrayList(); } BestPoints.AddRange(myBestPoints); } } } if (BestPoints == null) { return(false); } else { return(true); } }