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

Last change on this file since 25045 was 25045, checked in by pieren, 14 years ago

Move the grabber single instance from CadastrePlugin singleton to each WMSLayer instance to allow several municipalities grabbing in parallel.

  • Property svn:eol-style set to native
File size: 19.4 KB
Line 
1// License: GPL. v2 and later. Copyright 2008-2009 by Pieren <pieren3@gmail.com> and others
2package cadastre_fr;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.marktr;
6import static org.openstreetmap.josm.tools.I18n.tr;
7
8import java.awt.event.ActionEvent;
9import java.awt.event.ActionListener;
10import java.awt.event.KeyEvent;
11import java.io.File;
12
13import javax.swing.JCheckBoxMenuItem;
14import javax.swing.JDialog;
15import javax.swing.JMenu;
16import javax.swing.JMenuItem;
17import javax.swing.JOptionPane;
18import javax.swing.KeyStroke;
19
20import org.openstreetmap.josm.Main;
21import org.openstreetmap.josm.actions.JosmAction;
22import org.openstreetmap.josm.actions.UploadAction;
23import org.openstreetmap.josm.gui.MainMenu;
24import org.openstreetmap.josm.gui.MapFrame;
25import org.openstreetmap.josm.gui.IconToggleButton;
26import org.openstreetmap.josm.gui.layer.Layer;
27import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
28import org.openstreetmap.josm.plugins.Plugin;
29import org.openstreetmap.josm.plugins.PluginInformation;
30import org.openstreetmap.josm.data.projection.*;
31
32/**
33 *
34 * Plugin to access the French Cadastre WMS server at www.cadastre.gouv.fr This
35 * WMS server requires some specific handling like retrieving a cookie for a
36 * limitation in case of no activity, or the request to the server shall provide
37 * a city/town/village code.
38 *
39 * @author Pieren <pieren3@gmail.com>,
40 * @author <matthieu.lochegnies@gmail.com> for the extension to codeCommune
41 * @version 0.8
42 * History:
43 * 0.1 17-Jun-2008 first prototype using a first Lambert projection impl. in core
44 * 0.2 22-Jun-2008 first stable version
45 * 0.3 24-Jun-2008 add code departement
46 * 0.4 06-Jul-2008 - add images scales, icons, menu items disabling
47 * - remove dependencies of wmsplugin
48 * - add option to force a Lambert zone (for median locations)
49 * - add auto-sourcing
50 * 0.5 16-Aug-2008 - add transparency in layer (allowing multiple wms layers displayed together)
51 * - no overlapping of grabbed images if transparency is enabled
52 * - set one layer per location
53 * - use utf-8 charset in POST request to server
54 * - improve the preferences setting dialog
55 * - cancel the current download is now possible
56 * - add automatic images caching and load on request (+ manage cache directory size)
57 * - enable auto-sourcing only if a WMS layer is used
58 * 0.6 18-Aug-2008 - suppress the null-exception message after the dialog 'open a layer first'
59 * - process the overlapping images when cache is loaded from disk
60 * - save the last 'new location request' text again in preferences
61 * - avoid duplicate layers with same name
62 * - set text input for new locations in upper case
63 * - the cache directory is configurable in "cadastrewms.cacheDir"
64 * - improve configuration change updates
65 * 0.7 24-Aug-2008 - mask images only if transparency enabled
66 * - validate projection name by Lambert.toString() method
67 * 0.8 25-Jan-2009 - display returned list of communes if direct name is not recognized by server
68 * - new possible grab factor of 100 square meters fixed size
69 * - minor fixes due to changes in JOSM core classes
70 * - first draft of raster image support
71 * 0.9 05-Feb-2009 - grab vectorized full commune bbox, save in file, convert to OSM way
72 * and simplify
73 * 1.0 18-Feb-2009 - fix various bugs in color management and preference dialog
74 * - increase PNG picture size requested to WMS (800x1000)
75 * - set 4th grab scale fixed size configurable (from 25 to 1000 meters)
76 * 1.1 11-Jun-2009 - fixed a null exception error when trying to displace a vectorized layer
77 * - propose to use shortcut F11 for grabbing
78 * 1.2 16-Aug-2009 - implementation of raster image grabbing, cropping and georeferencing (not the
79 * overview rasters (Tableau d'assemblage) but directly small units (Feuille)
80 * 1.3 23-Aug-2009 - improve georeferencing action cancellation
81 * - fixed bug of raster image loaded from cache not working on Java1.6
82 * - improve mouse click bounce detection during georeferencing process
83 * 1.4 25-Oct-2009 - add support for new Lambert CC 9 Zones projection
84 * - add optional crosspieces display on raster image layers
85 * - add automatic raster images georeferencing when WMS provides data
86 * - re-implement manual adjustment mode in raster image layer
87 * 1.5 21-Nov-2009 - major changes in projection in core : no magical zone prediction anymore for
88 * Lambert 4 and 9 zones; grid translation implemented for Lambert 4 zones;
89 * support of subprojections in preferences for zones setting and UTM20N
90 * - removed autosourcing of empty new nodes
91 * 1.6 28-Nov-2009 - Fix minor issues if Grab is called without layer (possible since projection rework)
92 * 1.7 12-Dec-2009 - Change URL's changes for cookie and downgrade imgs resolution due to WMS changes
93 * 1.8 11-Mar-2010 - filter the mouse button 1 during georeferencing
94 * - retry if getting a new cookie failed (10 times during 30 seconds)
95 * - cookie expiration automatically detected and renewed (after 30 minutes)
96 * - proper WMS layer cleanup at destruction (workaround for memory leak)
97 * - new cache format (v3) storing original image and cropped image bbox + angle
98 * - new cache format (v4) storing original image size for later rotation
99 * - cache files read compatible with previous formats
100 * - raster image rotation issues fixed, now using shift+ctrl key instead of ctrl
101 * - raster image adjustment using default system menu modifier (ctrl for windows) for Mac support
102 * - image resolution configurable (high, medium, low) like the online interface
103 * - layer selection configurable for vectorized images
104 * - improved download cancellation
105 * - from Erik Amzallag:
106 * - possibility to modify the auto-sourcing text just before upload
107 * - from Clément Ménier:
108 * - new option allowing an auto-selection of the first cadastre layer for grab
109 * - non-modal JDialog in MenuActionGrabPlanImage
110 * - new options in the image filter (bilinear, bicubic)
111 * 1.9 05-Apr-2010 - added a scroll bar in preferences
112 * - download cancellation improved
113 * - last deployment for Java1.5 compatibility
114 * 2.0 xx-xxx-xxxx - update projection for "La Reunion" departement to RGR92, UTM40S.
115 * - add 'departement' as option in the municipality selection
116 * - fixed bug in cache directory size control (and disabled by default)
117 * - add map mode for addressing
118 * - from Nicolas Dumoulin:
119 * - add "tableau d'assemblage" in raster images for georeferencing (as option)
120 */
121public class CadastrePlugin extends Plugin {
122 static String VERSION = "2.0";
123
124 static JMenu cadastreJMenu;
125
126 public static String source = "";
127
128 // true if the checkbox "auto-sourcing" is set in the plugin menu
129 public static boolean autoSourcing = false;
130
131 // true when the plugin is first used, e.g. grab from WMS or download cache file
132 public static boolean pluginUsed = false;
133
134 public static String cacheDir = null;
135
136 public static boolean alterColors = false;
137
138 public static boolean backgroundTransparent = false;
139
140 public static float transparency = 1.0f;
141
142 public static boolean drawBoundaries = false;
143
144 public static int imageWidth, imageHeight;
145
146 public static String grabLayers, grabStyles = null;
147
148 static private boolean menuEnabled = false;
149
150 /**
151 * Creates the plugin and setup the default settings if necessary
152 *
153 * @throws Exception
154 */
155 public CadastrePlugin(PluginInformation info) throws Exception {
156 super(info);
157 System.out.println("Pluging cadastre-fr v"+VERSION+" started...");
158 if (Main.pref.get("cadastrewms.cacheDir").equals(""))
159 cacheDir = Main.pref.getPreferencesDir()+"plugins"+File.separatorChar+"cadastrewms"+File.separatorChar;
160 else {
161 cacheDir = Main.pref.get("cadastrewms.cacheDir");
162 if (cacheDir.charAt(cacheDir.length()-1) != File.separatorChar )
163 cacheDir += File.separatorChar;
164 }
165 System.out.println("current cache directory: "+cacheDir);
166
167 refreshConfiguration();
168
169 UploadAction.registerUploadHook(new CheckSourceUploadHook());
170
171 }
172
173 public static void refreshMenu() {
174 MainMenu menu = Main.main.menu;
175
176 if (cadastreJMenu == null) {
177 cadastreJMenu = menu.addMenu(marktr("Cadastre"), KeyEvent.VK_C, menu.defaultMenuPos, ht("/Plugin/CadastreFr"));
178 JosmAction grab = new MenuActionGrab();
179 JMenuItem menuGrab = new JMenuItem(grab);
180 KeyStroke ks = grab.getShortcut().getKeyStroke();
181 if (ks != null) {
182 menuGrab.setAccelerator(ks);
183 }
184 JMenuItem menuActionGrabPlanImage = new JMenuItem(new MenuActionGrabPlanImage());
185 JMenuItem menuSettings = new JMenuItem(new MenuActionNewLocation());
186 final JCheckBoxMenuItem menuSource = new JCheckBoxMenuItem(tr("Auto sourcing"));
187 menuSource.setSelected(autoSourcing);
188 menuSource.addActionListener(new ActionListener() {
189 public void actionPerformed(ActionEvent ev) {
190 Main.pref.put("cadastrewms.autosourcing", menuSource.isSelected());
191 autoSourcing = menuSource.isSelected();
192 }
193 });
194
195 //JMenuItem menuResetCookie = new JMenuItem(new MenuActionResetCookie());
196 //JMenuItem menuLambertZone = new JMenuItem(new MenuActionLambertZone());
197 JMenuItem menuLoadFromCache = new JMenuItem(new MenuActionLoadFromCache());
198 // temporary disabled:
199 //JMenuItem menuActionBoundaries = new JMenuItem(new MenuActionBoundaries());
200 //JMenuItem menuActionBuildings = new JMenuItem(new MenuActionBuildings());
201
202 cadastreJMenu.add(menuGrab);
203 cadastreJMenu.add(menuActionGrabPlanImage);
204 cadastreJMenu.add(menuSettings);
205 cadastreJMenu.add(menuSource);
206 //cadastreJMenu.add(menuResetCookie); not required any more
207 //cadastreJMenu.add(menuLambertZone);
208 //if (Main.pref.getBoolean("cadastrewms.buildingsMenu", false))
209 // cadastreJMenu.add(menuActionBuildings);
210 cadastreJMenu.add(menuLoadFromCache);
211 // all SVG features disabled until official WMS is released
212 //cadastreJMenu.add(menuActionBoundaries);
213 }
214 setEnabledAll(menuEnabled);
215 }
216
217 public static void refreshConfiguration() {
218 source = checkSourceMillesime();
219 autoSourcing = Main.pref.getBoolean("cadastrewms.autosourcing", true);
220 alterColors = Main.pref.getBoolean("cadastrewms.alterColors");
221 drawBoundaries = Main.pref.getBoolean("cadastrewms.drawBoundaries", false);
222 if (alterColors) {
223 backgroundTransparent = Main.pref.getBoolean("cadastrewms.backgroundTransparent");
224 transparency = Float.parseFloat(Main.pref.get("cadastrewms.brightness", "1.0f"));
225 } else {
226 backgroundTransparent = false;
227 transparency = 1.0f;
228 }
229 String currentResolution = Main.pref.get("cadastrewms.resolution", "high");
230 if (currentResolution.equals("high")) {
231 imageWidth = 1000; imageHeight = 800;
232 } else if (currentResolution.equals("medium")){
233 imageWidth = 800; imageHeight = 600;
234 } else {
235 imageWidth = 600; imageHeight = 400;
236 }
237 refreshLayersURL();
238
239 // overwrite F11 shortcut used from the beginning by this plugin and recently used
240 // for full-screen switch in JOSM core
241 int i = 0;
242 String p = Main.pref.get("shortcut.shortcut."+i, null);
243 boolean alreadyRedefined = false;
244 while (p != null) {
245 String[] s = p.split(";");
246 alreadyRedefined = alreadyRedefined || s[0].equals("menu:view:fullscreen");
247 i++;
248 p = Main.pref.get("shortcut.shortcut."+i, null);
249 }
250 if (!alreadyRedefined) {
251 int reply = JOptionPane.showConfirmDialog(null,
252 tr("Plugin cadastre-fr used traditionaly for grabbing the key shortcut F11\n"+
253 "which is currently allocated for full-screen switch by default\n"+
254 "Would you like to restore F11 for grab action ?"),
255 tr("Restore grab shortcut F11"),
256 JOptionPane.YES_NO_OPTION);
257 if (reply == JOptionPane.OK_OPTION) {
258 System.out.println("redefine fullscreen shortcut F11 to shift+F11");
259 Main.pref.put("shortcut.shortcut."+i, "menu:view:fullscreen;Toggle Full Screen view;122;5;122;64;false;true");
260 JOptionPane.showMessageDialog(Main.parent,tr("JOSM is stopped for the change to take effect."));
261 System.exit(0);
262 }
263 } else
264 System.out.println("shortcut F11 already redefined; do not change");
265
266 refreshMenu();
267 }
268
269 private static void refreshLayersURL() {
270 grabLayers = "";
271 grabStyles = "";
272 if (Main.pref.getBoolean("cadastrewms.layerWater", true)) {
273 grabLayers += "CDIF:LS3,";
274 grabStyles += "LS3_90,";
275 }
276 if (Main.pref.getBoolean("cadastrewms.layerBuilding", true)) {
277 grabLayers += "CDIF:LS2,";
278 grabStyles += "LS2_90,";
279 }
280 if (Main.pref.getBoolean("cadastrewms.layerSymbol", true)) {
281 grabLayers += "CDIF:LS1,";
282 grabStyles += "LS1_90,";
283 }
284 if (Main.pref.getBoolean("cadastrewms.layerParcel", true)) {
285 grabLayers += "CDIF:PARCELLE,";
286 grabStyles += "PARCELLE_90,";
287 }
288 if (Main.pref.getBoolean("cadastrewms.layerNumero", true)) {
289 grabLayers += "CDIF:NUMERO,";
290 grabStyles += "NUMERO_90,";
291 }
292 if (Main.pref.getBoolean("cadastrewms.layerLabel", true)) {
293 grabLayers += "CDIF:PT3,CDIF:PT2,CDIF:PT1,";
294 grabStyles += "PT3_90,PT2_90,PT1_90,";
295 }
296 if (Main.pref.getBoolean("cadastrewms.layerLieudit", true)) {
297 grabLayers += "CDIF:LIEUDIT,";
298 grabStyles += "LIEUDIT_90,";
299 }
300 if (Main.pref.getBoolean("cadastrewms.layerSection", true)) {
301 grabLayers += "CDIF:SUBSECTION,CDIF:SECTION,";
302 grabStyles += "SUBSECTION_90,SECTION_90,";
303 }
304 if (Main.pref.getBoolean("cadastrewms.layerCommune", true)) {
305 grabLayers += "CDIF:COMMUNE,";
306 grabStyles += "COMMUNE_90,";
307 }
308 if (grabLayers.length() > 0) { // remove the last ','
309 grabLayers = grabLayers.substring(0, grabLayers.length()-1);
310 grabStyles = grabStyles.substring(0, grabStyles.length()-1);
311 }
312 }
313
314 @Override
315 public PreferenceSetting getPreferenceSetting() {
316 return new CadastrePreferenceSetting();
317 }
318
319 private static void setEnabledAll(boolean isEnabled) {
320 for (int i = 0; i < cadastreJMenu.getItemCount(); i++) {
321 JMenuItem item = cadastreJMenu.getItem(i);
322 if (item != null)
323 if (item.getText().equals(MenuActionGrabPlanImage.name) /*||
324 item.getText().equals(MenuActionGrab.name) ||
325 item.getText().equals(MenuActionBoundaries.name) ||
326 item.getText().equals(MenuActionBuildings.name)*/) {
327 item.setEnabled(isEnabled);
328 }
329 }
330 menuEnabled = isEnabled;
331 }
332
333 public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
334 if (cadastreJMenu != null) {
335 if (oldFrame == null && newFrame != null) {
336 setEnabledAll(true);
337 Main.map.addMapMode(new IconToggleButton(new WMSAdjustAction(Main.map)));
338 Main.map.addMapMode(new IconToggleButton(new Address(Main.map)));
339 } else if (oldFrame != null && newFrame == null) {
340 setEnabledAll(false);
341 //Lambert.layoutZone = -1;
342 //LambertCC9Zones.layoutZone = -1;
343 }
344 }
345 }
346
347 public static boolean isCadastreProjection() {
348 return Main.proj.toString().equals(new Lambert().toString())
349 || Main.proj.toString().equals(new UTM_France_DOM().toString())
350 || Main.proj.toString().equals(new LambertCC9Zones().toString());
351 }
352
353 public static void safeSleep(long milliseconds) {
354 try {
355 Thread.sleep(milliseconds);
356 } catch (InterruptedException e) {}
357 }
358
359 // See OptionPaneUtil
360 // FIXME: this is a temporary solution.
361 public static void prepareDialog(JDialog dialog) {
362 if (Main.pref.getBoolean("window-handling.option-pane-always-on-top", true)) {
363 try {
364 dialog.setAlwaysOnTop(true);
365 } catch(SecurityException e) {
366 System.out.println(tr("Warning: failed to put option pane dialog always on top. Exception was: {0}", e.toString()));
367 }
368 }
369 dialog.setModal(true);
370 dialog.toFront();
371 dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
372 }
373
374 /**
375 * Adds the WMSLayer following this rule:<br/>
376 * - if a WMSLayer exists place this new layer just before this layer<br/>
377 * - Otherwise place it at the bottom
378 * @param wmsLayer the wmsLayer to add
379 */
380 public static void addWMSLayer(WMSLayer wmsLayer) {
381 if (Main.map != null && Main.map.mapView != null) {
382 int wmsNewLayerPos = Main.map.mapView.getAllLayers().size();
383 for(Layer l : Main.map.mapView.getLayersOfType(WMSLayer.class)) {
384 int wmsPos = Main.map.mapView.getLayerPos(l);
385 if (wmsPos < wmsNewLayerPos) wmsNewLayerPos = wmsPos;
386 }
387 Main.main.addLayer(wmsLayer);
388 // Move the layer to its new position
389 Main.map.mapView.moveLayer(wmsLayer, wmsNewLayerPos);
390 } else
391 Main.main.addLayer(wmsLayer);
392 }
393
394 private static String checkSourceMillesime() {
395 java.util.Calendar calendar = java.util.Calendar.getInstance();
396 int currentYear = calendar.get(java.util.Calendar.YEAR);
397 String src = Main.pref.get("cadastrewms.source",
398 "cadastre-dgi-fr source : Direction G\u00e9n\u00e9rale des Imp\u00f4ts - Cadastre. Mise \u00e0 jour : AAAA");
399 String srcYear = src.substring(src.lastIndexOf(" ")+1);
400 Integer year = null;
401 try {
402 year = Integer.decode(srcYear);
403 } catch (NumberFormatException e) {}
404 if (srcYear.equals("AAAA") || (year != null && year < currentYear)) {
405 System.out.println("Replace source year "+srcYear+" by current year "+currentYear);
406 src = src.substring(0, src.lastIndexOf(" ")+1)+currentYear;
407 Main.pref.put("cadastrewms.source", src);
408 }
409 return src;
410 }
411
412}
Note: See TracBrowser for help on using the repository browser.