/* * Copyright 2011 mapsforge.org * * 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.muxe.advancedtouristmap.routing; import org.mapsforge.core.Edge; import org.mapsforge.core.GeoCoordinate; import org.mapsforge.core.MercatorProjection; /** * @author Eike Send */ public class AngleCalc { private static final int MIN_DISTANCE_TO_JUNCTION_FOR_ANGLE_MEASURING = 10; /** * Calculate the angle between two IEdge objects / streets * * @param edge1 * the IEdge of the street before the crossing * @param edge2 * the IEdge of the street after the crossing * @return the angle between the given streets */ public static double getAngleOfEdges(Edge edge1, Edge edge2) { if (edge1 != null && edge2 != null) { // Let's see if i can get the angle between the last street and this // This is the crossing GeoCoordinate crossingCoordinate = edge2.getAllWaypoints()[0]; // The following is the last coordinate before the crossing GeoCoordinate coordinateBefore = edge1.getAllWaypoints()[edge1.getAllWaypoints().length - 2]; // Take a coordinate further away from the crossing if it's too close if (coordinateBefore.sphericalDistance(crossingCoordinate) < MIN_DISTANCE_TO_JUNCTION_FOR_ANGLE_MEASURING && edge1.getAllWaypoints().length > 2) { coordinateBefore = edge1.getAllWaypoints()[edge1.getAllWaypoints().length - 3]; } // Here comes the first coordinate after the crossing GeoCoordinate coordinateAfter = edge2.getAllWaypoints()[1]; if (coordinateAfter.sphericalDistance(crossingCoordinate) < MIN_DISTANCE_TO_JUNCTION_FOR_ANGLE_MEASURING && edge2.getAllWaypoints().length > 2) { coordinateAfter = edge2.getAllWaypoints()[2]; } double delta = getAngleOfCoords(coordinateBefore, crossingCoordinate, coordinateAfter); return delta; } return -360; } static double getAngleOfCoords(GeoCoordinate lastCoordinate, GeoCoordinate crossingCoordinate, GeoCoordinate firstCoordinate) { double delta; // calculate angles of the incoming street double deltaY = MercatorProjection.latitudeToMetersY(crossingCoordinate.getLatitude()) - MercatorProjection.latitudeToMetersY(lastCoordinate.getLatitude()); double deltaX = MercatorProjection .longitudeToMetersX(crossingCoordinate.getLongitude()) - MercatorProjection.longitudeToMetersX(lastCoordinate.getLongitude()); double alpha = java.lang.Math.toDegrees(java.lang.Math.atan(deltaX / deltaY)); if (deltaY < 0) { alpha += 180; // this compensates for the atan result being between -90 and +90 } // deg // calculate angles of the outgoing street deltaY = MercatorProjection.latitudeToMetersY(firstCoordinate.getLatitude()) - MercatorProjection.latitudeToMetersY(crossingCoordinate.getLatitude()); deltaX = MercatorProjection.longitudeToMetersX(firstCoordinate.getLongitude()) - MercatorProjection.longitudeToMetersX(crossingCoordinate.getLongitude()); double beta = java.lang.Math.toDegrees(java.lang.Math.atan(deltaX / deltaY)); if (deltaY < 0) { beta += 180; // this compensates for the atan result being between -90 and +90 } // deg // the angle difference is angle of the turn, delta = alpha - beta; // For some reason the angle is conterclockwise, so it's turned around delta = 360 - delta; // make sure there are no values above 360 or below 0 delta = java.lang.Math.round((delta + 360) % 360); return delta; } }