|
|
|
@ -1,8 +1,11 @@ |
|
|
|
package org.leolo.map.osm.extract; |
|
|
|
package org.leolo.map.osm.extract; |
|
|
|
|
|
|
|
|
|
|
|
import crosby.binary.BinaryParser; |
|
|
|
import de.topobyte.osm4j.core.access.DefaultOsmHandler; |
|
|
|
import crosby.binary.Osmformat; |
|
|
|
import de.topobyte.osm4j.core.access.OsmInputException; |
|
|
|
import crosby.binary.file.BlockInputStream; |
|
|
|
import de.topobyte.osm4j.core.access.OsmIterator; |
|
|
|
|
|
|
|
import de.topobyte.osm4j.core.access.OsmReader; |
|
|
|
|
|
|
|
import de.topobyte.osm4j.core.model.iface.*; |
|
|
|
|
|
|
|
import de.topobyte.osm4j.pbf.seq.PbfReader; |
|
|
|
import org.apache.commons.cli.*; |
|
|
|
import org.apache.commons.cli.*; |
|
|
|
import org.apache.logging.log4j.LogManager; |
|
|
|
import org.apache.logging.log4j.LogManager; |
|
|
|
import org.apache.logging.log4j.Logger; |
|
|
|
import org.apache.logging.log4j.Logger; |
|
|
|
@ -137,8 +140,11 @@ public class ExtractElement { |
|
|
|
actionFile = InputUtil.getInputFile(actionFilePath); |
|
|
|
actionFile = InputUtil.getInputFile(actionFilePath); |
|
|
|
log.atInfo().log("Database file size {}MB", dbFile.length()/1_000_000); |
|
|
|
log.atInfo().log("Database file size {}MB", dbFile.length()/1_000_000); |
|
|
|
log.atInfo().log("Action file size {}kB", actionFile.length()/1_000); |
|
|
|
log.atInfo().log("Action file size {}kB", actionFile.length()/1_000); |
|
|
|
doExtract(dbFile, actionFile, outputStream); |
|
|
|
try { |
|
|
|
|
|
|
|
doExtract(dbFile, actionFile, outputStream); |
|
|
|
|
|
|
|
}catch(IOException e){ |
|
|
|
|
|
|
|
log.atError().withThrowable(e).log("Exception when extracting the data!"); |
|
|
|
|
|
|
|
} |
|
|
|
} catch(MissingOptionException|MissingArgumentException moe) { |
|
|
|
} catch(MissingOptionException|MissingArgumentException moe) { |
|
|
|
System.out.println("FATAL ERROR : "+moe.getMessage()); |
|
|
|
System.out.println("FATAL ERROR : "+moe.getMessage()); |
|
|
|
printHelp(1); |
|
|
|
printHelp(1); |
|
|
|
@ -152,7 +158,7 @@ public class ExtractElement { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void doExtract(InputFile dbFile, InputFile actionFile, PrintStream outputStream) { |
|
|
|
private void doExtract(InputFile dbFile, InputFile actionFile, PrintStream outputStream) throws IOException{ |
|
|
|
//Step 1: parse the actionFile
|
|
|
|
//Step 1: parse the actionFile
|
|
|
|
ActionFile af; |
|
|
|
ActionFile af; |
|
|
|
try { |
|
|
|
try { |
|
|
|
@ -162,10 +168,20 @@ public class ExtractElement { |
|
|
|
System.exit(3); |
|
|
|
System.exit(3); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for(ExtractItem ei:af.getRelation()){ |
|
|
|
|
|
|
|
pendingRelations.add(ei.getId()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for(ExtractItem ei:af.getWay()){ |
|
|
|
|
|
|
|
pendingWays.add(ei.getId()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for(ExtractItem ei:af.getNode()){ |
|
|
|
|
|
|
|
pendingNodes.add(ei.getId()); |
|
|
|
|
|
|
|
} |
|
|
|
doSearch(dbFile, af); |
|
|
|
doSearch(dbFile, af); |
|
|
|
expandRelations(dbFile); |
|
|
|
expandRelations(dbFile, 1); |
|
|
|
processWay(dbFile); |
|
|
|
processWay(dbFile); |
|
|
|
processNode(dbFile); |
|
|
|
processNode(dbFile); |
|
|
|
|
|
|
|
log.atInfo().log("Done!"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -173,23 +189,138 @@ public class ExtractElement { |
|
|
|
* @param dbFile The database file going to be searched |
|
|
|
* @param dbFile The database file going to be searched |
|
|
|
* @param af The file which defines the action to be performed |
|
|
|
* @param af The file which defines the action to be performed |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private void doSearch(InputFile dbFile, ActionFile af) { |
|
|
|
private void doSearch(InputFile dbFile, ActionFile af) throws IOException{ |
|
|
|
//Placeholder
|
|
|
|
//Placeholder
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void processNode(InputFile dbFile) { |
|
|
|
private void processNode(InputFile dbFile) throws IOException{ |
|
|
|
if(pendingNodes.isEmpty()) |
|
|
|
if(pendingNodes.isEmpty()) |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
log.atInfo().log("Processing {} node(s)", pendingNodes.size()); |
|
|
|
|
|
|
|
OsmReader reader = new PbfReader(dbFile.getInputStream(), true); |
|
|
|
|
|
|
|
reader.setHandler(new DefaultOsmHandler() { |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void handle(OsmNode node) throws IOException { |
|
|
|
|
|
|
|
super.handle(node); |
|
|
|
|
|
|
|
if(pendingNodes.contains(node.getId())){ |
|
|
|
|
|
|
|
log.atDebug().log("Found node #{}", node.getId()); |
|
|
|
|
|
|
|
Node n = new Node(node.getLatitude(), node.getLongitude()); |
|
|
|
|
|
|
|
for(int i=0;i<node.getNumberOfTags();i++){ |
|
|
|
|
|
|
|
OsmTag t = node.getTag(i); |
|
|
|
|
|
|
|
log.atDebug().log("{}->{}", t.getKey(), t.getValue()); |
|
|
|
|
|
|
|
n.putTag(t.getKey(), t.getValue()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
allEntry.put(node.getId(), n); |
|
|
|
|
|
|
|
nodes.put(node.getId(), n); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void complete() throws IOException { |
|
|
|
|
|
|
|
super.complete(); |
|
|
|
|
|
|
|
log.atInfo().log("Finish reading the DB file"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
reader.read(); |
|
|
|
|
|
|
|
} catch (OsmInputException e) { |
|
|
|
|
|
|
|
log.atError().withThrowable(e).log("Error when reading the input!"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void processWay(InputFile dbFile) { |
|
|
|
private void processWay(InputFile dbFile) throws IOException{ |
|
|
|
if(pendingWays.isEmpty()) |
|
|
|
if(pendingWays.isEmpty()) |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
log.atInfo().log("Processing {} way(s)", pendingWays.size()); |
|
|
|
|
|
|
|
OsmReader reader = new PbfReader(dbFile.getInputStream(), true); |
|
|
|
|
|
|
|
reader.setHandler(new DefaultOsmHandler() { |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void handle(OsmWay w) throws IOException { |
|
|
|
|
|
|
|
super.handle(w); |
|
|
|
|
|
|
|
if(pendingWays.contains(w.getId())){ |
|
|
|
|
|
|
|
Way way = new Way(); |
|
|
|
|
|
|
|
log.atDebug().log("Found way #{}", w.getId()); |
|
|
|
|
|
|
|
for(int i=0;i<w.getNumberOfNodes();i++){ |
|
|
|
|
|
|
|
way.addMember(w.getNodeId(i)); |
|
|
|
|
|
|
|
pendingNodes.add(w.getNodeId(i)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for(int i=0;i<w.getNumberOfTags();i++){ |
|
|
|
|
|
|
|
OsmTag tag = w.getTag(i); |
|
|
|
|
|
|
|
log.atDebug().log("{}->{}", tag.getKey(), tag.getValue()); |
|
|
|
|
|
|
|
way.putTag(tag.getKey(), tag.getValue()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
allEntry.put(w.getId(), way); |
|
|
|
|
|
|
|
ways.put(w.getId(), way); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void complete() throws IOException { |
|
|
|
|
|
|
|
super.complete(); |
|
|
|
|
|
|
|
log.atInfo().log("Finish reading the DB file"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
reader.read(); |
|
|
|
|
|
|
|
} catch (OsmInputException e) { |
|
|
|
|
|
|
|
log.atError().withThrowable(e).log("Error when reading the input!"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void expandRelations(InputFile dbFile) { |
|
|
|
private void expandRelations(InputFile dbFile,final int round) throws IOException{ |
|
|
|
if(pendingRelations.isEmpty()) |
|
|
|
if(pendingRelations.isEmpty()) { |
|
|
|
|
|
|
|
log.atInfo().log("No relation to be expanded"); |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
HashSet<Long> nextRound = new HashSet<>(); |
|
|
|
|
|
|
|
log.atInfo().log("Expanding relations round {} with {} relation(s)", round, pendingRelations.size()); |
|
|
|
|
|
|
|
OsmReader reader = new PbfReader(dbFile.getInputStream(), true); |
|
|
|
|
|
|
|
reader.setHandler(new DefaultOsmHandler() { |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void handle(OsmRelation relation) throws IOException { |
|
|
|
|
|
|
|
super.handle(relation); |
|
|
|
|
|
|
|
if(pendingRelations.contains(relation.getId())){ |
|
|
|
|
|
|
|
log.atDebug().log("Relation {} found with {} member(s) and {} tag(s).", |
|
|
|
|
|
|
|
relation.getId(), |
|
|
|
|
|
|
|
relation.getNumberOfMembers(), |
|
|
|
|
|
|
|
relation.getNumberOfTags() |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
Relation rel = new Relation(); |
|
|
|
|
|
|
|
for(int i=0;i<relation.getNumberOfMembers();i++){ |
|
|
|
|
|
|
|
OsmRelationMember orm = relation.getMember(i); |
|
|
|
|
|
|
|
switch (orm.getType()){ |
|
|
|
|
|
|
|
case Relation -> nextRound.add(orm.getId()); |
|
|
|
|
|
|
|
case Way -> pendingWays.add(orm.getId()); |
|
|
|
|
|
|
|
case Node -> pendingNodes.add(orm.getId()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
rel.addMember(orm.getId()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for(int i=0;i<relation.getNumberOfTags();i++){ |
|
|
|
|
|
|
|
OsmTag tag = relation.getTag(i); |
|
|
|
|
|
|
|
log.atDebug().log("{}->{}", tag.getKey(), tag.getValue()); |
|
|
|
|
|
|
|
rel.putTag(tag.getKey(), tag.getValue()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
allEntry.put(relation.getId(), rel); |
|
|
|
|
|
|
|
relations.put(relation.getId(), rel); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void complete() throws IOException { |
|
|
|
|
|
|
|
super.complete(); |
|
|
|
|
|
|
|
log.atInfo().log("Finish reading round {} when expanding relation", round); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
reader.read(); |
|
|
|
|
|
|
|
} catch (OsmInputException e) { |
|
|
|
|
|
|
|
log.atError().withThrowable(e).log("Error when reading the input!"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
log.atInfo().log("There are {} relations to be expanded in next round", nextRound.size()); |
|
|
|
|
|
|
|
pendingRelations = nextRound; |
|
|
|
|
|
|
|
if(pendingRelations.size()>0){ |
|
|
|
|
|
|
|
expandRelations(dbFile, round+1); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void printHelp(int returnValue){ |
|
|
|
private void printHelp(int returnValue){ |
|
|
|
|