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

Last change on this file since 17089 was 17089, checked in by pieren, 16 years ago

raster image feature implementation

File size: 8.8 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 + "projection 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 mousePrevious.setLocation(0, 0);
94 mode = cGetCorners;
95 JOptionPane.showMessageDialog(Main.parent,tr("Click first corner for image cropping\n"+
96 "(two points required)"));
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 JOptionPane.showMessageDialog(Main.parent,tr("Click second corner for image cropping"));
117 }
118 if (countMouseClicked == 2) {
119 wmsLayer.cropImage(ea1, ea);
120 Main.map.mapView.repaint();
121 countMouseClicked = 0;
122 mode = cGetLambertCrosspieces;
123 JOptionPane.showMessageDialog(Main.parent,tr("Click first Lambert crosspiece for georeferencing\n"+
124 "(two points required)"));
125 }
126 } else if (mode == cGetLambertCrosspieces) {
127 if (countMouseClicked == 1) {
128 ea1 = ea;
129 georefpoint1 = inputLambertPosition();
130 if (georefpoint1 == null)
131 return;
132 JOptionPane.showMessageDialog(Main.parent,tr("Click second Lambert crosspiece for georeferencing\n"));
133 }
134 if (countMouseClicked == 2) {
135 Main.map.mapView.removeMouseListener(this);
136 georefpoint2 = inputLambertPosition();
137 if (georefpoint2 == null)
138 return;
139 affineTransform(ea1, ea, georefpoint1, georefpoint2);
140 wmsLayer.saveNewCache();
141 Main.map.mapView.repaint();
142 actionCompleted();
143 }
144 }
145 }
146
147 private EastNorth inputLambertPosition() {
148 JLabel labelEnterPosition = new JLabel(tr("Enter cadastre east,north position"));
149 JLabel labelWarning = new JLabel(tr("(Warning: verify north with arrow !!)"));
150 JPanel p = new JPanel(new GridBagLayout());
151 JLabel labelEast = new JLabel(tr("East"));
152 JLabel labelNorth = new JLabel(tr("North"));
153 final JTextField inputEast = new JTextField();
154 final JTextField inputNorth = new JTextField();
155 p.add(labelEnterPosition, GBC.eol());
156 p.add(labelWarning, GBC.eol());
157 p.add(labelEast, GBC.std().insets(0, 0, 10, 0));
158 p.add(inputEast, GBC.eol().fill(GBC.HORIZONTAL).insets(10, 5, 0, 5));
159 p.add(labelNorth, GBC.std().insets(0, 0, 10, 0));
160 p.add(inputNorth, GBC.eol().fill(GBC.HORIZONTAL).insets(10, 5, 0, 5));
161 JOptionPane pane = new JOptionPane(p, JOptionPane.INFORMATION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null);
162 pane.createDialog(Main.parent, tr("Set Lambert coordinate")).setVisible(true);
163 if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(pane.getValue()))
164 return null;
165 if (inputEast.getText().length() == 0 || inputNorth.getText().length() == 0)
166 return null;
167 try {
168 double e = Double.parseDouble(inputEast.getText());
169 double n = Double.parseDouble(inputNorth.getText());
170 return new EastNorth(e, n);
171 } catch (NumberFormatException e) {
172 return null;
173 }
174 }
175
176 /**
177 * Use point org1 as anchor for scale, then move org1 to dst1, then rotate org2 on dst2
178 * around org1/dst1 anchor
179 * @param org1 first point at original coordinate system (the grabbed image)
180 * @param org2 second point "
181 * @param dst1 first point at final destination coordinate system (the real east/north coordinate system)
182 * @param dst2 second point "
183 */
184 private void affineTransform(EastNorth org1, EastNorth org2, EastNorth dst1, EastNorth dst2) {
185 double angle = dst1.heading(dst2) - org1.heading(org2);
186 double proportion = dst1.distance(dst2)/org1.distance(org2);
187 // move
188 double dx = dst1.getX() - org1.getX();
189 double dy = dst1.getY() - org1.getY();
190 wmsLayer.images.get(0).shear(dx, dy);
191 org1 = org1.add(dx, dy); // org1=dst1 now
192 org2 = org2.add(dx, dy);
193 // rotate : org1(=dst1 now) is anchor for rotation and scale
194 wmsLayer.images.get(0).rotate(dst1, angle);
195 org2 = org2.rotate(dst1, angle);
196 // scale image from anchor org1(=dst1 now)
197 wmsLayer.images.get(0).scale(dst1, proportion);
198 }
199
200 public void mouseEntered(MouseEvent arg0) {
201 }
202
203 public void mouseExited(MouseEvent arg0) {
204 }
205
206 public void mousePressed(MouseEvent arg0) {
207 }
208
209 public void mouseReleased(MouseEvent arg0) {
210 }
211
212}
Note: See TracBrowser for help on using the repository browser.