Ticket #17131: gpx_distance.patch

File gpx_distance.patch, 7.1 KB (added by taylor.smock, 7 years ago)

Possible implementation

  • src/org/openstreetmap/josm/data/gpx/GpxDistance.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.data.gpx;
     3
     4import java.util.ArrayList;
     5import java.util.List;
     6import java.util.stream.Collectors;
     7
     8import org.openstreetmap.josm.data.coor.LatLon;
     9import org.openstreetmap.josm.data.gpx.GpxData;
     10import org.openstreetmap.josm.data.gpx.WayPoint;
     11import org.openstreetmap.josm.data.osm.Node;
     12import org.openstreetmap.josm.data.osm.OsmPrimitive;
     13import org.openstreetmap.josm.data.osm.Relation;
     14import org.openstreetmap.josm.data.osm.Way;
     15import org.openstreetmap.josm.gui.MainApplication;
     16import org.openstreetmap.josm.gui.layer.GpxLayer;
     17import org.openstreetmap.josm.gui.layer.Layer;
     18
     19public class GpxDistance {
     20    List<Layer> layers;
     21    public GpxDistance() {
     22        layers = MainApplication.getLayerManager().getLayers();
     23    }
     24
     25    public boolean isCloseTo(OsmPrimitive p, double maximumDistance) {
     26        double distance = getLowestDistance(p);
     27        return (distance < maximumDistance);
     28    }
     29
     30    /**
     31     * Get the lowest distance from the layers to p
     32     * @param p
     33     * @return
     34     */
     35    public double getLowestDistance(OsmPrimitive p) {
     36        double distance = Double.MAX_VALUE;
     37        for (Layer layer : layers) {
     38            double tdistance = getLowestDistance(p, layer);
     39            if (tdistance < distance) distance = tdistance;
     40        }
     41        return distance;
     42    }
     43    /**
     44     * Find the distance between a point and a layer of surveyed points
     45     * @param p
     46     * @param layer
     47     * @return The shortest distance
     48     */
     49    public double getLowestDistance(OsmPrimitive p, Layer layer) {
     50        if (layer instanceof GpxLayer) {
     51            GpxLayer gpxLayer = (GpxLayer) layer;
     52            GpxData gpxData = gpxLayer.data;
     53            List<WayPoint> trackPoints = gpxData.getTrackPoints().collect(Collectors.toList());
     54            double lowestDistance = Double.MAX_VALUE;
     55            for (WayPoint trackPoint : trackPoints) {
     56                double distance = getDistance(p, trackPoint);
     57                if (distance >= 0.0 && distance < lowestDistance) lowestDistance = distance;
     58            }
     59            return lowestDistance;
     60        }
     61        return Double.MAX_VALUE;
     62    }
     63
     64    /**
     65     * Get the distance between an object and a waypoint
     66     * @param p
     67     * @param waypoint
     68     * @return The shortest distance between p and waypoint
     69     */
     70    public double getDistance(OsmPrimitive p, WayPoint waypoint) {
     71        if (p instanceof Node) {
     72            return getDistanceNode((Node)p, waypoint);
     73        } else if (p instanceof Way) {
     74            return getDistanceWay((Way)p, waypoint);
     75        } else if (p instanceof Relation) {
     76            return getDistanceRelation((Relation)p, waypoint);
     77        }
     78        return Double.MAX_VALUE;
     79    }
     80
     81    /**
     82     * Get the shortest distance between a relation and a waypoint
     83     * @param relation
     84     * @param waypoint
     85     * @return The distance between the relationa and the waypoint
     86     */
     87    protected double getDistanceRelation(Relation relation, WayPoint waypoint) {
     88        double shortestDistance = Double.MAX_VALUE;
     89        List<Node> nodes = new ArrayList<Node>(relation.getMemberPrimitives(Node.class));
     90        List<Way> ways = new ArrayList<Way>(relation.getMemberPrimitives(Way.class));
     91        List<Relation> relations = new ArrayList<Relation>(relation.getMemberPrimitives(Relation.class));
     92        for (Relation nrelation : relations) {
     93            double distance = getDistanceRelation(nrelation, waypoint);
     94            if (distance < shortestDistance) shortestDistance = distance;
     95        }
     96        for (Way way : ways) {
     97            double distance = getDistanceWay(way, waypoint);
     98            if (distance < shortestDistance) shortestDistance = distance;
     99        }
     100        for (Node node : nodes) {
     101            double distance = getDistanceNode(node, waypoint);
     102            if (distance < shortestDistance) shortestDistance = distance;
     103        }
     104        return shortestDistance;
     105    }
     106
     107    /**
     108     * Get the shortest distance between a way and a waypoint
     109     * @param way
     110     * @param waypoint
     111     * @return The distance between the way and the waypoint
     112     */
     113    protected double getDistanceWay(Way way, WayPoint waypoint) {
     114        double shortestDistance = Double.MAX_VALUE;
     115        LatLon coords = waypoint.getCoor();
     116        for (int i = 0; i < way.getNodesCount() - 1; i++) {
     117            LatLon first = way.getNode(i).getCoor();
     118            LatLon second = way.getNode(i + 1).getCoor();
     119            double distance = Math.abs((second.getY() - first.getY()) * coords.getX() - (second.getX() - first.getX()) * coords.getY()
     120                    + second.getX() * first.getY() - second.getY() - first.getX()) /
     121                    Math.sqrt(Math.pow(second.getY() - first.getY(), 2) + Math.pow(second.getX() - first.getX(), 2));
     122            if (distance < shortestDistance) shortestDistance = distance;
     123        }
     124        return shortestDistance;
     125    }
     126
     127    /**
     128     * Get the distance between a node and a waypoint
     129     * @param node
     130     * @param waypoint
     131     * @return The distance between the two points
     132     */
     133    protected double getDistanceNode(Node node, WayPoint waypoint) {
     134        return waypoint.getCoor().distance(node.getCoor());
     135    }
     136}
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java

     
    2424import java.util.zip.CRC32;
    2525
    2626import org.openstreetmap.josm.data.coor.LatLon;
     27import org.openstreetmap.josm.data.gpx.GpxDistance;
    2728import org.openstreetmap.josm.data.osm.IPrimitive;
     29import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2830import org.openstreetmap.josm.data.osm.Node;
    2931import org.openstreetmap.josm.data.osm.Way;
    3032import org.openstreetmap.josm.data.osm.search.SearchCompiler;
     
    519521        }
    520522
    521523        /**
     524         * Returns the lowest distance between the OSM object and a GPX point
     525         * <p>
     526         * @param env the environment
     527         * @return the distance between the object and the closest gpx point or {@code Double.MAX_VALUE}
     528         */
     529        public static double gpx_distance(final Environment env) { // NO_UCD (unused code)
     530            if (env.osm instanceof OsmPrimitive) {
     531                GpxDistance gpxDistance = new GpxDistance();
     532                return gpxDistance.getLowestDistance((OsmPrimitive)env.osm);
     533            } else {
     534                return Double.MAX_VALUE;
     535            }
     536        }
     537
     538        /**
    522539         * Determines whether the object has a tag with the given key.
    523540         * @param env the environment
    524541         * @param key the OSM key