001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.preferences.imagery;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.GridBagLayout;
007import java.io.IOException;
008import java.util.Collections;
009
010import javax.swing.JButton;
011import javax.swing.JCheckBox;
012import javax.swing.JLabel;
013import javax.swing.JOptionPane;
014import javax.swing.JPanel;
015
016import org.openstreetmap.josm.data.imagery.DefaultLayer;
017import org.openstreetmap.josm.data.imagery.ImageryInfo;
018import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
019import org.openstreetmap.josm.data.imagery.WMTSCapabilities;
020import org.openstreetmap.josm.data.imagery.WMTSTileSource;
021import org.openstreetmap.josm.data.imagery.WMTSTileSource.Layer;
022import org.openstreetmap.josm.data.imagery.WMTSTileSource.WMTSGetCapabilitiesException;
023import org.openstreetmap.josm.gui.layer.imagery.WMTSLayerSelection;
024import org.openstreetmap.josm.tools.GBC;
025import org.openstreetmap.josm.tools.Logging;
026import org.openstreetmap.josm.tools.Utils;
027
028/**
029 * Panel for adding WMTS imagery sources
030 * @author Wiktor Niesiobędzki
031 * @since 8568
032 */
033public class AddWMTSLayerPanel extends AddImageryPanel {
034    private final transient JPanel layerPanel = new JPanel(new GridBagLayout());
035    private transient WMTSLayerSelection layerTable;
036    private final JCheckBox setDefaultLayer = new JCheckBox(tr("Set default layer?"));
037
038    /**
039     * default constructor
040     */
041    public AddWMTSLayerPanel() {
042        add(new JLabel(tr("{0} Make sure OSM has the permission to use this service", "1.")), GBC.eol());
043        add(new JLabel(tr("{0} Enter GetCapabilities URL", "2.")), GBC.eol());
044        add(rawUrl, GBC.eop().fill(GBC.HORIZONTAL));
045        rawUrl.setLineWrap(true);
046        rawUrl.setAlignmentY(TOP_ALIGNMENT);
047        JButton getLayers = new JButton(tr("{0} Get layers", "3."));
048        getLayers.setEnabled(setDefaultLayer.isSelected());
049        setDefaultLayer.addActionListener(e -> getLayers.setEnabled(setDefaultLayer.isSelected()));
050        add(setDefaultLayer, GBC.eop());
051        add(getLayers, GBC.eop().fill(GBC.HORIZONTAL));
052        add(new JLabel(tr("Choose default layer")), GBC.eol());
053        add(layerPanel, GBC.eol().fill());
054
055        addCommonSettings();
056
057        add(new JLabel(tr("{0} Enter name for this layer", "4.")), GBC.eol());
058        add(name, GBC.eol().fill(GBC.HORIZONTAL));
059        registerValidableComponent(rawUrl);
060        registerValidableComponent(setDefaultLayer);
061
062        getLayers.addActionListener(e -> {
063            try {
064                WMTSCapabilities capabilities = WMTSTileSource.getCapabilities(Utils.strip(rawUrl.getText()), getCommonHeaders());
065                layerTable = new WMTSLayerSelection(WMTSTileSource.groupLayersByNameAndTileMatrixSet(capabilities.getLayers()));
066                layerTable.getTable().getSelectionModel().addListSelectionListener(lsl -> {
067                    if (layerTable.getSelectedLayer() != null) {
068                        name.setText(capabilities.getBaseUrl() + ": " + layerTable.getSelectedLayer().getUserTitle());
069                    } else {
070                        name.setText(capabilities.getBaseUrl() + ": ");
071                    }
072                });
073                layerPanel.removeAll();
074                layerPanel.add(layerTable, GBC.eol().fill());
075                layerPanel.revalidate();
076            } catch (IOException | RuntimeException | WMTSGetCapabilitiesException ex) {
077                Logging.trace(ex);
078                JOptionPane.showMessageDialog(
079                        getParent(),
080                        tr("Error getting layers: {0}", ex.getMessage()),
081                        tr("WMTS Error"),
082                        JOptionPane.ERROR_MESSAGE);
083            }
084        });
085    }
086
087    @Override
088    protected ImageryInfo getImageryInfo() {
089        ImageryInfo ret = new ImageryInfo(getImageryName(), "wmts:" + sanitize(getImageryRawUrl(), ImageryType.WMTS));
090        if (setDefaultLayer.isSelected()) {
091            if (layerTable == null) {
092                // did not call get capabilities
093                throw new IllegalArgumentException(tr("You need to get fetch layers"));
094            }
095            Layer selectedLayer = layerTable.getSelectedLayer();
096            ret.setDefaultLayers(
097                    Collections.<DefaultLayer>singletonList(
098                            new DefaultLayer(
099                                    ImageryType.WMTS,
100                                    selectedLayer.getIdentifier(),
101                                    selectedLayer.getStyle(),
102                                    selectedLayer.getTileMatrixSet().getIdentifier()
103                                    )
104                            )
105                    );
106        }
107        ret.setCustomHttpHeaders(getCommonHeaders());
108        ret.setGeoreferenceValid(getCommonIsValidGeoreference());
109        ret.setImageryType(ImageryType.WMTS);
110        try {
111            new WMTSTileSource(ret); // check if constructor throws an error
112        } catch (IOException | WMTSGetCapabilitiesException e) {
113            Logging.warn(e);
114            throw new IllegalArgumentException(e); // if so, wrap exception, so proper message will be shown to the user
115        }
116        return ret;
117    }
118
119    @Override
120    protected boolean isImageryValid() {
121        return ((setDefaultLayer.isSelected() && layerTable != null && layerTable.getSelectedLayer() != null)
122                || !setDefaultLayer.isSelected()
123                ) && !getImageryName().isEmpty() && !getImageryRawUrl().isEmpty();
124    }
125}