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

Last change on this file since 3718 was 3715, checked in by Upliner, 13 years ago

Added imagery plugin to josm core. Imagery plugin is union of wmsplugin and slippymap plugins. It includes code by Tim Waters, Petr Dlouhý, Frederik Ramm and others. Also enables the remotecontol which was integrated in [3707].

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