source: josm/trunk/src/org/openstreetmap/josm/actions/Map_Rectifier_WMSmenuAction.java @ 5241

Revision 5050, 9.6 KB checked in by akks, 3 months ago (diff)

UrlLabel class simplification by Zverik, better label layout in VersionInfoPanel (see #7450, #7326)

  • Property svn:eol-style set to native
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.GridBagConstraints;
7import java.awt.GridBagLayout;
8import java.awt.event.ActionEvent;
9import java.awt.event.KeyEvent;
10import java.util.ArrayList;
11import java.util.regex.Matcher;
12import java.util.regex.Pattern;
13
14import javax.swing.ButtonGroup;
15import javax.swing.JLabel;
16import javax.swing.JOptionPane;
17import javax.swing.JPanel;
18import javax.swing.JRadioButton;
19import javax.swing.JTextField;
20
21import org.openstreetmap.josm.Main;
22import org.openstreetmap.josm.data.imagery.ImageryInfo;
23import org.openstreetmap.josm.gui.ExtendedDialog;
24import org.openstreetmap.josm.gui.layer.WMSLayer;
25import org.openstreetmap.josm.tools.GBC;
26import org.openstreetmap.josm.tools.Shortcut;
27import org.openstreetmap.josm.tools.UrlLabel;
28import org.openstreetmap.josm.tools.Utils;
29
30public class Map_Rectifier_WMSmenuAction extends JosmAction {
31    /**
32     * Class that bundles all required information of a rectifier service
33     */
34    public static class RectifierService {
35        private final String name;
36        private final String url;
37        private final String wmsUrl;
38        private final Pattern urlRegEx;
39        private final Pattern idValidator;
40        public JRadioButton btn;
41        /**
42         * @param name: Name of the rectifing service
43         * @param url: URL to the service where users can register, upload, etc.
44         * @param wmsUrl: URL to the WMS server where JOSM will grab the images. Insert __s__ where the ID should be placed
45         * @param urlRegEx: a regular expression that determines if a given URL is one of the service and returns the WMS id if so
46         * @param idValidator: regular expression that checks if a given ID is syntactically valid
47         */
48        public RectifierService(String name, String url, String wmsUrl, String urlRegEx, String idValidator) {
49            this.name = name;
50            this.url = url;
51            this.wmsUrl = wmsUrl;
52            this.urlRegEx = Pattern.compile(urlRegEx);
53            this.idValidator = Pattern.compile(idValidator);
54        }
55
56        public boolean isSelected() {
57            return btn.isSelected();
58        }
59    }
60
61    /**
62     * List of available rectifier services. May be extended from the outside
63     */
64    public ArrayList<RectifierService> services = new ArrayList<RectifierService>();
65
66    public Map_Rectifier_WMSmenuAction() {
67        super(tr("Rectified Image..."),
68                "OLmarker",
69                tr("Download Rectified Images From Various Services"),
70                Shortcut.registerShortcut("imagery:rectimg",
71                        tr("Imagery: {0}", tr("Rectified Image...")),
72                        KeyEvent.CHAR_UNDEFINED, Shortcut.NONE),
73                true
74        );
75
76        // Add default services
77        services.add(
78                new RectifierService("Metacarta Map Rectifier",
79                        "http://labs.metacarta.com/rectifier/",
80                        "http://labs.metacarta.com/rectifier/wms.cgi?id=__s__&srs=EPSG:4326"
81                        + "&Service=WMS&Version=1.1.0&Request=GetMap&format=image/png&",
82                        // This matches more than the "classic" WMS link, so users can pretty much
83                        // copy any link as long as it includes the ID
84                        "labs\\.metacarta\\.com/(?:.*?)(?:/|=)([0-9]+)(?:\\?|/|\\.|$)",
85                "^[0-9]+$")
86        );
87        services.add(
88                // TODO: Change all links to mapwarper.net once the project has moved.
89                // The RegEx already matches the new URL and old URLs will be forwarded
90                // to make the transition as smooth as possible for the users
91                new RectifierService("Geothings Map Warper",
92                        "http://warper.geothings.net/",
93                        "http://warper.geothings.net/maps/wms/__s__?request=GetMap&version=1.1.1"
94                        + "&styles=&format=image/png&srs=epsg:4326&exceptions=application/vnd.ogc.se_inimage&",
95                        // This matches more than the "classic" WMS link, so users can pretty much
96                        // copy any link as long as it includes the ID
97                        "(?:mapwarper\\.net|warper\\.geothings\\.net)/(?:.*?)/([0-9]+)(?:\\?|/|\\.|$)",
98                "^[0-9]+$")
99        );
100
101        // This service serves the purpose of "just this once" without forcing the user
102        // to commit the link to the preferences
103
104        // Clipboard content gets trimmed, so matching whitespace only ensures that this
105        // service will never be selected automatically.
106        services.add(new RectifierService(tr("Custom WMS Link"), "", "", "^\\s+$", ""));
107    }
108
109    @Override
110    public void actionPerformed(ActionEvent e) {
111        if (!isEnabled()) return;
112        JPanel panel = new JPanel(new GridBagLayout());
113        panel.add(new JLabel(tr("Supported Rectifier Services:")), GBC.eol());
114
115        JTextField tfWmsUrl = new JTextField(30);
116
117        String clip = Utils.getClipboardContent();
118        clip = clip == null ? "" : clip.trim();
119        ButtonGroup group = new ButtonGroup();
120
121        JRadioButton firstBtn = null;
122        for(RectifierService s : services) {
123            JRadioButton serviceBtn = new JRadioButton(s.name);
124            if(firstBtn == null) {
125                firstBtn = serviceBtn;
126            }
127            // Checks clipboard contents against current service if no match has been found yet.
128            // If the contents match, they will be inserted into the text field and the corresponding
129            // service will be pre-selected.
130            if(!clip.equals("") && tfWmsUrl.getText().equals("")
131                    && (s.urlRegEx.matcher(clip).find() || s.idValidator.matcher(clip).matches())) {
132                serviceBtn.setSelected(true);
133                tfWmsUrl.setText(clip);
134            }
135            s.btn = serviceBtn;
136            group.add(serviceBtn);
137            if(!s.url.equals("")) {
138                panel.add(serviceBtn, GBC.std());
139                panel.add(new UrlLabel(s.url, tr("Visit Homepage")), GBC.eol().anchor(GridBagConstraints.EAST), 2);
140            } else {
141                panel.add(serviceBtn, GBC.eol().anchor(GridBagConstraints.WEST));
142            }
143        }
144
145        // Fallback in case no match was found
146        if(tfWmsUrl.getText().equals("") && firstBtn != null) {
147            firstBtn.setSelected(true);
148        }
149
150        panel.add(new JLabel(tr("WMS URL or Image ID:")), GBC.eol());
151        panel.add(tfWmsUrl, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
152
153        ExtendedDialog diag = new ExtendedDialog(Main.parent,
154                tr("Add Rectified Image"),
155
156                new String[] {tr("Add Rectified Image"), tr("Cancel")});
157        diag.setContent(panel);
158        diag.setButtonIcons(new String[] {"OLmarker.png", "cancel.png"});
159
160        // This repeatedly shows the dialog in case there has been an error.
161        // The loop is break;-ed if the users cancels
162        outer: while(true) {
163            diag.showDialog();
164            int answer = diag.getValue();
165            // Break loop when the user cancels
166            if(answer != 1) {
167                break;
168            }
169
170            String text = tfWmsUrl.getText().trim();
171            // Loop all services until we find the selected one
172            for(RectifierService s : services) {
173                if(!s.isSelected()) {
174                    continue;
175                }
176
177                // We've reached the custom WMS URL service
178                // Just set the URL and hope everything works out
179                if(s.wmsUrl.equals("")) {
180                    addWMSLayer(s.name + " (" + text + ")", text);
181                    break outer;
182                }
183
184                // First try to match if the entered string as an URL
185                Matcher m = s.urlRegEx.matcher(text);
186                if(m.find()) {
187                    String id = m.group(1);
188                    String newURL = s.wmsUrl.replaceAll("__s__", id);
189                    String title = s.name + " (" + id + ")";
190                    addWMSLayer(title, newURL);
191                    break outer;
192                }
193                // If not, look if it's a valid ID for the selected service
194                if(s.idValidator.matcher(text).matches()) {
195                    String newURL = s.wmsUrl.replaceAll("__s__", text);
196                    String title = s.name + " (" + text + ")";
197                    addWMSLayer(title, newURL);
198                    break outer;
199                }
200
201                // We've found the selected service, but the entered string isn't suitable for
202                // it. So quit checking the other radio buttons
203                break;
204            }
205
206            // and display an error message. The while(true) ensures that the dialog pops up again
207            JOptionPane.showMessageDialog(Main.parent,
208                    tr("Couldn''t match the entered link or id to the selected service. Please try again."),
209                    tr("No valid WMS URL or id"),
210                    JOptionPane.ERROR_MESSAGE);
211            diag.setVisible(true);
212        }
213    }
214
215    /**
216     * Adds a WMS Layer with given title and URL
217     * @param title: Name of the layer as it will shop up in the layer manager
218     * @param url: URL to the WMS server
219     */
220    private void addWMSLayer(String title, String url) {
221        Main.main.addLayer(new WMSLayer(new ImageryInfo(title, url)));
222    }
223
224    @Override
225    protected void updateEnabledState() {
226        setEnabled(Main.map != null && Main.map.mapView != null && !Main.map.mapView.getAllLayers().isEmpty());
227    }
228}
Note: See TracBrowser for help on using the repository browser.