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

Last change on this file since 11240 was 11219, checked in by wiktorn, 7 years ago

Use all information from wms_endpoint definition.

After the user chose the layers to work with only a handful of information were passed to resulting WMS ImageryInfo. Now all information are passed, including attribution, headers, cookies, etc.

Closes: #13916

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