Changeset 5617 in josm for trunk/src/org


Ignore:
Timestamp:
2012-12-10T02:04:50+01:00 (12 years ago)
Author:
simon04
Message:

see #8254 - new imagery entry wms_endpoint: Store WMS endpoint only, select layers at usage

Location:
trunk/src/org/openstreetmap/josm
Files:
4 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java

    r5466 r5617  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.awt.Dimension;
    67import java.awt.event.ActionEvent;
     8import java.io.IOException;
     9import java.net.MalformedURLException;
    710import javax.swing.Action;
    811import javax.swing.ImageIcon;
    912import javax.swing.JOptionPane;
     13import javax.swing.JScrollPane;
    1014import org.openstreetmap.josm.Main;
    1115import org.openstreetmap.josm.data.imagery.ImageryInfo;
    1216import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
     17import org.openstreetmap.josm.gui.ExtendedDialog;
    1318import org.openstreetmap.josm.gui.actionsupport.AlignImageryPanel;
    1419import org.openstreetmap.josm.gui.layer.ImageryLayer;
     20import org.openstreetmap.josm.io.imagery.WMSImagery;
     21import org.openstreetmap.josm.gui.preferences.imagery.WMSLayerTree;
    1522import org.openstreetmap.josm.tools.ImageProvider;
    1623
     
    4451        if (!isEnabled()) return;
    4552        try {
    46             Main.main.addLayer(ImageryLayer.create(info));
    47             AlignImageryPanel.addNagPanelIfNeeded();
     53            final ImageryInfo infoToAdd = ImageryType.WMS_ENDPOINT.equals(info.getImageryType())
     54                    ? getWMSLayerInfo() : info;
     55            if (infoToAdd != null) {
     56                Main.main.addLayer(ImageryLayer.create(infoToAdd));
     57                AlignImageryPanel.addNagPanelIfNeeded();
     58            }
    4859        } catch (IllegalArgumentException ex) {
    4960            if (ex.getMessage() == null || ex.getMessage().isEmpty()) {
     
    5566            }
    5667        }
     68    }
     69
     70    protected ImageryInfo getWMSLayerInfo() {
     71        try {
     72            assert (ImageryType.WMS_ENDPOINT.equals(info.getImageryType()));
     73            final WMSImagery wms = new WMSImagery();
     74            wms.attemptGetCapabilities(info.getUrl());
     75
     76            System.out.println(wms.getLayers());
     77            final WMSLayerTree tree = new WMSLayerTree();
     78            tree.updateTree(wms);
     79
     80            if (1 != new ExtendedDialog(Main.parent, tr("Select WMS layers"), new String[]{tr("Add layers"), tr("Cancel")}) {{
     81                final JScrollPane scrollPane = new JScrollPane(tree.getLayerTree());
     82                setContent(scrollPane);
     83                scrollPane.setPreferredSize(new Dimension(400, 400));
     84            }}.showDialog().getValue()) {
     85                return null;
     86            }
     87
     88            String url = wms.buildGetMapUrl(tree.getSelectedLayers());
     89            return new ImageryInfo(info.getName(), url, "wms", info.getEulaAcceptanceRequired(), info.getCookies());
     90        } // exception handling from AddWMSLayerPanel.java
     91        catch (MalformedURLException ex) {
     92            JOptionPane.showMessageDialog(Main.parent, tr("Invalid service URL."),
     93                    tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
     94        } catch (IOException ex) {
     95            JOptionPane.showMessageDialog(Main.parent, tr("Could not retrieve WMS layer list."),
     96                    tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
     97        } catch (WMSImagery.WMSGetCapabilitiesException ex) {
     98            JOptionPane.showMessageDialog(Main.parent, tr("Could not parse WMS layer list."),
     99                    tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
     100            System.err.println("Could not parse WMS layer list. Incoming data:");
     101            System.err.println(ex.getIncomingData());
     102        }
     103        return null;
    57104    }
    58105   
  • trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java

    r5541 r5617  
    3636        HTML("html"),
    3737        BING("bing"),
    38         SCANEX("scanex");
     38        SCANEX("scanex"),
     39        WMS_ENDPOINT("wms_endpoint");
    3940
    4041        private String urlString;
  • trunk/src/org/openstreetmap/josm/gui/preferences/imagery/AddWMSLayerPanel.java

    r5587 r5617  
    33
    44import static org.openstreetmap.josm.tools.I18n.tr;
    5 import static org.openstreetmap.josm.tools.I18n.trc;
    65
    7 import java.awt.Component;
    8 import java.awt.Cursor;
    96import java.awt.Dimension;
    10 import java.awt.GridBagConstraints;
    117import java.awt.GridBagLayout;
    12 import java.awt.HeadlessException;
    138import java.awt.event.ActionEvent;
    149import java.awt.event.ActionListener;
    15 import java.awt.event.KeyAdapter;
    16 import java.awt.event.KeyEvent;
    17 import java.io.BufferedReader;
     10import java.awt.event.ItemEvent;
     11import java.awt.event.ItemListener;
     12import java.beans.PropertyChangeEvent;
     13import java.beans.PropertyChangeListener;
    1814import java.io.IOException;
    19 import java.io.InputStream;
    20 import java.io.StringReader;
    2115import java.net.MalformedURLException;
    22 import java.net.URL;
    23 import java.net.URLConnection;
    24 import java.util.HashSet;
    25 import java.util.Iterator;
    26 import java.util.LinkedList;
    27 import java.util.List;
    28 import java.util.Set;
    29 import java.util.regex.Pattern;
    30 
    3116import javax.swing.JButton;
     17import javax.swing.JCheckBox;
    3218import javax.swing.JLabel;
    3319import javax.swing.JOptionPane;
    34 import javax.swing.JPanel;
    3520import javax.swing.JScrollPane;
    36 import javax.swing.JTabbedPane;
    3721import javax.swing.JTextArea;
    3822import javax.swing.JTextField;
    39 import javax.swing.JTree;
    40 import javax.swing.event.ChangeEvent;
    41 import javax.swing.event.ChangeListener;
    42 import javax.swing.event.TreeSelectionEvent;
    43 import javax.swing.event.TreeSelectionListener;
    44 import javax.swing.tree.DefaultMutableTreeNode;
    45 import javax.swing.tree.DefaultTreeCellRenderer;
    46 import javax.swing.tree.DefaultTreeModel;
    47 import javax.swing.tree.MutableTreeNode;
    48 import javax.swing.tree.TreePath;
    49 import javax.xml.parsers.DocumentBuilder;
    50 import javax.xml.parsers.DocumentBuilderFactory;
    51 import javax.xml.parsers.ParserConfigurationException;
     23import org.openstreetmap.josm.data.imagery.ImageryInfo;
     24import org.openstreetmap.josm.gui.bbox.SlippyMapBBoxChooser;
     25import org.openstreetmap.josm.io.imagery.WMSImagery;
     26import org.openstreetmap.josm.tools.GBC;
    5227
    53 import org.openstreetmap.josm.data.Bounds;
    54 import org.openstreetmap.josm.data.imagery.ImageryInfo;
    55 import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
    56 import org.openstreetmap.josm.gui.bbox.SlippyMapBBoxChooser;
    57 import org.openstreetmap.josm.gui.layer.TMSLayer;
    58 import org.openstreetmap.josm.gui.preferences.projection.ProjectionChoice;
    59 import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
    60 import org.openstreetmap.josm.io.UTFInputStreamReader;
    61 import org.openstreetmap.josm.tools.GBC;
    62 import org.openstreetmap.josm.tools.Utils;
    63 import org.w3c.dom.Document;
    64 import org.w3c.dom.Element;
    65 import org.w3c.dom.Node;
    66 import org.w3c.dom.NodeList;
    67 import org.xml.sax.EntityResolver;
    68 import org.xml.sax.InputSource;
    69 import org.xml.sax.SAXException;
     28public class AddWMSLayerPanel extends AddImageryPanel {
    7029
    71 
    72 public class AddWMSLayerPanel extends JPanel {
    73     private List<LayerDetails> selectedLayers;
    74     private URL serviceUrl;
    75     private LayerDetails selectedLayer;
    76 
    77     private JTextField menuName;
    78     private JTextArea resultingLayerField;
    79     private MutableTreeNode treeRootNode;
    80     private DefaultTreeModel treeData;
    81     private JTree layerTree;
    82     private JButton showBoundsButton;
    83 
    84     private boolean previouslyShownUnsupportedCrsError = false;
    85     private JTextArea tmsURL;
    86     private JTextField tmsZoom;
     30    private final WMSImagery wms = new WMSImagery();
     31    private final JTextArea rawUrl = new JTextArea(3, 40);
     32    private final JCheckBox endpoint = new JCheckBox(tr("Store WMS endpoint only, select layers at usage"));
     33    private final WMSLayerTree tree = new WMSLayerTree();
     34    private final JTextArea wmsUrl = new JTextArea(3, 40);
     35    private final JTextField name = new JTextField();
    8736
    8837    public AddWMSLayerPanel() {
    8938        super(new GridBagLayout());
    90         add(new JLabel(tr("Menu Name")), GBC.std().insets(0,0,5,0));
    91         menuName = new JTextField(40);
    92         menuName.setText(tr("Unnamed Imagery Layer"));
    93         add(menuName, GBC.eop().insets(5,0,0,0).fill(GridBagConstraints.HORIZONTAL));
    9439
    95         final JTabbedPane tabbedPane = new JTabbedPane();
     40        add(new JLabel(tr("1. Enter service URL")), GBC.eol());
     41        add(rawUrl, GBC.eol().fill());
     42        rawUrl.setLineWrap(true);
     43        JButton getLayers = new JButton(tr("Get layers"));
     44        add(getLayers, GBC.eop().fill());
    9645
    97         final JPanel wmsFetchPanel = new JPanel(new GridBagLayout());
    98         tabbedPane.addTab(tr("WMS"), wmsFetchPanel);
    99         add(tabbedPane, GBC.eop().insets(5,0,0,0).weight(1.0, 1.0).fill(GridBagConstraints.BOTH));
     46        add(new JLabel(tr("2. Select layers")), GBC.eol());
     47        add(endpoint, GBC.eol().fill());
     48        tree.getLayerTree().setPreferredSize(new Dimension(400, 100));
     49        add(new JScrollPane(tree.getLayerTree()), GBC.eol().fill());
     50        final JButton showBounds = new JButton(tr("Show bounds"));
     51        showBounds.setEnabled(false);
     52        add(new JScrollPane(showBounds), GBC.eop().fill());
    10053
    101         final JTextArea serviceUrlText = new JTextArea(3, 40);
    102         serviceUrlText.setLineWrap(true);
    103         serviceUrlText.setText("http://sample.com/wms?");
    104         wmsFetchPanel.add(new JLabel(tr("Service URL")), GBC.std().insets(0,0,5,0));
    105         JScrollPane scrollPane = new JScrollPane(serviceUrlText,
    106                 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
    107                 JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    108         scrollPane.setMinimumSize(new Dimension(60, 60));
    109         wmsFetchPanel.add(scrollPane, GBC.eol().weight(1.0, 0.0).insets(5,0,0,0).fill(GridBagConstraints.HORIZONTAL));
    110         JButton getLayersButton = new JButton(tr("Get Layers"));
    111         getLayersButton.addActionListener(new ActionListener() {
     54        add(new JLabel(tr("3. Verify generated WMS URL")), GBC.eol());
     55        add(wmsUrl, GBC.eop().fill());
     56        wmsUrl.setLineWrap(true);
     57
     58        add(new JLabel(tr("4. Enter name for this layer")), GBC.eol());
     59        add(name, GBC.eop().fill());
     60
     61        getLayers.addActionListener(new ActionListener() {
    11262            @Override
    11363            public void actionPerformed(ActionEvent e) {
    114                 Cursor beforeCursor = getCursor();
    11564                try {
    116                     setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    117                     attemptGetCapabilities(sanitize(serviceUrlText.getText()));
    118                 } finally {
    119                     setCursor(beforeCursor);
     65                    wms.attemptGetCapabilities(rawUrl.getText());
     66                    tree.updateTree(wms);
     67                } catch (MalformedURLException ex) {
     68                    JOptionPane.showMessageDialog(getParent(), tr("Invalid service URL."),
     69                            tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
     70                } catch (IOException ex) {
     71                    JOptionPane.showMessageDialog(getParent(), tr("Could not retrieve WMS layer list."),
     72                            tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
     73                } catch (WMSImagery.WMSGetCapabilitiesException ex) {
     74                    JOptionPane.showMessageDialog(getParent(), tr("Could not parse WMS layer list."),
     75                            tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
     76                    System.err.println("Could not parse WMS layer list. Incoming data:");
     77                    System.err.println(ex.getIncomingData());
    12078                }
    12179            }
    12280        });
    123         wmsFetchPanel.add(getLayersButton, GBC.eop().anchor(GridBagConstraints.EAST));
    12481
    125         treeRootNode = new DefaultMutableTreeNode();
    126         treeData = new DefaultTreeModel(treeRootNode);
    127         layerTree = new JTree(treeData);
    128         layerTree.setCellRenderer(new LayerTreeCellRenderer());
    129         layerTree.addTreeSelectionListener(new TreeSelectionListener() {
    130 
     82        endpoint.addItemListener(new ItemListener() {
    13183            @Override
    132             public void valueChanged(TreeSelectionEvent e) {
    133                 TreePath[] selectionRows = layerTree.getSelectionPaths();
    134                 if(selectionRows == null) {
    135                     showBoundsButton.setEnabled(false);
    136                     selectedLayer = null;
    137                     return;
    138                 }
    139 
    140                 selectedLayers = new LinkedList<LayerDetails>();
    141                 for (TreePath i : selectionRows) {
    142                     Object userObject = ((DefaultMutableTreeNode) i.getLastPathComponent()).getUserObject();
    143                     if(userObject instanceof LayerDetails) {
    144                         LayerDetails detail = (LayerDetails) userObject;
    145                         if(!detail.isSupported()) {
    146                             layerTree.removeSelectionPath(i);
    147                             if(!previouslyShownUnsupportedCrsError) {
    148                                 JOptionPane.showMessageDialog(null, tr("That layer does not support any of JOSM''s projections,\n" +
    149                                         "so you can not use it. This message will not show again."),
    150                                         tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
    151                                 previouslyShownUnsupportedCrsError = true;
    152                             }
    153                         } else if(detail.ident != null) {
    154                             selectedLayers.add(detail);
    155                         }
    156                     }
    157                 }
    158 
    159                 if (!selectedLayers.isEmpty()) {
    160                     resultingLayerField.setText(buildGetMapUrl());
    161 
    162                     if(selectedLayers.size() == 1) {
    163                         showBoundsButton.setEnabled(true);
    164                         selectedLayer = selectedLayers.get(0);
    165                     }
    166                 } else {
    167                     showBoundsButton.setEnabled(false);
    168                     selectedLayer = null;
    169                 }
     84            public void itemStateChanged(ItemEvent e) {
     85                tree.getLayerTree().setEnabled(!endpoint.isSelected());
     86                showBounds.setEnabled(!endpoint.isSelected());
     87                wmsUrl.setEnabled(!endpoint.isSelected());
    17088            }
    17189        });
    172         wmsFetchPanel.add(new JScrollPane(layerTree), GBC.eol().weight(1.0, 1.0).insets(5,0,0,0).fill(GridBagConstraints.BOTH));
    17390
    174         JPanel layerManipulationButtons = new JPanel();
    175         showBoundsButton = new JButton(tr("Show Bounds"));
    176         showBoundsButton.setEnabled(false);
    177         showBoundsButton.addActionListener(new ActionListener() {
     91        tree.getLayerTree().addPropertyChangeListener("selectedLayers", new PropertyChangeListener() {
     92            @Override
     93            public void propertyChange(PropertyChangeEvent evt) {
     94                if (wms.getServiceUrl() != null) {
     95                    wmsUrl.setText(wms.buildGetMapUrl(tree.getSelectedLayers()));
     96                }
     97                showBounds.setEnabled(tree.getSelectedLayers().size() == 1);
     98            }
     99        });
     100
     101        showBounds.addActionListener(new ActionListener() {
    178102            @Override
    179103            public void actionPerformed(ActionEvent e) {
    180                 if(selectedLayer.bounds != null) {
     104                if (tree.getSelectedLayers().get(0).bounds != null) {
    181105                    SlippyMapBBoxChooser mapPanel = new SlippyMapBBoxChooser();
    182                     mapPanel.setBoundingBox(selectedLayer.bounds);
     106                    mapPanel.setBoundingBox(tree.getSelectedLayers().get(0).bounds);
    183107                    JOptionPane.showMessageDialog(null, mapPanel, tr("Show Bounds"), JOptionPane.PLAIN_MESSAGE);
    184108                } else {
     
    188112            }
    189113        });
    190         layerManipulationButtons.add(showBoundsButton);
    191114
    192         wmsFetchPanel.add(layerManipulationButtons, GBC.eol().insets(0,0,5,0));
    193 
    194         final JPanel tmsView = new JPanel(new GridBagLayout());
    195         tmsView.add(new JLabel(tr("TMS URL")), GBC.std().insets(0,0,5,0));
    196         tmsURL = new JTextArea(3, 40);
    197         tmsURL.setLineWrap(true);
    198         tmsURL.setText("http://sample.com/tms/{zoom}/{x}/{y}.jpg");
    199         tmsURL.addKeyListener(new KeyAdapter() {
    200             @Override
    201             public void keyReleased(KeyEvent e) {
    202                 resultingLayerField.setText(buildTMSUrl());
    203             }
    204         });
    205         JScrollPane tmsUrlScrollPane = new JScrollPane(tmsURL,
    206                 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
    207                 JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    208         tmsUrlScrollPane.setMinimumSize(new Dimension(60, 60));
    209         tmsView.add(tmsUrlScrollPane, GBC.eol().insets(5,0,0,0).fill(GridBagConstraints.HORIZONTAL));
    210         tmsView.add(new JLabel(trc("layer", "Zoom")), GBC.std().insets(0,0,5,0));
    211         tmsZoom = new JTextField(3);
    212         tmsZoom.addKeyListener(new KeyAdapter() {
    213             @Override
    214             public void keyReleased(KeyEvent e) {
    215                 resultingLayerField.setText(buildTMSUrl());
    216             }
    217         });
    218         tmsView.add(tmsZoom, GBC.eol().insets(5,0,0,0).fill(GridBagConstraints.HORIZONTAL));
    219         tmsView.add(new JLabel(), GBC.eop().weight(1.0, 1.0).fill(GridBagConstraints.BOTH));
    220         tabbedPane.addTab(tr("TMS"), tmsView);
    221 
    222         add(new JLabel(tr("Imagery URL")), GBC.std().insets(0,0,5,0));
    223         resultingLayerField = new JTextArea(3, 40);
    224         resultingLayerField.setLineWrap(true);
    225         JScrollPane bottomScrollPane = new JScrollPane(resultingLayerField,
    226                 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    227         bottomScrollPane.setMinimumSize(new Dimension(60, 60));
    228         add(bottomScrollPane, GBC.eol().weight(1.0, 0.0).insets(5,0,0,0).fill(GridBagConstraints.HORIZONTAL));
    229 
    230         tabbedPane.addChangeListener(new ChangeListener() {
    231             @Override
    232             public void stateChanged(ChangeEvent e) {
    233                 Component sel = tabbedPane.getSelectedComponent();
    234                 if(tmsView == sel) {
    235                     resultingLayerField.setText(buildTMSUrl());
    236                 } else if(wmsFetchPanel == sel) {
    237                     if(serviceUrl != null) {
    238                         resultingLayerField.setText(buildGetMapUrl());
    239                     }
    240                 }
    241             }
    242         });
    243115    }
    244116
    245     private String sanitize(String s) {
    246         return s.replaceAll("[\r\n]+","").trim();
    247     }
    248 
    249     private String buildTMSUrl() {
    250         StringBuilder a = new StringBuilder("tms");
    251         String z = sanitize(tmsZoom.getText());
    252         if(!z.isEmpty()) {
    253             a.append("["+z+"]");
    254         }
    255         a.append(":");
    256         a.append(sanitize(tmsURL.getText()));
    257         return a.toString();
    258     }
    259 
    260     private String buildRootUrl() {
    261         StringBuilder a = new StringBuilder(serviceUrl.getProtocol());
    262         a.append("://");
    263         a.append(serviceUrl.getHost());
    264         if(serviceUrl.getPort() != -1) {
    265             a.append(":");
    266             a.append(serviceUrl.getPort());
    267         }
    268         a.append(serviceUrl.getPath());
    269         a.append("?");
    270         if(serviceUrl.getQuery() != null) {
    271             a.append(serviceUrl.getQuery());
    272             if (!serviceUrl.getQuery().isEmpty() && !serviceUrl.getQuery().endsWith("&")) {
    273                 a.append("&");
    274             }
    275         }
    276         return a.toString();
    277     }
    278 
    279     private String buildGetMapUrl() {
    280         StringBuilder a = new StringBuilder();
    281         a.append(buildRootUrl());
    282         a.append("FORMAT=image/jpeg&VERSION=1.1.1&SERVICE=WMS&REQUEST=GetMap&LAYERS=");
    283         a.append(commaSepLayerList());
    284         a.append("&STYLES=&SRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}");
    285 
    286         return a.toString();
    287     }
    288 
    289     private String commaSepLayerList() {
    290         StringBuilder b = new StringBuilder();
    291 
    292         if (selectedLayers != null) {
    293             Iterator<LayerDetails> iterator = selectedLayers.iterator();
    294             while (iterator.hasNext()) {
    295                 LayerDetails layerDetails = iterator.next();
    296                 b.append(layerDetails.ident);
    297                 if(iterator.hasNext()) {
    298                     b.append(",");
    299                 }
    300             }
    301         }
    302 
    303         return b.toString();
    304     }
    305 
    306     private void showError(String incomingData, Exception e) {
    307         JOptionPane.showMessageDialog(this, tr("Could not parse WMS layer list."),
    308                 tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
    309         System.err.println("Could not parse WMS layer list. Incoming data:");
    310         System.err.println(incomingData);
    311         e.printStackTrace();
    312     }
    313 
    314     private void attemptGetCapabilities(String serviceUrlStr) {
    315         URL getCapabilitiesUrl = null;
    316         try {
    317             if (!Pattern.compile(".*GetCapabilities.*", Pattern.CASE_INSENSITIVE).matcher(serviceUrlStr).matches()) {
    318                 // If the url doesn't already have GetCapabilities, add it in
    319                 getCapabilitiesUrl = new URL(serviceUrlStr);
    320                 final String getCapabilitiesQuery = "VERSION=1.1.1&SERVICE=WMS&REQUEST=GetCapabilities";
    321                 if (getCapabilitiesUrl.getQuery() == null) {
    322                     getCapabilitiesUrl = new URL(serviceUrlStr + "?" + getCapabilitiesQuery);
    323                 } else if (!getCapabilitiesUrl.getQuery().isEmpty() && !getCapabilitiesUrl.getQuery().endsWith("&")) {
    324                     getCapabilitiesUrl = new URL(serviceUrlStr + "&" + getCapabilitiesQuery);
    325                 } else {
    326                     getCapabilitiesUrl = new URL(serviceUrlStr + getCapabilitiesQuery);
    327                 }
    328             } else {
    329                 // Otherwise assume it's a good URL and let the subsequent error
    330                 // handling systems deal with problems
    331                 getCapabilitiesUrl = new URL(serviceUrlStr);
    332             }
    333             serviceUrl = new URL(serviceUrlStr);
    334         } catch (HeadlessException e) {
    335             return;
    336         } catch (MalformedURLException e) {
    337             JOptionPane.showMessageDialog(this, tr("Invalid service URL."),
    338                     tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
    339             return;
    340         }
    341 
    342         String incomingData;
    343         try {
    344             System.out.println("GET "+getCapabilitiesUrl.toString());
    345             URLConnection openConnection = Utils.openHttpConnection(getCapabilitiesUrl);
    346             InputStream inputStream = openConnection.getInputStream();
    347             BufferedReader br = new BufferedReader(UTFInputStreamReader.create(inputStream, "UTF-8"));
    348             String line;
    349             StringBuilder ba = new StringBuilder();
    350             while ((line = br.readLine()) != null) {
    351                 ba.append(line);
    352                 ba.append("\n");
    353             }
    354             incomingData = ba.toString();
    355         } catch (IOException e) {
    356             JOptionPane.showMessageDialog(this, tr("Could not retrieve WMS layer list."),
    357                     tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
    358             return;
    359         }
    360 
    361         Document document;
    362         try {
    363             //System.out.println("WMS capabilities:\n"+incomingData+"\n");
    364             DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    365             builderFactory.setValidating(false);
    366             builderFactory.setNamespaceAware(true);
    367             DocumentBuilder builder = builderFactory.newDocumentBuilder();
    368             builder.setEntityResolver(new EntityResolver() {
    369                 @Override
    370                 public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
    371                     System.out.println("Ignoring DTD " + publicId + ", " + systemId);
    372                     return new InputSource(new StringReader(""));
    373                 }
    374             });
    375             document = builder.parse(new InputSource(new StringReader(incomingData)));
    376         } catch (ParserConfigurationException e) {
    377             showError(incomingData, e);
    378             return;
    379         } catch (SAXException e) {
    380             showError(incomingData, e);
    381             return;
    382         } catch (IOException e) {
    383             showError(incomingData, e);
    384             return;
    385         }
    386 
    387         // Some WMS service URLs specify a different base URL for their GetMap service
    388         Element child = getChild(document.getDocumentElement(), "Capability");
    389         child = getChild(child, "Request");
    390         child = getChild(child, "GetMap");
    391         child = getChild(child, "DCPType");
    392         child = getChild(child, "HTTP");
    393         child = getChild(child, "Get");
    394         child = getChild(child, "OnlineResource");
    395         if (child != null) {
    396             String baseURL = child.getAttribute("xlink:href");
    397             if (baseURL != null && !baseURL.equals(serviceUrlStr)) {
    398                 try {
    399                     System.out.println("GetCapabilities specifies a different service URL: " + baseURL);
    400                     serviceUrl = new URL(baseURL);
    401                 } catch (MalformedURLException e1) {
    402                 }
    403             }
    404         }
    405 
    406         try {
    407             treeRootNode.setUserObject(getCapabilitiesUrl.getHost());
    408             Element capabilityElem = getChild(document.getDocumentElement(), "Capability");
    409             List<Element> children = getChildren(capabilityElem, "Layer");
    410             List<LayerDetails> layers = parseLayers(children, new HashSet<String>());
    411             updateTreeList(layers);
    412         } catch(Exception e) {
    413             showError(incomingData, e);
    414             return;
    415         }
    416     }
    417 
    418     private void updateTreeList(List<LayerDetails> layers) {
    419         addLayersToTreeData(treeRootNode, layers);
    420         layerTree.expandRow(0);
    421     }
    422 
    423     private void addLayersToTreeData(MutableTreeNode parent, List<LayerDetails> layers) {
    424         for (LayerDetails layerDetails : layers) {
    425             DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode(layerDetails);
    426             addLayersToTreeData(treeNode, layerDetails.children);
    427             treeData.insertNodeInto(treeNode, parent, 0);
    428         }
    429     }
    430 
    431     private List<LayerDetails> parseLayers(List<Element> children, Set<String> parentCrs) {
    432         List<LayerDetails> details = new LinkedList<LayerDetails>();
    433         for (Element element : children) {
    434             details.add(parseLayer(element, parentCrs));
    435         }
    436         return details;
    437     }
    438 
    439     private LayerDetails parseLayer(Element element, Set<String> parentCrs) {
    440         String name = getChildContent(element, "Title", null, null);
    441         String ident = getChildContent(element, "Name", null, null);
    442 
    443         // The set of supported CRS/SRS for this layer
    444         Set<String> crsList = new HashSet<String>();
    445         // ...including this layer's already-parsed parent projections
    446         crsList.addAll(parentCrs);
    447 
    448         // Parse the CRS/SRS pulled out of this layer's XML element
    449         // I think CRS and SRS are the same at this point
    450         List<Element> crsChildren = getChildren(element, "CRS");
    451         crsChildren.addAll(getChildren(element, "SRS"));
    452         for (Element child : crsChildren) {
    453             String crs = (String) getContent(child);
    454             if(crs != null) {
    455                 String upperCase = crs.trim().toUpperCase();
    456                 crsList.add(upperCase);
    457             }
    458         }
    459 
    460         // Check to see if any of the specified projections are supported by JOSM
    461         boolean josmSupportsThisLayer = false;
    462         for (String crs : crsList) {
    463             josmSupportsThisLayer |= isProjSupported(crs);
    464         }
    465 
    466         Bounds bounds = null;
    467         Element bboxElem = getChild(element, "EX_GeographicBoundingBox");
    468         if(bboxElem != null) {
    469             // Attempt to use EX_GeographicBoundingBox for bounding box
    470             double left = Double.parseDouble(getChildContent(bboxElem, "westBoundLongitude", null, null));
    471             double top = Double.parseDouble(getChildContent(bboxElem, "northBoundLatitude", null, null));
    472             double right = Double.parseDouble(getChildContent(bboxElem, "eastBoundLongitude", null, null));
    473             double bot = Double.parseDouble(getChildContent(bboxElem, "southBoundLatitude", null, null));
    474             bounds = new Bounds(bot, left, top, right);
     117    @Override
     118    public ImageryInfo getImageryInfo() {
     119        final ImageryInfo info;
     120        if (endpoint.isSelected()) {
     121            info = new ImageryInfo(name.getText(), rawUrl.getText());
     122            info.setImageryType(ImageryInfo.ImageryType.WMS_ENDPOINT);
    475123        } else {
    476             // If that's not available, try LatLonBoundingBox
    477             bboxElem = getChild(element, "LatLonBoundingBox");
    478             if(bboxElem != null) {
    479                 double left = Double.parseDouble(bboxElem.getAttribute("minx"));
    480                 double top = Double.parseDouble(bboxElem.getAttribute("maxy"));
    481                 double right = Double.parseDouble(bboxElem.getAttribute("maxx"));
    482                 double bot = Double.parseDouble(bboxElem.getAttribute("miny"));
    483                 bounds = new Bounds(bot, left, top, right);
    484             }
    485         }
    486 
    487         List<Element> layerChildren = getChildren(element, "Layer");
    488         List<LayerDetails> childLayers = parseLayers(layerChildren, crsList);
    489 
    490         return new LayerDetails(name, ident, crsList, josmSupportsThisLayer, bounds, childLayers);
    491     }
    492 
    493     private boolean isProjSupported(String crs) {
    494         for (ProjectionChoice pc : ProjectionPreference.getProjectionChoices()) {
    495             if (pc.getPreferencesFromCode(crs) != null) return true;
    496         }
    497         return false;
    498     }
    499 
    500     public ImageryInfo getImageryInfo() {
    501         ImageryInfo info = new ImageryInfo(menuName.getText(), resultingLayerField.getText());
    502         if (ImageryType.TMS.equals(info.getImageryType())) {
    503             TMSLayer.checkUrl(info.getUrl());
    504         } else if (selectedLayers != null) {
    505             HashSet<String> proj = new HashSet<String>();
    506             for(LayerDetails l : selectedLayers) {
    507                 proj.addAll(l.getProjections());
    508             }
    509             info.setServerProjections(proj);
     124            info = wms.toImageryInfo(name.getText(), tree.getSelectedLayers());
     125            info.setUrl(wmsUrl.getText());
    510126        }
    511127        return info;
    512128    }
    513 
    514     private static String getChildContent(Element parent, String name, String missing, String empty) {
    515         Element child = getChild(parent, name);
    516         if (child == null)
    517             return missing;
    518         else {
    519             String content = (String) getContent(child);
    520             return (content != null) ? content : empty;
    521         }
    522     }
    523 
    524     private static Object getContent(Element element) {
    525         NodeList nl = element.getChildNodes();
    526         StringBuffer content = new StringBuffer();
    527         for (int i = 0; i < nl.getLength(); i++) {
    528             Node node = nl.item(i);
    529             switch (node.getNodeType()) {
    530             case Node.ELEMENT_NODE:
    531                 return node;
    532             case Node.CDATA_SECTION_NODE:
    533             case Node.TEXT_NODE:
    534                 content.append(node.getNodeValue());
    535                 break;
    536             }
    537         }
    538         return content.toString().trim();
    539     }
    540 
    541     private static List<Element> getChildren(Element parent, String name) {
    542         List<Element> retVal = new LinkedList<Element>();
    543         for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
    544             if (child instanceof Element && name.equals(child.getNodeName())) {
    545                 retVal.add((Element) child);
    546             }
    547         }
    548         return retVal;
    549     }
    550 
    551     private static Element getChild(Element parent, String name) {
    552         if (parent == null)
    553             return null;
    554         for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
    555             if (child instanceof Element && name.equals(child.getNodeName()))
    556                 return (Element) child;
    557         }
    558         return null;
    559     }
    560 
    561     static class LayerDetails {
    562 
    563         private String name;
    564         private String ident;
    565         private List<LayerDetails> children;
    566         private Bounds bounds;
    567         private Set<String> crsList;
    568         private boolean supported;
    569 
    570         public LayerDetails(String name, String ident, Set<String> crsList,
    571                 boolean supportedLayer, Bounds bounds,
    572                 List<LayerDetails> childLayers) {
    573             this.name = name;
    574             this.ident = ident;
    575             this.supported = supportedLayer;
    576             this.children = childLayers;
    577             this.bounds = bounds;
    578             this.crsList = crsList;
    579         }
    580 
    581         public boolean isSupported() {
    582             return this.supported;
    583         }
    584 
    585         public Set<String> getProjections() {
    586             return crsList;
    587         }
    588 
    589         @Override
    590         public String toString() {
    591             if(this.name == null || this.name.isEmpty())
    592                 return this.ident;
    593             else
    594                 return this.name;
    595         }
    596 
    597     }
    598 
    599     static class LayerTreeCellRenderer extends DefaultTreeCellRenderer {
    600         @Override
    601         public Component getTreeCellRendererComponent(JTree tree, Object value,
    602                 boolean sel, boolean expanded, boolean leaf, int row,
    603                 boolean hasFocus) {
    604             super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
    605                     row, hasFocus);
    606             DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) value;
    607             Object userObject = treeNode.getUserObject();
    608             if (userObject instanceof LayerDetails) {
    609                 LayerDetails layer = (LayerDetails) userObject;
    610                 setEnabled(layer.isSupported());
    611             }
    612             return this;
    613         }
    614     }
    615 
    616129}
  • trunk/src/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreference.java

    r5541 r5617  
    336336            activeToolbar.setBorderPainted(false);
    337337            activeToolbar.setOpaque(false);
    338             activeToolbar.add(new NewEntryAction());
     338            activeToolbar.add(new NewEntryAction(ImageryInfo.ImageryType.WMS));
     339            activeToolbar.add(new NewEntryAction(ImageryInfo.ImageryType.TMS));
    339340            //activeToolbar.add(edit); TODO
    340341            activeToolbar.add(remove);
     
    420421
    421422        private class NewEntryAction extends AbstractAction {
    422             public NewEntryAction() {
    423                 putValue(NAME, tr("New"));
    424                 putValue(SHORT_DESCRIPTION, tr("Add a new WMS/TMS entry by entering the URL"));
     423
     424            private final ImageryInfo.ImageryType type;
     425
     426            public NewEntryAction(ImageryInfo.ImageryType type) {
     427                putValue(NAME, type.toString());
     428                putValue(SHORT_DESCRIPTION, tr("Add a new {0} entry by entering the URL", type.toString()));
    425429                putValue(SMALL_ICON, ImageProvider.get("dialogs", "add"));
     430                this.type = type;
    426431            }
    427432
    428433            public void actionPerformed(ActionEvent evt) {
    429                 final AddWMSLayerPanel p = new AddWMSLayerPanel();
     434                final AddImageryPanel p;
     435                if (ImageryInfo.ImageryType.WMS.equals(type)) {
     436                    p = new AddWMSLayerPanel();
     437                } else if (ImageryInfo.ImageryType.TMS.equals(type)) {
     438                    p = new AddTMSLayerPanel();
     439                } else {
     440                    throw new IllegalStateException("Type " + type + " not supported");
     441                }
    430442                GuiHelper.prepareResizeableOptionPane(p, new Dimension(250, 350));
    431443                int answer = JOptionPane.showConfirmDialog(
Note: See TracChangeset for help on using the changeset viewer.