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

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

fix #8599: Remote control command add_way now creates closed ways correctly
Show old values and tooltips in add_tags dialog
All nodes added by add_node and add_way are merged with existing ones

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