Skip to content

Commit

Permalink
feature-#349 list traversal countries
Browse files Browse the repository at this point in the history
  • Loading branch information
Julian Psotta committed May 8, 2019
1 parent 8f967aa commit 404a60d
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ public enum ExtraInfo {
TOLLWAYS("tollways"),
TRAIL_DIFFICULTY("traildifficulty"),
OSM_ID("osmid"),
ROAD_ACCESS_RESTRICTIONS("roadaccessrestrictions");
ROAD_ACCESS_RESTRICTIONS("roadaccessrestrictions"),
COUNTRY_INFO("countryinfo");

private final String value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class RouteExtraInfoFlag {
public static final int TrailDifficulty = 512;
public static final int OsmId = 1024;
public static final int RoadAccessRestrictions = 2048;
public static final int CountryInfo = 4096;

public static boolean isSet(int extraInfo, int value) {
return (extraInfo & value) == value;
Expand Down Expand Up @@ -77,6 +78,8 @@ public static int getFromString(String value) {
break;
case "roadaccessrestrictions":
res |= RoadAccessRestrictions;
case "countryinfo":
res |= CountryInfo;
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import heigit.ors.matrix.MatrixResult;
import heigit.ors.routing.configuration.RouteProfileConfiguration;
import heigit.ors.routing.configuration.RoutingManagerConfiguration;
import heigit.ors.routing.graphhopper.extensions.reader.borders.CountryBordersReader;
import heigit.ors.routing.pathprocessors.ElevationSmoothPathProcessor;
import heigit.ors.routing.pathprocessors.ExtraInfoProcessor;
import heigit.ors.routing.traffic.RealTrafficDataProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
*/
package heigit.ors.routing.graphhopper.extensions.reader.borders;

import com.graphhopper.util.PointList;
import com.graphhopper.util.shapes.GHPoint3D;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
Expand Down Expand Up @@ -381,6 +383,18 @@ public static int getCountryIdByISOCode(String code) {
return currentInstance != null ? currentInstance.isoCodes.getOrDefault(code.toUpperCase(), 0) : 0;
}

public static CountryBordersPolygon[] getCountriesByPointList(PointList pointList) {
CountryBordersPolygon[] countries = new CountryBordersPolygon[0];
for (GHPoint3D point :
pointList) {
Coordinate coordinate = new Coordinate(point.lon, point.lat);
CountryBordersPolygon[] countries2 = currentInstance.getCandidateCountry(coordinate);
CountryBordersPolygon[] countries23 = currentInstance.getCandidateCountry(coordinate);

}
return countries;
}

/**
* Read information from the id csv. This includes a unique identifier, the local name of the country and the
* English name of the country. Optionally reads ISO codes from column 4 and 5 (expecting them to contain the
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
/* This file is part of Openrouteservice.
*
* Openrouteservice 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 2.1
* Openrouteservice 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 2.1
* 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.
* 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 <https://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Lesser General Public License along with this library;
* if not, see <https://www.gnu.org/licenses/>.
*/
package heigit.ors.routing.graphhopper.extensions.storages;

Expand All @@ -19,16 +19,22 @@
import com.graphhopper.storage.GraphExtension;
import com.graphhopper.storage.RAMDirectory;

import org.apache.log4j.Logger;

/**
* Graph storage class for the Border Restriction routing
*/
public class BordersGraphStorage implements GraphExtension {
public enum Property { TYPE, START, END };
private static final Logger LOGGER = Logger.getLogger(BordersGraphStorage.class.getName());

public enum Property { TYPE, START, END, COUNTRY1, COUNTRY2}
/* pointer for no entry */
protected final int NO_ENTRY = -1;
private final int EF_BORDER = 0; // byte location of border type
private final int EF_START = 2; // byte location of the start country id
private final int EF_END = 4; // byte location of the end country id
private final int EF_COUNTRY_1 = 8; // byte location of the first country id
private final int EF_COUNTRY_2 = 16; // byte location of the second country id

// border types
public static final short NO_BORDER = 0;
Expand All @@ -40,7 +46,6 @@ public enum Property { TYPE, START, END };
private int edgesCount; // number of edges with custom values

public BordersGraphStorage() {
//EF_BORDER = 0;

int edgeEntryIndex = 0;
edgeEntryBytes = edgeEntryIndex + 6; // item uses 3 short values which are 2 bytes length each
Expand All @@ -52,13 +57,14 @@ public BordersGraphStorage() {
*
* This method takes the internal ID of the edge and adds the information obtained from the Borders CSV file to it
* so that the values can be taken into account when generating a route.
*
* @param edgeId Internal ID of the graph edge
* @param borderType Level of border crossing (0 - No border, 1 - controlled border, 2 - open border=
* @param start ID of the country that the edge starts in
* @param end ID of the country that the edge ends in
* @param edgeId Internal ID of the graph edge
* @param borderType Level of border crossing (0 - No border, 1 - controlled border, 2 - open border=
* @param start ID of the country that the edge starts in
* @param end ID of the country that the edge ends in
* @param country1
* @param country2
*/
public void setEdgeValue(int edgeId, short borderType, short start, short end) {
public void setEdgeValue(int edgeId, short borderType, short start, short end, short country1, short country2) {
edgesCount++;
ensureEdgesIndex(edgeId);

Expand All @@ -68,35 +74,47 @@ public void setEdgeValue(int edgeId, short borderType, short start, short end) {
orsEdges.setShort(edgePointer + EF_BORDER, borderType);
orsEdges.setShort(edgePointer + EF_START, start);
orsEdges.setShort(edgePointer + EF_END, end);
orsEdges.setShort(edgePointer + EF_COUNTRY_1, country1);
orsEdges.setShort(edgePointer + EF_COUNTRY_2, country2);
}

private void ensureEdgesIndex(int edgeId) { orsEdges.ensureCapacity(((long) edgeId + 1) * edgeEntryBytes); }

/**
* Get the specified custom value of the edge that was assigned to it in the setValueEdge method<br/><br/>
*
* <p>
* The method takes an identifier to the edge and then gets the requested value for the edge from the storage
*
* @param edgeId Internal ID of the edge to get values for
* @param prop The property of the edge to get (TYPE - border type (0,1,2), START - the ID of the country
* the edge starts in, END - the ID of the country the edge ends in.
* @return The value of the requested property
* @param edgeId Internal ID of the edge to get values for
* @param prop The property of the edge to get (TYPE - border type (0,1,2), START - the ID of the country
* the edge starts in, END - the ID of the country the edge ends in.
* @return The value of the requested property
*/
public short getEdgeValue(int edgeId, Property prop) {
// TODO maybe implement a second function that accesses only the country data
long edgePointer = (long) edgeId * edgeEntryBytes;
short border = 0, start = 0, end = 0;
short border;
short start;
short end;
short country1;
short country2;
border = orsEdges.getShort(edgePointer + EF_BORDER);
start = orsEdges.getShort(edgePointer + EF_START);
end = orsEdges.getShort(edgePointer + EF_END);
country1 = orsEdges.getShort(edgePointer + EF_COUNTRY_1);
country2 = orsEdges.getShort(edgePointer + EF_COUNTRY_2);

switch (prop) {
case TYPE:

return border;
case START:
return start;
case END:
return end;
case COUNTRY1:
return country1;
case COUNTRY2:
return country2;
default:
return 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Point;
import heigit.ors.exceptions.MissingConfigParameterException;
import heigit.ors.routing.graphhopper.extensions.reader.borders.CountryBordersPolygon;
import heigit.ors.routing.graphhopper.extensions.reader.borders.CountryBordersReader;
Expand Down Expand Up @@ -126,6 +125,10 @@ public void processWay(ReaderWay way, Coordinate[] coords, HashMap<Integer, Hash
if (countries.length > 1 && !countries[0].equals(countries[1])) {
way.setTag("country1", countries[0]);
way.setTag("country2", countries[1]);
} else if (countries.length == 1 && !countries[0].isEmpty()) {
way.setTag("country1", countries[0]);
} else if (countries.length == 1 && countries[0].isEmpty()){
way.setTag("country2", countries[1]);
}
}
}
Expand All @@ -139,35 +142,46 @@ public void processWay(ReaderWay way, Coordinate[] coords, HashMap<Integer, Hash
* @param way The OSM way obtained from the OSM reader. This way corresponds to the edge to be processed
* @param edge The graph edge to be process
*/
@Override
public void processEdge(ReaderWay way, EdgeIteratorState edge) {
// Make sure we actually have the storage initialised - if there were errors accessing the data then this could be the case
if(_storage != null) {
// If there is no border crossing then we set the edge value to be 0

// First get the start and end countries - if either of these is empty, then there is no crossing
if (way.hasTag("country1") && way.hasTag("country2")) {
String startVal = way.getTag("country1");
String endVal = way.getTag("country2");

// Lookup values
short start = 0, end = 0;

try {
start = Short.parseShort(cbReader.getId(startVal));
end = Short.parseShort(cbReader.getId(endVal));
} catch (NumberFormatException nfe) {
LOGGER.error("Error in lookup for ids " + startVal + " and " + endVal);
}

short type = (cbReader.isOpen(cbReader.getEngName(startVal), cbReader.getEngName(endVal))) ? (short) 2 : (short) 1;

_storage.setEdgeValue(edge.getEdge(), type, start, end);
} else {
_storage.setEdgeValue(edge.getEdge(), (short) 0, (short) 0, (short) 0);
}
}
}
@Override
public void processEdge(ReaderWay way, EdgeIteratorState edge) {
// Make sure we actually have the storage initialised - if there were errors accessing the data then this could be the case
if (_storage != null) {
// If there is no border crossing then we set the edge value to be 0

// First get the start and end countries - if either of these is empty, then there is no crossing
short country1 = 0;
short country2 = 0;
if (way.hasTag("country1") && way.hasTag("country2")) {
String startVal = way.getTag("country1");
String endVal = way.getTag("country2");
// Lookup values
short start = 0;
short end = 0;
try {
start = Short.parseShort(cbReader.getId(startVal));
end = Short.parseShort(cbReader.getId(endVal));
country1 = Short.parseShort(cbReader.getId(startVal));
country2 = Short.parseShort(cbReader.getId(endVal));
} catch (NumberFormatException nfe) {
LOGGER.error("Error in lookup for ids " + startVal + " and " + endVal);
}
// Todo add add three extra bits to the edge value relating the country
short type = (cbReader.isOpen(cbReader.getEngName(startVal), cbReader.getEngName(endVal))) ? (short) 2 : (short) 1;

_storage.setEdgeValue(edge.getEdge(), type, start, end, country1, country2);
} else if (way.hasTag("country1")) {
String startVal = way.getTag("country1");
try {
country1 = Short.parseShort(cbReader.getId(startVal));
} catch (NumberFormatException nfe) {
LOGGER.error("Error in lookup for ids " + startVal);
}
_storage.setEdgeValue(edge.getEdge(), (short) 0, (short) 0, (short) 0, country1, country2);
} else {
_storage.setEdgeValue(edge.getEdge(), (short) 0, (short) 0, (short) 0, country1, country2);
}
}
}

/**
* Method identifying the name of the extension which is used in various building processes
Expand Down Expand Up @@ -257,6 +271,9 @@ public String[] findBorderCrossing(Coordinate[] coords) {
// Replace the arraylist
countries = temp;
}
// if (countries.size() > 2){
// countries = countries;
// }
// Now we have a list of all the countries that the nodes are in - if this is more than one it is likely it is
// crossing a border, but not certain as in some disputed areas, countries overlap and so it may not cross any
// border.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@
import heigit.ors.routing.util.extrainfobuilders.RouteExtraInfoBuilder;
import heigit.ors.routing.util.extrainfobuilders.SimpleRouteExtraInfoBuilder;
import heigit.ors.routing.util.extrainfobuilders.SteepnessExtraInfoBuilder;
import org.apache.log4j.Logger;

import java.util.*;

public class ExtraInfoProcessor extends PathProcessor {
private static final Logger LOGGER = Logger.getLogger(BordersGraphStorage.class.getName());

private WaySurfaceTypeGraphStorage _extWaySurface;
private WayCategoryGraphStorage _extWayCategory;
private GreenIndexGraphStorage _extGreenIndex;
Expand All @@ -42,7 +45,8 @@ public class ExtraInfoProcessor extends PathProcessor {
private HillIndexGraphStorage _extHillIndex;
private OsmIdGraphStorage _extOsmId;
private RoadAccessRestrictionsGraphStorage _extRoadAccessRestrictions;

private BordersGraphStorage _extCountryTraversalInfo;

private RouteExtraInfo _surfaceInfo;
private RouteExtraInfoBuilder _surfaceInfoBuilder;

Expand Down Expand Up @@ -80,6 +84,9 @@ public class ExtraInfoProcessor extends PathProcessor {
private RouteExtraInfo _roadAccessRestrictionsInfo;
private RouteExtraInfoBuilder _roadAccessRestrictionsBuilder;

private RouteExtraInfo _countryTraversalInfo;
private RouteExtraInfoBuilder _countryTraversalBuilder;

private List<Integer> warningExtensions;

private int _profileType = RoutingProfileType.UNKNOWN;
Expand Down Expand Up @@ -204,7 +211,14 @@ public ExtraInfoProcessor(ORSGraphHopper graphHopper, RoutingRequest req) throws
_roadAccessRestrictionsInfo = new RouteExtraInfo("roadaccessrestrictions", _extRoadAccessRestrictions);
_roadAccessRestrictionsBuilder = new SimpleRouteExtraInfoBuilder(_roadAccessRestrictionsInfo);
}

boolean yes = true;
if (yes) {
_extCountryTraversalInfo = GraphStorageUtils.getGraphExtension(graphHopper.getGraphHopperStorage(), BordersGraphStorage.class);
if(_extCountryTraversalInfo == null)
throw new Exception("BordersGraphStorage is not found");
_countryTraversalInfo = new RouteExtraInfo("countryinfo", _extCountryTraversalInfo);
_countryTraversalBuilder = new SimpleRouteExtraInfoBuilder(_countryTraversalInfo);
}
buffer = new byte[4];
}

Expand Down Expand Up @@ -276,13 +290,40 @@ public List<RouteExtraInfo> getExtras()
extras.add(_osmIdInfo);
if (_roadAccessRestrictionsInfo != null)
extras.add(_roadAccessRestrictionsInfo);
if (_countryTraversalInfo != null)
extras.add(_countryTraversalInfo);
return extras;
}

@Override
public void processEdge(EdgeIteratorState edge, boolean isLastEdge, PointList geom) {
double dist = edge.getDistance();
short country1;
short country2;

// TODO Add extra info for crossed countries
if (_extCountryTraversalInfo != null){
country1 = _extCountryTraversalInfo.getEdgeValue(EdgeIteratorStateHelper.getOriginalEdge(edge), BordersGraphStorage.Property.COUNTRY1);
country2 = _extCountryTraversalInfo.getEdgeValue(EdgeIteratorStateHelper.getOriginalEdge(edge), BordersGraphStorage.Property.COUNTRY2);
if (country1 != 0)
LOGGER.info("country1: " + country1);
else
LOGGER.info("");

if (country2 != 0)
LOGGER.info("country2: " + country2);
else
LOGGER.info("");
if (_countryTraversalBuilder != null && country2 == 0) {
_countryTraversalBuilder.addSegment(country1, country1, geom, dist, isLastEdge && _lastSegment);
}
if (_countryTraversalBuilder != null && country2 != 0) {
int integer = Integer.parseInt(country1 + String.valueOf(0) + country2);
_countryTraversalBuilder.addSegment(integer, integer, geom, dist, isLastEdge && _lastSegment);

}

}
if (_extWaySurface != null && _wayTypeInfo != null || _surfaceInfo != null)
{
WaySurfaceDescription wsd = _extWaySurface.getEdgeValue(EdgeIteratorStateHelper.getOriginalEdge(edge), buffer);
Expand Down
Loading

0 comments on commit 404a60d

Please sign in to comment.