/** * Tracer - plugin for JOSM * Jan Bilak * This program is free software and licensed under GPL. */ package org.openstreetmap.josm.plugins.tracer; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.Cursor; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.actions.mapmode.MapMode; import org.openstreetmap.josm.command.AddCommand; import org.openstreetmap.josm.command.Command; import org.openstreetmap.josm.command.SequenceCommand; import org.openstreetmap.josm.data.coor.LatLon; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.Way; import org.openstreetmap.josm.gui.PleaseWaitRunnable; import org.openstreetmap.josm.gui.progress.ProgressMonitor; import org.openstreetmap.josm.gui.MapFrame; import org.openstreetmap.josm.tools.ImageProvider; import org.openstreetmap.josm.tools.Shortcut; import org.xml.sax.SAXException; class TracerAction extends MapMode implements MouseListener { private static final long serialVersionUID = 1L; protected boolean cancel; private boolean ctrl; private boolean alt; private boolean shift; protected TracerServer server = new TracerServer(); public TracerAction(MapFrame mapFrame) { super(tr("Tracer"), "tracer-sml", tr("Tracer."), Shortcut.registerShortcut("tools:tracer", tr("Tool: {0}", tr("Tracer")), KeyEvent.VK_T, Shortcut.DIRECT), mapFrame, getCursor()); } @Override public void enterMode() { if (!isEnabled()) { return; } super.enterMode(); Main.map.mapView.setCursor(getCursor()); Main.map.mapView.addMouseListener(this); } @Override public void exitMode() { super.exitMode(); Main.map.mapView.removeMouseListener(this); } private static Cursor getCursor() { return ImageProvider.getCursor("crosshair", "tracer-sml"); } protected void traceAsync(Point clickPoint) { cancel = false; /** * Positional data */ final LatLon pos = Main.map.mapView.getLatLon(clickPoint.x, clickPoint.y); try { PleaseWaitRunnable tracerTask = new PleaseWaitRunnable(tr("Tracing")) { @Override protected void realRun() throws SAXException { traceSync(pos, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); } @Override protected void finish() { } @Override protected void cancel() { TracerAction.this.cancel(); } }; Thread executeTraceThread = new Thread(tracerTask); executeTraceThread.start(); } catch (Exception e) { e.printStackTrace(); } } private void tagBuilding(Way way) { if(!alt) way.put("building", "yes"); way.put("source", "cuzk:km"); } private void traceSync(LatLon pos, ProgressMonitor progressMonitor) { Collection<Command> commands = new LinkedList<>(); progressMonitor.beginTask(null, 3); try { ArrayList<LatLon> coordList = server.trace(pos); if (coordList.size() == 0) { return; } // make nodes a way Way way = new Way(); Node firstNode = null; for (LatLon coord : coordList) { Node node = new Node(coord); if (firstNode == null) { firstNode = node; } commands.add(new AddCommand(node)); way.addNode(node); } way.addNode(firstNode); tagBuilding(way); commands.add(new AddCommand(way)); // connect to other buildings if (!ctrl) { commands.add(ConnectWays.connect(way)); } if (!commands.isEmpty()) { Main.main.undoRedo.add(new SequenceCommand(tr("Tracer building"), commands)); if (shift) { Main.getLayerManager().getEditDataSet().addSelected(way); } else { Main.getLayerManager().getEditDataSet().setSelected(way); } } else { System.out.println("Failed"); } } finally { progressMonitor.finishTask(); } } public void cancel() { cancel = true; } @Override public void mouseClicked(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { if (!Main.map.mapView.isActiveLayerDrawable()) { return; } requestFocusInMapView(); updateKeyModifiers(e); if (e.getButton() == MouseEvent.BUTTON1) { traceAsync(e.getPoint()); } } @Override protected void updateKeyModifiers(MouseEvent e) { ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0; alt = (e.getModifiers() & (ActionEvent.ALT_MASK | InputEvent.ALT_GRAPH_MASK)) != 0; shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0; } @Override public void mouseReleased(MouseEvent e) { } }