/// <summary> /// Adds new points to the SnapClass' point index. /// </summary> /// <param name="newShape">The shape containing data to add to the points index.</param> public void AddShapeData(int shpIndex, int snaplayeridx) { int numPoints = 0; double [] pts; System.Array arr = ((MapWinGIS.Shapefile)m_sfs[snaplayeridx]).QuickPoints(shpIndex, ref numPoints); pts = new double[arr.Length]; arr.CopyTo(pts, 0); arr = null; for (int j = 0; j < pts.Length; j += 2) { if (((System.Collections.SortedList)m_lists[snaplayeridx]).ContainsKey(pts[j])) { // the x value is already in the list. Add the y value to the "values" list. System.Collections.SortedList yLst; yLst = (System.Collections.SortedList)((System.Collections.SortedList)m_lists[snaplayeridx]).GetByIndex(((System.Collections.SortedList)m_lists[snaplayeridx]).IndexOfKey(pts[j])); if (yLst.ContainsKey(pts[j + 1]) == false) { // does not contain the y point yet SnapData data = new SnapData(shpIndex, (int)j / 2, new PointD(pts[j], pts[j + 1])); System.Collections.ArrayList l = new System.Collections.ArrayList(); l.Add(data); yLst.Add(pts[j + 1], l); } else { // already containt the y point (duplicate point) SnapData data = new SnapData(shpIndex, (int)j / 2, new PointD(pts[j], pts[j + 1])); ((System.Collections.ArrayList)yLst.GetByIndex(yLst.IndexOfKey(pts[j + 1]))).Add(data); } } else { System.Collections.SortedList y_list = new System.Collections.SortedList(); SnapData data = new SnapData(shpIndex, (int)j / 2, new PointD(pts[j], pts[j + 1])); System.Collections.ArrayList l = new System.Collections.ArrayList(); l.Add(data); y_list.Add(pts[j + 1], l); ((System.Collections.SortedList)m_lists[snaplayeridx]).Add(pts[j], y_list); } } pts = null; }
/// <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); } }