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

Last change on this file since 32425 was 32425, checked in by donvip, 8 years ago

remove calls to deprecated methods

File size: 13.4 KB
Line 
1package cadastre_fr;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4
5import java.awt.GridBagLayout;
6import java.awt.event.MouseEvent;
7import java.awt.event.MouseListener;
8import java.beans.PropertyChangeEvent;
9import java.beans.PropertyChangeListener;
10
11import javax.swing.JDialog;
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.data.coor.EastNorth;
19import org.openstreetmap.josm.tools.GBC;
20
21public class RasterImageGeoreferencer implements MouseListener {
22
23 private int countMouseClicked = 0;
24 private int mode = 0;
25 private int cGetCorners = 1;
26 private int cGetLambertCrosspieces = 2;
27 private EastNorth ea1;
28 private EastNorth ea2;
29 private long mouseClickedTime = 0;
30 private WMSLayer wmsLayer;
31 private EastNorth georefpoint1;
32 private EastNorth georefpoint2;
33 private boolean ignoreMouseClick = false;
34 private boolean clickOnTheMap = false;
35
36 /**
37 * The time which needs to pass between two clicks during georeferencing, in milliseconds
38 */
39 private int initialClickDelay;
40
41 public void addListener(){
42 Main.map.mapView.addMouseListener(this);
43 }
44
45 /**
46 *
47 * @return false if all operations are canceled
48 */
49 public boolean startCropping(WMSLayer wmsLayer) {
50 this.wmsLayer = wmsLayer;
51 mode = cGetCorners;
52 countMouseClicked = 0;
53 initialClickDelay = Main.pref.getInteger("cadastrewms.georef-click-delay",200);
54 mouseClickedTime = System.currentTimeMillis();
55 Object[] options = { "OK", "Cancel" };
56 int ret = JOptionPane.showOptionDialog( null,
57 tr("Click first corner for image cropping\n(two points required)"),
58 tr("Image cropping"),
59 JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
60 null, options, options[0]);
61 if (ret == JOptionPane.OK_OPTION) {
62 mouseClickedTime = System.currentTimeMillis();
63 } else
64 if (canceledOrRestartCurrAction("image cropping"))
65 return startCropping(wmsLayer);
66 return true;
67 }
68
69 /**
70 *
71 * @return false if all operations are canceled
72 */
73 public boolean startGeoreferencing(WMSLayer wmsLayer) {
74 this.wmsLayer = wmsLayer;
75 countMouseClicked = 0;
76 mode = cGetLambertCrosspieces;
77 initialClickDelay = Main.pref.getInteger("cadastrewms.georef-click-delay",200);
78 mouseClickedTime = System.currentTimeMillis();
79 Object[] options = { "OK", "Cancel" };
80 int ret = JOptionPane.showOptionDialog( null,
81 tr("Click first Lambert crosspiece for georeferencing\n(two points required)"),
82 tr("Image georeferencing"),
83 JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
84 null, options, options[0]);
85 if (ret == JOptionPane.OK_OPTION) {
86 mouseClickedTime = System.currentTimeMillis();
87 } else
88 if (canceledOrRestartCurrAction("georeferencing"))
89 return startGeoreferencing(wmsLayer);
90 return true;
91 }
92
93 public boolean isRunning()
94 {
95 return (countMouseClicked != 0 || mode != 0);
96 }
97
98 @Override
99 public void mouseClicked(MouseEvent e) {
100 if (System.currentTimeMillis() - mouseClickedTime < initialClickDelay) {
101 Main.info("mouse click bounce detected");
102 return; // mouse click anti-bounce
103 }
104 else
105 mouseClickedTime = System.currentTimeMillis();
106 if (e.getButton() != MouseEvent.BUTTON1)
107 return;
108 if (ignoreMouseClick) return; // In case we are currently just allowing zooming to read lambert coordinates
109 EastNorth ea = Main.getProjection().latlon2eastNorth(Main.map.mapView.getLatLon(e.getX(), e.getY()));
110 Main.info("click:"+countMouseClicked+" ,"+ea+", mode:"+mode);
111 if (clickOnTheMap) {
112 clickOnTheMap = false;
113 handleNewCoordinates(ea.east(), ea.north());
114 } else {
115 // ignore clicks outside the image
116 if (ea.east() < wmsLayer.getImage(0).min.east() || ea.east() > wmsLayer.getImage(0).max.east()
117 || ea.north() < wmsLayer.getImage(0).min.north() || ea.north() > wmsLayer.getImage(0).max.north())
118 {
119 Main.info("ignore click outside the image");
120 return;
121 }
122 countMouseClicked++;
123 if (mode == cGetCorners) {
124 if (countMouseClicked == 1) {
125 ea1 = ea;
126 continueCropping();
127 }
128 if (countMouseClicked == 2) {
129 wmsLayer.cropImage(ea1, ea);
130 Main.map.mapView.repaint();
131 startGeoreferencing(wmsLayer);
132 }
133 } else if (mode == cGetLambertCrosspieces) {
134 if (countMouseClicked == 1) {
135 ea1 = ea;
136 inputLambertPosition(); // This will automatically asks for second point and continue the georeferencing
137 }
138 if (countMouseClicked == 2) {
139 ea2 = ea;
140 inputLambertPosition(); // This will automatically ends the georeferencing
141 }
142 }
143 }
144 }
145
146
147 /**
148 *
149 * @return false if all operations are canceled
150 */
151 private boolean canceledOrRestartCurrAction(String action) {
152 Object[] options = { "Cancel", "Retry" };
153 int selectedValue = JOptionPane.showOptionDialog( null,
154 tr("Do you want to cancel completely\n"+
155 "or just retry "+action+" ?"), "",
156 JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
157 null, options, options[0]);
158 countMouseClicked = 0;
159 if (selectedValue == 0) { // "Cancel"
160 // remove layer
161 Main.getLayerManager().removeLayer(wmsLayer);
162 wmsLayer = null;
163 Main.map.mapView.removeMouseListener(this);
164 return false;
165 }
166 return true;
167 }
168
169 /**
170 * Use point org1 as anchor for scale, then move org1 to dst1, then rotate org2 on dst2
171 * around org1/dst1 anchor
172 * @param org1 first point at original coordinate system (the grabbed image)
173 * @param org2 second point "
174 * @param dst1 first point at final destination coordinate system (the real east/north coordinate system)
175 * @param dst2 second point "
176 */
177 private void affineTransform(EastNorth org1, EastNorth org2, EastNorth dst1, EastNorth dst2) {
178 // handle an NPE case I'm not able to reproduce
179 if(org1==null || org2==null || dst1==null || dst2==null)
180 {
181 JOptionPane.showMessageDialog(Main.parent,
182 tr("Ooops. I failed to catch all coordinates\n"+
183 "correctly. Retry please."));
184 Main.warn("failed to transform: one coordinate missing:"
185 +"org1="+org1+", org2="+org2+", dst1="+dst1+", dst2="+dst2);
186 return;
187 }
188 double angle = dst1.heading(dst2) - org1.heading(org2);
189 double proportion = dst1.distance(dst2)/org1.distance(org2);
190 // move
191 double dx = dst1.getX() - org1.getX();
192 double dy = dst1.getY() - org1.getY();
193 wmsLayer.getImage(0).shear(dx, dy);
194 org1 = org1.add(dx, dy); // org1=dst1 now
195 org2 = org2.add(dx, dy);
196 // rotate : org1(=dst1 now) is anchor for rotation and scale
197 wmsLayer.getImage(0).rotate(dst1, angle);
198 org2 = org2.rotate(dst1, angle);
199 // scale image from anchor org1(=dst1 now)
200 wmsLayer.getImage(0).scale(dst1, proportion);
201 }
202
203 /**
204 * Ends the georeferencing by computing the affine transformation
205 */
206 private void endGeoreferencing() {
207 Main.map.mapView.removeMouseListener(this);
208 affineTransform(ea1, ea2, georefpoint1, georefpoint2);
209 wmsLayer.grabThread.saveNewCache();
210 Main.map.mapView.repaint();
211 actionCompleted();
212 clickOnTheMap = false;
213 ignoreMouseClick = false;
214 }
215
216 private void inputLambertPosition() {
217 JLabel labelEnterPosition = new JLabel(
218 tr("Enter cadastre east,north position"));
219 JLabel labelWarning = new JLabel(
220 tr("(Warning: verify north with arrow !!)"));
221 JPanel p = new JPanel(new GridBagLayout());
222 JLabel labelEast = new JLabel(tr("East"));
223 JLabel labelNorth = new JLabel(tr("North"));
224 final JTextField inputEast = new JTextField();
225 final JTextField inputNorth = new JTextField();
226 p.add(labelEnterPosition, GBC.eol());
227 p.add(labelWarning, GBC.eol());
228 p.add(labelEast, GBC.std().insets(0, 0, 10, 0));
229 p.add(inputEast, GBC.eol().fill(GBC.HORIZONTAL).insets(10, 5, 0, 5));
230 p.add(labelNorth, GBC.std().insets(0, 0, 10, 0));
231 p.add(inputNorth, GBC.eol().fill(GBC.HORIZONTAL).insets(10, 5, 0, 5));
232 final Object[] options = {tr("OK"),
233 tr("Cancel"),
234 tr("I use the mouse")};
235 final JOptionPane pane = new JOptionPane(p,
236 JOptionPane.INFORMATION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION,
237 null, options, options[0]);
238 String number;
239 if (countMouseClicked == 1)
240 number = "first";
241 else
242 number = "second";
243 JDialog dialog = pane.createDialog(Main.parent, tr(
244 "Set {0} Lambert coordinates", number));
245 dialog.setModal(false);
246 ignoreMouseClick = true; // To avoid mouseClicked from being called
247 // during coordinates reading
248 dialog.setAlwaysOnTop(true);
249 dialog.setVisible(true);
250 pane.addPropertyChangeListener(new PropertyChangeListener() {
251 @Override
252 public void propertyChange(PropertyChangeEvent evt) {
253 if (JOptionPane.VALUE_PROPERTY.equals(evt.getPropertyName())) {
254 ignoreMouseClick = false;
255 // Cancel
256 if (pane.getValue().equals(options[1])) {
257 if (canceledOrRestartCurrAction("georeferencing"))
258 startGeoreferencing(wmsLayer);
259 }
260 // Click on the map
261 if (pane.getValue().equals(options[2])) {
262 clickOnTheMap = true;
263 } else {
264 // OK (coordinates manually entered)
265 clickOnTheMap = false;
266 if (inputEast.getText().length() != 0
267 && inputNorth.getText().length() != 0) {
268 double e, n;
269 try {
270 e = Double.parseDouble(inputEast.getText());
271 n = Double.parseDouble(inputNorth.getText());
272 } catch (NumberFormatException ex) {
273 return;
274 }
275 handleNewCoordinates(e, n);
276 }
277 }
278 }
279 }
280 });
281 }
282
283 /**
284 *
285 * @return false if all operations are canceled
286 */
287private boolean continueCropping() {
288 Object[] options = { "OK", "Cancel" };
289 int ret = JOptionPane.showOptionDialog( null,
290 tr("Click second corner for image cropping"),
291 tr("Image cropping"),
292 JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
293 null, options, options[0]);
294 if (ret != JOptionPane.OK_OPTION) {
295 if (canceledOrRestartCurrAction("image cropping"))
296 return startCropping(wmsLayer);
297 }
298 return true;
299}
300
301public void transformGeoreferencedImg() {
302 georefpoint1 = new EastNorth(wmsLayer.X0, wmsLayer.Y0);
303 georefpoint2 = new EastNorth(wmsLayer.X0+wmsLayer.fX*wmsLayer.communeBBox.max.getX(),
304 wmsLayer.Y0+wmsLayer.fY*wmsLayer.communeBBox.max.getX());
305 ea1 = new EastNorth(wmsLayer.getImage(0).min.east(), wmsLayer.getImage(0).max.north());
306 EastNorth ea2 = wmsLayer.getImage(0).max;
307 affineTransform(ea1, ea2, georefpoint1, georefpoint2);
308 wmsLayer.grabThread.saveNewCache();
309 Main.map.mapView.repaint();
310}
311
312
313 /**
314 *
315 * @return false if all operations are canceled
316 */
317private boolean continueGeoreferencing() {
318 Object[] options = { "OK", "Cancel" };
319 int ret = JOptionPane.showOptionDialog( null,
320 tr("Click second Lambert crosspiece for georeferencing"),
321 tr("Image georeferencing"),
322 JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
323 null, options, options[0]);
324 if (ret != JOptionPane.OK_OPTION) {
325 if (canceledOrRestartCurrAction("georeferencing"))
326 return startGeoreferencing(wmsLayer);
327 }
328 return true;
329}
330
331 private void handleNewCoordinates(double e, double n) {
332 if (countMouseClicked == 1) {
333 georefpoint1 = new EastNorth(e, n);
334 continueGeoreferencing();
335 } else {
336 georefpoint2 = new EastNorth(e, n);
337 endGeoreferencing();
338 }
339 }
340
341 private void actionCompleted() {
342 countMouseClicked = 0;
343 mode = 0;
344 mouseClickedTime = System.currentTimeMillis();
345 }
346
347 public void actionInterrupted() {
348 actionCompleted();
349 if (wmsLayer != null) {
350 Main.getLayerManager().removeLayer(wmsLayer);
351 wmsLayer = null;
352 }
353 }
354
355 @Override
356 public void mouseEntered(MouseEvent arg0) {
357 }
358
359 @Override
360 public void mouseExited(MouseEvent arg0) {
361 }
362
363 @Override
364 public void mousePressed(MouseEvent arg0) {
365 }
366
367 @Override
368 public void mouseReleased(MouseEvent arg0) {
369 }
370}
Note: See TracBrowser for help on using the repository browser.