Opened 6 years ago
Closed 6 years ago
#17131 closed enhancement (fixed)
[Patch] mapcss should have the ability to get the distance to a gpx track
Reported by: | taylor.smock | Owned by: | team |
---|---|---|---|
Priority: | normal | Milestone: | 19.02 |
Component: | Core validator | Version: | latest |
Keywords: | mapcss | Cc: |
Description
way[highway][!surface][gpx_distance() < 30] { throwError: tr("A highway doesn't have a surface type"); }
Attachments (9)
Change History (19)
by , 6 years ago
Attachment: | gpx_distance.patch added |
---|
comment:1 by , 6 years ago
Milestone: | → 18.12 |
---|---|
Summary: | mapcss should have the ability to get the distance to a gpx track → [Patch] mapcss should have the ability to get the distance to a gpx track |
Thanks for the patch!
Some things to do to include it:
- please run
ant pmd checkstyle
and fix all reported issues - The methods should be static, there's no need to instantiate an object just to get a list of current layers
- you can use
LayerManager.getLayersOfType(GpxLayer.class)
- the code must be robust to incomplete primitives (for example: a node without coordinate will throw an NPE here)
- you don't use any method of
org.openstreetmap.josm.tools.Geometry
, I'm sure there aredistance
methods there you should use rather than make the calculation inGpxDistance
comment:2 by , 6 years ago
I think I managed to get the methods to be static, I switched to using LayerManager (but in an odd way due to switching to static methods -- I don't know if it will work), I made the code a bit more robust for incomplete primitives.
As far as org.openstreetmap.josm.tools.Geometry
, I didn't see any distance
methods in it. I should probably look at moving many (or all) of the methods in GpxDistance to Geometry.
As far as ant pmd checkstyle
goes, I couldn't run it. This is probably due to a hardcoded path somewhere in build.xml for ant. I fixed it with ln -s "$(which ant)" /usr/local/share/ant
, and the patch no longer has warnings from it.
iMacs-iMac-6:core tsmock$ ant pmd checkstyle Buildfile: /Users/tsmock/workspace/josm/core/build.xml init-properties: pmd: WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by net.sourceforge.pmd.ant.Formatter (file:/Users/tsmock/workspace/josm/core/tools/pmd/pmd-core-6.6.0.jar) to field java.io.Console.cs WARNING: Please consider reporting this to the maintainers of net.sourceforge.pmd.ant.Formatter WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release Analysis cache invalidated, rulesets changed. Incremental analysis can't check execution classpath contents java.nio.file.NoSuchFileException: /usr/local/share/ant <TRIMMED>
iMacs-iMac-6:core tsmock$ which ant /usr/local/bin/ant
by , 6 years ago
Attachment: | gpx_distance_v2.patch added |
---|
Patch after feedback (ant pmd checkstyle NOT run)
comment:3 by , 6 years ago
Thanks. In getDistanceWay you should call LatLon.greatCircleDistance
instead of the complex calculation. Otherwise looks fine.
comment:4 by , 6 years ago
I'm not certain how to use LatLon.greatCircleDistance to get the distance between a point and a way. It only takes a latlon, right?
So I would do something like this:
double tdistance = ((coords.getX() - first.getX()) * (second.getX() - first.getX()) + (coords.getY() - first.getY()) * (second.getY() - first.getY())) / (Math.pow(second.getX() - first.getX(), 2) + Math.pow(second.getY() - first.getY(), 2)); double x = first.getX() + tdistance * (second.getX() - first.getX()); double y = first.getY() + tdistance * (second.getY() - first.getY()); LatLon npoint = new LatLon(y, x); distance = npoint.greatCircleDistance(coords);
instead of
distance = Math.abs((second.getY() - first.getY()) * coords.getX() - (second.getX() - first.getX()) * coords.getY() + second.getX() * first.getY() - second.getY() - first.getX()) / Math.sqrt(Math.pow(second.getY() - first.getY(), 2) + Math.pow(second.getX() - first.getX(), 2));
In my local copy, I did modify getDistanceLatLon
to use LatLon.greatCircleDistance
, since that makes more sense than LatLon.distance
for OpenStreetMap.
by , 6 years ago
Attachment: | gpx_distance_v3.patch added |
---|
Modified to use greatCircleDistance
where possible and ant pmd checkstyle
has been run
comment:5 by , 6 years ago
I think you could still replace this calculation by a call to Geometry.closestPointToSegment
:
/** * Calculates closest point to a line segment. * @param segmentP1 First point determining line segment * @param segmentP2 Second point determining line segment * @param point Point for which a closest point is searched on line segment [P1,P2] * @return segmentP1 if it is the closest point, segmentP2 if it is the closest point, * a new point if closest point is between segmentP1 and segmentP2. * @see #closestPointToLine * @since 3650 */ public static EastNorth closestPointToSegment(EastNorth segmentP1, EastNorth segmentP2, EastNorth point)
comment:6 by , 6 years ago
Milestone: | 18.12 → 19.01 |
---|
by , 6 years ago
Attachment: | gpx_distance_v4.patch added |
---|
Now uses Geometry.closestPointToSegment
for getting the shortest distance from a point to a way.
comment:7 by , 6 years ago
OK we're almost there :) Be careful with calling getCoor()
method on the same object, several times. It will create a new LatLon instance at each call and thus the code will be memory-hungry, this must be avoided in rendering code by making sure the method is called only once per object:
EastNorth first = new EastNorth(way.getNode(i).getCoor().getX(), way.getNode(i).getCoor().getY()); // <-- EastNorth second = new EastNorth(way.getNode(i+1).getCoor().getX(), way.getNode(i+1).getCoor().getY()); // <-- if (first.isValid() && second.isValid()) { EastNorth closestPoint = Geometry.closestPointToSegment(first, second, enwaypoint); distance = closestPoint.distance(waypoint.getCoor().getX(), waypoint.getCoor().getY()); // <--
Also, please add a @since xxx
in javadoc of new public class GpxDistance
and new public method ExpressionFactory.gpx_distance
. And then we're done :)
by , 6 years ago
Attachment: | gpx_distance_v5.patch added |
---|
Add @since xxx to javadocs and make calls to getCoor() once per object
by , 6 years ago
Attachment: | GpxDistance_v6.patch added |
---|
Add tests and fix some bugs that were exposed
by , 6 years ago
Attachment: | GpxDistance_v6.2.patch added |
---|
Fix some issues I noticed during testing and start work on method for GeoImage layers
by , 6 years ago
Attachment: | GpxDistance_v7.patch added |
---|
Creates a new gpxdata object from image gps points where it is not already associated with a gpx track
comment:8 by , 6 years ago
Milestone: | 19.01 → 19.02 |
---|
by , 6 years ago
Attachment: | GpxDistance_v8.patch added |
---|
Significantly improve performance by not rebuilding the same fake gpxlayer everytime -- it now stores the fake layer in the GeoImageLayer
.
comment:9 by , 6 years ago
Status update (pursuant https://josm.openstreetmap.de/wiki/DevelopersGuide/PatchGuide)
Possible implementation