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

Last change on this file since 17702 was 17702, checked in by stoecker, 15 years ago

fixed typos

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