[3719] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
[3715] | 2 | package org.openstreetmap.josm.actions;
|
---|
| 3 |
|
---|
[7665] | 4 | import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
|
---|
[3715] | 5 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
| 6 |
|
---|
[5617] | 7 | import java.awt.Dimension;
|
---|
[9918] | 8 | import java.awt.GraphicsEnvironment;
|
---|
[6000] | 9 | import java.awt.GridBagLayout;
|
---|
[3715] | 10 | import java.awt.event.ActionEvent;
|
---|
[5617] | 11 | import java.io.IOException;
|
---|
| 12 | import java.net.MalformedURLException;
|
---|
[8576] | 13 | import java.util.HashSet;
|
---|
| 14 | import java.util.Set;
|
---|
[6248] | 15 |
|
---|
[6000] | 16 | import javax.swing.JComboBox;
|
---|
[4531] | 17 | import javax.swing.JOptionPane;
|
---|
[6000] | 18 | import javax.swing.JPanel;
|
---|
[5617] | 19 | import javax.swing.JScrollPane;
|
---|
[6248] | 20 |
|
---|
[3715] | 21 | import org.openstreetmap.josm.Main;
|
---|
| 22 | import org.openstreetmap.josm.data.imagery.ImageryInfo;
|
---|
[3733] | 23 | import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
|
---|
[5617] | 24 | import org.openstreetmap.josm.gui.ExtendedDialog;
|
---|
[8469] | 25 | import org.openstreetmap.josm.gui.layer.AlignImageryPanel;
|
---|
[3715] | 26 | import org.openstreetmap.josm.gui.layer.ImageryLayer;
|
---|
[6248] | 27 | import org.openstreetmap.josm.gui.preferences.imagery.WMSLayerTree;
|
---|
[6707] | 28 | import org.openstreetmap.josm.gui.util.GuiHelper;
|
---|
[5617] | 29 | import org.openstreetmap.josm.io.imagery.WMSImagery;
|
---|
[8576] | 30 | import org.openstreetmap.josm.io.imagery.WMSImagery.LayerDetails;
|
---|
[6000] | 31 | import org.openstreetmap.josm.tools.GBC;
|
---|
[4721] | 32 | import org.openstreetmap.josm.tools.ImageProvider;
|
---|
[7693] | 33 | import org.openstreetmap.josm.tools.ImageProvider.ImageResourceCallback;
|
---|
| 34 | import org.openstreetmap.josm.tools.ImageResource;
|
---|
[3715] | 35 |
|
---|
[6707] | 36 | /**
|
---|
[7509] | 37 | * Action displayed in imagery menu to add a new imagery layer.
|
---|
[6707] | 38 | * @since 3715
|
---|
| 39 | */
|
---|
[4032] | 40 | public class AddImageryLayerAction extends JosmAction implements AdaptableAction {
|
---|
[8308] | 41 | private final transient ImageryInfo info;
|
---|
[3715] | 42 |
|
---|
[6707] | 43 | /**
|
---|
| 44 | * Constructs a new {@code AddImageryLayerAction} for the given {@code ImageryInfo}.
|
---|
| 45 | * If an http:// icon is specified, it is fetched asynchronously.
|
---|
| 46 | * @param info The imagery info
|
---|
| 47 | */
|
---|
[3715] | 48 | public AddImageryLayerAction(ImageryInfo info) {
|
---|
[8510] | 49 | super(info.getMenuName(), /* ICON */"imagery_menu", tr("Add imagery layer {0}", info.getName()), null, false, false);
|
---|
[3715] | 50 | putValue("toolbar", "imagery_" + info.getToolbarName());
|
---|
[7665] | 51 | putValue("help", ht("/Preferences/Imagery"));
|
---|
[3715] | 52 | this.info = info;
|
---|
[3733] | 53 | installAdapters();
|
---|
[4713] | 54 |
|
---|
| 55 | // change toolbar icon from if specified
|
---|
| 56 | try {
|
---|
[7693] | 57 | String icon = info.getIcon();
|
---|
| 58 | if (icon != null) {
|
---|
| 59 | new ImageProvider(icon).setOptional(true).getInBackground(new ImageResourceCallback() {
|
---|
[6707] | 60 | @Override
|
---|
[7693] | 61 | public void finished(final ImageResource result) {
|
---|
[6707] | 62 | if (result != null) {
|
---|
| 63 | GuiHelper.runInEDT(new Runnable() {
|
---|
| 64 | @Override
|
---|
| 65 | public void run() {
|
---|
[7693] | 66 | result.getImageIcon(AddImageryLayerAction.this);
|
---|
[6707] | 67 | }
|
---|
| 68 | });
|
---|
| 69 | }
|
---|
| 70 | }
|
---|
| 71 | });
|
---|
[4713] | 72 | }
|
---|
| 73 | } catch (Exception ex) {
|
---|
| 74 | throw new RuntimeException(ex.getMessage(), ex);
|
---|
| 75 | }
|
---|
[3715] | 76 | }
|
---|
| 77 |
|
---|
| 78 | @Override
|
---|
| 79 | public void actionPerformed(ActionEvent e) {
|
---|
[3733] | 80 | if (!isEnabled()) return;
|
---|
[4531] | 81 | try {
|
---|
[5617] | 82 | final ImageryInfo infoToAdd = ImageryType.WMS_ENDPOINT.equals(info.getImageryType())
|
---|
| 83 | ? getWMSLayerInfo() : info;
|
---|
| 84 | if (infoToAdd != null) {
|
---|
| 85 | Main.main.addLayer(ImageryLayer.create(infoToAdd));
|
---|
[9134] | 86 | AlignImageryPanel.addNagPanelIfNeeded(infoToAdd);
|
---|
[5617] | 87 | }
|
---|
[4531] | 88 | } catch (IllegalArgumentException ex) {
|
---|
| 89 | if (ex.getMessage() == null || ex.getMessage().isEmpty()) {
|
---|
| 90 | throw ex;
|
---|
| 91 | } else {
|
---|
| 92 | JOptionPane.showMessageDialog(Main.parent,
|
---|
| 93 | ex.getMessage(), tr("Error"),
|
---|
| 94 | JOptionPane.ERROR_MESSAGE);
|
---|
| 95 | }
|
---|
| 96 | }
|
---|
[3715] | 97 | }
|
---|
[5617] | 98 |
|
---|
| 99 | protected ImageryInfo getWMSLayerInfo() {
|
---|
| 100 | try {
|
---|
[8345] | 101 | assert ImageryType.WMS_ENDPOINT.equals(info.getImageryType());
|
---|
[5617] | 102 | final WMSImagery wms = new WMSImagery();
|
---|
| 103 | wms.attemptGetCapabilities(info.getUrl());
|
---|
| 104 |
|
---|
| 105 | final WMSLayerTree tree = new WMSLayerTree();
|
---|
| 106 | tree.updateTree(wms);
|
---|
[7017] | 107 | final JComboBox<String> formats = new JComboBox<>(wms.getFormats().toArray(new String[0]));
|
---|
[6930] | 108 | formats.setSelectedItem(wms.getPreferredFormats());
|
---|
[6000] | 109 | formats.setToolTipText(tr("Select image format for WMS layer"));
|
---|
[5617] | 110 |
|
---|
[9918] | 111 | if (!GraphicsEnvironment.isHeadless()) {
|
---|
| 112 | if (1 != new ExtendedDialog(Main.parent, tr("Select WMS layers"), new String[]{tr("Add layers"), tr("Cancel")}) { {
|
---|
| 113 | final JScrollPane scrollPane = new JScrollPane(tree.getLayerTree());
|
---|
| 114 | scrollPane.setPreferredSize(new Dimension(400, 400));
|
---|
| 115 | final JPanel panel = new JPanel(new GridBagLayout());
|
---|
| 116 | panel.add(scrollPane, GBC.eol().fill());
|
---|
| 117 | panel.add(formats, GBC.eol().fill(GBC.HORIZONTAL));
|
---|
| 118 | setContent(panel);
|
---|
| 119 | } }.showDialog().getValue()) {
|
---|
| 120 | return null;
|
---|
| 121 | }
|
---|
[5617] | 122 | }
|
---|
| 123 |
|
---|
[6000] | 124 | final String url = wms.buildGetMapUrl(
|
---|
| 125 | tree.getSelectedLayers(), (String) formats.getSelectedItem());
|
---|
[8576] | 126 | Set<String> supportedCrs = new HashSet<>();
|
---|
[8582] | 127 | boolean first = true;
|
---|
[8763] | 128 | StringBuilder layersString = new StringBuilder();
|
---|
[8582] | 129 | for (LayerDetails layer: tree.getSelectedLayers()) {
|
---|
| 130 | if (first) {
|
---|
| 131 | supportedCrs.addAll(layer.getProjections());
|
---|
| 132 | first = false;
|
---|
[8576] | 133 | }
|
---|
[8763] | 134 | layersString.append(layer.name);
|
---|
| 135 | layersString.append(", ");
|
---|
[8582] | 136 | supportedCrs.retainAll(layer.getProjections());
|
---|
[8576] | 137 | }
|
---|
[8763] | 138 |
|
---|
[8576] | 139 | ImageryInfo ret = new ImageryInfo(info.getName(), url, "wms", info.getEulaAcceptanceRequired(), info.getCookies());
|
---|
[8763] | 140 | if (layersString.length() > 2) {
|
---|
[8846] | 141 | ret.setName(ret.getName() + ' ' + layersString.substring(0, layersString.length() - 2));
|
---|
[8763] | 142 | }
|
---|
[8576] | 143 | ret.setServerProjections(supportedCrs);
|
---|
| 144 | return ret;
|
---|
[8342] | 145 | } catch (MalformedURLException ex) {
|
---|
[9918] | 146 | if (!GraphicsEnvironment.isHeadless()) {
|
---|
| 147 | JOptionPane.showMessageDialog(Main.parent, tr("Invalid service URL."),
|
---|
| 148 | tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
|
---|
| 149 | }
|
---|
| 150 | Main.error(ex, false);
|
---|
[5617] | 151 | } catch (IOException ex) {
|
---|
[9918] | 152 | if (!GraphicsEnvironment.isHeadless()) {
|
---|
| 153 | JOptionPane.showMessageDialog(Main.parent, tr("Could not retrieve WMS layer list."),
|
---|
| 154 | tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
|
---|
| 155 | }
|
---|
| 156 | Main.error(ex, false);
|
---|
[5617] | 157 | } catch (WMSImagery.WMSGetCapabilitiesException ex) {
|
---|
[9918] | 158 | if (!GraphicsEnvironment.isHeadless()) {
|
---|
| 159 | JOptionPane.showMessageDialog(Main.parent, tr("Could not parse WMS layer list."),
|
---|
| 160 | tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
|
---|
| 161 | }
|
---|
[6248] | 162 | Main.error("Could not parse WMS layer list. Incoming data:\n"+ex.getIncomingData());
|
---|
[5617] | 163 | }
|
---|
| 164 | return null;
|
---|
| 165 | }
|
---|
[6069] | 166 |
|
---|
[3733] | 167 | @Override
|
---|
| 168 | protected void updateEnabledState() {
|
---|
[8509] | 169 | ImageryType type = info.getImageryType();
|
---|
[5458] | 170 | // never enable blacklisted entries. Do not add same imagery layer twice (fix #2519)
|
---|
[8853] | 171 | if (info.isBlacklisted()) {
|
---|
[3826] | 172 | setEnabled(false);
|
---|
[8509] | 173 | } else if (type == ImageryType.TMS || type == ImageryType.BING || type == ImageryType.SCANEX) {
|
---|
[3826] | 174 | setEnabled(true);
|
---|
[5460] | 175 | } else if (Main.isDisplayingMapView() && !Main.map.mapView.getAllLayers().isEmpty()) {
|
---|
[3826] | 176 | setEnabled(true);
|
---|
| 177 | } else {
|
---|
| 178 | setEnabled(false);
|
---|
| 179 | }
|
---|
[3733] | 180 | }
|
---|
| 181 | }
|
---|