source: josm/trunk/src/org/openstreetmap/josm/actions/MapRectifierWMSmenuAction.java@ 7828

Last change on this file since 7828 was 7813, checked in by stoecker, 9 years ago

see #10858 - fix rectifier action help page

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