// License: GPL. For details, see LICENSE file. package pdfimport; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.Color; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.openstreetmap.josm.data.osm.DataSet; import org.openstreetmap.josm.data.osm.Node; 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.progress.ProgressMonitor; public class OsmBuilder { enum Mode { Draft, Final, Debug } private final FilePlacement placement; private String layerName; private String fillName; private String lineName; private Mode mode; private ProgressMonitor monitor; private int monitorPos; private int monitorTotal; public OsmBuilder(FilePlacement placement) { this.placement = placement; } public DataSet build(List<LayerContents> data, Mode mode, ProgressMonitor monitor) { this.monitor = monitor; this.monitorPos = 0; this.mode = mode; DataSet result = new DataSet(); //count total items for progress monitor. this.monitorTotal = 0; for (LayerContents layer: data) { this.monitorTotal += layer.paths.size(); for (PdfMultiPath mp: layer.multiPaths) { this.monitorTotal += mp.paths.size(); } } monitor.beginTask(tr("Building JOSM layer."), this.monitorTotal); for (LayerContents layer: data) { this.addLayer(result, layer); } monitor.finishTask(); return result; } private void addLayer(DataSet target, LayerContents layer) { Map<Point2D, Node> point2Node = new HashMap<>(); this.fillName = this.printColor(layer.info.fill); this.lineName = this.printColor(layer.info.stroke); this.layerName = "" + layer.info.nr; //insert nodes for (Point2D pt: layer.points) { Node node = new Node(); node.setCoor(this.placement.tranformCoords(pt)); target.addPrimitive(node); point2Node.put(pt, node); } //insert ways Map<PdfPath, Way> path2Way = new HashMap<>(); for (PdfPath path: layer.paths) { Way w = this.insertWay(path, point2Node, -1, false); target.addPrimitive(w); path2Way.put(path, w); } int pathId = 0; for (PdfMultiPath mpath: layer.multiPaths) { for (PdfPath path: mpath.paths) { Way w = this.insertWay(path, point2Node, pathId, true); target.addPrimitive(w); path2Way.put(path, w); } pathId++; } if (this.mode != Mode.Draft) { //insert relations for (PdfMultiPath mpath: layer.multiPaths) { Relation rel = new Relation(); Map<String, String> keys = new HashMap<>(); keys.put("type", "multipolygon"); keys.put("area", "yes"); rel.setKeys(keys); for (PdfPath path: mpath.paths) { Way w = path2Way.get(path); rel.addMember(new RelationMember("", w)); } target.addPrimitive(rel); } } } private Way insertWay(PdfPath path, Map<Point2D, Node> point2Node, int multipathId, boolean multipolygon) { if (this.monitorPos % 100 == 0) { monitor.setExtraText(tr(" "+this.monitorPos+"/"+this.monitorTotal)); monitor.setTicks(this.monitorPos); } this.monitorPos++; List<Node> nodes = new ArrayList<>(path.points.size()); for (Point2D point: path.points) { Node node = point2Node.get(point); if (node == null) { throw new RuntimeException(); } nodes.add(node); } Map<String, String> keys = new HashMap<>(); if (this.mode != Mode.Draft) { keys.put("PDF_nr", "" + path.nr); keys.put("PDF_layer", this.layerName); if (path.isClosed()) { keys.put("PDF_closed", "yes"); } if (this.fillName != null) { keys.put("PDF_fillColor", this.fillName); } if (this.lineName != null) { keys.put("PDF_lineColor", this.lineName); } if (multipathId != -1) { keys.put("PDF_multipath", ""+ multipathId); } else if (path.layer.info.fill != null && !multipolygon) { keys.put("area", "yes"); } } if (this.mode == Mode.Debug) { keys.put("PDF_pathLayer", ""+path.layer.info.nr); keys.put("PDF_lineWidth", ""+path.layer.info.width); keys.put("PDF_lineDash", ""+path.layer.info.dash); keys.put("PDF_layerHash", ""+path.layer.info.hashCode()); keys.put("PDF_layerDivider", ""+path.layer.info.divider); } Way newWay = new Way(); newWay.setNodes(nodes); newWay.setKeys(keys); return newWay; } private String printColor(Color col) { if (col == null) { return null; } String s = Integer.toHexString(col.getRGB() & 0xffffff); while (s.length() < 6) { s = "0" + s; } return "#" + s; } }