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.event.ActionEvent; 007import java.awt.event.ActionListener; 008import java.awt.event.ItemEvent; 009import java.awt.event.ItemListener; 010import java.beans.PropertyChangeEvent; 011import java.beans.PropertyChangeListener; 012import java.io.IOException; 013import java.net.MalformedURLException; 014import java.net.URL; 015 016import javax.swing.DefaultComboBoxModel; 017import javax.swing.JButton; 018import javax.swing.JCheckBox; 019import javax.swing.JComboBox; 020import javax.swing.JLabel; 021import javax.swing.JOptionPane; 022import javax.swing.JScrollPane; 023 024import org.openstreetmap.josm.Main; 025import org.openstreetmap.josm.data.imagery.ImageryInfo; 026import org.openstreetmap.josm.gui.bbox.SlippyMapBBoxChooser; 027import org.openstreetmap.josm.gui.widgets.JosmTextArea; 028import org.openstreetmap.josm.io.imagery.WMSImagery; 029import org.openstreetmap.josm.tools.GBC; 030import org.openstreetmap.josm.tools.Utils; 031 032public class AddWMSLayerPanel extends AddImageryPanel { 033 034 private final WMSImagery wms = new WMSImagery(); 035 private final JCheckBox endpoint = new JCheckBox(tr("Store WMS endpoint only, select layers at usage")); 036 private final WMSLayerTree tree = new WMSLayerTree(); 037 private final JComboBox formats = new JComboBox(); 038 private final JLabel wmsInstruction; 039 private final JosmTextArea wmsUrl = new JosmTextArea(3, 40); 040 private final JButton showBounds = new JButton(tr("Show bounds")); 041 042 /** 043 * Constructs a new {@code AddWMSLayerPanel}. 044 */ 045 public AddWMSLayerPanel() { 046 047 add(new JLabel(tr("1. Enter service URL")), GBC.eol()); 048 add(rawUrl, GBC.eol().fill()); 049 rawUrl.setLineWrap(true); 050 JButton getLayers = new JButton(tr("Get layers")); 051 add(getLayers, GBC.eop().fill()); 052 053 add(new JLabel(tr("2. Select layers")), GBC.eol()); 054 add(endpoint, GBC.eol().fill()); 055 add(new JScrollPane(tree.getLayerTree()), GBC.eol().fill().weight(1, 100)); 056 057 showBounds.setEnabled(false); 058 add(new JScrollPane(showBounds), GBC.eop().fill()); 059 060 add(new JLabel(tr("3. Select image format")), GBC.eol()); 061 add(formats, GBC.eol().fill()); 062 063 add(wmsInstruction = new JLabel(tr("4. Verify generated WMS URL")), GBC.eol()); 064 add(wmsUrl, GBC.eop().fill()); 065 wmsUrl.setLineWrap(true); 066 067 add(new JLabel(tr("5. Enter name for this layer")), GBC.eol()); 068 add(name, GBC.eop().fill()); 069 070 getLayers.addActionListener(new ActionListener() { 071 @Override 072 public void actionPerformed(ActionEvent e) { 073 try { 074 wms.attemptGetCapabilities(rawUrl.getText()); 075 tree.updateTree(wms); 076 formats.setModel(new DefaultComboBoxModel(wms.getFormats().toArray())); 077 } catch (MalformedURLException ex) { 078 JOptionPane.showMessageDialog(getParent(), tr("Invalid service URL."), 079 tr("WMS Error"), JOptionPane.ERROR_MESSAGE); 080 } catch (IOException ex) { 081 JOptionPane.showMessageDialog(getParent(), tr("Could not retrieve WMS layer list."), 082 tr("WMS Error"), JOptionPane.ERROR_MESSAGE); 083 } catch (WMSImagery.WMSGetCapabilitiesException ex) { 084 JOptionPane.showMessageDialog(getParent(), tr("Could not parse WMS layer list."), 085 tr("WMS Error"), JOptionPane.ERROR_MESSAGE); 086 Main.error("Could not parse WMS layer list. Incoming data:\n"+ex.getIncomingData()); 087 } 088 } 089 }); 090 091 endpoint.addItemListener(new ItemListener() { 092 @Override 093 public void itemStateChanged(ItemEvent e) { 094 tree.getLayerTree().setEnabled(!endpoint.isSelected()); 095 showBounds.setEnabled(!endpoint.isSelected()); 096 wmsInstruction.setEnabled(!endpoint.isSelected()); 097 formats.setEnabled(!endpoint.isSelected()); 098 wmsUrl.setEnabled(!endpoint.isSelected()); 099 if (endpoint.isSelected()) { 100 URL url = wms.getServiceUrl(); 101 if (url != null) { 102 name.setText(url.getHost()); 103 } 104 } else { 105 onLayerSelectionChanged(); 106 } 107 } 108 }); 109 110 tree.getLayerTree().addPropertyChangeListener("selectedLayers", new PropertyChangeListener() { 111 @Override 112 public void propertyChange(PropertyChangeEvent evt) { 113 onLayerSelectionChanged(); 114 } 115 }); 116 117 formats.addActionListener(new ActionListener() { 118 @Override 119 public void actionPerformed(ActionEvent e) { 120 onLayerSelectionChanged(); 121 } 122 }); 123 124 showBounds.addActionListener(new ActionListener() { 125 @Override 126 public void actionPerformed(ActionEvent e) { 127 if (tree.getSelectedLayers().get(0).bounds != null) { 128 SlippyMapBBoxChooser mapPanel = new SlippyMapBBoxChooser(); 129 mapPanel.setBoundingBox(tree.getSelectedLayers().get(0).bounds); 130 JOptionPane.showMessageDialog(null, mapPanel, tr("Show Bounds"), JOptionPane.PLAIN_MESSAGE); 131 } else { 132 JOptionPane.showMessageDialog(null, tr("No bounding box was found for this layer."), 133 tr("WMS Error"), JOptionPane.ERROR_MESSAGE); 134 } 135 } 136 }); 137 138 registerValidableComponent(endpoint); 139 registerValidableComponent(rawUrl); 140 registerValidableComponent(wmsUrl); 141 } 142 143 protected final void onLayerSelectionChanged() { 144 if (wms.getServiceUrl() != null) { 145 wmsUrl.setText(wms.buildGetMapUrl(tree.getSelectedLayers(), (String) formats.getSelectedItem())); 146 name.setText(wms.getServiceUrl().getHost() + ": " + Utils.join(", ", tree.getSelectedLayers())); 147 } 148 showBounds.setEnabled(tree.getSelectedLayers().size() == 1); 149 } 150 151 @Override 152 public ImageryInfo getImageryInfo() { 153 final ImageryInfo info; 154 if (endpoint.isSelected()) { 155 info = new ImageryInfo(getImageryName(), getImageryRawUrl()); 156 info.setImageryType(ImageryInfo.ImageryType.WMS_ENDPOINT); 157 } else { 158 info = wms.toImageryInfo(getImageryName(), tree.getSelectedLayers()); 159 info.setUrl(getWmsUrl()); 160 } 161 return info; 162 } 163 164 protected final String getWmsUrl() { 165 return sanitize(wmsUrl.getText()); 166 } 167 168 @Override 169 protected boolean isImageryValid() { 170 if (getImageryName().isEmpty()) { 171 return false; 172 } 173 if (endpoint.isSelected()) { 174 return !getImageryRawUrl().isEmpty(); 175 } else { 176 return !getWmsUrl().isEmpty(); 177 } 178 } 179}