CodeSelectionPanel(String initialCode, ActionListener listener) { this.listener = listener; data = new ArrayList<>(Projections.getAllProjectionCodes()); Collections.sort(data, new CodeComparator()); filteredData = new ArrayList<>(data); build(); setCode(initialCode != null ? initialCode : DEFAULT_CODE); selectionList.addListSelectionListener(this); }
/** Setup test. */ @Before public void setUp() { User.clearUserMap(); my = new DataSet(); my.setVersion("0.6"); their = new DataSet(); their.setVersion("0.6"); Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); // Mercator }
private void buildGUI() { GridBagConstraints c = new GridBagConstraints(); c.gridheight = 1; c.gridwidth = 1; c.weightx = 1; c.weighty = 1; c.fill = GridBagConstraints.BOTH; this.projectionCombo = new JComboBox(); this.projectionCombo.addItem(tr("Select projection...")); for (Projection p : Projections.getProjections()) { this.projectionCombo.addItem(p); } this.projectionPreferencesButton = new JButton(tr("Prefs")); updateProjectionPrefButton(); this.loadFileButton = new JButton(tr("Load file...")); this.okButton = new JButton(tr("Place")); this.saveButton = new JButton(tr("Save")); this.showButton = new JButton(tr("Show target")); this.cancelButton = new JButton(tr("Discard")); this.loadProgress = new JProgressBar(); this.progressRenderer = new LoadProgressRenderer(this.loadProgress); this.minXField = new JTextField(""); this.minYField = new JTextField(""); this.minEastField = new JTextField(""); this.minNorthField = new JTextField(""); this.getMinButton = new JButton(tr("Take X and Y from selected node")); this.maxXField = new JTextField(""); this.maxYField = new JTextField(""); this.maxEastField = new JTextField(""); this.maxNorthField = new JTextField(""); this.getMaxButton = new JButton(tr("Take X and Y from selected node")); this.debugModeCheck = new JCheckBox(tr("Debug info")); this.mergeCloseNodesCheck = new JCheckBox(tr("Merge close nodes")); this.mergeCloseNodesTolerance = new JTextField("1e-3"); this.removeSmallObjectsCheck = new JCheckBox(tr("Remove objects smaller than")); this.removeSmallObjectsSize = new JTextField("1"); this.removeLargeObjectsCheck = new JCheckBox(tr("Remove objects larger than")); this.removeLargeObjectsSize = new JTextField("10"); this.colorFilterCheck = new JCheckBox(tr("Only this color")); this.colorFilterColor = new JTextField("#000000"); this.removeParallelSegmentsCheck = new JCheckBox(tr("Remove parallel lines")); this.removeParallelSegmentsTolerance = new JTextField("3"); this.limitPathCountCheck = new JCheckBox(tr("Take only first X paths")); this.limitPathCount = new JTextField("10000"); this.splitOnColorChangeCheck = new JCheckBox(tr("Color/width change")); this.splitOnShapeClosedCheck = new JCheckBox(tr("Shape closed")); this.splitOnSingleSegmentCheck = new JCheckBox(tr("Single segments")); this.splitOnOrthogonalCheck = new JCheckBox(tr("Orthogonal shapes")); JPanel configPanel = new JPanel(new GridBagLayout()); configPanel.setBorder(BorderFactory.createTitledBorder(tr("Import settings"))); c.gridx = 0; c.gridy = 0; c.gridwidth = 1; configPanel.add(this.mergeCloseNodesCheck, c); c.gridx = 1; c.gridy = 0; c.gridwidth = 1; c.anchor = GridBagConstraints.NORTHEAST; configPanel.add(new JLabel("Tolerance :"), c); c.gridx = 2; c.gridy = 0; c.gridwidth = 1; c.anchor = GridBagConstraints.NORTHWEST; configPanel.add(this.mergeCloseNodesTolerance, c); c.gridx = 0; c.gridy = 1; c.gridwidth = 1; configPanel.add(this.removeSmallObjectsCheck, c); c.gridx = 1; c.gridy = 1; c.gridwidth = 1; c.anchor = GridBagConstraints.NORTHEAST; configPanel.add(new JLabel("Tolerance :"), c); c.gridx = 2; c.gridy = 1; c.gridwidth = 1; c.anchor = GridBagConstraints.NORTHWEST; configPanel.add(this.removeSmallObjectsSize, c); c.gridx = 0; c.gridy = 2; c.gridwidth = 1; configPanel.add(this.removeLargeObjectsCheck, c); c.gridx = 1; c.gridy = 2; c.gridwidth = 1; c.anchor = GridBagConstraints.NORTHEAST; configPanel.add(new JLabel("Tolerance :"), c); c.gridx = 2; c.gridy = 2; c.gridwidth = 1; c.anchor = GridBagConstraints.NORTHWEST; configPanel.add(this.removeLargeObjectsSize, c); c.gridx = 0; c.gridy = 3; c.gridwidth = 1; configPanel.add(this.removeParallelSegmentsCheck, c); c.gridx = 1; c.gridy = 3; c.gridwidth = 1; c.anchor = GridBagConstraints.NORTHEAST; configPanel.add(new JLabel("Max distance :"), c); c.gridx = 2; c.gridy = 3; c.gridwidth = 1; c.anchor = GridBagConstraints.NORTHWEST; configPanel.add(this.removeParallelSegmentsTolerance, c); c.gridx = 0; c.gridy = 4; c.gridwidth = 2; configPanel.add(this.limitPathCountCheck, c); c.gridx = 2; c.gridy = 4; c.gridwidth = 1; configPanel.add(this.limitPathCount, c); c.gridx = 0; c.gridy = 5; c.gridwidth = 1; configPanel.add(this.colorFilterCheck, c); c.gridx = 2; c.gridy = 5; c.gridwidth = 1; configPanel.add(this.colorFilterColor, c); c.gridx = 0; c.gridy = 6; c.gridwidth = 2; configPanel.add(this.debugModeCheck, c); c.gridx = 0; c.gridy = 7; c.gridwidth = 1; configPanel.add(new JLabel(tr("Introduce separate layers for:")), c); c.gridx = 1; c.gridy = 7; c.gridwidth = 1; configPanel.add(this.splitOnShapeClosedCheck, c); c.gridx = 2; c.gridy = 7; c.gridwidth = 1; configPanel.add(this.splitOnSingleSegmentCheck, c); c.gridx = 1; c.gridy = 8; c.gridwidth = 1; configPanel.add(this.splitOnColorChangeCheck, c); c.gridx = 2; c.gridy = 8; c.gridwidth = 1; configPanel.add(this.splitOnOrthogonalCheck, c); JPanel projectionPanel = new JPanel(new GridBagLayout()); projectionPanel.setBorder(BorderFactory.createTitledBorder(tr("Bind to coordinates"))); JPanel projectionSubPanel = new JPanel(); projectionSubPanel.setLayout(new BoxLayout(projectionSubPanel, BoxLayout.X_AXIS)); projectionSubPanel.add(new JLabel(tr("Projection:"))); projectionSubPanel.add(this.projectionCombo); projectionSubPanel.add(this.projectionPreferencesButton); c.gridx = 0; c.gridy = 0; c.gridwidth = 3; projectionPanel.add(projectionSubPanel, c); c.gridx = 0; c.gridy = 1; c.gridwidth = 2; projectionPanel.add(new JLabel(tr("Bottom left (min) corner:")), c); c.gridx = 0; c.gridy = 2; c.gridwidth = 1; projectionPanel.add(new JLabel(tr("PDF X and Y")), c); c.gridx = 1; c.gridy = 2; c.gridwidth = 1; projectionPanel.add(new JLabel(tr("East and North")), c); c.gridx = 0; c.gridy = 3; c.gridwidth = 1; projectionPanel.add(this.minXField, c); c.gridx = 0; c.gridy = 4; c.gridwidth = 1; projectionPanel.add(this.minYField, c); c.gridx = 1; c.gridy = 3; c.gridwidth = 1; projectionPanel.add(this.minEastField, c); c.gridx = 1; c.gridy = 4; c.gridwidth = 1; projectionPanel.add(this.minNorthField, c); c.gridx = 0; c.gridy = 5; c.gridwidth = 1; projectionPanel.add(this.getMinButton, c); c.gridx = 0; c.gridy = 6; c.gridwidth = 2; projectionPanel.add(new JLabel(tr("Top right (max) corner:")), c); c.gridx = 0; c.gridy = 7; c.gridwidth = 1; projectionPanel.add(new JLabel(tr("PDF X and Y")), c); c.gridx = 1; c.gridy = 7; c.gridwidth = 1; projectionPanel.add(new JLabel(tr("East and North")), c); c.gridx = 0; c.gridy = 8; c.gridwidth = 1; projectionPanel.add(this.maxXField, c); c.gridx = 0; c.gridy = 9; c.gridwidth = 1; projectionPanel.add(this.maxYField, c); c.gridx = 1; c.gridy = 8; c.gridwidth = 1; projectionPanel.add(this.maxEastField, c); c.gridx = 1; c.gridy = 9; c.gridwidth = 1; projectionPanel.add(this.maxNorthField, c); c.gridx = 0; c.gridy = 10; c.gridwidth = 1; projectionPanel.add(this.getMaxButton, c); JPanel okCancelPanel = new JPanel(new GridLayout(1, 3)); okCancelPanel.add(this.cancelButton); okCancelPanel.add(this.showButton); okCancelPanel.add(this.okButton); okCancelPanel.add(this.saveButton); JPanel panel = new JPanel(new GridBagLayout()); c.gridx = 0; c.gridy = 0; c.gridwidth = 1; panel.add(configPanel, c); c.gridx = 0; c.gridy = 1; c.gridwidth = 1; panel.add(loadFileButton, c); c.gridx = 0; c.gridy = 2; c.gridwidth = 1; panel.add(projectionPanel, c); c.gridx = 0; c.gridy = 3; c.gridwidth = 1; panel.add(okCancelPanel, c); c.gridx = 0; c.gridy = 4; c.gridwidth = 1; panel.add(this.loadProgress, c); this.setSize(450, 550); this.setContentPane(panel); }
@Override public Projection getProjection() { return Projections.getProjectionByCode(code); }
private void parseJos(Document doc, ProgressMonitor progressMonitor) throws IllegalDataException { Element root = doc.getDocumentElement(); if (!equal(root.getTagName(), "josm-session")) { error(tr("Unexpected root element ''{0}'' in session file", root.getTagName())); } String version = root.getAttribute("version"); if (!"0.1".equals(version)) { error(tr("Version ''{0}'' of session file is not supported. Expected: 0.1", version)); } Element viewportEl = getElementByTagName(root, "viewport"); if (viewportEl != null) { EastNorth center = null; Element centerEl = getElementByTagName(viewportEl, "center"); if (centerEl != null && centerEl.hasAttribute("lat") && centerEl.hasAttribute("lon")) { try { LatLon centerLL = new LatLon( Double.parseDouble(centerEl.getAttribute("lat")), Double.parseDouble(centerEl.getAttribute("lon"))); center = Projections.project(centerLL); } catch (NumberFormatException ex) { } } if (center != null) { Element scaleEl = getElementByTagName(viewportEl, "scale"); if (scaleEl != null && scaleEl.hasAttribute("meter-per-pixel")) { try { double meterPerPixel = Double.parseDouble(scaleEl.getAttribute("meter-per-pixel")); Projection proj = Main.getProjection(); // Get a "typical" distance in east/north units that // corresponds to a couple of pixels. Shouldn't be too // large, to keep it within projection bounds and // not too small to avoid rounding errors. double dist = 0.01 * proj.getDefaultZoomInPPD(); LatLon ll1 = proj.eastNorth2latlon(new EastNorth(center.east() - dist, center.north())); LatLon ll2 = proj.eastNorth2latlon(new EastNorth(center.east() + dist, center.north())); double meterPerEasting = ll1.greatCircleDistance(ll2) / dist / 2; double scale = meterPerPixel / meterPerEasting; // unit: easting per pixel viewport = new ViewportData(center, scale); } catch (NumberFormatException ex) { } } } } Element layersEl = getElementByTagName(root, "layers"); if (layersEl == null) return; String activeAtt = layersEl.getAttribute("active"); try { active = (activeAtt != null && !activeAtt.isEmpty()) ? Integer.parseInt(activeAtt) - 1 : -1; } catch (NumberFormatException e) { Main.warn( "Unsupported value for 'active' layer attribute. Ignoring it. Error was: " + e.getMessage()); active = -1; } MultiMap<Integer, Integer> deps = new MultiMap<Integer, Integer>(); Map<Integer, Element> elems = new HashMap<Integer, Element>(); NodeList nodes = layersEl.getChildNodes(); for (int i = 0; i < nodes.getLength(); ++i) { Node node = nodes.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { Element e = (Element) node; if (equal(e.getTagName(), "layer")) { if (!e.hasAttribute("index")) { error(tr("missing mandatory attribute ''index'' for element ''layer''")); } Integer idx = null; try { idx = Integer.parseInt(e.getAttribute("index")); } catch (NumberFormatException ex) { } if (idx == null) { error(tr("unexpected format of attribute ''index'' for element ''layer''")); } if (elems.containsKey(idx)) { error( tr( "attribute ''index'' ({0}) for element ''layer'' must be unique", Integer.toString(idx))); } elems.put(idx, e); deps.putVoid(idx); String depStr = e.getAttribute("depends"); if (depStr != null) { for (String sd : depStr.split(",")) { Integer d = null; try { d = Integer.parseInt(sd); } catch (NumberFormatException ex) { Main.warn(ex); } if (d != null) { deps.put(idx, d); } } } } } } List<Integer> sorted = Utils.topologicalSort(deps); final Map<Integer, Layer> layersMap = new TreeMap<Integer, Layer>(Collections.reverseOrder()); final Map<Integer, SessionLayerImporter> importers = new HashMap<Integer, SessionLayerImporter>(); final Map<Integer, String> names = new HashMap<Integer, String>(); progressMonitor.setTicksCount(sorted.size()); LAYER: for (int idx : sorted) { Element e = elems.get(idx); if (e == null) { error(tr("missing layer with index {0}", idx)); } if (!e.hasAttribute("name")) { error(tr("missing mandatory attribute ''name'' for element ''layer''")); } String name = e.getAttribute("name"); names.put(idx, name); if (!e.hasAttribute("type")) { error(tr("missing mandatory attribute ''type'' for element ''layer''")); } String type = e.getAttribute("type"); SessionLayerImporter imp = getSessionLayerImporter(type); if (imp == null) { CancelOrContinueDialog dialog = new CancelOrContinueDialog(); dialog.show( tr("Unable to load layer"), tr("Cannot load layer of type ''{0}'' because no suitable importer was found.", type), JOptionPane.WARNING_MESSAGE, progressMonitor); if (dialog.isCancel()) { progressMonitor.cancel(); return; } else { continue; } } else { importers.put(idx, imp); List<LayerDependency> depsImp = new ArrayList<LayerDependency>(); for (int d : deps.get(idx)) { SessionLayerImporter dImp = importers.get(d); if (dImp == null) { CancelOrContinueDialog dialog = new CancelOrContinueDialog(); dialog.show( tr("Unable to load layer"), tr( "Cannot load layer {0} because it depends on layer {1} which has been skipped.", idx, d), JOptionPane.WARNING_MESSAGE, progressMonitor); if (dialog.isCancel()) { progressMonitor.cancel(); return; } else { continue LAYER; } } depsImp.add(new LayerDependency(d, layersMap.get(d), dImp)); } ImportSupport support = new ImportSupport(name, idx, depsImp); Layer layer = null; Exception exception = null; try { layer = imp.load(e, support, progressMonitor.createSubTaskMonitor(1, false)); } catch (IllegalDataException ex) { exception = ex; } catch (IOException ex) { exception = ex; } if (exception != null) { exception.printStackTrace(); CancelOrContinueDialog dialog = new CancelOrContinueDialog(); dialog.show( tr("Error loading layer"), tr( "<html>Could not load layer {0} ''{1}''.<br>Error is:<br>{2}</html>", idx, name, exception.getMessage()), JOptionPane.ERROR_MESSAGE, progressMonitor); if (dialog.isCancel()) { progressMonitor.cancel(); return; } else { continue; } } if (layer == null) throw new RuntimeException(); layersMap.put(idx, layer); } progressMonitor.worked(1); } layers = new ArrayList<Layer>(); for (int idx : layersMap.keySet()) { Layer layer = layersMap.get(idx); if (layer == null) { continue; } Element el = elems.get(idx); if (el.hasAttribute("visible")) { layer.setVisible(Boolean.parseBoolean(el.getAttribute("visible"))); } if (el.hasAttribute("opacity")) { try { double opacity = Double.parseDouble(el.getAttribute("opacity")); layer.setOpacity(opacity); } catch (NumberFormatException ex) { Main.warn(ex); } } } for (Entry<Integer, Layer> e : layersMap.entrySet()) { Layer l = e.getValue(); if (l == null) { continue; } l.setName(names.get(e.getKey())); layers.add(l); } }
/** @author ak */ public class SvgImportTask extends PleaseWaitRunnable { LinkedList<Node> nodes = new LinkedList<>(); LinkedList<Way> ways = new LinkedList<>(); private List<File> files; private boolean canceled; public SvgImportTask(List<File> files) { super(I18n.tr("Importing..."), false); this.files = new ArrayList<>(files); } @Override protected void cancel() { this.canceled = true; } @Override protected void finish() {} Projection projection = Projections.getProjectionByCode("EPSG:3857"); // Mercator EastNorth center; double scale; Way currentway; double lastX; double lastY; private void appendNode(double x, double y) throws IOException { if (currentway == null) { throw new IOException("Shape is started incorectly"); } Node nd = new Node(projection.eastNorth2latlon(center.add(x * scale, -y * scale))); if (nd.getCoor().isOutSideWorld()) { throw new IOException("Shape goes outside the world"); } currentway.addNode(nd); nodes.add(nd); lastX = x; lastY = y; } private void appendNode(Point2D point) throws IOException { appendNode(point.getX(), point.getY()); } private static double sqr(double x) { return x * x; } private static double cube(double x) { return x * x * x; } private static Point2D interpolate_quad( double ax, double ay, double bx, double by, double cx, double cy, double t) { return new Point2D.Double( sqr(1 - t) * ax + 2 * (1 - t) * t * bx + t * t * cx, sqr(1 - t) * ay + 2 * (1 - t) * t * by + t * t * cy); } private static Point2D interpolate_cubic( double ax, double ay, double bx, double by, double cx, double cy, double dx, double dy, double t) { return new Point2D.Double( cube(1 - t) * ax + 3 * sqr(1 - t) * t * bx + 3 * (1 - t) * t * t * cx + t * t * t * dx, cube(1 - t) * ay + 3 * sqr(1 - t) * t * by + 3 * (1 - t) * t * t * cy + t * t * t * dy); } private void processElement(SVGElement el, AffineTransform transform) throws IOException { if (el instanceof Group) { AffineTransform oldTransform = transform; AffineTransform xform = ((Group) el).getXForm(); if (transform == null) { transform = xform; } else if (xform != null) { transform = new AffineTransform(transform); transform.concatenate(xform); } for (Object child : ((Group) el).getChildren(null)) { processElement((SVGElement) child, transform); } transform = oldTransform; } else if (el instanceof ShapeElement) { Shape shape = ((ShapeElement) el).getShape(); if (transform != null) { shape = transform.createTransformedShape(shape); } PathIterator it = shape.getPathIterator(null); while (!it.isDone()) { double[] coords = new double[6]; switch (it.currentSegment(coords)) { case PathIterator.SEG_MOVETO: currentway = new Way(); ways.add(currentway); appendNode(coords[0], coords[1]); break; case PathIterator.SEG_LINETO: appendNode(coords[0], coords[1]); break; case PathIterator.SEG_CLOSE: if (currentway.firstNode().getCoor().equalsEpsilon(nodes.getLast().getCoor())) { currentway.removeNode(nodes.removeLast()); } currentway.addNode(currentway.firstNode()); break; case PathIterator.SEG_QUADTO: double lastx = lastX; double lasty = lastY; for (int i = 1; i < Settings.getCurveSteps(); i++) { appendNode( interpolate_quad( lastx, lasty, coords[0], coords[1], coords[2], coords[3], i / Settings.getCurveSteps())); } appendNode(coords[2], coords[3]); break; case PathIterator.SEG_CUBICTO: lastx = lastX; lasty = lastY; for (int i = 1; i < Settings.getCurveSteps(); i++) { appendNode( interpolate_cubic( lastx, lasty, coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], i / Settings.getCurveSteps())); } appendNode(coords[4], coords[5]); break; } it.next(); } } } @Override protected void realRun() throws IOException, OsmTransferException { LatLon center = Main.getProjection().eastNorth2latlon(Main.map.mapView.getCenter()); scale = Settings.getScaleNumerator() / Settings.getScaleDivisor() / Math.cos(Math.toRadians(center.lat())); this.center = projection.latlon2eastNorth(center); try { SVGUniverse universe = new SVGUniverse(); universe.setVerbose(Main.pref.getBoolean("importvec.verbose", false)); for (File f : files) { if (f.isDirectory()) continue; if (canceled) { return; } SVGDiagram diagram = universe.getDiagram(f.toURI()); ShapeElement root = diagram.getRoot(); if (root == null) { throw new IOException("Can't find root SVG element"); } Rectangle2D bbox = root.getBoundingBox(); this.center = this.center.add(-bbox.getCenterX() * scale, bbox.getCenterY() * scale); processElement(root, null); } } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException(e); } LinkedList<Command> cmds = new LinkedList<>(); for (Node n : nodes) { cmds.add(new AddCommand(n)); } for (Way w : ways) { cmds.add(new AddCommand(w)); } Main.main.undoRedo.add(new SequenceCommand("Import primitives", cmds)); } }