source: osm/applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/MenuActionGrabPlanImage.java@ 17181

Last change on this file since 17181 was 17181, checked in by pieren, 15 years ago

better handling of dialogs cancellations

File size: 12.0 KB
Line 
1package cadastre_fr;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4
5import java.awt.GridBagLayout;
6import java.awt.Point;
7import java.awt.event.ActionEvent;
8import java.awt.event.MouseEvent;
9import java.awt.event.MouseListener;
10import java.util.ArrayList;
11
12import javax.swing.JLabel;
13import javax.swing.JOptionPane;
14import javax.swing.JPanel;
15import javax.swing.JTextField;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.actions.JosmAction;
19import org.openstreetmap.josm.data.coor.EastNorth;
20import org.openstreetmap.josm.gui.layer.Layer;
21import org.openstreetmap.josm.tools.GBC;
22
23public class MenuActionGrabPlanImage extends JosmAction implements Runnable, MouseListener {
24
25 /**
26 * Action calling the wms grabber for non georeferenced images called "plan image"
27 */
28 private static final long serialVersionUID = 1L;
29
30 public static String name = "Georeference an image";
31
32 private DownloadWMSPlanImage downloadWMSPlanImage;
33 private WMSLayer wmsLayer;
34 private int countMouseClicked = 0;
35 private int mode = 0;
36 private int cGetCorners = 1;
37 private int cGetLambertCrosspieces = 2;
38 private EastNorth ea1;
39 private Point mousePrevious = new Point();
40 private EastNorth georefpoint1;
41 private EastNorth georefpoint2;
42
43 public MenuActionGrabPlanImage() {
44 super(tr(name), "cadastre_small", tr("Grab non-georeferenced image"), null, false);
45 }
46
47 public void actionCompleted() {
48 countMouseClicked = 0;
49 mode = 0;
50 mousePrevious.setLocation(0, 0);
51 }
52
53 public void actionInterrupted() {
54 actionCompleted();
55 wmsLayer = null;
56 }
57
58 @Override
59 protected void updateEnabledState() {
60 if (wmsLayer == null || Main.map == null || Main.map.mapView == null) return;
61 if (countMouseClicked == 0 && mode == 0) return;
62 for (Layer l : Main.map.mapView.getAllLayersAsList())
63 if (l == wmsLayer)
64 return;
65 JOptionPane.showMessageDialog(Main.parent, tr("Georeferencing interrupted"));
66 actionInterrupted();
67 }
68
69 public void actionPerformed(ActionEvent ae) {
70 if (Main.map != null) {
71 if (CadastrePlugin.isCadastreProjection()) {
72 //wmsLayer = WMSDownloadAction.getLayer();
73 wmsLayer = new MenuActionNewLocation().addNewLayer(new ArrayList<WMSLayer>());
74 if (wmsLayer == null) return;
75 downloadWMSPlanImage = new DownloadWMSPlanImage();
76 downloadWMSPlanImage.download(wmsLayer);
77 // download sub-images of the cadastre scan and join them into one single
78 Main.worker.execute(this);
79 } else {
80 JOptionPane.showMessageDialog(Main.parent,
81 tr("To enable the cadastre WMS plugin, change\n"
82 + "the current projection to one of the cadastre\n"
83 + "projections and retry"));
84 }
85 }
86 }
87
88 public void run() {
89 // wait until plan image is fully loaded and joined into one single image
90 boolean loadedFromCache = downloadWMSPlanImage.waitFinished();
91 if (wmsLayer.images.size() == 1 && !loadedFromCache) {
92 Main.map.mapView.addMouseListener(this);
93 if (Main.pref.getBoolean("cadastrewms.noImageCropping", false) == false)
94 startCropping();
95 else
96 startGeoreferencing();
97 } else // action cancelled or image loaded from cache (and already georeferenced)
98 Main.map.repaint();
99 }
100
101 public void mouseClicked(MouseEvent e) {
102 if (e.getX() == mousePrevious.getX() && e.getY() == mousePrevious.getY())
103 return; // double click filtered
104 else
105 mousePrevious.setLocation(e.getX(), e.getY());
106 countMouseClicked++;
107 EastNorth ea = Main.proj.latlon2eastNorth(Main.map.mapView.getLatLon(e.getX(), e.getY()));
108 System.out.println("clic:"+countMouseClicked+" ,"+ea);
109 // ignore clicks outside the image
110 if (ea.east() < wmsLayer.images.get(0).min.east() || ea.east() > wmsLayer.images.get(0).max.east()
111 || ea.north() < wmsLayer.images.get(0).min.north() || ea.north() > wmsLayer.images.get(0).max.north())
112 return;
113 if (mode == cGetCorners) {
114 if (countMouseClicked == 1) {
115 ea1 = ea;
116 continueCropping();
117 }
118 if (countMouseClicked == 2) {
119 wmsLayer.cropImage(ea1, ea);
120 Main.map.mapView.repaint();
121 startGeoreferencing();
122 }
123 } else if (mode == cGetLambertCrosspieces) {
124 if (countMouseClicked == 1) {
125 ea1 = ea;
126 if (inputLambertPosition())
127 continueGeoreferencing();
128 }
129 if (countMouseClicked == 2) {
130 if (inputLambertPosition()) {
131 Main.map.mapView.removeMouseListener(this);
132 affineTransform(ea1, ea, georefpoint1, georefpoint2);
133 wmsLayer.saveNewCache();
134 Main.map.mapView.repaint();
135 actionCompleted();
136 }
137 }
138 }
139 }
140
141 /**
142 *
143 * @return false if all operations are canceled
144 */
145 private boolean startCropping() {
146 mode = cGetCorners;
147 countMouseClicked = 0;
148 Object[] options = { "OK", "Cancel" };
149 int ret = JOptionPane.showOptionDialog( null,
150 tr("Click first corner for image cropping\n(two points required)"),
151 tr("Image cropping"),
152 JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
153 null, options, options[0]);
154 if (ret == JOptionPane.OK_OPTION) {
155 mousePrevious.setLocation(0, 0);
156 } else
157 if (canceledOrRestartCurrAction("image cropping"))
158 return startCropping();
159 return true;
160 }
161
162 /**
163 *
164 * @return false if all operations are canceled
165 */
166 private boolean continueCropping() {
167 Object[] options = { "OK", "Cancel" };
168 int ret = JOptionPane.showOptionDialog( null,
169 tr("Click second corner for image cropping"),
170 tr("Image cropping"),
171 JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
172 null, options, options[0]);
173 if (ret != JOptionPane.OK_OPTION) {
174 if (canceledOrRestartCurrAction("image cropping"))
175 return startCropping();
176 }
177 return true;
178 }
179
180 /**
181 *
182 * @return false if all operations are canceled
183 */
184 private boolean startGeoreferencing() {
185 countMouseClicked = 0;
186 mode = cGetLambertCrosspieces;
187 Object[] options = { "OK", "Cancel" };
188 int ret = JOptionPane.showOptionDialog( null,
189 tr("Click first Lambert crosspiece for georeferencing\n(two points required)"),
190 tr("Image georeferencing"),
191 JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
192 null, options, options[0]);
193 if (ret == JOptionPane.OK_OPTION) {
194 mousePrevious.setLocation(0, 0);
195 } else
196 if (canceledOrRestartCurrAction("georeferencing"))
197 return startGeoreferencing();
198 return true;
199 }
200
201 /**
202 *
203 * @return false if all operations are canceled
204 */
205 private boolean continueGeoreferencing() {
206 Object[] options = { "OK", "Cancel" };
207 int ret = JOptionPane.showOptionDialog( null,
208 tr("Click second Lambert crosspiece for georeferencing"),
209 tr("Image georeferencing"),
210 JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
211 null, options, options[0]);
212 if (ret != JOptionPane.OK_OPTION) {
213 if (canceledOrRestartCurrAction("georeferencing"))
214 return startGeoreferencing();
215 }
216 return true;
217 }
218
219 /**
220 *
221 * @return false if all operations are canceled
222 */
223 private boolean canceledOrRestartCurrAction(String action) {
224 Object[] options = { "Cancel", "Retry" };
225 int selectedValue = JOptionPane.showOptionDialog( null,
226 tr("Do you want to cancel completely\n"+
227 "or just retry "+action+" ?"), "",
228 JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
229 null, options, options[0]);
230 if (selectedValue == 0) { // "Cancel"
231 // remove layer
232 Main.map.mapView.removeLayer(wmsLayer);
233 wmsLayer = null;
234 Main.map.mapView.removeMouseListener(this);
235 return false;
236 } else
237 countMouseClicked = 0;
238 return true;
239 }
240
241 private boolean inputLambertPosition() {
242 JLabel labelEnterPosition = new JLabel(tr("Enter cadastre east,north position"));
243 JLabel labelWarning = new JLabel(tr("(Warning: verify north with arrow !!)"));
244 JPanel p = new JPanel(new GridBagLayout());
245 JLabel labelEast = new JLabel(tr("East"));
246 JLabel labelNorth = new JLabel(tr("North"));
247 final JTextField inputEast = new JTextField();
248 final JTextField inputNorth = new JTextField();
249 p.add(labelEnterPosition, GBC.eol());
250 p.add(labelWarning, GBC.eol());
251 p.add(labelEast, GBC.std().insets(0, 0, 10, 0));
252 p.add(inputEast, GBC.eol().fill(GBC.HORIZONTAL).insets(10, 5, 0, 5));
253 p.add(labelNorth, GBC.std().insets(0, 0, 10, 0));
254 p.add(inputNorth, GBC.eol().fill(GBC.HORIZONTAL).insets(10, 5, 0, 5));
255 JOptionPane pane = new JOptionPane(p, JOptionPane.INFORMATION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null);
256 String number;
257 if (countMouseClicked == 1) number = "first";
258 else number = "second";
259 pane.createDialog(Main.parent, tr("Set "+number+" Lambert coordinate")).setVisible(true);
260 if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(pane.getValue())) {
261 if (canceledOrRestartCurrAction("georeferencing"))
262 startGeoreferencing();
263 return false;
264 }
265 if (inputEast.getText().length() != 0 && inputNorth.getText().length() != 0) {
266 try {
267 double e = Double.parseDouble(inputEast.getText());
268 double n = Double.parseDouble(inputNorth.getText());
269 if (countMouseClicked == 1)
270 georefpoint1 = new EastNorth(e, n);
271 else
272 georefpoint2 = new EastNorth(e, n);
273 return true;
274 } catch (NumberFormatException e) {
275 return false;
276 }
277 }
278 return false;
279 }
280
281 /**
282 * Use point org1 as anchor for scale, then move org1 to dst1, then rotate org2 on dst2
283 * around org1/dst1 anchor
284 * @param org1 first point at original coordinate system (the grabbed image)
285 * @param org2 second point "
286 * @param dst1 first point at final destination coordinate system (the real east/north coordinate system)
287 * @param dst2 second point "
288 */
289 private void affineTransform(EastNorth org1, EastNorth org2, EastNorth dst1, EastNorth dst2) {
290 double angle = dst1.heading(dst2) - org1.heading(org2);
291 double proportion = dst1.distance(dst2)/org1.distance(org2);
292 // move
293 double dx = dst1.getX() - org1.getX();
294 double dy = dst1.getY() - org1.getY();
295 wmsLayer.images.get(0).shear(dx, dy);
296 org1 = org1.add(dx, dy); // org1=dst1 now
297 org2 = org2.add(dx, dy);
298 // rotate : org1(=dst1 now) is anchor for rotation and scale
299 wmsLayer.images.get(0).rotate(dst1, angle);
300 org2 = org2.rotate(dst1, angle);
301 // scale image from anchor org1(=dst1 now)
302 wmsLayer.images.get(0).scale(dst1, proportion);
303 }
304
305 public void mouseEntered(MouseEvent arg0) {
306 }
307
308 public void mouseExited(MouseEvent arg0) {
309 }
310
311 public void mousePressed(MouseEvent arg0) {
312 }
313
314 public void mouseReleased(MouseEvent arg0) {
315 }
316
317}
Note: See TracBrowser for help on using the repository browser.