// License: GPL. For details, see LICENSE file.
package poly;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.Relation;
import org.openstreetmap.josm.data.osm.RelationMember;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.gui.layer.Layer;
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
import org.openstreetmap.josm.io.OsmExporter;
/**
* Writes poly files.
*
* @author zverik
*/
public class PolyExporter extends OsmExporter {
public PolyExporter() {
super(PolyType.FILE_FILTER);
}
@Override
public void exportData(File file, Layer layer) throws IOException {
if (layer instanceof OsmDataLayer) {
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF8"))) {
DataSet ds = ((OsmDataLayer) layer).data;
Map<Way, Boolean> ways = new TreeMap<>();
String polygonName = file.getName();
if (polygonName.indexOf('.') > 0)
polygonName = polygonName.substring(0, polygonName.indexOf('.'));
for (Way w : ds.getWays()) {
if (w.isClosed()) {
boolean outer = isOuter(w);
ways.put(w, outer);
if (w.hasKey("name"))
polygonName = w.get("name").replace("\n", " ");
}
}
ways = sortOuterInner(ways);
int counter = 1;
writer.write(polygonName);
writer.newLine();
for (Way w : ways.keySet()) {
if (!ways.get(w))
writer.write('!');
writer.write(String.valueOf(counter++));
writer.newLine();
for (Node n : w.getNodes()) {
writer.write(String.format(Locale.ENGLISH, " %f %f", n.getCoor().lon(), n.getCoor().lat()));
writer.newLine();
}
writer.write("END");
writer.newLine();
}
writer.write("END");
writer.newLine();
}
}
}
private boolean isOuter(Way w) {
for (OsmPrimitive p : w.getReferrers()) {
if (p instanceof Relation && ((Relation) p).isMultipolygon()) {
for (RelationMember m : ((Relation) p).getMembers()) {
if (m.refersTo(w) && "inner".equals(m.getRole())) {
return false;
}
}
}
}
return true;
}
private Map<Way, Boolean> sortOuterInner(Map<Way, Boolean> ways) {
LinkedHashMap<Way, Boolean> result = new LinkedHashMap<>(ways.size());
List<Way> inner = new ArrayList<>();
for (Way w : ways.keySet()) {
Boolean outer = ways.get(w);
if (outer)
result.put(w, outer);
else
inner.add(w);
}
for (Way w : inner) {
result.put(w, Boolean.FALSE);
}
return result;
}
}