/********************************************************************/ // Test the point if it's within the line segements of the curShape // returns the insertIndex if within tolerance else -1 /********************************************************************/ private bool WithinTolerance(double x, double y, int shpIndex, double tol, ref double storeX, ref double storeY, ref int insertIndex) { int numPoints = 0; Point p1, p2; double m1, m2; double dist, shortestDist = 9999999999; double b1, b2; double newX, newY; int index = -1; try { //get the array of points for this shape MapWinGIS.Shapefile sf = m_Globals.CurrentLayer; System.Array points = sf.QuickPoints(shpIndex, ref numPoints); //System.Collections.ArrayList points = (System.Collections.ArrayList)m_Points[shpIndex]; if (numPoints <= 1) { return(false); } for (int p = 0; p < numPoints * 2 - 2; p += 2) { p1 = new Point((double)points.GetValue(p), (double)points.GetValue(p + 1)); p2 = new Point((double)points.GetValue(p + 2), (double)points.GetValue(p + 3)); //p1 = (Point)points[i]; //p2 = (Point)points[i+1]; //find the slope make sure there is no divide by zero if (p2.x == p1.x) { m1 = 0; } else { m1 = (p2.y - p1.y) / (p2.x - p1.x); } //find the y-intercept b1 = p1.y - m1 * p1.x; //find the slope of the perpendicular line relative to the given point if (m1 == 0) { m2 = 0; } else { m2 = -1 / m1; } //find the y-intercept of the perpendicular line relative to the given point b2 = y - m2 * x; //find the intersection point between the two lines if (m1 - m2 == 0) // Horizontal line { newX = p1.x; if (p1.y == p2.y) { newY = m1 * newX + b1; newX = x; } else { newY = m1 * newX + b2; } } else { newX = (b2 - b1) / (m1 - m2); newY = m1 * newX + b1; } //check to make sure the new point is within the line segment if (PointWithinLineSegementBounds(p1, p2, new Point(newX, newY))) { //find the dist between the cursor point and the new point dist = PointD.Dist(x, y, newX, newY); //keep track of the shortest distance if (dist <= shortestDist) { storeX = newX; storeY = newY; shortestDist = dist; index = p / 2; } } } if (shortestDist <= tol) { insertIndex = index + 1; return(true); } } catch (System.Exception ex) { m_MapWin.ShowErrorDialog(ex); } //the point is not within the line segment tolerance insertIndex = -1; return(false); }
public void MouseUpEvent(int Button, int Shift, int x, int y, ref bool Handled) { Handled = true; if (Button == (int)MapWindow.Interfaces.vb6Buttons.Left) { PointD snappedPoint = null; System.Collections.ArrayList bestPoints = null; double newx = 0, newy = 0; m_globals.MapWin.View.PixelToProj((double)x, (double)y, ref newx, ref newy); if (m_snapper != null && m_snapper.CanSnap(m_globals.CurrentTolerance, newx, newy, m_Shape, ref bestPoints) == true) { snappedPoint = ((SnapData)bestPoints[0]).point; m_Shape.AddPoint(snappedPoint); if (m_SFType == MapWindow.Interfaces.eLayerType.PolygonShapefile) { int last = m_Shape.NumPoints - 1; if ((m_Shape.NumPoints > 2) && (m_Shape[0].x == m_Shape[last].x || m_Shape[0].y == m_Shape[last].y)) { // the polygon has been finished. AddShape(m_Shape); return; } } else if (m_SFType == MapWindow.Interfaces.eLayerType.PointShapefile) { AddShape(m_Shape); return; } } else // can't snap { double tx = 0, ty = 0; m_globals.MapWin.View.PixelToProj(x, y, ref tx, ref ty); m_Shape.AddPoint(new PointD(tx, ty)); if (m_SFType == MapWindow.Interfaces.eLayerType.PointShapefile) { AddShape(m_Shape); } } DrawShape(); } else // right button clicked, finish the shape off { if (m_SFType == MapWindow.Interfaces.eLayerType.PolygonShapefile) { // Make sure the first and last points are the same int last = m_Shape.NumPoints - 1; if (m_Shape[0].x != m_Shape[last].x || m_Shape[0].y != m_Shape[last].y) { // they are not the same m_Shape.AddPoint(new PointD(m_Shape[0].x, m_Shape[0].y)); } } AddShape(m_Shape); } m_globals.MapWin.View.Draw.ClearDrawing(m_drawHandle); }