001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.io.remotecontrol.handler; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.Point; 007import java.util.Collections; 008 009import org.openstreetmap.josm.actions.AutoScaleAction; 010import org.openstreetmap.josm.actions.AutoScaleAction.AutoScaleMode; 011import org.openstreetmap.josm.command.AddCommand; 012import org.openstreetmap.josm.data.UndoRedoHandler; 013import org.openstreetmap.josm.data.coor.LatLon; 014import org.openstreetmap.josm.data.osm.DataSet; 015import org.openstreetmap.josm.data.osm.Node; 016import org.openstreetmap.josm.data.osm.OsmPrimitive; 017import org.openstreetmap.josm.gui.MainApplication; 018import org.openstreetmap.josm.gui.MapView; 019import org.openstreetmap.josm.gui.util.GuiHelper; 020import org.openstreetmap.josm.io.remotecontrol.AddTagsDialog; 021import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault; 022import org.openstreetmap.josm.spi.preferences.Config; 023import org.openstreetmap.josm.tools.Logging; 024 025/** 026 * Handler for add_node request. 027 */ 028public class AddNodeHandler extends RequestHandler { 029 030 /** 031 * The remote control command name used to add a node. 032 */ 033 public static final String command = "add_node"; 034 035 private double lat; 036 private double lon; 037 038 @Override 039 protected void handleRequest() { 040 GuiHelper.runInEDT(this::addNode); 041 } 042 043 @Override 044 public String[] getMandatoryParams() { 045 return new String[] {"lat", "lon"}; 046 } 047 048 @Override 049 public String[] getOptionalParams() { 050 return new String[] {"addtags"}; 051 } 052 053 @Override 054 public String getUsage() { 055 return "adds a node (given by its latitude and longitude) to the current dataset"; 056 } 057 058 @Override 059 public String[] getUsageExamples() { 060 return new String[] { 061 "/add_node?lat=11&lon=22", 062 "/add_node?lon=13.3&lat=53.2&addtags=natural=tree|name=%20%20%20==Great%20Oak==" 063 }; 064 } 065 066 @Override 067 public String getPermissionMessage() { 068 return tr("Remote Control has been asked to create a new node.") + 069 "<br>" + tr("Coordinates: ") + args.get("lat") + ", " + args.get("lon"); 070 } 071 072 @Override 073 public PermissionPrefWithDefault getPermissionPref() { 074 return PermissionPrefWithDefault.CREATE_OBJECTS; 075 } 076 077 /** 078 * Adds a node, implements the GET /add_node?lon=...&lat=... request. 079 */ 080 private void addNode() { 081 082 // Parse the arguments 083 Logging.info("Adding node at (" + lat + ", " + lon + ')'); 084 085 // Create a new node 086 LatLon ll = new LatLon(lat, lon); 087 088 Node node = null; 089 090 if (MainApplication.isDisplayingMapView()) { 091 MapView mapView = MainApplication.getMap().mapView; 092 Point p = mapView.getPoint(ll); 093 node = mapView.getNearestNode(p, OsmPrimitive::isUsable); 094 if (node != null && node.getCoor().greatCircleDistance(ll) > Config.getPref().getDouble("remotecontrol.tolerance", 0.1)) { 095 node = null; // node is too far 096 } 097 } 098 099 DataSet ds = MainApplication.getLayerManager().getEditDataSet(); 100 if (node == null) { 101 node = new Node(ll); 102 // Now execute the commands to add this node. 103 UndoRedoHandler.getInstance().add(new AddCommand(ds, node)); 104 } 105 106 ds.setSelected(node); 107 if (PermissionPrefWithDefault.CHANGE_VIEWPORT.isAllowed()) { 108 AutoScaleAction.autoScale(AutoScaleMode.SELECTION); 109 } else { 110 MainApplication.getMap().mapView.repaint(); 111 } 112 // parse parameter addtags=tag1=value1|tag2=vlaue2 113 AddTagsDialog.addTags(args, sender, Collections.singleton(node)); 114 } 115 116 @Override 117 protected void validateRequest() throws RequestHandlerBadRequestException { 118 try { 119 lat = Double.parseDouble(args != null ? args.get("lat") : ""); 120 lon = Double.parseDouble(args != null ? args.get("lon") : ""); 121 } catch (NumberFormatException e) { 122 throw new RequestHandlerBadRequestException("NumberFormatException ("+e.getMessage()+')', e); 123 } 124 if (MainApplication.getLayerManager().getEditLayer() == null) { 125 throw new RequestHandlerBadRequestException(tr("There is no layer opened to add node")); 126 } 127 } 128}