/** * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program. * If not, see <http://www.gnu.org/licenses/>. */ package org.openstreetmap.josm.plugins.columbusCSV; import static java.lang.Math.asin; import static java.lang.Math.cos; import static java.lang.Math.sin; import static java.lang.Math.sqrt; import static java.lang.Math.toDegrees; import static java.lang.Math.toRadians; import java.util.ArrayList; import java.util.List; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.coor.LatLon; import org.openstreetmap.josm.data.gpx.WayPoint; /** * @author Oliver Wieland <oliver.wieland@online.de> Provides several static methods to access way point * attributes. */ public class WayPointHelper { /** * The name of the elevation height of a way point. */ public static final String HEIGHT_ATTRIBUTE = "ele"; private static final double R = 6378135; private WayPointHelper() { // Private constructor for the utility class. } /** * Gets the elevation (Z coordinate) of a JOSM way point. * * @param wpt * The way point instance. * @return The x coordinate or 0, if the given way point is null or contains * not height attribute. */ public static double getElevation(WayPoint wpt) { if (wpt != null) { if (!wpt.attr.containsKey(HEIGHT_ATTRIBUTE)) { return 0; } String height = wpt.getString(WayPointHelper.HEIGHT_ATTRIBUTE); try { return Double.parseDouble(height); } catch (NumberFormatException e) { Main.error(String.format( "Cannot parse double from '%s': %s", height, e .getMessage())); } } return 0; } public static double getLonDist(WayPoint w1, WayPoint w2) { LatLon ll = new LatLon(w1.getCoor().lat(), w2.getCoor().lon()); return w1.getCoor().greatCircleDistance(ll); } public static double getLatDist(WayPoint w1, WayPoint w2) { LatLon ll = new LatLon(w2.getCoor().lat(), w1.getCoor().lon()); return w1.getCoor().greatCircleDistance(ll); } /** * Moves a given lat/lon coordinate by a given amount of meters in * x and y direction. * @param src The original lat/lon coordinate. * @param dlat The distance in latitude direction in meters * @param dlon The distance in longitude direction in meters * @return */ public static LatLon moveLatLon(LatLon src, double dlat, double dlon) { double lat1 = toRadians(src.lat()); double lon1 = toRadians(src.lon()); double dlonsin2 = sin(dlon/2 / R); double dlatsin2 = sin(dlat/2 / R); double dlatcos = cos(lon1); double lon2rad = 2 * asin(sqrt(dlonsin2 * dlonsin2 / dlatcos/dlatcos)) + lon1; double lat2rad = 2 * asin(dlatsin2) + lat1; double lon2 = toDegrees(lon2rad); double lat2 = toDegrees(lat2rad); return new LatLon(lat2, lon2); } /** * Reduces a given list of way points to the specified target size. * * @param origList * The original list containing the way points. * @param targetSize * The desired target size of the list. The resulting list may * contain fewer items, so targetSize should be considered as * maximum. * @return A list containing the reduced list. */ public static List<WayPoint> downsampleWayPoints(List<WayPoint> origList, int targetSize) { if (origList == null) return null; if (targetSize <= 0) throw new IllegalArgumentException( "targetSize must be greater than zero"); int origSize = origList.size(); if (origSize <= targetSize) { return origList; } int delta = (int) Math.max(Math.ceil(origSize / targetSize), 2); List<WayPoint> res = new ArrayList<>(targetSize); for (int i = 0; i < origSize; i += delta) { res.add(origList.get(i)); } return res; } }