Skip to content

Commit 754d0ec

Browse files
author
Peter
committed
store and access pillarNodes; found one more problem with pillar nodes (finding subnetworks)
1 parent 43ff693 commit 754d0ec

21 files changed

+418
-228
lines changed

config-example.properties

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,14 @@ osmreader.sortGraph=true
1414
# use levelgraph to speed things up (requires more RAM/disc space for holding the graph)
1515
#osmreader.levelgraph=true
1616
# the following options require levelgraph=true
17-
#osmreader.towerNodesShortcuts=true
1817
#osmreader.chShortcuts=true
19-
osmreader.algoIterations=1000
2018

2119
# other options than CAR are currently not supported
2220
osmreader.type=CAR
2321

24-
# how much resolution do you want to resolve lat,lon
25-
# default should be good for you
26-
osmreader.locationIndexCapacity=200000
27-
28-
2922
osmreader.test=false
3023
osmreader.runshortestpath=false
31-
24+
osmreader.algoIterations=1000
3225

3326
# specifiy via command line
3427
#osmreader.graph-location=

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

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.graphhopper.routing.util.AlgorithmPreparation;
2121
import com.graphhopper.routing.util.FastestCarCalc;
2222
import com.graphhopper.routing.ch.PrepareContractionHierarchies;
23-
import com.graphhopper.routing.util.PrepareTowerNodesShortcuts;
2423
import com.graphhopper.routing.util.PrepareRoutingSubnetworks;
2524
import com.graphhopper.routing.util.RoutingAlgorithmSpecialAreaTests;
2625
import com.graphhopper.storage.Directory;
@@ -32,7 +31,6 @@
3231
import com.graphhopper.storage.Location2IDQuadtree;
3332
import com.graphhopper.storage.RAMDirectory;
3433
import com.graphhopper.util.CmdArgs;
35-
import com.graphhopper.util.DistanceCalc;
3634
import com.graphhopper.util.GraphUtility;
3735
import com.graphhopper.util.Helper;
3836
import com.graphhopper.util.Helper7;
@@ -85,14 +83,13 @@ public static void main(String[] strs) throws Exception {
8583
private static Logger logger = LoggerFactory.getLogger(OSMReader.class);
8684
private int locations;
8785
private int skippedLocations;
88-
private int nextEdgeIndex;
86+
private int edgeCount;
8987
private int skippedEdges;
9088
private GraphStorage graphStorage;
9189
private OSMReaderHelper helper;
9290
private int expectedNodes;
9391
private TLongArrayList tmpLocs = new TLongArrayList(10);
9492
private Map<String, Object> properties = new HashMap<String, Object>();
95-
private DistanceCalc callback = new DistanceCalc();
9693
private AcceptStreet acceptStreets = new AcceptStreet(true, false, false, false);
9794
private AlgorithmPreparation prepare;
9895
private Location2IDQuadtree index;
@@ -151,7 +148,11 @@ public static OSMReader osm2Graph(OSMReader osmReader, CmdArgs args) throws IOEx
151148
final String algoStr = args.get("osmreader.algo", "astar");
152149
osmReader.setDefaultAlgoPrepare(Helper.createAlgoPrepare(algoStr));
153150
osmReader.setSort(args.getBool("osmreader.sortGraph", false));
154-
osmReader.setTowerNodeShortcuts(args.getBool("osmreader.towerNodesShortcuts", false));
151+
152+
// TODO LATER make this configurable in OSMReaderHelper
153+
if (args.getBool("osmreader.towerNodesShortcuts", false))
154+
throw new IllegalArgumentException("towerNodes are always automatically created");
155+
155156
osmReader.setCHShortcuts(args.get("osmreader.chShortcuts", "no"));
156157
if (!osmReader.loadExisting()) {
157158
String strOsm = args.get("osmreader.osm", "");
@@ -250,7 +251,7 @@ public void flush() {
250251
if (indexCapacity < 0)
251252
indexCapacity = Helper.calcIndexSize(graphStorage.getBounds());
252253
logger.info("now initializing and flushing index with " + indexCapacity);
253-
getLocation2IDIndex().prepareIndex(indexCapacity);
254+
getLocation2IDIndex().prepareIndex(indexCapacity);
254255
index.flush();
255256
}
256257

@@ -278,7 +279,7 @@ public void writeOsm2Graph(InputStream is) {
278279
if ("node".equals(sReader.getLocalName())) {
279280
processNode(sReader);
280281
if (counter % 10000000 == 0) {
281-
logger.info(counter + ", locs:" + locations + " (" + skippedLocations + "), edges:" + nextEdgeIndex
282+
logger.info(counter + ", locs:" + locations + " (" + skippedLocations + "), edges:" + edgeCount
282283
+ " (" + skippedEdges + "), " + Helper.getMemInfo());
283284
}
284285
} else if ("way".equals(sReader.getLocalName())) {
@@ -295,7 +296,7 @@ public void writeOsm2Graph(InputStream is) {
295296
}
296297
// counter does +=2 until the next loop
297298
if ((counter / 2) % 1000000 == 0) {
298-
logger.info(counter + ", locs:" + locations + " (" + skippedLocations + "), edges:" + nextEdgeIndex
299+
logger.info(counter + ", locs:" + locations + " (" + skippedLocations + "), edges:" + edgeCount
299300
+ " (" + skippedEdges + "), " + Helper.getMemInfo());
300301
}
301302
}
@@ -393,18 +394,11 @@ public boolean isHighway(XMLStreamReader sReader) throws XMLStreamException {
393394

394395
public void processHighway(XMLStreamReader sReader) throws XMLStreamException {
395396
if (isHighway(sReader) && tmpLocs.size() > 1) {
396-
int l = tmpLocs.size();
397-
long prevOsmId = tmpLocs.get(0);
397+
int all = tmpLocs.size();
398398
int flags = acceptStreets.toFlags(properties);
399-
for (int ii = 1; ii < l; ii++) {
400-
long currOsmId = tmpLocs.get(ii);
401-
boolean ret = helper.addEdge(prevOsmId, currOsmId, flags, callback);
402-
if (ret)
403-
nextEdgeIndex++;
404-
else
405-
skippedEdges++;
406-
prevOsmId = currOsmId;
407-
}
399+
int successfullAdded = helper.addEdge(tmpLocs, flags);
400+
edgeCount += successfullAdded;
401+
skippedEdges += all - successfullAdded;
408402
}
409403
}
410404

@@ -431,15 +425,6 @@ public OSMReader setCHShortcuts(String chShortcuts) {
431425
return this;
432426
}
433427

434-
/**
435-
* @param bool if yes then shortcuts will be introduced to skip all nodes with only 2 edges.
436-
*/
437-
public OSMReader setTowerNodeShortcuts(boolean bool) {
438-
if (bool)
439-
prepare = new PrepareTowerNodesShortcuts();
440-
return this;
441-
}
442-
443428
private void setDefaultAlgoPrepare(AlgorithmPreparation defaultPrepare) {
444429
prepare = defaultPrepare;
445430
prepare.setGraph(graphStorage);

src/main/java/com/graphhopper/reader/OSMReaderHelper.java

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
import com.graphhopper.storage.GraphStorage;
2020
import com.graphhopper.util.DistanceCalc;
2121
import com.graphhopper.util.EdgeIterator;
22-
import com.graphhopper.util.GraphUtility;
22+
import gnu.trove.list.TDoubleList;
23+
import gnu.trove.list.TIntList;
24+
import gnu.trove.list.TLongList;
25+
import gnu.trove.list.array.TIntArrayList;
2326
import java.io.InputStream;
2427
import org.slf4j.Logger;
2528
import org.slf4j.LoggerFactory;
@@ -35,53 +38,64 @@ public abstract class OSMReaderHelper {
3538
protected int zeroCounter = 0;
3639
protected final Graph g;
3740
protected final int expectedNodes;
41+
private DistanceCalc callback = new DistanceCalc();
3842

3943
public OSMReaderHelper(Graph g, int expectedNodes) {
4044
this.g = g;
4145
this.expectedNodes = expectedNodes;
4246
}
4347

48+
public void setCallback(DistanceCalc callback) {
49+
this.callback = callback;
50+
}
51+
4452
public int getExpectedNodes() {
4553
return expectedNodes;
4654
}
4755

56+
public void preProcess(InputStream osmXml) {
57+
}
58+
4859
public boolean addNode(long osmId, double lat, double lon) {
4960
return true;
5061
}
5162

52-
public abstract boolean addEdge(long nodeIdFrom, long nodeIdTo, int flags, DistanceCalc callback);
63+
public abstract int addEdge(TLongList nodes, int flags);
5364

54-
public void preProcess(InputStream osmXml) {
55-
}
65+
public int addEdge(TDoubleList latitudes, TDoubleList longitudes,
66+
TIntList allNodes, int flags) {
67+
int nodes = allNodes.size();
68+
if (latitudes.size() != nodes || longitudes.size() != nodes)
69+
throw new IllegalArgumentException("latitudes.size must be equals to longitudes.size and node list size " + nodes);
5670

57-
public boolean addEdge(double laf, double lof, double lat, double lot,
58-
int fromIndex, int toIndex, int flags, DistanceCalc callback) {
59-
double dist = callback.calcDist(laf, lof, lat, lot);
60-
if (dist == 0) {
71+
double towerNodeDistance = 0;
72+
double prevLat = latitudes.get(0);
73+
double prevLon = longitudes.get(0);
74+
double lat;
75+
double lon;
76+
for (int i = 1; i < nodes; i++) {
77+
lat = latitudes.get(i);
78+
lon = longitudes.get(i);
79+
towerNodeDistance += callback.calcDist(prevLat, prevLon, lat, lon);
80+
prevLat = lat;
81+
prevLon = lon;
82+
}
83+
if (towerNodeDistance == 0) {
6184
// As investigation shows often two paths should have crossed via one identical point
6285
// but end up in two very close points. later this will be removed/fixed while
6386
// removing short edges where one node is of degree 2
6487
zeroCounter++;
65-
dist = 0.0001;
66-
} else if (dist < 0) {
67-
logger.info(counter + " - distances negative. " + fromIndex + " (" + laf + ", " + lof + ")->"
68-
+ toIndex + "(" + lat + ", " + lot + ") :" + dist);
69-
return false;
88+
towerNodeDistance = 0.0001;
7089
}
7190

72-
EdgeIterator iter = GraphUtility.until(g.getOutgoing(fromIndex), toIndex);
73-
if (!iter.isEmpty()) {
74-
if (flags == iter.flags() && dist > iter.distance()) {
75-
// silently skip if exactly the same way and the new one would be longer
76-
// return true;
77-
}
78-
// else logger.warn("longer edge already exists " + fromIndex + "->" + toIndex + "!? "
79-
// + "existing: " + iter.distance() + "|" + BitUtil.toBitString(iter.flags(), 8)
80-
// + " new:" + dist + "|" + BitUtil.toBitString(flags, 8));
91+
int fromIndex = allNodes.get(0);
92+
int toIndex = allNodes.get(nodes - 1);
93+
EdgeIterator iter = g.edge(fromIndex, toIndex, towerNodeDistance, flags);
94+
if (nodes > 2) {
95+
TIntList pillarNodes = allNodes.subList(1, nodes - 1);
96+
iter.pillarNodes(pillarNodes);
8197
}
82-
83-
g.edge(fromIndex, toIndex, dist, flags);
84-
return true;
98+
return nodes;
8599
}
86100

87101
public String getInfo() {

src/main/java/com/graphhopper/reader/OSMReaderHelperDoubleParse.java

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
import com.graphhopper.storage.DataAccess;
1919
import com.graphhopper.storage.Directory;
2020
import com.graphhopper.storage.GraphStorage;
21-
import com.graphhopper.util.DistanceCalc;
2221
import com.graphhopper.util.Helper;
2322
import com.graphhopper.util.Helper7;
23+
import gnu.trove.list.TLongList;
24+
import gnu.trove.list.array.TDoubleArrayList;
25+
import gnu.trove.list.array.TIntArrayList;
2426
import gnu.trove.list.array.TLongArrayList;
2527
import gnu.trove.map.hash.TIntIntHashMap;
28+
import gnu.trove.map.hash.TLongIntHashMap;
2629
import java.io.InputStream;
2730
import java.util.HashMap;
2831
import java.util.Map;
@@ -43,7 +46,7 @@
4346
public class OSMReaderHelperDoubleParse extends OSMReaderHelper {
4447

4548
private final Logger logger = LoggerFactory.getLogger(getClass());
46-
private TIntIntHashMap osmIdToIndexMap;
49+
private TLongIntHashMap osmIdToIndexMap;
4750
// very slow: private SparseLongLongArray osmIdToIndexMap;
4851
// not applicable as ways introduces the nodes in 'wrong' order: new OSMIDSegmentedMap
4952
private int internalId = 0;
@@ -55,20 +58,21 @@ public class OSMReaderHelperDoubleParse extends OSMReaderHelper {
5558
public OSMReaderHelperDoubleParse(GraphStorage storage, int expectedNodes) {
5659
super(storage, expectedNodes);
5760
dir = storage.getDirectory();
58-
indexToCount = dir.findCreate("tmpOSMReaderMap");
59-
osmIdToIndexMap = new TIntIntHashMap(expectedNodes, 1.4f, -1, -1);
61+
indexToCount = dir.findCreate("tmpOSMReaderMap");
62+
// we expect 4 nodes between two tower nodes => 2/6 => 1/3
63+
osmIdToIndexMap = new TLongIntHashMap(expectedNodes / 3, 1.4f, -1, -1);
6064
}
6165

6266
@Override
6367
public boolean addNode(long osmId, double lat, double lon) {
64-
int count = osmIdToIndexMap.get((int) osmId);
68+
int count = osmIdToIndexMap.get(osmId);
6569
if (count > FILLED)
6670
return false;
6771

6872
g.setNode(internalId, lat, lon);
6973
indexToCount.ensureCapacity(4 * (internalId + 1));
7074
indexToCount.setInt(internalId, 1 - (count - FILLED));
71-
osmIdToIndexMap.put((int) osmId, internalId);
75+
osmIdToIndexMap.put(osmId, internalId);
7276
internalId++;
7377
return true;
7478
}
@@ -79,21 +83,35 @@ public int getExpectedNodes() {
7983
}
8084

8185
@Override
82-
public boolean addEdge(long nodeIdFrom, long nodeIdTo, int flags, DistanceCalc callback) {
83-
int fromIndex = (int) osmIdToIndexMap.get((int) nodeIdFrom);
84-
int toIndex = (int) osmIdToIndexMap.get((int) nodeIdTo);
85-
if (fromIndex < 0 || toIndex < 0)
86-
return false;
87-
88-
try {
89-
double laf = g.getLatitude(fromIndex);
90-
double lof = g.getLongitude(fromIndex);
91-
double lat = g.getLatitude(toIndex);
92-
double lot = g.getLongitude(toIndex);
93-
return addEdge(laf, lof, lat, lot, fromIndex, toIndex, flags, callback);
94-
} catch (Exception ex) {
95-
throw new RuntimeException("Problem to add edge! with node " + fromIndex + "->" + toIndex + " osm:" + nodeIdFrom + "->" + nodeIdTo, ex);
86+
public int addEdge(TLongList nodes, int flags) {
87+
TDoubleArrayList longitudes = new TDoubleArrayList(nodes.size());
88+
TDoubleArrayList latitudes = new TDoubleArrayList(nodes.size());
89+
TIntArrayList allNodes = new TIntArrayList(nodes.size());
90+
int successfullyAdded = 0;
91+
for (int i = 0; i < nodes.size(); i++) {
92+
int tmpNode = osmIdToIndexMap.get(nodes.get(i));
93+
if (tmpNode < 0)
94+
continue;
95+
96+
allNodes.add(tmpNode);
97+
latitudes.add(g.getLatitude(tmpNode));
98+
longitudes.add(g.getLongitude(tmpNode));
99+
// split way into more than one edge!
100+
if (allNodes.size() > 1 && indexToCount.getInt(tmpNode) > 1) {
101+
successfullyAdded += addEdge(latitudes, longitudes, allNodes, flags);
102+
latitudes.clear();
103+
longitudes.clear();
104+
allNodes.clear();
105+
allNodes.add(tmpNode);
106+
latitudes.add(g.getLatitude(tmpNode));
107+
longitudes.add(g.getLongitude(tmpNode));
108+
}
96109
}
110+
if (allNodes.size() > 1)
111+
successfullyAdded += addEdge(latitudes, longitudes, allNodes, flags);
112+
return successfullyAdded;
113+
// throw new RuntimeException("Problem to add edge! with node "
114+
// + fromIndex + "->" + toIndex + " osm:" + nodeIdFrom + "->" + nodeIdTo, ex);
97115
}
98116

99117
@Override
@@ -126,7 +144,7 @@ public String toString() {
126144
*/
127145
@Override
128146
public void preProcess(InputStream osmXml) {
129-
indexToCount.createNew(expectedNodes);
147+
indexToCount.createNew(expectedNodes);
130148
if (osmXml == null)
131149
throw new IllegalStateException("Stream cannot be empty");
132150

src/main/java/com/graphhopper/reader/OSMReaderHelperSingleParse.java

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.graphhopper.util.DistanceCalc;
2222
import com.graphhopper.util.Helper;
2323
import com.graphhopper.util.shapes.CoordTrig;
24+
import gnu.trove.list.TLongList;
2425
import org.slf4j.LoggerFactory;
2526

2627
/**
@@ -57,25 +58,26 @@ public void startWayProcessing() {
5758
}
5859

5960
@Override
60-
public boolean addEdge(long nodeIdFrom, long nodeIdTo, int flags, DistanceCalc callback) {
61-
int fromIndex = (int) osmIdToIndexMap.get(nodeIdFrom);
62-
int toIndex = (int) osmIdToIndexMap.get(nodeIdTo);
63-
if (fromIndex == osmIdToIndexMap.getNoEntryValue() || toIndex == osmIdToIndexMap.getNoEntryValue())
64-
return false;
65-
66-
try {
67-
CoordTrig from = arr.get(fromIndex);
68-
CoordTrig to = arr.get(toIndex);
69-
if (from == null || to == null)
70-
return false;
71-
72-
g.setNode(fromIndex, from.lat, from.lon);
73-
g.setNode(toIndex, to.lat, to.lon);
74-
return addEdge(from.lat, from.lon, to.lat, to.lon, fromIndex, toIndex, flags, callback);
75-
} catch (Exception ex) {
76-
throw new RuntimeException("Problem to add edge! with node ids " + fromIndex + "->" + toIndex
77-
+ " vs. osm ids:" + nodeIdFrom + "->" + nodeIdTo, ex);
78-
}
61+
public int addEdge(TLongList nodes, int flags) {
62+
throw new UnsupportedOperationException("todo");
63+
// int fromIndex = (int) osmIdToIndexMap.get(nodeIdFrom);
64+
// int toIndex = (int) osmIdToIndexMap.get(nodeIdTo);
65+
// if (fromIndex == osmIdToIndexMap.getNoEntryValue() || toIndex == osmIdToIndexMap.getNoEntryValue())
66+
// return false;
67+
//
68+
// try {
69+
// CoordTrig from = arr.get(fromIndex);
70+
// CoordTrig to = arr.get(toIndex);
71+
// if (from == null || to == null)
72+
// return false;
73+
//
74+
// g.setNode(fromIndex, from.lat, from.lon);
75+
// g.setNode(toIndex, to.lat, to.lon);
76+
// return addEdge(from.lat, from.lon, to.lat, to.lon, fromIndex, toIndex, flags, callback);
77+
// } catch (Exception ex) {
78+
// throw new RuntimeException("Problem to add edge! with node ids " + fromIndex + "->" + toIndex
79+
// + " vs. osm ids:" + nodeIdFrom + "->" + nodeIdTo, ex);
80+
// }
7981
}
8082

8183
@Override

0 commit comments

Comments
 (0)