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