# Changeset 5715 in josm for trunk

Ignore:
Timestamp:
2013-02-13T19:12:38+01:00 (7 years ago)
Message:

see #8416. GpxLayer refactoring: inner classes goes to org.openstreetmap.josm.gui.layer.gpx
Any change of behavior is a bug!

Location:
trunk/src/org/openstreetmap/josm
Files:
4 edited

Unmodified
Removed
• ## trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java

 r5681 import java.util.LinkedList; import java.util.Map; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.Bounds; import org.openstreetmap.josm.data.coor.EastNorth; /** return result; } /** * Makes a WayPoint at the projection of point P onto the track providing P is less than * tolerance away from the track * * @param P : the point to determine the projection for * @param tolerance : must be no further than this from the track * @return the closest point on the track to P, which may be the first or last point if off the * end of a segment, or may be null if nothing close enough */ public WayPoint nearestPointOnTrack(EastNorth P, double tolerance) { /* * assume the coordinates of P are xp,yp, and those of a section of track between two * trackpoints are R=xr,yr and S=xs,ys. Let N be the projected point. * * The equation of RS is Ax + By + C = 0 where A = ys - yr B = xr - xs C = - Axr - Byr * * Also, note that the distance RS^2 is A^2 + B^2 * * If RS^2 == 0.0 ignore the degenerate section of track * * PN^2 = (Axp + Byp + C)^2 / RS^2 that is the distance from P to the line * * so if PN^2 is less than PNmin^2 (initialized to tolerance) we can reject the line; * otherwise... determine if the projected poijnt lies within the bounds of the line: PR^2 - * PN^2 <= RS^2 and PS^2 - PN^2 <= RS^2 * * where PR^2 = (xp - xr)^2 + (yp-yr)^2 and PS^2 = (xp - xs)^2 + (yp-ys)^2 * * If so, calculate N as xn = xr + (RN/RS) B yn = y1 + (RN/RS) A * * where RN = sqrt(PR^2 - PN^2) */ double PNminsq = tolerance * tolerance; EastNorth bestEN = null; double bestTime = 0.0; double px = P.east(); double py = P.north(); double rx = 0.0, ry = 0.0, sx, sy, x, y; if (tracks == null) return null; for (GpxTrack track : tracks) { for (GpxTrackSegment seg : track.getSegments()) { WayPoint R = null; for (WayPoint S : seg.getWayPoints()) { EastNorth c = S.getEastNorth(); if (R == null) { R = S; rx = c.east(); ry = c.north(); x = px - rx; y = py - ry; double PRsq = x * x + y * y; if (PRsq < PNminsq) { PNminsq = PRsq; bestEN = c; bestTime = R.time; } } else { sx = c.east(); sy = c.north(); double A = sy - ry; double B = rx - sx; double C = -A * rx - B * ry; double RSsq = A * A + B * B; if (RSsq == 0.0) { continue; } double PNsq = A * px + B * py + C; PNsq = PNsq * PNsq / RSsq; if (PNsq < PNminsq) { x = px - rx; y = py - ry; double PRsq = x * x + y * y; x = px - sx; y = py - sy; double PSsq = x * x + y * y; if (PRsq - PNsq <= RSsq && PSsq - PNsq <= RSsq) { double RNoverRS = Math.sqrt((PRsq - PNsq) / RSsq); double nx = rx - RNoverRS * B; double ny = ry + RNoverRS * A; bestEN = new EastNorth(nx, ny); bestTime = R.time + RNoverRS * (S.time - R.time); PNminsq = PNsq; } } R = S; rx = sx; ry = sy; } } if (R != null) { EastNorth c = R.getEastNorth(); /* if there is only one point in the seg, it will do this twice, but no matter */ rx = c.east(); ry = c.north(); x = px - rx; y = py - ry; double PRsq = x * x + y * y; if (PRsq < PNminsq) { PNminsq = PRsq; bestEN = c; bestTime = R.time; } } } } if (bestEN == null) return null; WayPoint best = new WayPoint(Main.getProjection().eastNorth2latlon(bestEN)); best.time = bestTime; return best; } }