Changeset 23190 in osm for applications/editors/josm/plugins/buildings_tools
- Timestamp:
- 2010-09-15T18:54:18+02:00 (15 years ago)
- Location:
- applications/editors/josm/plugins/buildings_tools/src/buildings_tools
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/buildings_tools/src/buildings_tools/AddressDialog.java
r22529 r23190 20 20 @SuppressWarnings("serial") 21 21 public class AddressDialog extends ExtendedDialog { 22 23 24 25 26 22 private static String lhousenum,lstreetname; 23 private static boolean inc = true; 24 private JTextField housenum = new JTextField(); 25 private JTextField streetname = new JTextField(); 26 private Choice cincdec = new Choice(); 27 27 28 29 30 31 32 33 34 28 private JPanel panel = new JPanel(new GridBagLayout()); 29 private void addLabelled(String str, Component c) { 30 JLabel label = new JLabel(str); 31 panel.add(label, GBC.std()); 32 label.setLabelFor(c); 33 panel.add(c, GBC.eol().fill(GBC.HORIZONTAL)); 34 } 35 35 36 public AddressDialog() { 37 super(Main.parent, tr("Building address"), 38 new String[] { tr("OK"), tr("Cancel") }, 39 true); 40 41 contentInsets = new Insets(15,15,5,15); 42 setButtonIcons(new String[] {"ok.png", "cancel.png" }); 43 44 addLabelled(tr("House number:"),housenum); 45 addLabelled(tr("Street Name:"),streetname); 46 housenum.setText(nextHouseNum()); 47 streetname.setText(lstreetname); 36 public AddressDialog() { 37 super(Main.parent, tr("Building address"), 38 new String[] { tr("OK"), tr("Cancel") }, 39 true); 48 40 49 cincdec.add(tr("Increment")); 50 cincdec.add(tr("Decrement")); 51 cincdec.select(inc?0:1); 52 addLabelled(tr("Numbers:"), cincdec); 41 contentInsets = new Insets(15,15,5,15); 42 setButtonIcons(new String[] {"ok.png", "cancel.png" }); 53 43 54 setContent(panel); 55 setupDialog(); 56 setVisible(true); 57 } 58 59 private static String nextHouseNum() { 60 if (lhousenum==null) return ""; 61 try { 62 Integer num = NumberFormat.getInstance().parse(lhousenum).intValue(); 63 if (inc) num=num+2; else num = num-2; 64 return num.toString(); 65 } catch (ParseException e) { 66 return lhousenum; 67 } 68 } 69 public void saveValues() { 70 lhousenum = housenum.getText(); 71 lstreetname = streetname.getText(); 72 inc = cincdec.getSelectedIndex() == 0; 73 } 74 public String getHouseNum() { 75 return housenum.getText(); 76 } 77 public String getStreetName() { 78 return streetname.getText(); 79 } 44 addLabelled(tr("House number:"),housenum); 45 addLabelled(tr("Street Name:"),streetname); 46 housenum.setText(nextHouseNum()); 47 streetname.setText(lstreetname); 48 49 cincdec.add(tr("Increment")); 50 cincdec.add(tr("Decrement")); 51 cincdec.select(inc?0:1); 52 addLabelled(tr("Numbers:"), cincdec); 53 54 setContent(panel); 55 setupDialog(); 56 setVisible(true); 57 } 58 59 private static String nextHouseNum() { 60 if (lhousenum==null) return ""; 61 try { 62 Integer num = NumberFormat.getInstance().parse(lhousenum).intValue(); 63 if (inc) num=num+2; else num = num-2; 64 return num.toString(); 65 } catch (ParseException e) { 66 return lhousenum; 67 } 68 } 69 public void saveValues() { 70 lhousenum = housenum.getText(); 71 lstreetname = streetname.getText(); 72 inc = cincdec.getSelectedIndex() == 0; 73 } 74 public String getHouseNum() { 75 return housenum.getText(); 76 } 77 public String getStreetName() { 78 return streetname.getText(); 79 } 80 80 } -
applications/editors/josm/plugins/buildings_tools/src/buildings_tools/AdvancedSettingsDialog.java
r23124 r23190 18 18 19 19 public class AdvancedSettingsDialog extends ExtendedDialog { 20 20 private TagEditorModel tagsModel = new TagEditorModel(); 21 21 22 23 22 private JCheckBox cBigMode = new JCheckBox(tr("Big buildings mode")); 23 private JCheckBox cSoftCur = new JCheckBox(tr("Rotate crosshair")); 24 24 25 26 27 28 29 30 25 public AdvancedSettingsDialog() { 26 super(Main.parent, tr("Advanced settings"), 27 new String[] { tr("OK"), tr("Cancel") }, 28 true); 29 contentInsets = new Insets(15, 15, 5, 15); 30 setButtonIcons(new String[] { "ok.png", "cancel.png" }); 31 31 32 33 32 final JPanel panel = new JPanel(new GridBagLayout()); 33 panel.add(new JLabel(tr("Buildings tags:")), GBC.eol().fill(GBC.HORIZONTAL)); 34 34 35 36 37 38 35 for (Entry<String, String> entry : ToolSettings.getTags().entrySet()) { 36 tagsModel.add(entry.getKey(), entry.getValue()); 37 } 38 panel.add(new TagEditorPanel(tagsModel, null), GBC.eop().fill(GBC.BOTH)); 39 39 40 41 40 panel.add(cBigMode, GBC.eol().fill(GBC.HORIZONTAL)); 41 panel.add(cSoftCur, GBC.eol().fill(GBC.HORIZONTAL)); 42 42 43 44 43 cBigMode.setSelected(ToolSettings.isBBMode()); 44 cSoftCur.setSelected(ToolSettings.isSoftCursor()); 45 45 46 46 setContent(panel); 47 47 48 49 50 48 setupDialog(); 49 setVisible(true); 50 } 51 51 52 53 54 52 public boolean isBBMode() { 53 return cBigMode.isSelected(); 54 } 55 55 56 57 58 56 public boolean isSoftCursor() { 57 return cSoftCur.isSelected(); 58 } 59 59 60 61 62 63 64 60 public void saveSettings() { 61 tagsModel.applyToTags(ToolSettings.getTags()); 62 ToolSettings.setBBMode(isBBMode()); 63 ToolSettings.setSoftCursor(isSoftCursor()); 64 } 65 65 } -
applications/editors/josm/plugins/buildings_tools/src/buildings_tools/AngleSnap.java
r21846 r23190 11 11 12 12 public class AngleSnap { 13 14 13 private static final double PI_2 = Math.PI / 2; 14 TreeSet<Double> snapSet = new TreeSet<Double>(); 15 15 16 17 18 16 public void clear() { 17 snapSet.clear(); 18 } 19 19 20 21 22 20 public void addSnap(double snap) { 21 snapSet.add(snap % PI_2); 22 } 23 23 24 25 26 27 28 29 30 31 32 33 34 35 36 24 public Double addSnap(Node[] nodes) { 25 if (nodes.length == 2) { 26 EastNorth p1, p2; 27 p1 = latlon2eastNorth(((Node) nodes[0]).getCoor()); 28 p2 = latlon2eastNorth(((Node) nodes[1]).getCoor()); 29 double heading = p1.heading(p2); 30 addSnap(heading); 31 addSnap(heading + Math.PI / 4); 32 return heading; 33 } else { 34 return null; 35 } 36 } 37 37 38 39 40 41 42 43 44 45 46 38 public void addSnap(Way way) { 39 for (Pair<Node, Node> pair : way.getNodePairs(false)) { 40 EastNorth a, b; 41 a = latlon2eastNorth(pair.a.getCoor()); 42 b = latlon2eastNorth(pair.b.getCoor()); 43 double heading = a.heading(b); 44 addSnap(heading); 45 } 46 } 47 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 48 public Double getAngle() { 49 if (snapSet.isEmpty()) { 50 return null; 51 } 52 double first = snapSet.first(); 53 double last = snapSet.last(); 54 if (first < Math.PI / 4 && last > Math.PI / 4) { 55 last -= PI_2; 56 } 57 if (Math.abs(first - last) < 0.001) { 58 double center = (first + last) / 2; 59 if (center < 0) 60 center += PI_2; 61 return center; 62 } else { 63 return null; 64 } 65 } 66 66 67 68 69 70 71 72 73 74 75 76 77 78 67 public double snapAngle(double angle) { 68 if (snapSet.isEmpty()) { 69 return angle; 70 } 71 int quadrant = (int) Math.floor(angle / PI_2); 72 double ang = angle % PI_2; 73 Double prev = snapSet.floor(ang); 74 if (prev == null) 75 prev = snapSet.last() - PI_2; 76 Double next = snapSet.ceiling(ang); 77 if (next == null) 78 next = snapSet.first() + PI_2; 79 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 80 if (Math.abs(ang - next) > Math.abs(ang - prev)) { 81 if (Math.abs(ang - prev) > Math.PI / 8) { 82 return angle; 83 } else { 84 double ret = prev + PI_2 * quadrant; 85 if (ret < 0) 86 ret += 2 * Math.PI; 87 return ret; 88 } 89 } else { 90 if (Math.abs(ang - next) > Math.PI / 8) { 91 return angle; 92 } else { 93 double ret = next + PI_2 * quadrant; 94 if (ret > 2 * Math.PI) 95 ret -= 2 * Math.PI; 96 return ret; 97 } 98 } 99 } 100 100 } -
applications/editors/josm/plugins/buildings_tools/src/buildings_tools/Building.java
r22904 r23190 28 28 29 29 class Building { 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 30 private static final double eqlen = 40075004; // length of equator in metres 31 private final EastNorth[] en = new EastNorth[4]; 32 33 double meter = 0; 34 35 private double len = 0; 36 private double width; 37 private double heading; 38 private AngleSnap angleSnap = new AngleSnap(); 39 private Double drawingAngle; 40 41 public void clearAngleSnap() { 42 angleSnap.clear(); 43 drawingAngle = null; 44 } 45 46 public void addAngleSnap(Node[] nodes) { 47 drawingAngle = angleSnap.addSnap(nodes); 48 } 49 50 public void addAngleSnap(Way way) { 51 angleSnap.addSnap(way); 52 if (drawingAngle == null) { 53 drawingAngle = angleSnap.getAngle(); 54 } 55 } 56 57 public double getLength() { 58 return len; 59 } 60 61 public double getWidth() { 62 return width; 63 } 64 65 public boolean isRectDrawing() { 66 return drawingAngle != null && ToolSettings.getWidth() == 0 && ToolSettings.getLenStep() == 0; 67 } 68 69 public Double getDrawingAngle() { 70 return drawingAngle; 71 } 72 73 public void reset() { 74 len = 0; 75 76 for (int i = 0; i < 4; i++) 77 en[i] = null; 78 } 79 80 public EastNorth getPoint(int num) { 81 return en[num]; 82 } 83 84 private void updMetrics() { 85 meter = 2 * Math.PI / (Math.cos(Math.toRadians(eastNorth2latlon(en[0]).lat())) * eqlen); 86 len = 0; 87 } 88 89 public void setBase(EastNorth base) { 90 en[0] = base; 91 updMetrics(); 92 } 93 94 public void setBase(Node base) { 95 en[0] = latlon2eastNorth(base.getCoor()); 96 updMetrics(); 97 } 98 99 /** 100 * @returns Projection of the point to the heading vector in metres 101 */ 102 private double projection1(EastNorth p) { 103 final EastNorth vec = en[0].sub(p); 104 return (Math.sin(heading) * vec.east() + Math.cos(heading) * vec.north()) / meter; 105 } 106 107 /** 108 * @returns Projection of the point to the perpendicular of the heading 109 * vector in metres 110 */ 111 private double projection2(EastNorth p) { 112 final EastNorth vec = en[0].sub(p); 113 return (Math.cos(heading) * vec.east() - Math.sin(heading) * vec.north()) / meter; 114 } 115 116 private void updatePos() { 117 if (len == 0) 118 return; 119 final EastNorth p1 = en[0]; 120 en[1] = new EastNorth(p1.east() + Math.sin(heading) * len * meter, p1.north() + Math.cos(heading) * len * meter); 121 en[2] = new EastNorth(p1.east() + Math.sin(heading) * len * meter + Math.cos(heading) * width * meter, 122 p1.north() + Math.cos(heading) * len * meter - Math.sin(heading) * width * meter); 123 en[3] = new EastNorth(p1.east() + Math.cos(heading) * width * meter, 124 p1.north() - Math.sin(heading) * width * meter); 125 } 126 127 public void setLengthWidth(double length, double width) { 128 this.len = length; 129 this.width = width; 130 updatePos(); 131 } 132 133 public void setWidth(EastNorth p3) { 134 this.width = projection2(p3); 135 updatePos(); 136 } 137 138 public void setPlace(EastNorth p2, double width, double lenstep, boolean ignoreConstraints) { 139 if (en[0] == null) 140 throw new IllegalStateException("setPlace() called without the base point"); 141 this.heading = en[0].heading(p2); 142 if (!ignoreConstraints) 143 this.heading = angleSnap.snapAngle(this.heading); 144 145 this.width = width; 146 this.len = projection1(p2); 147 if (lenstep > 0 && !ignoreConstraints) 148 this.len = Math.round(this.len / lenstep) * lenstep; 149 150 updatePos(); 151 152 Main.map.statusLine.setHeading(Math.toDegrees(heading)); 153 if (this.drawingAngle != null && !ignoreConstraints) { 154 double ang = Math.toDegrees(heading - this.drawingAngle); 155 if (ang < 0) 156 ang += 360; 157 if (ang > 360) 158 ang -= 360; 159 Main.map.statusLine.setAngle(ang); 160 } 161 } 162 163 public void setPlaceRect(EastNorth p2) { 164 if (en[0] == null) 165 throw new IllegalStateException("SetPlaceRect() called without the base point"); 166 if (!isRectDrawing()) 167 throw new IllegalStateException("Invalid drawing mode"); 168 heading = drawingAngle; 169 setLengthWidth(projection1(p2), projection2(p2)); 170 Main.map.statusLine.setHeading(Math.toDegrees(heading)); 171 } 172 173 public void angFix(EastNorth point) { 174 EastNorth en3 = en[2]; 175 EastNorth mid = en[0].getCenter(en3); 176 double radius = en3.distance(mid); 177 heading = mid.heading(point); 178 heading = en[0].heading(mid.add(Math.sin(heading) * radius, Math.cos(heading) * radius)); 179 setLengthWidth(projection1(en3), projection2(en3)); 180 en[2] = en3; 181 } 182 183 public void paint(Graphics2D g, MapView mv) { 184 if (len == 0) 185 return; 186 GeneralPath b = new GeneralPath(); 187 Point pp1 = mv.getPoint(eastNorth2latlon(en[0])); 188 Point pp2 = mv.getPoint(eastNorth2latlon(en[1])); 189 Point pp3 = mv.getPoint(eastNorth2latlon(en[2])); 190 Point pp4 = mv.getPoint(eastNorth2latlon(en[3])); 191 192 b.moveTo(pp1.x, pp1.y); 193 b.lineTo(pp2.x, pp2.y); 194 b.lineTo(pp3.x, pp3.y); 195 b.lineTo(pp4.x, pp4.y); 196 b.lineTo(pp1.x, pp1.y); 197 g.draw(b); 198 } 199 200 private Node findNode(EastNorth en) { 201 DataSet ds = Main.main.getCurrentDataSet(); 202 LatLon l = eastNorth2latlon(en); 203 List<Node> nodes = ds.searchNodes(new BBox(l.lon() - 0.0000001, l.lat() - 0.0000001, 204 l.lon() + 0.0000001, l.lat() + 0.0000001)); 205 Node bestnode = null; 206 double mindist = 0.0003; 207 for (Node n : nodes) { 208 double dist = n.getCoor().distanceSq(l); 209 if (dist < mindist && OsmPrimitive.isUsablePredicate.evaluate(n)) { 210 bestnode = n; 211 mindist = dist; 212 } 213 } 214 return bestnode; 215 } 216 217 public Way create() { 218 if (len == 0) 219 return null; 220 final boolean[] created = new boolean[4]; 221 final Node[] nodes = new Node[4]; 222 for (int i = 0; i < 4; i++) { 223 224 Node n = findNode(en[i]); 225 if (n == null) { 226 nodes[i] = new Node(eastNorth2latlon(en[i])); 227 created[i] = true; 228 } else { 229 nodes[i] = n; 230 created[i] = false; 231 } 232 if (nodes[i].getCoor().isOutSideWorld()) { 233 JOptionPane.showMessageDialog(Main.parent, 234 tr("Cannot place building outside of the world.")); 235 return null; 236 } 237 } 238 Way w = new Way(); 239 w.addNode(nodes[0]); 240 if (projection2(en[2]) > 0 ^ len < 0) { 241 w.addNode(nodes[1]); 242 w.addNode(nodes[2]); 243 w.addNode(nodes[3]); 244 } else { 245 w.addNode(nodes[3]); 246 w.addNode(nodes[2]); 247 w.addNode(nodes[1]); 248 } 249 w.addNode(nodes[0]); 250 w.setKeys(ToolSettings.getTags()); 251 Collection<Command> cmds = new LinkedList<Command>(); 252 for (int i = 0; i < 4; i++) { 253 if (created[i]) 254 cmds.add(new AddCommand(nodes[i])); 255 } 256 cmds.add(new AddCommand(w)); 257 Command c = new SequenceCommand(tr("Create building"), cmds); 258 Main.main.undoRedo.add(c); 259 return w; 260 } 261 261 } -
applications/editors/josm/plugins/buildings_tools/src/buildings_tools/BuildingSizeAction.java
r21846 r23190 12 12 public class BuildingSizeAction extends JosmAction { 13 13 14 15 16 17 18 19 20 21 14 public BuildingSizeAction() { 15 super(tr("Set buildings size"), "mapmode/building", tr("Set buildings size"), 16 Shortcut.registerShortcut("edit:buildingsdialog", 17 tr("Edit: {0}", tr("Set buildings size")), 18 KeyEvent.VK_W, Shortcut.GROUP_EDIT, 19 Shortcut.SHIFT_DEFAULT), 20 true); 21 } 22 22 23 24 25 26 27 28 23 public void actionPerformed(ActionEvent arg0) { 24 BuildingSizeDialog dlg = new BuildingSizeDialog(); 25 if (dlg.getValue() == 1) { 26 dlg.saveSettings(); 27 } 28 } 29 29 } -
applications/editors/josm/plugins/buildings_tools/src/buildings_tools/BuildingSizeDialog.java
r22529 r23190 23 23 @SuppressWarnings("serial") 24 24 public class BuildingSizeDialog extends ExtendedDialog { 25 26 27 28 25 private JFormattedTextField twidth = new JFormattedTextField(NumberFormat.getInstance()); 26 private JFormattedTextField tlenstep = new JFormattedTextField(NumberFormat.getInstance()); 27 private JCheckBox caddr = new JCheckBox(tr("Use Address dialog")); 28 private JCheckBox cAutoSelect = new JCheckBox(tr("Auto-select building")); 29 29 30 31 32 33 34 35 30 static void addLabelled(JPanel panel, String str, Component c) { 31 JLabel label = new JLabel(str); 32 panel.add(label, GBC.std()); 33 label.setLabelFor(c); 34 panel.add(c, GBC.eol().fill(GBC.HORIZONTAL)); 35 } 36 36 37 38 39 40 41 42 37 public BuildingSizeDialog() { 38 super(Main.parent, tr("Set buildings size"), 39 new String[] { tr("OK"), tr("Cancel") }, 40 true); 41 contentInsets = new Insets(15, 15, 5, 15); 42 setButtonIcons(new String[] { "ok.png", "cancel.png" }); 43 43 44 45 46 47 48 44 final JPanel panel = new JPanel(new GridBagLayout()); 45 addLabelled(panel, tr("Buildings width:"), twidth); 46 addLabelled(panel, tr("Length step:"), tlenstep); 47 panel.add(caddr, GBC.eol().fill(GBC.HORIZONTAL)); 48 panel.add(cAutoSelect, GBC.eol().fill(GBC.HORIZONTAL)); 49 49 50 51 52 53 50 twidth.setValue(ToolSettings.getWidth()); 51 tlenstep.setValue(ToolSettings.getLenStep()); 52 caddr.setSelected(ToolSettings.isUsingAddr()); 53 cAutoSelect.setSelected(ToolSettings.isAutoSelect()); 54 54 55 56 57 58 59 60 61 62 63 64 65 55 JButton bAdv = new JButton(tr("Advanced...")); 56 bAdv.addActionListener(new ActionListener() { 57 @Override 58 public void actionPerformed(ActionEvent arg0) { 59 AdvancedSettingsDialog dlg = new AdvancedSettingsDialog(); 60 if (dlg.getValue() == 1) { 61 dlg.saveSettings(); 62 } 63 } 64 }); 65 panel.add(bAdv, GBC.eol().insets(0, 5, 0, 0).anchor(GBC.EAST)); 66 66 67 68 69 70 67 setContent(panel); 68 setupDialog(); 69 setVisible(true); 70 } 71 71 72 73 74 75 76 77 78 72 public double width() { 73 try { 74 return NumberFormat.getInstance().parse(twidth.getText()).doubleValue(); 75 } catch (ParseException e) { 76 return 0; 77 } 78 } 79 79 80 81 82 83 84 85 86 80 public double lenstep() { 81 try { 82 return NumberFormat.getInstance().parse(tlenstep.getText()).doubleValue(); 83 } catch (ParseException e) { 84 return 0; 85 } 86 } 87 87 88 89 90 88 public boolean useAddr() { 89 return caddr.isSelected(); 90 } 91 91 92 93 94 95 96 92 public void saveSettings() { 93 ToolSettings.setSizes(width(), lenstep()); 94 ToolSettings.setAddrDialog(useAddr()); 95 ToolSettings.setAutoSelect(cAutoSelect.isSelected()); 96 } 97 97 } -
applications/editors/josm/plugins/buildings_tools/src/buildings_tools/BuildingsToolsPlugin.java
r21875 r23190 12 12 13 13 public class BuildingsToolsPlugin extends Plugin { 14 14 public static Mercator proj = new Mercator(); 15 15 16 17 18 19 20 21 16 public static EastNorth latlon2eastNorth(LatLon p) { 17 return proj.latlon2eastNorth(p); 18 } 19 public static LatLon eastNorth2latlon(EastNorth p) { 20 return proj.eastNorth2latlon(p); 21 } 22 22 23 24 25 26 27 28 29 30 31 32 23 public BuildingsToolsPlugin(PluginInformation info) { 24 super(info); 25 Main.main.menu.editMenu.addSeparator(); 26 MainMenu.add(Main.main.menu.editMenu, new BuildingSizeAction()); 27 } 28 @Override public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) { 29 if (oldFrame==null && newFrame!=null) { 30 Main.map.addMapMode(new IconToggleButton(new DrawBuildingAction(Main.map))); 31 } 32 } 33 33 } -
applications/editors/josm/plugins/buildings_tools/src/buildings_tools/DrawBuildingAction.java
r22904 r23190 42 42 @SuppressWarnings("serial") 43 43 public class DrawBuildingAction extends MapMode implements MapViewPaintable, AWTEventListener, SelectionChangedListener { 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 * 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 44 private enum Mode { 45 None, Drawing, DrawingWidth, DrawingAngFix 46 } 47 48 final private Cursor cursorCrosshair; 49 final private Cursor cursorJoinNode; 50 private Cursor currCursor; 51 private Cursor customCursor; 52 53 private Mode mode = Mode.None; 54 private Mode nextMode = Mode.None; 55 56 private Color selectedColor; 57 private Point drawStartPos; 58 private Point mousePos; 59 private boolean isCtrlDown; 60 private boolean isShiftDown; 61 62 Building building = new Building(); 63 64 public DrawBuildingAction(MapFrame mapFrame) { 65 super(tr("Draw buildings"), "building", tr("Draw buildings"), 66 Shortcut.registerShortcut("mapmode:buildings", 67 tr("Mode: {0}", tr("Draw buildings")), 68 KeyEvent.VK_W, Shortcut.GROUP_EDIT), 69 mapFrame, getCursor()); 70 71 cursorCrosshair = getCursor(); 72 cursorJoinNode = ImageProvider.getCursor("crosshair", "joinnode"); 73 currCursor = cursorCrosshair; 74 75 selectedColor = Main.pref.getColor(marktr("selected"), Color.red); 76 } 77 78 private static Cursor getCursor() { 79 try { 80 return ImageProvider.getCursor("crosshair", null); 81 } catch (Exception e) { 82 } 83 return Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR); 84 } 85 86 /** 87 * Displays the given cursor instead of the normal one 88 * 89 * @param Cursors 90 * One of the available cursors 91 */ 92 private void setCursor(final Cursor c) { 93 if (currCursor.equals(c)) 94 return; 95 try { 96 // We invoke this to prevent strange things from happening 97 EventQueue.invokeLater(new Runnable() { 98 public void run() { 99 // Don't change cursor when mode has changed already 100 if (!(Main.map.mapMode instanceof DrawBuildingAction)) 101 return; 102 Main.map.mapView.setCursor(c); 103 } 104 }); 105 currCursor = c; 106 } catch (Exception e) { 107 } 108 } 109 110 private static void showAddrDialog(Way w) { 111 AddressDialog dlg = new AddressDialog(); 112 int answer = dlg.getValue(); 113 if (answer == 1) { 114 dlg.saveValues(); 115 String tmp; 116 tmp = dlg.getHouseNum(); 117 if (tmp != null && tmp != "") 118 w.put("addr:housenumber", tmp); 119 tmp = dlg.getStreetName(); 120 if (tmp != null && tmp != "") 121 w.put("addr:street", tmp); 122 } 123 } 124 125 @Override 126 public void enterMode() { 127 super.enterMode(); 128 if (getCurrentDataSet() == null) { 129 Main.map.selectSelectTool(false); 130 return; 131 } 132 currCursor = cursorCrosshair; 133 Main.map.mapView.addMouseListener(this); 134 Main.map.mapView.addMouseMotionListener(this); 135 Main.map.mapView.addTemporaryLayer(this); 136 DataSet.addSelectionListener(this); 137 updateSnap(getCurrentDataSet().getSelected()); 138 try { 139 Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK); 140 } catch (SecurityException ex) { 141 } 142 } 143 144 @Override 145 public void exitMode() { 146 super.exitMode(); 147 Main.map.mapView.removeMouseListener(this); 148 Main.map.mapView.removeMouseMotionListener(this); 149 Main.map.mapView.removeTemporaryLayer(this); 150 DataSet.removeSelectionListener(this); 151 try { 152 Toolkit.getDefaultToolkit().removeAWTEventListener(this); 153 } catch (SecurityException ex) { 154 } 155 if (mode != Mode.None) 156 Main.map.mapView.repaint(); 157 mode = Mode.None; 158 } 159 160 public void cancelDrawing() { 161 mode = Mode.None; 162 if (Main.map == null || Main.map.mapView == null) 163 return; 164 Main.map.statusLine.setHeading(-1); 165 Main.map.statusLine.setAngle(-1); 166 building.reset(); 167 Main.map.mapView.repaint(); 168 updateStatusLine(); 169 } 170 171 public void eventDispatched(AWTEvent arg0) { 172 if (!(arg0 instanceof KeyEvent)) 173 return; 174 KeyEvent ev = (KeyEvent) arg0; 175 int modifiers = ev.getModifiersEx(); 176 boolean isCtrlDown = (modifiers & KeyEvent.CTRL_DOWN_MASK) != 0; 177 boolean isShiftDown = (modifiers & KeyEvent.SHIFT_DOWN_MASK) != 0; 178 if (this.isCtrlDown != isCtrlDown || this.isShiftDown != isShiftDown) { 179 this.isCtrlDown = isCtrlDown; 180 this.isShiftDown = isShiftDown; 181 processMouseEvent(null); 182 updCursor(); 183 if (mode != Mode.None) 184 Main.map.mapView.repaint(); 185 } 186 187 if (ev.getKeyCode() == KeyEvent.VK_ESCAPE && ev.getID() == KeyEvent.KEY_PRESSED) { 188 if (mode != Mode.None) 189 ev.consume(); 190 191 cancelDrawing(); 192 } 193 } 194 195 private EastNorth getEastNorth() { 196 Node n; 197 if (isCtrlDown) { 198 n = null; 199 } else { 200 n = Main.map.mapView.getNearestNode(mousePos, OsmPrimitive.isUsablePredicate); 201 } 202 if (n == null) { 203 return latlon2eastNorth(Main.map.mapView.getLatLon(mousePos.x, mousePos.y)); 204 } else { 205 return latlon2eastNorth(n.getCoor()); 206 } 207 } 208 209 private boolean isRectDrawing() { 210 return building.isRectDrawing() && (!isShiftDown || ToolSettings.isBBMode()); 211 } 212 213 private Mode modeDrawing() { 214 EastNorth p = getEastNorth(); 215 if (isRectDrawing()) { 216 building.setPlaceRect(p); 217 return isShiftDown ? Mode.DrawingAngFix : Mode.None; 218 } else { 219 building.setPlace(p, ToolSettings.getWidth(), ToolSettings.getLenStep(), isShiftDown); 220 Main.map.statusLine.setDist(building.getLength()); 221 return this.nextMode = ToolSettings.getWidth() == 0 ? Mode.DrawingWidth : Mode.None; 222 } 223 } 224 225 private Mode modeDrawingWidth() { 226 building.setWidth(getEastNorth()); 227 Main.map.statusLine.setDist(Math.abs(building.getWidth())); 228 return Mode.None; 229 } 230 231 private Mode modeDrawingAngFix() { 232 building.angFix(getEastNorth()); 233 return Mode.None; 234 } 235 236 private void processMouseEvent(MouseEvent e) { 237 if (e != null) { 238 mousePos = e.getPoint(); 239 isCtrlDown = e.isControlDown(); 240 isShiftDown = e.isShiftDown(); 241 } 242 if (mode == Mode.None) { 243 nextMode = Mode.None; 244 return; 245 } 246 247 if (mode == Mode.Drawing) { 248 nextMode = modeDrawing(); 249 } else if (mode == Mode.DrawingWidth) { 250 nextMode = modeDrawingWidth(); 251 } else if (mode == Mode.DrawingAngFix) { 252 nextMode = modeDrawingAngFix(); 253 } else 254 throw new AssertionError("Invalid drawing mode"); 255 } 256 257 public void paint(Graphics2D g, MapView mv, Bounds bbox) { 258 if (mode == Mode.None) 259 return; 260 if (building.getLength() == 0) 261 return; 262 263 g.setColor(selectedColor); 264 g.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 265 266 building.paint(g, mv); 267 268 g.setStroke(new BasicStroke(1)); 269 270 } 271 272 private void drawingStart(MouseEvent e) { 273 mousePos = e.getPoint(); 274 drawStartPos = mousePos; 275 276 Node n = Main.map.mapView.getNearestNode(mousePos, OsmPrimitive.isUsablePredicate); 277 if (n == null) { 278 building.setBase(latlon2eastNorth(Main.map.mapView.getLatLon(mousePos.x, mousePos.y))); 279 } else { 280 building.setBase(n); 281 } 282 mode = Mode.Drawing; 283 updateStatusLine(); 284 } 285 286 private void drawingAdvance(MouseEvent e) { 287 processMouseEvent(e); 288 if (this.mode != Mode.None && this.nextMode == Mode.None) { 289 drawingFinish(); 290 } else { 291 mode = this.nextMode; 292 updateStatusLine(); 293 } 294 } 295 296 private void drawingFinish() { 297 if (building.getLength() != 0) { 298 Way w = building.create(); 299 if (w != null && ToolSettings.isUsingAddr()) 300 showAddrDialog(w); 301 if (ToolSettings.isAutoSelect() && 302 (Main.main.getCurrentDataSet().getSelected().isEmpty() || isShiftDown)) { 303 Main.main.getCurrentDataSet().setSelected(w); 304 } 305 } 306 cancelDrawing(); 307 } 308 309 @Override 310 public void mousePressed(MouseEvent e) { 311 if (e.getButton() != MouseEvent.BUTTON1) 312 return; 313 if (!Main.map.mapView.isActiveLayerDrawable()) 314 return; 315 316 if (mode == Mode.None) 317 drawingStart(e); 318 } 319 320 @Override 321 public void mouseDragged(MouseEvent e) { 322 processMouseEvent(e); 323 updCursor(); 324 if (mode != Mode.None) 325 Main.map.mapView.repaint(); 326 } 327 328 @Override 329 public void mouseReleased(MouseEvent e) { 330 if (e.getButton() != MouseEvent.BUTTON1) 331 return; 332 if (!Main.map.mapView.isActiveLayerDrawable()) 333 return; 334 boolean dragged = true; 335 if (drawStartPos != null) 336 dragged = e.getPoint().distance(drawStartPos) > 10; 337 drawStartPos = null; 338 339 if (mode == Mode.Drawing && !dragged) 340 return; 341 if (mode == Mode.None) 342 return; 343 344 drawingAdvance(e); 345 } 346 347 private void updCursor() { 348 if (mousePos == null) 349 return; 350 if (!Main.isDisplayingMapView()) 351 return; 352 Node n = null; 353 if (!isCtrlDown) 354 n = Main.map.mapView.getNearestNode(mousePos, OsmPrimitive.isUsablePredicate); 355 if (n != null) { 356 setCursor(cursorJoinNode); 357 } else { 358 if (customCursor != null && (!isShiftDown || isRectDrawing())) 359 setCursor(customCursor); 360 else 361 setCursor(cursorCrosshair); 362 } 363 364 } 365 366 @Override 367 public void mouseMoved(MouseEvent e) { 368 if (!Main.map.mapView.isActiveLayerDrawable()) 369 return; 370 processMouseEvent(e); 371 updCursor(); 372 if (mode != Mode.None) 373 Main.map.mapView.repaint(); 374 } 375 376 @Override 377 public String getModeHelpText() { 378 if (mode == Mode.None) 379 return tr("Point on the corner of the building to start drawing"); 380 if (mode == Mode.Drawing) 381 return tr("Point on opposite end of the building"); 382 if (mode == Mode.DrawingWidth) 383 return tr("Set width of the building"); 384 return ""; 385 } 386 387 @Override 388 public boolean layerIsSupported(Layer l) { 389 return l instanceof OsmDataLayer; 390 } 391 392 public void updateSnap(Collection<? extends OsmPrimitive> newSelection) { 393 building.clearAngleSnap(); 394 // update snap only if selection isn't too big 395 if (newSelection.size() <= 10) { 396 LinkedList<Node> nodes = new LinkedList<Node>(); 397 LinkedList<Way> ways = new LinkedList<Way>(); 398 399 for (OsmPrimitive p : newSelection) { 400 switch (p.getType()) { 401 case NODE: 402 nodes.add((Node) p); 403 break; 404 case WAY: 405 ways.add((Way) p); 406 break; 407 } 408 } 409 410 building.addAngleSnap(nodes.toArray(new Node[0])); 411 for (Way w : ways) { 412 building.addAngleSnap(w); 413 } 414 } 415 updateCustomCursor(); 416 } 417 418 private void updateCustomCursor() { 419 Double angle = building.getDrawingAngle(); 420 if (angle == null || !ToolSettings.isSoftCursor()) { 421 customCursor = null; 422 return; 423 } 424 final int R = 9; // crosshair outer radius 425 final int r = 3; // crosshair inner radius 426 BufferedImage img = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB); 427 Graphics2D g = img.createGraphics(); 428 429 GeneralPath b = new GeneralPath(); 430 b.moveTo(16 - Math.cos(angle) * R, 16 - Math.sin(angle) * R); 431 b.lineTo(16 - Math.cos(angle) * r, 16 - Math.sin(angle) * r); 432 b.moveTo(16 + Math.cos(angle) * R, 16 + Math.sin(angle) * R); 433 b.lineTo(16 + Math.cos(angle) * r, 16 + Math.sin(angle) * r); 434 b.moveTo(16 + Math.sin(angle) * R, 16 - Math.cos(angle) * R); 435 b.lineTo(16 + Math.sin(angle) * r, 16 - Math.cos(angle) * r); 436 b.moveTo(16 - Math.sin(angle) * R, 16 + Math.cos(angle) * R); 437 b.lineTo(16 - Math.sin(angle) * r, 16 + Math.cos(angle) * r); 438 439 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 440 g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); 441 442 g.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 443 g.setColor(Color.WHITE); 444 g.draw(b); 445 446 g.setStroke(new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); 447 g.setColor(Color.BLACK); 448 g.draw(b); 449 450 customCursor = Toolkit.getDefaultToolkit().createCustomCursor(img, new Point(16, 16), "custom crosshair"); 451 452 updCursor(); 453 } 454 455 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 456 updateSnap(newSelection); 457 } 458 458 } -
applications/editors/josm/plugins/buildings_tools/src/buildings_tools/ToolSettings.java
r22904 r23190 7 7 8 8 public class ToolSettings { 9 10 11 12 13 9 private static double width = 0; 10 private static double lenstep = 0; 11 private static boolean useAddr; 12 private static final Map<String, String> tags = new HashMap<String, String>(); 13 private static boolean autoSelect; 14 14 15 16 17 15 static { 16 tags.put("building", "yes"); 17 } 18 18 19 20 21 19 public static void setAddrDialog(boolean _useAddr) { 20 useAddr = _useAddr; 21 } 22 22 23 24 25 26 23 public static void setSizes(double newwidth, double newlenstep) { 24 width = newwidth; 25 lenstep = newlenstep; 26 } 27 27 28 29 30 28 public static double getWidth() { 29 return width; 30 } 31 31 32 33 34 32 public static double getLenStep() { 33 return lenstep; 34 } 35 35 36 37 38 36 public static boolean isUsingAddr() { 37 return useAddr; 38 } 39 39 40 41 42 40 public static Map<String, String> getTags() { 41 return tags; 42 } 43 43 44 45 46 44 public static void setBBMode(boolean bbmode) { 45 Main.pref.put("buildings_tools.bbmode", bbmode); 46 } 47 47 48 49 50 48 public static boolean isBBMode() { 49 return Main.pref.getBoolean("buildings_tools.bbmode", false); 50 } 51 51 52 53 54 52 public static void setSoftCursor(boolean softCursor) { 53 Main.pref.put("buildings_tools.softcursor", softCursor); 54 } 55 55 56 57 58 56 public static boolean isSoftCursor() { 57 return Main.pref.getBoolean("buildings_tools.softcursor", false); 58 } 59 59 60 61 62 60 public static boolean isAutoSelect() { 61 return autoSelect; 62 } 63 63 64 65 66 64 public static void setAutoSelect(boolean _autoSelect) { 65 autoSelect = _autoSelect; 66 } 67 67 }
Note:
See TracChangeset
for help on using the changeset viewer.