diff --git a/jsprit-core/src/main/java/jsprit/core/util/GreatCircleCosts.java b/jsprit-core/src/main/java/jsprit/core/util/GreatCircleCosts.java new file mode 100644 index 00000000..9b8eb2e0 --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/util/GreatCircleCosts.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (C) 2014 Stefan Schroeder + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + ******************************************************************************/ +package jsprit.core.util; + + + +import jsprit.core.problem.cost.AbstractForwardVehicleRoutingTransportCosts; +import jsprit.core.problem.driver.Driver; +import jsprit.core.problem.vehicle.Vehicle; + +/** + * + * @author stefan schroeder + * + */ + +public class GreatCircleCosts extends AbstractForwardVehicleRoutingTransportCosts { + + public double speed = 1.; + + public double detour = 1.; + + public void setSpeed(double speed) { + this.speed = speed; + } + + /** + * Sets the detour factor. + *

+ * The distance is calculated by the great circle distance * detour factor. + *

+ * @param detour + */ + public void setDetour(double detour) { + this.detour = detour; + } + + private Locations locations; + + private GreatCircleDistanceCalculator.DistanceUnit distanceUnit = GreatCircleDistanceCalculator.DistanceUnit.Kilometer; + + public GreatCircleCosts(Locations locations) { + super(); + this.locations = locations; + } + + + public GreatCircleCosts(Locations locations, GreatCircleDistanceCalculator.DistanceUnit distanceUnit) { + super(); + this.locations = locations; + this.distanceUnit = distanceUnit; + } + + @Override + public double getTransportCost(String fromId, String toId, double time,Driver driver, Vehicle vehicle) { + double distance; + try { + distance = calculateDistance(fromId, toId); + } catch (NullPointerException e) { + throw new NullPointerException("cannot calculate euclidean distance. coordinates are missing. either add coordinates or use another transport-cost-calculator."); + } + double costs = distance; + if(vehicle != null){ + if(vehicle.getType() != null){ + costs = distance * vehicle.getType().getVehicleCostParams().perDistanceUnit; + } + } + return costs; + } + + @Override + public double getTransportTime(String fromId, String toId, double time, Driver driver, Vehicle vehicle) { + return calculateDistance(fromId, toId) / speed; + } + + private double calculateDistance(String fromId, String toId) { + Coordinate fromCoordinate = locations.getCoord(fromId); + Coordinate toCoordinate = locations.getCoord(toId); + return GreatCircleDistanceCalculator.calculateDistance(fromCoordinate, toCoordinate, distanceUnit) * detour; + } + +} diff --git a/jsprit-core/src/main/java/jsprit/core/util/GreatCircleDistanceCalculator.java b/jsprit-core/src/main/java/jsprit/core/util/GreatCircleDistanceCalculator.java index 3e90aeda..578f6fce 100644 --- a/jsprit-core/src/main/java/jsprit/core/util/GreatCircleDistanceCalculator.java +++ b/jsprit-core/src/main/java/jsprit/core/util/GreatCircleDistanceCalculator.java @@ -22,6 +22,12 @@ package jsprit.core.util; */ public class GreatCircleDistanceCalculator { + public enum DistanceUnit { + + Meter, Kilometer + + } + private static final double R = 6372.8; // km /** @@ -36,7 +42,7 @@ public class GreatCircleDistanceCalculator { * @param coord2 - to coord * @return great circle distance */ - public static double calculateDistance(Coordinate coord1, Coordinate coord2){ + public static double calculateDistance(Coordinate coord1, Coordinate coord2, DistanceUnit unit){ double lon1 = coord1.getX(); double lon2 = coord2.getX(); double lat1 = coord1.getY(); @@ -49,7 +55,11 @@ public class GreatCircleDistanceCalculator { double a = Math.sin(delta_Lat / 2) * Math.sin(delta_Lat / 2) + Math.sin(delta_Lon / 2) * Math.sin(delta_Lon / 2) * Math.cos(lat1) * Math.cos(lat2); double c = 2 * Math.asin(Math.sqrt(a)); - return R * c; + double distance = R * c; + if(unit.equals(DistanceUnit.Meter)){ + distance = distance * 1000.; + } + return distance; } }