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
-
AddressDialog.java (modified) (1 diff)
-
AdvancedSettingsDialog.java (modified) (1 diff)
-
AngleSnap.java (modified) (1 diff)
-
Building.java (modified) (1 diff)
-
BuildingSizeAction.java (modified) (1 diff)
-
BuildingSizeDialog.java (modified) (1 diff)
-
BuildingsToolsPlugin.java (modified) (1 diff)
-
DrawBuildingAction.java (modified) (1 diff)
-
ToolSettings.java (modified) (1 diff)
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 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();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 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 }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 private TagEditorModel tagsModel = new TagEditorModel();20 private TagEditorModel tagsModel = new TagEditorModel(); 21 21 22 private JCheckBox cBigMode = new JCheckBox(tr("Big buildings mode"));23 private JCheckBox cSoftCur = new JCheckBox(tr("Rotate crosshair"));22 private JCheckBox cBigMode = new JCheckBox(tr("Big buildings mode")); 23 private JCheckBox cSoftCur = new JCheckBox(tr("Rotate crosshair")); 24 24 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" });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 final JPanel panel = new JPanel(new GridBagLayout());33 panel.add(new JLabel(tr("Buildings tags:")), GBC.eol().fill(GBC.HORIZONTAL));32 final JPanel panel = new JPanel(new GridBagLayout()); 33 panel.add(new JLabel(tr("Buildings tags:")), GBC.eol().fill(GBC.HORIZONTAL)); 34 34 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));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 panel.add(cBigMode, GBC.eol().fill(GBC.HORIZONTAL));41 panel.add(cSoftCur, GBC.eol().fill(GBC.HORIZONTAL));40 panel.add(cBigMode, GBC.eol().fill(GBC.HORIZONTAL)); 41 panel.add(cSoftCur, GBC.eol().fill(GBC.HORIZONTAL)); 42 42 43 cBigMode.setSelected(ToolSettings.isBBMode());44 cSoftCur.setSelected(ToolSettings.isSoftCursor());43 cBigMode.setSelected(ToolSettings.isBBMode()); 44 cSoftCur.setSelected(ToolSettings.isSoftCursor()); 45 45 46 setContent(panel);46 setContent(panel); 47 47 48 setupDialog();49 setVisible(true);50 }48 setupDialog(); 49 setVisible(true); 50 } 51 51 52 public boolean isBBMode() {53 return cBigMode.isSelected();54 }52 public boolean isBBMode() { 53 return cBigMode.isSelected(); 54 } 55 55 56 public boolean isSoftCursor() {57 return cSoftCur.isSelected();58 }56 public boolean isSoftCursor() { 57 return cSoftCur.isSelected(); 58 } 59 59 60 public void saveSettings() {61 tagsModel.applyToTags(ToolSettings.getTags());62 ToolSettings.setBBMode(isBBMode());63 ToolSettings.setSoftCursor(isSoftCursor());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 private static final double PI_2 = Math.PI / 2;14 TreeSet<Double> snapSet = new TreeSet<Double>();13 private static final double PI_2 = Math.PI / 2; 14 TreeSet<Double> snapSet = new TreeSet<Double>(); 15 15 16 public void clear() {17 snapSet.clear();18 }16 public void clear() { 17 snapSet.clear(); 18 } 19 19 20 public void addSnap(double snap) {21 snapSet.add(snap % PI_2);22 }20 public void addSnap(double snap) { 21 snapSet.add(snap % PI_2); 22 } 23 23 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 }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 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 }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 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 }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 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;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 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 }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 private static final double eqlen = 40075004; // length of equator in metres31 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 metres101 */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 heading109 * vector in metres110 */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 }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 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 }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 public void actionPerformed(ActionEvent arg0) {24 BuildingSizeDialog dlg = new BuildingSizeDialog();25 if (dlg.getValue() == 1) {26 dlg.saveSettings();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 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"));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 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 }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 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" });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 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));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 twidth.setValue(ToolSettings.getWidth());51 tlenstep.setValue(ToolSettings.getLenStep());52 caddr.setSelected(ToolSettings.isUsingAddr());53 cAutoSelect.setSelected(ToolSettings.isAutoSelect());50 twidth.setValue(ToolSettings.getWidth()); 51 tlenstep.setValue(ToolSettings.getLenStep()); 52 caddr.setSelected(ToolSettings.isUsingAddr()); 53 cAutoSelect.setSelected(ToolSettings.isAutoSelect()); 54 54 55 JButton bAdv = new JButton(tr("Advanced..."));56 bAdv.addActionListener(new ActionListener() {57 @Override58 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));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 setContent(panel);68 setupDialog();69 setVisible(true);70 }67 setContent(panel); 68 setupDialog(); 69 setVisible(true); 70 } 71 71 72 public double width() {73 try {74 return NumberFormat.getInstance().parse(twidth.getText()).doubleValue();75 } catch (ParseException e) {76 return 0;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 public double lenstep() {81 try {82 return NumberFormat.getInstance().parse(tlenstep.getText()).doubleValue();83 } catch (ParseException e) {84 return 0;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 public boolean useAddr() {89 return caddr.isSelected();90 }88 public boolean useAddr() { 89 return caddr.isSelected(); 90 } 91 91 92 public void saveSettings() {93 ToolSettings.setSizes(width(), lenstep());94 ToolSettings.setAddrDialog(useAddr());95 ToolSettings.setAutoSelect(cAutoSelect.isSelected());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 public static Mercator proj = new Mercator();14 public static Mercator proj = new Mercator(); 15 15 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 }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 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 }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 private enum Mode {45 None, Drawing, DrawingWidth, DrawingAngFix46 }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 one88 * 89 * @param Cursors90 * One of the available cursors91 */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 happening97 EventQueue.invokeLater(new Runnable() {98 public void run() {99 // Don't change cursor when mode has changed already100 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 @Override126 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 @Override145 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 } else254 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 @Override310 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 @Override321 public void mouseDragged(MouseEvent e) {322 processMouseEvent(e);323 updCursor();324 if (mode != Mode.None)325 Main.map.mapView.repaint();326 }327 328 @Override329 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 else361 setCursor(cursorCrosshair);362 }363 364 }365 366 @Override367 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 @Override377 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 @Override388 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 big395 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 radius425 final int r = 3; // crosshair inner radius426 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 }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 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;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 static {16 tags.put("building", "yes");17 }15 static { 16 tags.put("building", "yes"); 17 } 18 18 19 public static void setAddrDialog(boolean _useAddr) {20 useAddr = _useAddr;21 }19 public static void setAddrDialog(boolean _useAddr) { 20 useAddr = _useAddr; 21 } 22 22 23 public static void setSizes(double newwidth, double newlenstep) {24 width = newwidth;25 lenstep = newlenstep;26 }23 public static void setSizes(double newwidth, double newlenstep) { 24 width = newwidth; 25 lenstep = newlenstep; 26 } 27 27 28 public static double getWidth() {29 return width;30 }28 public static double getWidth() { 29 return width; 30 } 31 31 32 public static double getLenStep() {33 return lenstep;34 }32 public static double getLenStep() { 33 return lenstep; 34 } 35 35 36 public static boolean isUsingAddr() {37 return useAddr;38 }36 public static boolean isUsingAddr() { 37 return useAddr; 38 } 39 39 40 public static Map<String, String> getTags() {41 return tags;42 }40 public static Map<String, String> getTags() { 41 return tags; 42 } 43 43 44 public static void setBBMode(boolean bbmode) {45 Main.pref.put("buildings_tools.bbmode", bbmode);46 }44 public static void setBBMode(boolean bbmode) { 45 Main.pref.put("buildings_tools.bbmode", bbmode); 46 } 47 47 48 public static boolean isBBMode() {49 return Main.pref.getBoolean("buildings_tools.bbmode", false);50 }48 public static boolean isBBMode() { 49 return Main.pref.getBoolean("buildings_tools.bbmode", false); 50 } 51 51 52 public static void setSoftCursor(boolean softCursor) {53 Main.pref.put("buildings_tools.softcursor", softCursor);54 }52 public static void setSoftCursor(boolean softCursor) { 53 Main.pref.put("buildings_tools.softcursor", softCursor); 54 } 55 55 56 public static boolean isSoftCursor() {57 return Main.pref.getBoolean("buildings_tools.softcursor", false);58 }56 public static boolean isSoftCursor() { 57 return Main.pref.getBoolean("buildings_tools.softcursor", false); 58 } 59 59 60 public static boolean isAutoSelect() {61 return autoSelect;62 }60 public static boolean isAutoSelect() { 61 return autoSelect; 62 } 63 63 64 public static void setAutoSelect(boolean _autoSelect) {65 autoSelect = _autoSelect;66 }64 public static void setAutoSelect(boolean _autoSelect) { 65 autoSelect = _autoSelect; 66 } 67 67 }
Note:
See TracChangeset
for help on using the changeset viewer.
