Skip to content

Commit e3c83dc

Browse files
authored
Remove DataReader interface, stop using GraphHopperOSM (graphhopper#2233)
1 parent 67b400f commit e3c83dc

File tree

25 files changed

+227
-418
lines changed

25 files changed

+227
-418
lines changed

core/src/main/java/com/graphhopper/GraphHopper.java

Lines changed: 81 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
import com.graphhopper.config.CHProfile;
2121
import com.graphhopper.config.LMProfile;
2222
import com.graphhopper.config.Profile;
23-
import com.graphhopper.reader.DataReader;
2423
import com.graphhopper.reader.dem.*;
24+
import com.graphhopper.reader.osm.OSMReader;
2525
import com.graphhopper.reader.osm.conditional.DateRangeParser;
2626
import com.graphhopper.routing.DefaultWeightingFactory;
2727
import com.graphhopper.routing.Router;
@@ -35,6 +35,7 @@
3535
import com.graphhopper.routing.lm.LMConfig;
3636
import com.graphhopper.routing.lm.LMPreparationHandler;
3737
import com.graphhopper.routing.lm.LandmarkStorage;
38+
import com.graphhopper.routing.lm.PrepareLandmarks;
3839
import com.graphhopper.routing.subnetwork.PrepareRoutingSubnetworks;
3940
import com.graphhopper.routing.subnetwork.PrepareRoutingSubnetworks.PrepareJob;
4041
import com.graphhopper.routing.util.DefaultFlagEncoderFactory;
@@ -43,6 +44,9 @@
4344
import com.graphhopper.routing.util.FlagEncoderFactory;
4445
import com.graphhopper.routing.util.parsers.DefaultTagParserFactory;
4546
import com.graphhopper.routing.util.parsers.TagParserFactory;
47+
import com.graphhopper.routing.util.spatialrules.AbstractSpatialRule;
48+
import com.graphhopper.routing.util.spatialrules.SpatialRuleLookup;
49+
import com.graphhopper.routing.util.spatialrules.SpatialRuleLookupBuilder;
4650
import com.graphhopper.routing.weighting.DefaultTurnCostProvider;
4751
import com.graphhopper.routing.weighting.TurnCostProvider;
4852
import com.graphhopper.routing.weighting.Weighting;
@@ -101,13 +105,15 @@ public class GraphHopper implements GraphHopperAPI {
101105
private int maxRegionSearch = 4;
102106
// for prepare
103107
private int minNetworkSize = 200;
108+
// for LM
109+
private final JsonFeatureCollection landmarkSplittingFeatureCollection;
104110

105111
// preparation handlers
106112
private final LMPreparationHandler lmPreparationHandler = new LMPreparationHandler();
107113
private final CHPreparationHandler chPreparationHandler = new CHPreparationHandler();
108114

109115
// for data reader
110-
private String dataReaderFile;
116+
private String osmFile;
111117
private double dataReaderWayPointMaxDistance = 1;
112118
private int dataReaderWorkerThreads = 2;
113119
private ElevationProvider eleProvider = ElevationProvider.NOOP;
@@ -117,6 +123,11 @@ public class GraphHopper implements GraphHopperAPI {
117123
private PathDetailsBuilderFactory pathBuilderFactory = new PathDetailsBuilderFactory();
118124

119125
public GraphHopper() {
126+
this(null);
127+
}
128+
129+
public GraphHopper(JsonFeatureCollection landmarkSplittingFeatureCollection) {
130+
this.landmarkSplittingFeatureCollection = landmarkSplittingFeatureCollection;
120131
}
121132

122133
/**
@@ -322,19 +333,19 @@ public GraphHopper setGraphHopperLocation(String ghLocation) {
322333
}
323334

324335
public String getDataReaderFile() {
325-
return dataReaderFile;
336+
return osmFile;
326337
}
327338

328339
/**
329-
* This file can be any file type supported by the DataReader. E.g. for the OSMReader it is the
330-
* OSM xml (.osm), a compressed xml (.osm.zip or .osm.gz) or a protobuf file (.pbf)
340+
* This file can be an osm xml (.osm), a compressed xml (.osm.zip or .osm.gz) or a protobuf file
341+
* (.pbf).
331342
*/
332-
public GraphHopper setDataReaderFile(String dataReaderFileStr) {
343+
public GraphHopper setDataReaderFile(String osmFile) {
333344
ensureNotLoaded();
334-
if (isEmpty(dataReaderFileStr))
335-
throw new IllegalArgumentException("Data reader file cannot be empty.");
345+
if (isEmpty(osmFile))
346+
throw new IllegalArgumentException("OSM file cannot be empty.");
336347

337-
dataReaderFile = dataReaderFileStr;
348+
this.osmFile = osmFile;
338349
return this;
339350
}
340351

@@ -430,14 +441,14 @@ public GraphHopper init(GraphHopperConfig ghConfig) {
430441

431442
String tmpOsmFile = ghConfig.getString("datareader.file", "");
432443
if (!isEmpty(tmpOsmFile))
433-
dataReaderFile = tmpOsmFile;
444+
osmFile = tmpOsmFile;
434445

435446
String graphHopperFolder = ghConfig.getString("graph.location", "");
436447
if (isEmpty(graphHopperFolder) && isEmpty(ghLocation)) {
437-
if (isEmpty(dataReaderFile))
448+
if (isEmpty(osmFile))
438449
throw new IllegalArgumentException("If no graph.location is provided you need to specify an OSM file.");
439450

440-
graphHopperFolder = pruneFileEnd(dataReaderFile) + "-gh";
451+
graphHopperFolder = pruneFileEnd(osmFile) + "-gh";
441452
}
442453

443454
// graph
@@ -604,72 +615,59 @@ public void importAndClose() {
604615
/**
605616
* Creates the graph from OSM data.
606617
*/
607-
private GraphHopper process(String graphHopperLocation, boolean closeEarly) {
618+
private void process(String graphHopperLocation, boolean closeEarly) {
608619
setGraphHopperLocation(graphHopperLocation);
609620
GHLock lock = null;
610621
try {
622+
if (ghStorage == null)
623+
throw new IllegalStateException("GraphHopperStorage must be initialized before starting the import");
611624
if (ghStorage.getDirectory().getDefaultType().isStoring()) {
612625
lockFactory.setLockDir(new File(graphHopperLocation));
613626
lock = lockFactory.create(fileLockName, true);
614627
if (!lock.tryLock())
615628
throw new RuntimeException("To avoid multiple writers we need to obtain a write lock but it failed. In " + graphHopperLocation, lock.getObtainFailedReason());
616629
}
617-
618-
readData();
630+
ensureWriteAccess();
631+
importOSM();
619632
cleanUp();
620633
postProcessing(closeEarly);
621634
flush();
622635
} finally {
623636
if (lock != null)
624637
lock.release();
625638
}
626-
return this;
627-
}
628-
629-
private void readData() {
630-
try {
631-
DataReader reader = importData();
632-
DateFormat f = createFormatter();
633-
ghStorage.getProperties().put("datareader.import.date", f.format(new Date()));
634-
if (reader.getDataDate() != null)
635-
ghStorage.getProperties().put("datareader.data.date", f.format(reader.getDataDate()));
636-
} catch (IOException ex) {
637-
throw new RuntimeException("Cannot read file " + getDataReaderFile(), ex);
638-
}
639639
}
640640

641-
protected DataReader importData() throws IOException {
642-
ensureWriteAccess();
643-
if (ghStorage == null)
644-
throw new IllegalStateException("Load graph before importing OSM data");
645-
646-
if (dataReaderFile == null)
641+
protected void importOSM() {
642+
if (osmFile == null)
647643
throw new IllegalStateException("Couldn't load from existing folder: " + ghLocation
648644
+ " but also cannot use file for DataReader as it wasn't specified!");
649645

650-
DataReader reader = createReader(ghStorage);
651-
logger.info("using " + ghStorage.toString() + ", memory:" + getMemInfo());
652-
reader.readGraph();
653-
return reader;
654-
}
655-
656-
protected DataReader createReader(GraphHopperStorage ghStorage) {
657-
throw new UnsupportedOperationException("Cannot create DataReader. Solutions: avoid import via calling load directly, "
658-
+ "provide a DataReader or use e.g. GraphHopperOSM or a different subclass");
659-
}
660-
661-
protected DataReader initDataReader(DataReader reader) {
662-
if (dataReaderFile == null)
663-
throw new IllegalArgumentException("No file for DataReader specified");
664-
665-
logger.info("start creating graph from " + dataReaderFile);
666-
return reader.setFile(new File(dataReaderFile)).
646+
logger.info("start creating graph from " + osmFile);
647+
OSMReader reader = new OSMReader(ghStorage).setFile(_getOSMFile()).
667648
setElevationProvider(eleProvider).
668649
setWorkerThreads(dataReaderWorkerThreads).
669650
setWayPointMaxDistance(dataReaderWayPointMaxDistance).
670651
setWayPointElevationMaxDistance(routerConfig.getElevationWayPointMaxDistance()).
671652
setSmoothElevation(smoothElevation).
672653
setLongEdgeSamplingDistance(longEdgeSamplingDistance);
654+
logger.info("using " + ghStorage.toString() + ", memory:" + getMemInfo());
655+
try {
656+
reader.readGraph();
657+
} catch (IOException ex) {
658+
throw new RuntimeException("Cannot read file " + getDataReaderFile(), ex);
659+
}
660+
DateFormat f = createFormatter();
661+
ghStorage.getProperties().put("datareader.import.date", f.format(new Date()));
662+
if (reader.getDataDate() != null)
663+
ghStorage.getProperties().put("datareader.data.date", f.format(reader.getDataDate()));
664+
}
665+
666+
/**
667+
* Currently we use this for a few tests where the dataReaderFile is loaded from the classpath
668+
*/
669+
protected File _getOSMFile() {
670+
return new File(osmFile);
673671
}
674672

675673
/**
@@ -1045,23 +1043,41 @@ protected void prepareCH(boolean closeEarly) {
10451043
* For landmarks it is required to always call this method: either it creates the landmark data or it loads it.
10461044
*/
10471045
protected void loadOrPrepareLM(boolean closeEarly) {
1048-
boolean tmpPrepare = lmPreparationHandler.isEnabled() && !lmPreparationHandler.getPreparations().isEmpty();
1049-
if (tmpPrepare) {
1050-
for (LMProfile profile : lmPreparationHandler.getLMProfiles()) {
1051-
if (!getProfileVersion(profile.getProfile()).isEmpty()
1052-
&& !getProfileVersion(profile.getProfile()).equals("" + profilesByName.get(profile.getProfile()).getVersion()))
1053-
throw new IllegalArgumentException("LM preparation of " + profile.getProfile() + " already exists in storage and doesn't match configuration");
1054-
}
1055-
ensureWriteAccess();
1056-
ghStorage.freeze();
1057-
if (lmPreparationHandler.loadOrDoWork(ghStorage.getProperties(), closeEarly)) {
1058-
ghStorage.getProperties().put(Landmark.PREPARE + "done", true);
1059-
for (LMProfile profile : lmPreparationHandler.getLMProfiles()) {
1060-
// potentially overwrite existing keys from CH
1061-
setProfileVersion(profile.getProfile(), profilesByName.get(profile.getProfile()).getVersion());
1046+
if (!lmPreparationHandler.isEnabled() || lmPreparationHandler.getPreparations().isEmpty()) {
1047+
return;
1048+
}
1049+
1050+
if (landmarkSplittingFeatureCollection != null && !landmarkSplittingFeatureCollection.getFeatures().isEmpty()) {
1051+
SpatialRuleLookup ruleLookup = SpatialRuleLookupBuilder.buildIndex(
1052+
Collections.singletonList(landmarkSplittingFeatureCollection), "area",
1053+
(id, polygons) -> new AbstractSpatialRule(polygons) {
1054+
@Override
1055+
public String getId() {
1056+
return id;
1057+
}
1058+
});
1059+
for (PrepareLandmarks prep : getLMPreparationHandler().getPreparations()) {
1060+
// the ruleLookup splits certain areas from each other but avoids making this a permanent change so that other algorithms still can route through these regions.
1061+
if (ruleLookup != null && !ruleLookup.getRules().isEmpty()) {
1062+
prep.setSpatialRuleLookup(ruleLookup);
10621063
}
10631064
}
10641065
}
1066+
1067+
for (LMProfile profile : lmPreparationHandler.getLMProfiles()) {
1068+
if (!getProfileVersion(profile.getProfile()).isEmpty()
1069+
&& !getProfileVersion(profile.getProfile()).equals("" + profilesByName.get(profile.getProfile()).getVersion()))
1070+
throw new IllegalArgumentException("LM preparation of " + profile.getProfile() + " already exists in storage and doesn't match configuration");
1071+
}
1072+
ensureWriteAccess();
1073+
ghStorage.freeze();
1074+
if (lmPreparationHandler.loadOrDoWork(ghStorage.getProperties(), closeEarly)) {
1075+
ghStorage.getProperties().put(Landmark.PREPARE + "done", true);
1076+
for (LMProfile profile : lmPreparationHandler.getLMProfiles()) {
1077+
// potentially overwrite existing keys from CH
1078+
setProfileVersion(profile.getProfile(), profilesByName.get(profile.getProfile()).getVersion());
1079+
}
1080+
}
10651081
}
10661082

10671083
/**

core/src/main/java/com/graphhopper/reader/DataReader.java

Lines changed: 0 additions & 55 deletions
This file was deleted.

core/src/main/java/com/graphhopper/reader/osm/OSMReader.java

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
*
6565
* @author Peter Karich
6666
*/
67-
public class OSMReader implements DataReader, TurnCostParser.ExternalInternalMap {
67+
public class OSMReader implements TurnCostParser.ExternalInternalMap {
6868
protected static final int EMPTY_NODE = -1;
6969
// pillar node is >= 3
7070
protected static final int PILLAR_NODE = 1;
@@ -127,7 +127,6 @@ public OSMReader(GraphHopperStorage ghStorage) {
127127
tcs = graph.getTurnCostStorage();
128128
}
129129

130-
@Override
131130
public void readGraph() throws IOException {
132131
if (encodingManager == null)
133132
throw new IllegalStateException("Encoding manager was not set.");
@@ -918,38 +917,32 @@ void putRelFlagsMap(long osmId, IntsRef relFlags) {
918917
osmWayIdToRouteWeightMap.put(osmId, relFlagsAsLong);
919918
}
920919

921-
@Override
922920
public OSMReader setWayPointMaxDistance(double maxDist) {
923921
doSimplify = maxDist > 0;
924922
simplifyAlgo.setMaxDistance(maxDist);
925923
return this;
926924
}
927925

928-
@Override
929-
public DataReader setWayPointElevationMaxDistance(double elevationWayPointMaxDistance) {
926+
public OSMReader setWayPointElevationMaxDistance(double elevationWayPointMaxDistance) {
930927
simplifyAlgo.setElevationMaxDistance(elevationWayPointMaxDistance);
931928
return this;
932929
}
933930

934-
@Override
935-
public DataReader setSmoothElevation(boolean smoothElevation) {
931+
public OSMReader setSmoothElevation(boolean smoothElevation) {
936932
this.smoothElevation = smoothElevation;
937933
return this;
938934
}
939935

940-
@Override
941-
public DataReader setLongEdgeSamplingDistance(double longEdgeSamplingDistance) {
936+
public OSMReader setLongEdgeSamplingDistance(double longEdgeSamplingDistance) {
942937
this.longEdgeSamplingDistance = longEdgeSamplingDistance;
943938
return this;
944939
}
945940

946-
@Override
947941
public OSMReader setWorkerThreads(int numOfWorkers) {
948942
this.workerThreads = numOfWorkers;
949943
return this;
950944
}
951945

952-
@Override
953946
public OSMReader setElevationProvider(ElevationProvider eleProvider) {
954947
if (eleProvider == null)
955948
throw new IllegalStateException("Use the NOOP elevation provider instead of null or don't call setElevationProvider");
@@ -961,8 +954,7 @@ public OSMReader setElevationProvider(ElevationProvider eleProvider) {
961954
return this;
962955
}
963956

964-
@Override
965-
public DataReader setFile(File osmFile) {
957+
public OSMReader setFile(File osmFile) {
966958
this.osmFile = osmFile;
967959
return this;
968960
}
@@ -975,7 +967,9 @@ private void printInfo(String str) {
975967
+ " " + Helper.getMemInfo());
976968
}
977969

978-
@Override
970+
/**
971+
* @return the timestamp given in the OSM file header or null if not found
972+
*/
979973
public Date getDataDate() {
980974
return osmDataDate;
981975
}

0 commit comments

Comments
 (0)