Ticket #17131: gpx_distance_v5.patch

File gpx_distance_v5.patch, 9.9 KB (added by taylor.smock, 7 years ago)

Add @since xxx to javadocs and make calls to getCoor() once per object

  • 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.EastNorth;
     9import org.openstreetmap.josm.data.coor.LatLon;
     10import org.openstreetmap.josm.data.osm.Node;
     11import org.openstreetmap.josm.data.osm.OsmPrimitive;
     12import org.openstreetmap.josm.data.osm.Relation;
     13import org.openstreetmap.josm.data.osm.Way;
     14import org.openstreetmap.josm.gui.MainApplication;
     15import org.openstreetmap.josm.gui.layer.GpxLayer;
     16import org.openstreetmap.josm.gui.layer.Layer;
     17import org.openstreetmap.josm.gui.layer.LayerManager;
     18import org.openstreetmap.josm.tools.Geometry;
     19
     20/**
     21 * A class to find the distance between an OsmPrimitive and a GPX point
     22 *
     23 * @author Taylor Smock
     24 *
     25 */
     26public final class GpxDistance {
     27    private GpxDistance() {
     28        // This class should not be instantiated
     29    }
     30
     31    /**
     32     * @param p The OsmPrimitive that we are checking the maximum distance for
     33     * @param maximumDistance The maximum distance from a GPX point to the OsmPrimitive
     34     * @return true if the distance to the closest GPX point is lower than maximumDistance
     35     * @since xxx
     36     */
     37    public static boolean isCloseTo(OsmPrimitive p, double maximumDistance) {
     38        double distance = getLowestDistance(p);
     39        return (distance < maximumDistance);
     40    }
     41
     42    /**
     43     * Get the lowest distance from the layers to p
     44     * @param p OsmPrimitive from which to get the lowest distance to a GPX point
     45     * @return the lowest distance from any GpxLayer to p.
     46     * @since xxx
     47     */
     48    public static double getLowestDistance(OsmPrimitive p) {
     49        LayerManager layerManager = MainApplication.getLayerManager();
     50        List<Layer> layers = layerManager.getLayers();
     51        double distance = Double.MAX_VALUE;
     52        for (Layer layer : layers) {
     53            double tdistance = getLowestDistance(p, layer);
     54            if (tdistance < distance) distance = tdistance;
     55        }
     56        return distance;
     57    }
     58
     59    /**
     60     * Find the distance between a point and a layer of surveyed points
     61     * @param p OsmPrimitive from which to get the lowest distance to a GPX point
     62     * @param layer Layer from which to get the GPX points (currently, only GpxLayer is supported)
     63     * @return The shortest distance
     64     * @since xxx
     65     */
     66    public static double getLowestDistance(OsmPrimitive p, Layer layer) {
     67        if (layer instanceof GpxLayer) {
     68            GpxLayer gpxLayer = (GpxLayer) layer;
     69            GpxData gpxData = gpxLayer.data;
     70            List<WayPoint> trackPoints = gpxData.getTrackPoints().collect(Collectors.toList());
     71            double lowestDistance = Double.MAX_VALUE;
     72            for (WayPoint trackPoint : trackPoints) {
     73                double distance = getDistance(p, trackPoint);
     74                if (distance >= 0.0 && distance < lowestDistance) lowestDistance = distance;
     75            }
     76            return lowestDistance;
     77        }
     78        return Double.MAX_VALUE;
     79    }
     80
     81    /**
     82     * Get the distance between an object and a waypoint
     83     * @param p OsmPrimitive to get the distance to the WayPoint
     84     * @param waypoint WayPoint to get the distance from
     85     * @return The shortest distance between p and waypoint
     86     * @since xxx
     87     */
     88    public static double getDistance(OsmPrimitive p, WayPoint waypoint) {
     89        if (p instanceof Node) {
     90            return getDistanceNode((Node) p, waypoint);
     91        } else if (p instanceof Way) {
     92            return getDistanceWay((Way) p, waypoint);
     93        } else if (p instanceof Relation) {
     94            return getDistanceRelation((Relation) p, waypoint);
     95        }
     96        return Double.MAX_VALUE;
     97    }
     98
     99    /**
     100     * Get the shortest distance between a relation and a waypoint
     101     * @param relation Relation to get the distance from
     102     * @param waypoint WayPoint to get the distance to
     103     * @return The distance between the relation and the waypoint
     104     * @since xxx
     105     */
     106    public static double getDistanceRelation(Relation relation, WayPoint waypoint) {
     107        double shortestDistance = Double.MAX_VALUE;
     108        List<Node> nodes = new ArrayList<>(relation.getMemberPrimitives(Node.class));
     109        List<Way> ways = new ArrayList<>(relation.getMemberPrimitives(Way.class));
     110        List<Relation> relations = new ArrayList<>(relation.getMemberPrimitives(Relation.class));
     111        if (nodes.isEmpty() && ways.isEmpty() && relations.isEmpty()) return Double.MAX_VALUE;
     112        for (Relation nrelation : relations) {
     113            double distance = getDistanceRelation(nrelation, waypoint);
     114            if (distance < shortestDistance) shortestDistance = distance;
     115        }
     116        for (Way way : ways) {
     117            double distance = getDistanceWay(way, waypoint);
     118            if (distance < shortestDistance) shortestDistance = distance;
     119        }
     120        for (Node node : nodes) {
     121            double distance = getDistanceNode(node, waypoint);
     122            if (distance < shortestDistance) shortestDistance = distance;
     123        }
     124        return shortestDistance;
     125    }
     126
     127    /**
     128     * Get the shortest distance between a way and a waypoint
     129     * @param way Way to get the distance from
     130     * @param waypoint WayPoint to get the distance to
     131     * @return The distance between the way and the waypoint
     132     * @since xxx
     133     */
     134    public static double getDistanceWay(Way way, WayPoint waypoint) {
     135        double shortestDistance = Double.MAX_VALUE;
     136        LatLon llwaypoint = waypoint.getCoor();
     137        EastNorth enwaypoint = new EastNorth(llwaypoint.getX(), llwaypoint.getY());
     138        for (int i = 0; i < way.getNodesCount() - 1; i++) {
     139            double distance = Double.MAX_VALUE;
     140            LatLon llfirst = way.getNode(i).getCoor();
     141            LatLon llsecond = way.getNode(i + 1).getCoor();
     142            EastNorth first = new EastNorth(llfirst.getX(), llfirst.getY());
     143            EastNorth second = new EastNorth(llsecond.getX(), llsecond.getY());
     144            if (first.isValid() && second.isValid()) {
     145                EastNorth closestPoint = Geometry.closestPointToSegment(first, second, enwaypoint);
     146                distance = closestPoint.distance(llwaypoint.getX(), llwaypoint.getY());
     147            } else if (first.isValid() && !second.isValid()) {
     148                distance = getDistanceEastNorth(first, waypoint);
     149            } else if (!first.isValid() && second.isValid()) {
     150                distance = getDistanceEastNorth(second, waypoint);
     151            } else if (!first.isValid() && !second.isValid()) {
     152                distance = Double.MAX_VALUE;
     153            }
     154            if (distance < shortestDistance) shortestDistance = distance;
     155
     156        }
     157        return shortestDistance;
     158    }
     159
     160    /**
     161     * Get the distance between a node and a waypoint
     162     * @param node Node to get the distance from
     163     * @param waypoint WayPoint to get the distance to
     164     * @return The distance between the two points
     165     * @since xxx
     166     */
     167    public static double getDistanceNode(Node node, WayPoint waypoint) {
     168        return getDistanceLatLon(node.getCoor(), waypoint);
     169    }
     170
     171    /**
     172     * Get the distance between coordinates (provided by EastNorth) and a waypoint
     173     * @param en The EastNorth to get the distance to
     174     * @param waypoint WayPoint to get the distance to
     175     * @return The distance between the two points
     176     * @since xxx
     177     */
     178    public static double getDistanceEastNorth(EastNorth en, WayPoint waypoint) {
     179        if (!en.isValid() || waypoint.getCoor() == null) return Double.MAX_VALUE;
     180        return getDistanceLatLon(new LatLon(en.getY(), en.getX()), waypoint);
     181    }
     182
     183    /**
     184     * Get the distance between coordinates (latitude longitude) and a waypoint
     185     * @param latlon LatLon to get the distance from
     186     * @param waypoint WayPoint to get the distance to
     187     * @return The distance between the two points
     188     * @since xxx
     189     */
     190    public static double getDistanceLatLon(LatLon latlon, WayPoint waypoint) {
     191        if (latlon == null || waypoint.getCoor() == null) return Double.MAX_VALUE;
     192        return waypoint.getCoor().greatCircleDistance(latlon);
     193    }
     194}
  • 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;
    2829import org.openstreetmap.josm.data.osm.Node;
     30import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2931import org.openstreetmap.josm.data.osm.Way;
    3032import org.openstreetmap.josm.data.osm.search.SearchCompiler;
    3133import org.openstreetmap.josm.data.osm.search.SearchCompiler.Match;
     
    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         * @since xxx
     529         */
     530        public static double gpx_distance(final Environment env) { // NO_UCD (unused code)
     531            if (env.osm instanceof OsmPrimitive) {
     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