source: josm/trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/AddWayHandler.java@ 5876

Last change on this file since 5876 was 5876, checked in by akks, 11 years ago

Remote control: allow adding tags without confirmation for current session (add_tags), see #8612
added parsing of request headers and detecting request sender by IP and "referer" HTTP header

File size: 5.4 KB
Line 
1package org.openstreetmap.josm.io.remotecontrol.handler;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4
5import java.awt.Point;
6import java.util.ArrayList;
7import java.util.Arrays;
8import java.util.HashMap;
9import java.util.LinkedList;
10import java.util.List;
11
12import org.openstreetmap.josm.Main;
13import org.openstreetmap.josm.actions.AutoScaleAction;
14import org.openstreetmap.josm.command.AddCommand;
15import org.openstreetmap.josm.command.Command;
16import org.openstreetmap.josm.command.SequenceCommand;
17import org.openstreetmap.josm.data.coor.LatLon;
18import org.openstreetmap.josm.data.osm.Node;
19import org.openstreetmap.josm.data.osm.OsmPrimitive;
20import org.openstreetmap.josm.data.osm.Way;
21import org.openstreetmap.josm.gui.util.GuiHelper;
22import org.openstreetmap.josm.io.remotecontrol.AddTagsDialog;
23import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
24import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler.RequestHandlerBadRequestException;
25
26/**
27 * Adds a way to the current dataset. For instance, {@code /add_way?way=lat1,lon2;lat2,lon2}.
28 */
29public class AddWayHandler extends RequestHandler {
30
31 /**
32 * The remote control command name used to add a way.
33 */
34 public static final String command = "add_way";
35
36 private final List<LatLon> allCoordinates = new ArrayList<LatLon>();
37
38 /**
39 * The place to remeber already added nodes (they are reused if needed @since 5845
40 */
41 HashMap<LatLon, Node> addedNodes;
42
43 @Override
44 public String[] getMandatoryParams() {
45 return new String[]{"way"};
46 }
47
48 @Override
49 protected void handleRequest() throws RequestHandlerErrorException, RequestHandlerBadRequestException {
50 GuiHelper.runInEDTAndWait(new Runnable() {
51 @Override public void run() {
52 addWay();
53 }
54 });
55 // parse parameter addtags=tag1=value1|tag2=value2
56 AddTagsDialog.addTags(args, sender);
57 }
58
59 @Override
60 public String getPermissionMessage() {
61 return tr("Remote Control has been asked to create a new way.");
62 }
63
64 @Override
65 public PermissionPrefWithDefault getPermissionPref() {
66 return PermissionPrefWithDefault.CREATE_OBJECTS;
67 }
68
69 @Override
70 protected void validateRequest() throws RequestHandlerBadRequestException {
71 allCoordinates.clear();
72 for (String coordinatesString : args.get("way").split(";\\s*")) {
73 String[] coordinates = coordinatesString.split(",\\s*", 2);
74 if (coordinates.length < 2) {
75 throw new RequestHandlerBadRequestException(
76 tr("Invalid coordinates: {0}", Arrays.toString(coordinates)));
77 }
78 try {
79 double lat = Double.parseDouble(coordinates[0]);
80 double lon = Double.parseDouble(coordinates[1]);
81 allCoordinates.add(new LatLon(lat, lon));
82 } catch (NumberFormatException e) {
83 throw new RequestHandlerBadRequestException("NumberFormatException ("+e.getMessage()+")");
84 }
85 }
86 if (allCoordinates.isEmpty()) {
87 throw new RequestHandlerBadRequestException(tr("Empty ways"));
88 } else if (allCoordinates.size() == 1) {
89 throw new RequestHandlerBadRequestException(tr("One node ways"));
90 }
91 if (!Main.main.hasEditLayer()) {
92 throw new RequestHandlerBadRequestException(tr("There is no layer opened to add way"));
93 }
94 }
95
96 /**
97 * Find the node with almost the same ccords in dataset or in already added nodes
98 * @since 5845
99 **/
100 Node findOrCreateNode(LatLon ll, List<Command> commands) {
101 Node nd = null;
102
103 if (Main.map != null && Main.map.mapView != null) {
104 Point p = Main.map.mapView.getPoint(ll);
105 nd = Main.map.mapView.getNearestNode(p, OsmPrimitive.isUsablePredicate);
106 if (nd!=null && nd.getCoor().greatCircleDistance(ll) > Main.pref.getDouble("remote.tolerance", 0.1)) {
107 nd = null; // node is too far
108 }
109 }
110
111 Node prev = null;
112 for (LatLon lOld: addedNodes.keySet()) {
113 if (lOld.greatCircleDistance(ll) < Main.pref.getDouble("remotecontrol.tolerance", 0.1)) {
114 prev = addedNodes.get(lOld);
115 break;
116 }
117 }
118
119 if (prev!=null) {
120 nd = prev;
121 } else if (nd==null) {
122 nd = new Node(ll);
123 // Now execute the commands to add this node.
124 commands.add(new AddCommand(nd));
125 addedNodes.put(ll, nd);
126 }
127 return nd;
128 }
129
130 /*
131 * This function creates the way with given coordinates of nodes
132 */
133 private void addWay() {
134 addedNodes = new HashMap<LatLon, Node>();
135 Way way = new Way();
136 List<Command> commands = new LinkedList<Command>();
137 for (LatLon ll : allCoordinates) {
138 Node node = findOrCreateNode(ll, commands);
139 way.addNode(node);
140 }
141 allCoordinates.clear();
142 commands.add(new AddCommand(way));
143 Main.main.undoRedo.add(new SequenceCommand(tr("Add way"), commands));
144 Main.main.getCurrentDataSet().setSelected(way);
145 if (PermissionPrefWithDefault.CHANGE_VIEWPORT.isAllowed()) {
146 AutoScaleAction.autoScale("selection");
147 } else {
148 Main.map.mapView.repaint();
149 }
150 }
151}
Note: See TracBrowser for help on using the repository browser.