001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.gpx;
003
004import java.util.ArrayList;
005import java.util.List;
006
007import org.openstreetmap.josm.data.coor.EastNorth;
008import org.openstreetmap.josm.data.coor.LatLon;
009import org.openstreetmap.josm.data.osm.Node;
010import org.openstreetmap.josm.data.osm.OsmPrimitive;
011import org.openstreetmap.josm.data.osm.Relation;
012import org.openstreetmap.josm.data.osm.Way;
013import org.openstreetmap.josm.tools.Geometry;
014
015/**
016 * A class to find the distance between an {@link OsmPrimitive} and a GPX point.
017 *
018 * @author Taylor Smock
019 * @since 14802
020 */
021public final class GpxDistance {
022    private GpxDistance() {
023        // This class should not be instantiated
024    }
025
026    /**
027     * Find the distance between a point and a dataset of surveyed points
028     * @param p OsmPrimitive from which to get the lowest distance to a GPX point
029     * @param gpxData Data from which to get the GPX points
030     * @return The shortest distance
031     */
032    public static double getLowestDistance(OsmPrimitive p, GpxData gpxData) {
033        return gpxData.getTrackPoints()
034                .mapToDouble(tp -> Geometry.getDistance(p, new Node(tp.getCoor())))
035                .filter(x -> x >= 0)
036                .min().orElse(Double.MAX_VALUE);
037    }
038
039    /**
040     * Get the distance between an object and a waypoint
041     * @param p OsmPrimitive to get the distance to the WayPoint
042     * @param waypoint WayPoint to get the distance from
043     * @return The shortest distance between p and waypoint
044     * @deprecated Use {@code Geometry.getDistance(p, new Node(waypoint.getCoor()))}
045     * instead
046     */
047    @Deprecated
048    public static double getDistance(OsmPrimitive p, WayPoint waypoint) {
049        return Geometry.getDistance(p, new Node(waypoint.getCoor()));
050    }
051
052    /**
053     * Get the shortest distance between a relation and a waypoint
054     * @param relation Relation to get the distance from
055     * @param waypoint WayPoint to get the distance to
056     * @return The distance between the relation and the waypoint
057     * @deprecated Use {@code Geometry.getDistance(relation, new Node(waypoint.getCoor()))}
058     * instead
059     */
060    @Deprecated
061    public static double getDistanceRelation(Relation relation, WayPoint waypoint) {
062        double shortestDistance = Double.MAX_VALUE;
063        List<Node> nodes = new ArrayList<>(relation.getMemberPrimitives(Node.class));
064        List<Way> ways = new ArrayList<>(relation.getMemberPrimitives(Way.class));
065        List<Relation> relations = new ArrayList<>(relation.getMemberPrimitives(Relation.class));
066        if (nodes.isEmpty() && ways.isEmpty() && relations.isEmpty()) return Double.MAX_VALUE;
067        for (Relation nrelation : relations) {
068            double distance = getDistanceRelation(nrelation, waypoint);
069            if (distance < shortestDistance) shortestDistance = distance;
070        }
071        for (Way way : ways) {
072            double distance = getDistanceWay(way, waypoint);
073            if (distance < shortestDistance) shortestDistance = distance;
074        }
075        for (Node node : nodes) {
076            double distance = getDistanceNode(node, waypoint);
077            if (distance < shortestDistance) shortestDistance = distance;
078        }
079        return shortestDistance;
080    }
081
082    /**
083     * Get the shortest distance between a way and a waypoint
084     * @param way Way to get the distance from
085     * @param waypoint WayPoint to get the distance to
086     * @return The distance between the way and the waypoint
087     * @deprecated Use {@code Geometry.getDistanceWayNode(way, new Node(waypoint.getCoor()))} instead
088     */
089    @Deprecated
090    public static double getDistanceWay(Way way, WayPoint waypoint) {
091        if (way == null || waypoint == null) return Double.MAX_VALUE;
092        return Geometry.getDistanceWayNode(way, new Node(waypoint.getCoor()));
093    }
094
095    /**
096     * Get the distance between a node and a waypoint
097     * @param node Node to get the distance from
098     * @param waypoint WayPoint to get the distance to
099     * @return The distance between the two points
100     * @deprecated Use {@code Geometry.getDistance(node, new Node(waypoint.getCoor()))}
101     * instead
102     */
103    @Deprecated
104    public static double getDistanceNode(Node node, WayPoint waypoint) {
105        if (node == null || waypoint == null) return Double.MAX_VALUE;
106        return Geometry.getDistance(node, new Node(waypoint.getCoor()));
107    }
108
109    /**
110     * Get the distance between coordinates (provided by EastNorth) and a waypoint
111     * @param en The EastNorth to get the distance to
112     * @param waypoint WayPoint to get the distance to
113     * @return The distance between the two points
114     * @deprecated Use {@code Geometry.getDistance(new Node(en), new Node(waypoint.getCoor()))} instead
115     */
116    @Deprecated
117    public static double getDistanceEastNorth(EastNorth en, WayPoint waypoint) {
118        if (en == null || waypoint == null) return Double.MAX_VALUE;
119        return Geometry.getDistance(new Node(en), new Node(waypoint.getCoor()));
120    }
121
122    /**
123     * Get the distance between coordinates (latitude longitude) and a waypoint
124     * @param latlon LatLon to get the distance from
125     * @param waypoint WayPoint to get the distance to
126     * @return The distance between the two points
127     * @deprecated Use {@code Geometry.getDistance(new Node(latlon), new Node(waypoint.getCoor()))} instead
128     */
129    @Deprecated
130    public static double getDistanceLatLon(LatLon latlon, WayPoint waypoint) {
131        if (latlon == null || waypoint == null || waypoint.getCoor() == null) return Double.MAX_VALUE;
132        return Geometry.getDistance(new Node(latlon), new Node(waypoint.getCoor()));
133    }
134}