source: josm/trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java@ 11625

Last change on this file since 11625 was 11625, checked in by stoecker, 7 years ago

fix #12313 - make eli-best and other texts available as tooltip in menu and toolbar, no idea why stripping HTML block is necessary

  • Property svn:eol-style set to native
File size: 8.3 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.Dimension;
8import java.awt.GraphicsEnvironment;
9import java.awt.GridBagLayout;
10import java.awt.event.ActionEvent;
11import java.io.IOException;
12import java.net.MalformedURLException;
13import java.util.ArrayList;
14import java.util.Collection;
15import java.util.HashSet;
16import java.util.List;
17import java.util.Set;
18
19import javax.swing.JComboBox;
20import javax.swing.JOptionPane;
21import javax.swing.JPanel;
22import javax.swing.JScrollPane;
23
24import org.openstreetmap.josm.Main;
25import org.openstreetmap.josm.data.imagery.DefaultLayer;
26import org.openstreetmap.josm.data.imagery.ImageryInfo;
27import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
28import org.openstreetmap.josm.data.imagery.WMTSTileSource;
29import org.openstreetmap.josm.gui.ExtendedDialog;
30import org.openstreetmap.josm.gui.layer.AlignImageryPanel;
31import org.openstreetmap.josm.gui.layer.ImageryLayer;
32import org.openstreetmap.josm.gui.preferences.imagery.WMSLayerTree;
33import org.openstreetmap.josm.gui.util.GuiHelper;
34import org.openstreetmap.josm.io.imagery.WMSImagery;
35import org.openstreetmap.josm.io.imagery.WMSImagery.LayerDetails;
36import org.openstreetmap.josm.io.imagery.WMSImagery.WMSGetCapabilitiesException;
37import org.openstreetmap.josm.tools.CheckParameterUtil;
38import org.openstreetmap.josm.tools.GBC;
39import org.openstreetmap.josm.tools.ImageProvider;
40
41/**
42 * Action displayed in imagery menu to add a new imagery layer.
43 * @since 3715
44 */
45public class AddImageryLayerAction extends JosmAction implements AdaptableAction {
46 private final transient ImageryInfo info;
47
48 static class SelectWmsLayersDialog extends ExtendedDialog {
49 SelectWmsLayersDialog(WMSLayerTree tree, JComboBox<String> formats) {
50 super(Main.parent, tr("Select WMS layers"), new String[]{tr("Add layers"), tr("Cancel")});
51 final JScrollPane scrollPane = new JScrollPane(tree.getLayerTree());
52 scrollPane.setPreferredSize(new Dimension(400, 400));
53 final JPanel panel = new JPanel(new GridBagLayout());
54 panel.add(scrollPane, GBC.eol().fill());
55 panel.add(formats, GBC.eol().fill(GBC.HORIZONTAL));
56 setContent(panel);
57 }
58 }
59
60 /**
61 * Constructs a new {@code AddImageryLayerAction} for the given {@code ImageryInfo}.
62 * If an http:// icon is specified, it is fetched asynchronously.
63 * @param info The imagery info
64 */
65 public AddImageryLayerAction(ImageryInfo info) {
66 super(info.getMenuName(), /* ICON */"imagery_menu", tr("Add imagery layer {0}", info.getName()), null, false, false);
67 putValue("toolbar", "imagery_" + info.getToolbarName());
68 putValue("help", ht("/Preferences/Imagery"));
69 setTooltip(info.getToolTipText().replaceAll("</?html>",""));
70 this.info = info;
71 installAdapters();
72
73 // change toolbar icon from if specified
74 String icon = info.getIcon();
75 if (icon != null) {
76 new ImageProvider(icon).setOptional(true).getResourceAsync().thenAccept(result -> {
77 if (result != null) {
78 GuiHelper.runInEDT(() -> result.attachImageIcon(this));
79 }
80 });
81 }
82 }
83
84 /**
85 * Converts general ImageryInfo to specific one, that does not need any user action to initialize
86 * see: https://josm.openstreetmap.de/ticket/13868
87 * @param info ImageryInfo that will be converted (or returned when no conversion needed)
88 * @return ImageryInfo object that's ready to be used to create TileSource
89 */
90 private ImageryInfo convertImagery(ImageryInfo info) {
91 try {
92 switch(info.getImageryType()) {
93 case WMS_ENDPOINT:
94 // convert to WMS type
95 return getWMSLayerInfo();
96 case WMTS:
97 // specify which layer to use
98 DefaultLayer layerId = new WMTSTileSource(info).userSelectLayer();
99 if (layerId != null) {
100 ImageryInfo copy = new ImageryInfo(info);
101 Collection<DefaultLayer> defaultLayers = new ArrayList<>(1);
102 defaultLayers.add(layerId);
103 copy.setDefaultLayers(defaultLayers);
104 return copy;
105 }
106 // layer not selected - refuse to add
107 return null;
108 default:
109 return info;
110 }
111 } catch (MalformedURLException ex) {
112 if (!GraphicsEnvironment.isHeadless()) {
113 JOptionPane.showMessageDialog(Main.parent, tr("Invalid service URL."),
114 tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
115 }
116 Main.error(ex, false);
117 } catch (IOException ex) {
118 if (!GraphicsEnvironment.isHeadless()) {
119 JOptionPane.showMessageDialog(Main.parent, tr("Could not retrieve WMS layer list."),
120 tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
121 }
122 Main.error(ex, false);
123 } catch (WMSGetCapabilitiesException ex) {
124 if (!GraphicsEnvironment.isHeadless()) {
125 JOptionPane.showMessageDialog(Main.parent, tr("Could not parse WMS layer list."),
126 tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
127 }
128 Main.error(ex, "Could not parse WMS layer list. Incoming data:\n"+ex.getIncomingData());
129 }
130 return null;
131 }
132
133 @Override
134 public void actionPerformed(ActionEvent e) {
135 if (!isEnabled()) return;
136 try {
137 final ImageryInfo infoToAdd = convertImagery(info);
138 if (infoToAdd != null) {
139 Main.getLayerManager().addLayer(ImageryLayer.create(infoToAdd));
140 AlignImageryPanel.addNagPanelIfNeeded(infoToAdd);
141 }
142 } catch (IllegalArgumentException ex) {
143 if (ex.getMessage() == null || ex.getMessage().isEmpty() || GraphicsEnvironment.isHeadless()) {
144 throw ex;
145 } else {
146 JOptionPane.showMessageDialog(Main.parent,
147 ex.getMessage(), tr("Error"),
148 JOptionPane.ERROR_MESSAGE);
149 }
150 }
151 }
152
153 protected ImageryInfo getWMSLayerInfo() throws IOException, WMSGetCapabilitiesException {
154 CheckParameterUtil.ensureThat(ImageryType.WMS_ENDPOINT.equals(info.getImageryType()), "wms_endpoint imagery type expected");
155
156 final WMSImagery wms = new WMSImagery();
157 wms.attemptGetCapabilities(info.getUrl());
158
159 final WMSLayerTree tree = new WMSLayerTree();
160 tree.updateTree(wms);
161 List<String> wmsFormats = wms.getFormats();
162 final JComboBox<String> formats = new JComboBox<>(wmsFormats.toArray(new String[wmsFormats.size()]));
163 formats.setSelectedItem(wms.getPreferredFormats());
164 formats.setToolTipText(tr("Select image format for WMS layer"));
165
166 if (!GraphicsEnvironment.isHeadless() && 1 != new SelectWmsLayersDialog(tree, formats).showDialog().getValue()) {
167 return null;
168 }
169
170 final String url = wms.buildGetMapUrl(
171 tree.getSelectedLayers(), (String) formats.getSelectedItem());
172 Set<String> supportedCrs = new HashSet<>();
173 boolean first = true;
174 StringBuilder layersString = new StringBuilder();
175 for (LayerDetails layer: tree.getSelectedLayers()) {
176 if (first) {
177 supportedCrs.addAll(layer.getProjections());
178 first = false;
179 }
180 layersString.append(layer.name);
181 layersString.append(", ");
182 supportedCrs.retainAll(layer.getProjections());
183 }
184
185 // copy all information from WMS
186 ImageryInfo ret = new ImageryInfo(info);
187 // and update according to user choice
188 ret.setUrl(url);
189 ret.setImageryType(ImageryType.WMS);
190 if (layersString.length() > 2) {
191 ret.setName(ret.getName() + ' ' + layersString.substring(0, layersString.length() - 2));
192 }
193 ret.setServerProjections(supportedCrs);
194 return ret;
195 }
196
197 @Override
198 protected void updateEnabledState() {
199 if (info.isBlacklisted()) {
200 setEnabled(false);
201 } else {
202 setEnabled(true);
203 }
204 }
205}
Note: See TracBrowser for help on using the repository browser.