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