From fc2164d12844eb9fc88ba18a41c869d0e8841d57 Mon Sep 17 00:00:00 2001 From: LO Kam Tao Leo Date: Tue, 27 Sep 2022 07:59:21 +0100 Subject: [PATCH] Exporting relations --- .gitignore | 1 + .../org/leolo/map/osm/extract/ExtractElement.java | 29 ++++++-- .../org/leolo/map/osm/extract/ExtractResult.java | 40 +++++++++++ .../org/leolo/map/osm/extract/OutputFormat.java | 8 +++ .../leolo/map/osm/extract/format/KMLFormatter.java | 82 ++++++++++++++++++++++ .../map/osm/extract/format/PlainFormatter.java | 4 +- .../leolo/map/osm/extract/model/ExtractItem.java | 3 +- .../org/leolo/map/osm/extract/model/MapEntry.java | 4 +- .../java/org/leolo/map/osm/extract/model/Node.java | 16 +++++ .../org/leolo/map/osm/extract/model/Relation.java | 9 +++ .../leolo/map/osm/extract/model/SearchItem.java | 1 + 11 files changed, 189 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/leolo/map/osm/extract/ExtractResult.java diff --git a/.gitignore b/.gitignore index b0f32a9..abb5a23 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,4 @@ build/ ri_log action.xml .idea/ +output/ diff --git a/src/main/java/org/leolo/map/osm/extract/ExtractElement.java b/src/main/java/org/leolo/map/osm/extract/ExtractElement.java index 739f6ab..ab67656 100644 --- a/src/main/java/org/leolo/map/osm/extract/ExtractElement.java +++ b/src/main/java/org/leolo/map/osm/extract/ExtractElement.java @@ -14,7 +14,6 @@ import org.xml.sax.SAXException; import javax.xml.parsers.ParserConfigurationException; import java.io.*; import java.util.*; -import java.util.concurrent.*; public class ExtractElement { @@ -138,10 +137,20 @@ public class ExtractElement { log.atInfo().log("Database file size {}MB", dbFile.length()/1_000_000); log.atInfo().log("Action file size {}kB", actionFile.length()/1_000); try { - doExtract(dbFile, actionFile, outputStream); + doExtract(dbFile, actionFile); }catch(IOException e){ log.atError().withThrowable(e).log("Exception when extracting the data!"); } + Class formatClass = FormatterManager.getInstance().get(format); + OutputFormat of; + try{ + of = (OutputFormat) formatClass.getConstructor().newInstance(); + }catch (Exception e){ + log.atFatal().withThrowable(e).log("Unable to create an instance of OutputFormat"); + System.exit(1); + return; + } + doOutput(actionFile, outputStream, of); } catch(MissingOptionException|MissingArgumentException moe) { System.out.println("FATAL ERROR : "+moe.getMessage()); printHelp(1); @@ -155,7 +164,7 @@ public class ExtractElement { } } - private void doExtract(InputFile dbFile, InputFile actionFile, PrintStream outputStream) throws IOException{ + private void doExtract(InputFile dbFile, InputFile actionFile) throws IOException{ //Step 1: parse the actionFile ActionFile af; try { @@ -178,7 +187,19 @@ public class ExtractElement { expandRelations(dbFile, 1); processWay(dbFile); processNode(dbFile); - log.atInfo().log("Done!"); + log.atInfo().log("Done processing input!"); + } + + private void doOutput(InputFile actionFile, PrintStream outputStream, OutputFormat of) { + ExtractResult extractResult = new ExtractResult(allEntry, relations, ways, nodes); + PrintWriter out = new PrintWriter(outputStream); + of.writeHeader(out); + for(long id:relations.keySet()){ + of.writeRelation(out, id, extractResult); + } + of.writeTailer(out); + out.flush(); + out.close(); } /** diff --git a/src/main/java/org/leolo/map/osm/extract/ExtractResult.java b/src/main/java/org/leolo/map/osm/extract/ExtractResult.java new file mode 100644 index 0000000..a38f830 --- /dev/null +++ b/src/main/java/org/leolo/map/osm/extract/ExtractResult.java @@ -0,0 +1,40 @@ +package org.leolo.map.osm.extract; + +import org.leolo.map.osm.extract.model.MapEntry; +import org.leolo.map.osm.extract.model.Node; +import org.leolo.map.osm.extract.model.Relation; +import org.leolo.map.osm.extract.model.Way; + +import java.util.Hashtable; +import java.util.Map; + +public class ExtractResult { + + private Map allEntry = new Hashtable<>(); + private Map relations = new Hashtable<>(); + private Map ways = new Hashtable<>(); + private Map nodes = new Hashtable<>(); + + public ExtractResult(Map allEntry, Map relations, Map ways, Map nodes) { + this.allEntry = allEntry; + this.relations = relations; + this.ways = ways; + this.nodes = nodes; + } + + public Map getAllEntry() { + return allEntry; + } + + public Map getRelations() { + return relations; + } + + public Map getWays() { + return ways; + } + + public Map getNodes() { + return nodes; + } +} diff --git a/src/main/java/org/leolo/map/osm/extract/OutputFormat.java b/src/main/java/org/leolo/map/osm/extract/OutputFormat.java index ef844bc..89841a1 100644 --- a/src/main/java/org/leolo/map/osm/extract/OutputFormat.java +++ b/src/main/java/org/leolo/map/osm/extract/OutputFormat.java @@ -1,4 +1,12 @@ package org.leolo.map.osm.extract; +import java.io.PrintWriter; + public interface OutputFormat { + public void writeHeader(PrintWriter output); + public void writeTailer(PrintWriter output); + public void writeRelation(PrintWriter output,long id, ExtractResult extractResult); + public void writeWay(PrintWriter output,long id, ExtractResult extractResult); + public void writeNode(PrintWriter output,long id, ExtractResult extractResult); + } diff --git a/src/main/java/org/leolo/map/osm/extract/format/KMLFormatter.java b/src/main/java/org/leolo/map/osm/extract/format/KMLFormatter.java index 8129604..bb688ba 100644 --- a/src/main/java/org/leolo/map/osm/extract/format/KMLFormatter.java +++ b/src/main/java/org/leolo/map/osm/extract/format/KMLFormatter.java @@ -1,8 +1,90 @@ package org.leolo.map.osm.extract.format; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.leolo.map.osm.extract.ExtractResult; import org.leolo.map.osm.extract.OutputFormat; import org.leolo.map.osm.extract.OutputFormatter; +import org.leolo.map.osm.extract.model.MapEntry; +import org.leolo.map.osm.extract.model.Node; +import org.leolo.map.osm.extract.model.Relation; +import org.leolo.map.osm.extract.model.Way; + +import java.io.PrintWriter; @OutputFormatter(formatName = {"kml","application/vnd.google-earth.kml+xml"}) public class KMLFormatter implements OutputFormat { + private Logger log = LogManager.getLogger(); + @Override + public void writeHeader(PrintWriter output) { + output.print(""); + output.print(""); + output.print(""); + output.print(""); + } + + @Override + public void writeTailer(PrintWriter output) { + output.print(""); + } + + @Override + public void writeRelation(PrintWriter output, long id, ExtractResult extractResult) { + Relation rel = extractResult.getRelations().get(id); + output.print(getRelationString(id, extractResult)); + } + + private CharSequence getRelationString(long id, ExtractResult extractResult){ + Relation rel = extractResult.getRelations().get(id); + StringBuffer sb = new StringBuffer(); + sb.append(""); + sb.append("#sty_1"); + sb.append(""); + sb.append("Tag NameTag Value"); + rel.tagSet().stream().forEach((tagName)->{ + StringBuilder tag = new StringBuilder(); + tag.append("").append(tagName).append("").append(rel.getTag(tagName)).append(""); + sb.append(tag); + }); + sb.append("]]>"); + rel.parallelStream().forEach((member)->{ + MapEntry me = extractResult.getAllEntry().get(member); + if(me==null){ + log.atWarn().log("Missing entry {}", id); + return; + } + if(me instanceof Relation){ + //Calling same function to create nested folder + sb.append(getRelationString(member, extractResult)); + }else if(me instanceof Way){ + //Handling nameless way + StringBuffer wayOut = new StringBuffer(); + Way way = (Way) me; + wayOut.append("#sty_0"); + wayOut.append(""); + for(int i=0;i"); + wayOut.append(""); + sb.append(wayOut); + } + }); + sb.append(""); + return sb; + } + + @Override + public void writeWay(PrintWriter output, long id, ExtractResult extractResult) { + + } + + @Override + public void writeNode(PrintWriter output, long id, ExtractResult extractResult) { + + } } diff --git a/src/main/java/org/leolo/map/osm/extract/format/PlainFormatter.java b/src/main/java/org/leolo/map/osm/extract/format/PlainFormatter.java index 2c3266d..55908ed 100644 --- a/src/main/java/org/leolo/map/osm/extract/format/PlainFormatter.java +++ b/src/main/java/org/leolo/map/osm/extract/format/PlainFormatter.java @@ -3,6 +3,6 @@ package org.leolo.map.osm.extract.format; import org.leolo.map.osm.extract.OutputFormat; import org.leolo.map.osm.extract.OutputFormatter; -@OutputFormatter(formatName = "plain") -public class PlainFormatter implements OutputFormat { +//@OutputFormatter(formatName = "plain") +public class PlainFormatter{// implements OutputFormat { } diff --git a/src/main/java/org/leolo/map/osm/extract/model/ExtractItem.java b/src/main/java/org/leolo/map/osm/extract/model/ExtractItem.java index b2c2ef2..36d95b5 100644 --- a/src/main/java/org/leolo/map/osm/extract/model/ExtractItem.java +++ b/src/main/java/org/leolo/map/osm/extract/model/ExtractItem.java @@ -2,11 +2,12 @@ package org.leolo.map.osm.extract.model; import java.util.Hashtable; import java.util.Map; +import java.util.TreeMap; public class ExtractItem implements Comparable{ private long id; private String label; - private Map parameter = new Hashtable<>(); + private Map parameter = new TreeMap<>(); private boolean fromFile = false; public boolean isFromFile() { diff --git a/src/main/java/org/leolo/map/osm/extract/model/MapEntry.java b/src/main/java/org/leolo/map/osm/extract/model/MapEntry.java index 8134cb7..63b0501 100644 --- a/src/main/java/org/leolo/map/osm/extract/model/MapEntry.java +++ b/src/main/java/org/leolo/map/osm/extract/model/MapEntry.java @@ -3,9 +3,10 @@ package org.leolo.map.osm.extract.model; import java.util.Hashtable; import java.util.Map; import java.util.Set; +import java.util.TreeMap; public class MapEntry { - private Map tags = new Hashtable<>(); + private Map tags = new TreeMap<>(); public int tagCount() { return tags.size(); @@ -30,4 +31,5 @@ public class MapEntry { public Set tagSet() { return tags.keySet(); } + } diff --git a/src/main/java/org/leolo/map/osm/extract/model/Node.java b/src/main/java/org/leolo/map/osm/extract/model/Node.java index 453d75d..2a0451a 100644 --- a/src/main/java/org/leolo/map/osm/extract/model/Node.java +++ b/src/main/java/org/leolo/map/osm/extract/model/Node.java @@ -9,4 +9,20 @@ public class Node extends MapEntry{ this.lat = lat; this.lon = lon; } + + public double getLat() { + return lat; + } + + public void setLat(double lat) { + this.lat = lat; + } + + public double getLon() { + return lon; + } + + public void setLon(double lon) { + this.lon = lon; + } } diff --git a/src/main/java/org/leolo/map/osm/extract/model/Relation.java b/src/main/java/org/leolo/map/osm/extract/model/Relation.java index 1d0d93f..106be9a 100644 --- a/src/main/java/org/leolo/map/osm/extract/model/Relation.java +++ b/src/main/java/org/leolo/map/osm/extract/model/Relation.java @@ -1,6 +1,7 @@ package org.leolo.map.osm.extract.model; import java.util.*; +import java.util.stream.Stream; public class Relation extends MapEntry{ private List members = new Vector<>(); @@ -25,4 +26,12 @@ public class Relation extends MapEntry{ public Long getMember(int index) { return members.get(index); } + + public Stream stream() { + return members.stream(); + } + + public Stream parallelStream() { + return members.parallelStream(); + } } diff --git a/src/main/java/org/leolo/map/osm/extract/model/SearchItem.java b/src/main/java/org/leolo/map/osm/extract/model/SearchItem.java index 9403fe0..d30ecb2 100644 --- a/src/main/java/org/leolo/map/osm/extract/model/SearchItem.java +++ b/src/main/java/org/leolo/map/osm/extract/model/SearchItem.java @@ -64,4 +64,5 @@ public abstract class SearchItem { public boolean matchRelation(OsmRelation relation){ return matchEntity(relation); } + }