Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #377 alternative routes #403

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
### Added
- Added support for ISO 3166-1 Alpha-2 / Alpha-3 codes for routing directions option avoid_countries (Issue #195)
- Added support for GH alternative_route algorithm (Issue #377)
- Added check on matrix service to make sure that the requested locations are within the bounding area of the graph (Issue #408)
### Fixed
- Fixed `geometry_simplify` parameter, which had no effect before. `geometry_simplify` is incompatible with `extra_info` (#381)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ public ResultTest() {
addParameter("preference", "fastest");
addParameter("bikeProfile", "cycling-regular");
addParameter("carProfile", "driving-car");

// query for testing the alternative routes algorithm
addParameter("coordinatesAR", "8.673191,49.446812|8.689499,49.398295");
}

@Test
Expand Down Expand Up @@ -1502,4 +1505,27 @@ public void testSimplifyHasLessWayPoints() {
.body("features[0].geometry.coordinates.size()", is(34))
.statusCode(200);
}

@Test
public void testAlternativeRoutes() {
given()
.param("coordinates", getParameter("coordinatesAR"))
.param("instructions", "true")
.param("preference", getParameter("preference"))
.param("profile", getParameter("carProfile"))
.param("options", "{\"alternative_routes_count\": 2}")
.when().log().ifValidationFails()
.get(getEndPointName())
.then()
.assertThat()
.body("any { it.key == 'routes' }", is(true))
.body("routes.size()", is(2))
.body("routes[0].summary.distance", is(5942.1f))
.body("routes[0].summary.duration", is(776.1f))
.body("routes[1].summary.distance", is(6435))
.body("routes[1].summary.duration", is(801.5f))
.statusCode(200);
}

}

59 changes: 29 additions & 30 deletions openrouteservice/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -165,36 +165,37 @@
</plugins>
</build>

<repositories>
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net repository</name>
<url>http://download.java.net/maven/2</url>
</repository>
<repository>
<id>bintray-nitram509-jbrotli</id>
<name>bintray</name>
<url>http://dl.bintray.com/nitram509/jbrotli</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>osgeo</id>
<name>Open Source Geospatial Foundation Repository</name>
<url>http://download.osgeo.org/webdav/geotools/</url>
</repository>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>opengeo</id>
<name>OpenGeo Maven Repository</name>
<url>http://repo.boundlessgeo.com/main </url>
</repository>
<repositories>
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net repository</name>
<url>http://download.java.net/maven/2</url>
</repository>
<repository>
<id>bintray-nitram509-jbrotli</id>
<name>bintray</name>
<url>http://dl.bintray.com/nitram509/jbrotli</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>osgeo</id>
<name>Open Source Geospatial Foundation Repository</name>
<url>http://download.osgeo.org/webdav/geotools/</url>
</repository>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>opengeo</id>
<name>OpenGeo Maven Repository</name>
<url>http://repo.boundlessgeo.com/main </url>
</repository>
</repositories>


<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
Expand Down Expand Up @@ -269,7 +270,6 @@
<version>3.0.3</version>
</dependency>


<dependency>
<groupId>com.github.GIScience.graphhopper</groupId>
<artifactId>graphhopper-core</artifactId>
Expand All @@ -282,7 +282,6 @@
<version>v0.10.1.12</version>
</dependency>


<!-- remove the comment to enable debugging
<dependency>
<groupId>com.graphhopper</groupId>
Expand Down
152 changes: 91 additions & 61 deletions openrouteservice/src/main/java/heigit/ors/routing/RouteResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,123 +14,109 @@
package heigit.ors.routing;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.graphhopper.util.PointList;
import com.graphhopper.util.shapes.BBox;
import com.vividsolutions.jts.geom.Coordinate;
import heigit.ors.common.DistanceUnit;
import heigit.ors.util.FormatUtility;
import heigit.ors.util.GeomUtility;

public class RouteResult
{
private RouteSummary _summary;
private Coordinate[] _geometry;
private List<RouteSegment> _segments;
private List<RouteExtraInfo> _extraInfo;
private int[] _wayPointsIndices = null;
private int _locationIndex = 0;
private RouteSummary summary;
private Coordinate[] geometry;
private List<RouteSegment> segments;
private List<RouteExtraInfo> extraInfo;
private List<Integer> wayPointsIndices;
private List<RouteWarning> routeWarnings;
private PointList pointlist;

public RouteResult(int routeExtras) throws Exception
{
_segments = new ArrayList<RouteSegment>();
_summary = new RouteSummary();

public RouteResult(int routeExtras) {
segments = new ArrayList<>();
summary = new RouteSummary();
if (routeExtras != 0)
_extraInfo = new ArrayList<RouteExtraInfo>();

extraInfo = new ArrayList<>();
routeWarnings = new ArrayList<>();
wayPointsIndices = new ArrayList<>();
}

public void addSegment(RouteSegment seg)
{
_segments.add(seg);
segments.add(seg);
}

public List<RouteSegment> getSegments()
{
return _segments;
return segments;
}

public RouteSummary getSummary()
{
return _summary;
return summary;
}

public Coordinate[] getGeometry() {
return _geometry;
return geometry;
}

public void addPoints(PointList points, boolean skipFirstPoint, boolean includeElevation)
public void addPointsToGeometry(PointList points, boolean skipFirstPoint, boolean includeElevation)
{
int index = skipFirstPoint ? 1 : 0;

if (_geometry == null)
if (geometry == null)
{
int newSize = points.size() - index;
_geometry = new Coordinate[newSize];
geometry = new Coordinate[newSize];

if (includeElevation && points.is3D())
{
for (int i = index; i < newSize; ++i)
_geometry[i] = new Coordinate(points.getLon(i), points.getLat(i), points.getEle(i));
geometry[i] = new Coordinate(points.getLon(i), points.getLat(i), points.getEle(i));
}
else
{
for (int i= index; i < newSize; ++i)
_geometry[i] = new Coordinate(points.getLon(i), points.getLat(i));
geometry[i] = new Coordinate(points.getLon(i), points.getLat(i));
}
}
else
{
int oldSize = _geometry.length;
int oldSize = geometry.length;
int pointsSize = points.size() - index;
int newSize = oldSize + pointsSize;
Coordinate[] coords = new Coordinate[newSize];

for (int i = 0; i < oldSize; i++)
coords[i] = _geometry[i];
for (int i = 0; i < oldSize; i++) {
coords[i] = geometry[i];
}

if (includeElevation && points.is3D())
{
for (int i = 0; i < pointsSize; ++i)
{
int j = i + index;
for (int i = 0; i < pointsSize; ++i) {
int j = i + index;
if (includeElevation && points.is3D())
coords[oldSize + i] = new Coordinate(points.getLon(j), points.getLat(j), points.getEle(j));
}
}
else
{
for (int i = 0; i < pointsSize; ++i)
{
int j = i + index;
else
coords[oldSize + i] = new Coordinate(points.getLon(j), points.getLat(j));
}
}
_geometry = coords;

geometry = coords;
}
}


public List<RouteExtraInfo> getExtraInfo()
{
return _extraInfo;
return extraInfo;
}

public void addExtraInfo(RouteExtraInfo info)
private void addExtraInfo(RouteExtraInfo info)
{
if(_extraInfo == null)
_extraInfo = new ArrayList<>();
_extraInfo.add(info);
if(extraInfo == null)
extraInfo = new ArrayList<>();
extraInfo.add(info);
}

public void addExtraInfo(Collection<RouteExtraInfo> infos)
{
if(_extraInfo == null)
_extraInfo = new ArrayList<>();
_extraInfo.addAll(infos);
}

public void addWarning(RouteWarning warning) {
routeWarnings.add(warning);
}
Expand All @@ -139,19 +125,63 @@ public List<RouteWarning> getWarnings() {
return routeWarnings;
}

public int[] getWayPointsIndices() {
return _wayPointsIndices;
public void addPointlist(PointList pointlistToAdd) {
if (pointlist == null) {
pointlist = pointlistToAdd;
} else {
pointlist.add(pointlistToAdd);
}
}

public List<Integer> getWayPointsIndices() {
return wayPointsIndices;
}

public void setWayPointsIndices(int[] wayPointsIndices) {
_wayPointsIndices = wayPointsIndices;
public void addWayPointIndex(int index) {
wayPointsIndices.add(index);
}

public int getLocationIndex() {
return _locationIndex;
void addExtras(RoutingRequest request, List<RouteExtraInfo> extras) {
if (extras == null)
return;
// add the extras if they generate a "warning" or they were requested
for (RouteExtraInfo extra : extras) {
if (extra.isUsedForWarnings() && extra.getWarningGraphExtension().generatesWarning(extra)) {
addWarning(extra.getWarningGraphExtension().getWarning());
addExtraInfo(extra);
} else if (RouteExtraInfoFlag.isSet(request.getExtraInfo(), RouteExtraInfoFlag.getFromString(extra.getName()))) {
addExtraInfo(extra);
}
}
}

public void setLocationIndex(int locationIndex) {
_locationIndex = locationIndex;
/**
* set route summary values according to segments in this route and request parameters
* @param request for parameter lookup (consider traffic, units, include elevation)
*/
void calculateRouteSummary(RoutingRequest request) {
double distance = 0.0;
double duration = 0.0;
for (RouteSegment seg : getSegments()) {
distance += seg.getDistance();
duration += request.getSearchParameters().getConsiderTraffic() ? seg.getDurationTraffic() : seg.getDuration();
}
summary.setDuration(duration);
summary.setDistance(FormatUtility.roundToDecimalsForUnits(distance, request.getUnits()));
double averageSpeed = 0;
if (duration > 0)
averageSpeed = distance / (request.getUnits() == DistanceUnit.Meters ? 1000 : 1) / (duration / 3600);
summary.setAverageSpeed(FormatUtility.roundToDecimals(averageSpeed, 1));
summary.setBBox(GeomUtility.calculateBoundingBox(pointlist));
if (request.getIncludeElevation()) {
double ascent = 0.0;
double descent = 0.0;
for (RouteSegment seg : getSegments()) {
ascent += seg.getAscent();
descent += seg.getDescent();
}
summary.setAscent(FormatUtility.roundToDecimals(ascent, 1));
summary.setDescent(FormatUtility.roundToDecimals(descent, 1));
}
}
}
Loading