Browse Source

Exporting relations

feature/kml_out
LO Kam Tao Leo 3 years ago
parent
commit
fc2164d128
  1. 1
      .gitignore
  2. 29
      src/main/java/org/leolo/map/osm/extract/ExtractElement.java
  3. 40
      src/main/java/org/leolo/map/osm/extract/ExtractResult.java
  4. 8
      src/main/java/org/leolo/map/osm/extract/OutputFormat.java
  5. 82
      src/main/java/org/leolo/map/osm/extract/format/KMLFormatter.java
  6. 4
      src/main/java/org/leolo/map/osm/extract/format/PlainFormatter.java
  7. 3
      src/main/java/org/leolo/map/osm/extract/model/ExtractItem.java
  8. 4
      src/main/java/org/leolo/map/osm/extract/model/MapEntry.java
  9. 16
      src/main/java/org/leolo/map/osm/extract/model/Node.java
  10. 9
      src/main/java/org/leolo/map/osm/extract/model/Relation.java
  11. 1
      src/main/java/org/leolo/map/osm/extract/model/SearchItem.java

1
.gitignore vendored

@ -39,3 +39,4 @@ build/
ri_log
action.xml
.idea/
output/

29
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();
}
/**

40
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<Long, MapEntry> allEntry = new Hashtable<>();
private Map<Long, Relation> relations = new Hashtable<>();
private Map<Long, Way> ways = new Hashtable<>();
private Map<Long, Node> nodes = new Hashtable<>();
public ExtractResult(Map<Long, MapEntry> allEntry, Map<Long, Relation> relations, Map<Long, Way> ways, Map<Long, Node> nodes) {
this.allEntry = allEntry;
this.relations = relations;
this.ways = ways;
this.nodes = nodes;
}
public Map<Long, MapEntry> getAllEntry() {
return allEntry;
}
public Map<Long, Relation> getRelations() {
return relations;
}
public Map<Long, Way> getWays() {
return ways;
}
public Map<Long, Node> getNodes() {
return nodes;
}
}

8
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);
}

82
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("<?xml version='1.0'?><kml xmlns='http://www.opengis.net/kml/2.2' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='https://schemas.opengis.net/kml/2.3/ogckml23.xsd'>");
output.print("<Document>");
output.print("<Style id='sty_0'>");
output.print("<LineStyle><color>501400FF</color><width>3</width></LineStyle>");
output.print("</Style>");
output.print("<Style id='sty_1'><ListStyle><listItemType>checkHideChildren</listItemType></ListStyle></Style>");
}
@Override
public void writeTailer(PrintWriter output) {
output.print("</Document></kml>");
}
@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("<Folder id='rel_").append(Long.toHexString(id)).append("'>");
sb.append("<styleUrl>#sty_1</styleUrl>");
sb.append("<name><![CDATA[").append(rel.getTag("name")).append("<]]></name>");
sb.append("<description><![CDATA[<table><tr><th>Tag Name</th><th>Tag Value</th></tr>");
rel.tagSet().stream().forEach((tagName)->{
StringBuilder tag = new StringBuilder();
tag.append("<tr><td>").append(tagName).append("</td><td>").append(rel.getTag(tagName)).append("</td>");
sb.append(tag);
});
sb.append("</table>]]></description>");
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("<Placemark><styleUrl>#sty_0</styleUrl><LineString id='rel_").append(Long.toHexString(id))
.append("_w_").append(Long.toHexString(member)).append("'>");
wayOut.append("<coordinates>");
for(int i=0;i<way.memberCount();i++){
Node node = extractResult.getNodes().get(way.getMember(i));
wayOut.append(node.getLon()).append(",").append(node.getLat()).append(" ");
}
wayOut.append("</coordinates>");
wayOut.append("</LineString></Placemark>");
sb.append(wayOut);
}
});
sb.append("</Folder>");
return sb;
}
@Override
public void writeWay(PrintWriter output, long id, ExtractResult extractResult) {
}
@Override
public void writeNode(PrintWriter output, long id, ExtractResult extractResult) {
}
}

4
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 {
}

3
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<ExtractItem>{
private long id;
private String label;
private Map<String, Object> parameter = new Hashtable<>();
private Map<String, Object> parameter = new TreeMap<>();
private boolean fromFile = false;
public boolean isFromFile() {

4
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<String, String> tags = new Hashtable<>();
private Map<String, String> tags = new TreeMap<>();
public int tagCount() {
return tags.size();
@ -30,4 +31,5 @@ public class MapEntry {
public Set<String> tagSet() {
return tags.keySet();
}
}

16
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;
}
}

9
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<Long> members = new Vector<>();
@ -25,4 +26,12 @@ public class Relation extends MapEntry{
public Long getMember(int index) {
return members.get(index);
}
public Stream<Long> stream() {
return members.stream();
}
public Stream<Long> parallelStream() {
return members.parallelStream();
}
}

1
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);
}
}

Loading…
Cancel
Save