001: package org.geotools.demo;
002:
003: import java.awt.BorderLayout;
004: import java.awt.Color;
005: import java.awt.Component;
006: import java.awt.Dimension;
007: import java.awt.Graphics;
008: import java.awt.Graphics2D;
009: import java.awt.Image;
010: import java.awt.event.ActionEvent;
011: import java.awt.event.ActionListener;
012: import java.awt.event.ItemEvent;
013: import java.awt.event.ItemListener;
014: import java.net.MalformedURLException;
015: import java.net.URL;
016: import java.util.Arrays;
017: import java.util.HashMap;
018: import java.util.Iterator;
019: import java.util.List;
020: import java.util.Map;
021: import java.util.Set;
022: import java.util.Map.Entry;
023:
024: import javax.swing.DefaultComboBoxModel;
025: import javax.swing.DefaultListCellRenderer;
026: import javax.swing.Icon;
027: import javax.swing.ImageIcon;
028: import javax.swing.JButton;
029: import javax.swing.JComboBox;
030: import javax.swing.JFrame;
031: import javax.swing.JList;
032: import javax.swing.JOptionPane;
033: import javax.swing.JPanel;
034: import javax.swing.JScrollPane;
035: import javax.swing.event.ListSelectionEvent;
036: import javax.swing.event.ListSelectionListener;
037:
038: import org.geotools.data.ows.CRSEnvelope;
039: import org.geotools.data.ows.Layer;
040: import org.geotools.data.ows.OperationType;
041: import org.geotools.data.ows.WMSCapabilities;
042: import org.geotools.data.ows.WMSRequest;
043: import org.geotools.data.wms.WMSUtils;
044: import org.geotools.data.wms.WebMapServer;
045: import org.geotools.data.wms.request.GetLegendGraphicRequest;
046: import org.geotools.data.wms.request.GetMapRequest;
047: import org.opengis.layer.Style;
048:
049: /**
050: * This lab explores the use of the GeoTools WMS client code.
051: * <p>
052: * The GeoTools WMS client is a little bit more than simply sending away GetMap
053: * request:
054: * <ul>
055: * <li></li>
056: * </ul>
057: *
058: * @author Jody Garnett
059: */
060: public class WMSLab extends JFrame {
061: private static final long serialVersionUID = -3039255518595806472L;
062:
063: /** Original coverage we are working on */
064: WebMapServer wms;
065: CoveragePanel panel;
066: Image image;
067: JList layers;
068: JButton getMapButton;
069: JComboBox styleCombo;
070: /**
071: * Map<Layer,Style> as controlled by styleCombo box
072: */
073: Map styles = new HashMap();
074: Layer selectedLayer = null;
075:
076: DefaultComboBoxModel availableStyles;
077:
078: /**
079: * Explore the functionality of the provided GridCoverage (think
080: * BufferedImage + CRS).
081: * <p>
082: * A GridCoverage literally a set of features that "covers" an area without
083: * gaps; in the case of grid coverage the area is covered by an regular
084: * grid.
085: * <p>
086: * Coverage work by letting you call a "sample" operation in order to
087: * retrieve a Record of the data at the location. A grid coverage lets you
088: * express the location using row and column.
089: * <p>
090: *
091: * @param coverage
092: */
093: public WMSLab(WebMapServer server) {
094: this .wms = server;
095: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
096: setLayout(new BorderLayout());
097:
098: String title = getWMSTitle(wms);
099: setTitle(title);
100:
101: Set good = WMSUtils.getQueryableLayers(wms.getCapabilities());
102: this .layers = new JList(good.toArray());
103: layers.setCellRenderer(new LayerCellRenderer());
104: layers.getSelectionModel().addListSelectionListener(
105: new ListSelectionListener() {
106: public void valueChanged(ListSelectionEvent e) {
107: setSelectedLayer((Layer) layers
108: .getSelectedValue());
109: }
110: });
111: JScrollPane scrollPane = new JScrollPane(layers);
112: scrollPane.setPreferredSize(new Dimension(200, 400));
113: add(scrollPane, BorderLayout.WEST);
114:
115: this .panel = new CoveragePanel();
116: add(panel, BorderLayout.CENTER);
117:
118: JPanel buttons = new JPanel();
119: getMapButton = new JButton("GetMap");
120: getMapButton.addActionListener(new ActionListener() {
121: public void actionPerformed(ActionEvent e) {
122: getMap();
123: }
124: });
125: buttons.add(getMapButton);
126: availableStyles = new DefaultComboBoxModel();
127: styleCombo = new JComboBox(availableStyles);
128: styleCombo.addItemListener(new ItemListener() {
129: public void itemStateChanged(ItemEvent e) {
130: if (selectedLayer != null) {
131: styles.put(selectedLayer, styleCombo
132: .getSelectedItem());
133: }
134: }
135: });
136: styleCombo.setRenderer(new StyleCellRenderer());
137: buttons.add(styleCombo);
138:
139: add(buttons, BorderLayout.NORTH);
140: pack();
141: }
142:
143: private String getWMSTitle(WebMapServer wms) {
144: return null;
145: }
146:
147: public void setSelectedLayer(Layer selected) {
148: availableStyles.removeAllElements();
149: this .selectedLayer = selected;
150: if (selected != null) {
151: // availableStyles.addElement("default");
152: List styles = selected.getStyles();
153: for (Iterator i = styles.iterator(); i.hasNext();) {
154: Style style = (Style) i.next();
155: availableStyles.addElement(style);
156: }
157: }
158: styleCombo.repaint();
159: }
160:
161: class StyleCellRenderer extends DefaultListCellRenderer {
162: private static final long serialVersionUID = 7421698429520525469L;
163:
164: public Component getListCellRendererComponent(JList list,
165: Object value, // value
166: // to
167: // display
168: int index, // cell index
169: boolean iss, // is the cell selected
170: boolean chf) // the list and the cell have the focus
171: {
172: super .getListCellRendererComponent(list, value, index, iss,
173: chf);
174: Style style = (Style) value;
175: if (style == null)
176: return this ;
177:
178: String title = style.getTitle() == null ? style.getName()
179: : style.getTitle().toString();
180: setText(title);
181: return this ;
182: }
183:
184: Icon getIcon(Style style) {
185: List urlList = style.getLegendURLs();
186: if (urlList == null || urlList.isEmpty())
187: return null;
188:
189: URL url = (URL) style.getLegendURLs().get(0);
190: ImageIcon icon = new ImageIcon(url);
191: return icon;
192: }
193: }
194:
195: class LayerCellRenderer extends DefaultListCellRenderer {
196: private static final long serialVersionUID = 1173012107250651733L;
197: HashMap icons = new HashMap();
198:
199: public Component getListCellRendererComponent(JList list,
200: Object value, // value
201: // to
202: // display
203: int index, // cell index
204: boolean iss, // is the cell selected
205: boolean chf) // the list and the cell have the focus
206: {
207: super .getListCellRendererComponent(list, value, index, iss,
208: chf);
209: Layer layer = (Layer) value;
210: setText(layer.getTitle());
211: Icon glyph;
212: if (icons.containsKey(layer)) {
213: glyph = (Icon) icons.get(layer);
214: } else {
215: glyph = getLegendGraphics(layer);
216: icons.put(layer, glyph);
217: }
218: setIcon(glyph);
219: setToolTipText(layer.getName());
220: return this ;
221: }
222: }
223:
224: public Icon getLegendGraphics(Layer layer) {
225: return null;
226: }
227:
228: private String getNamedStyle(Layer layer) {
229: Object layerStyle = styles.get(layer);
230: String namedStyle = null;
231: if (layerStyle == null) {
232: namedStyle = null;
233: } else if (layerStyle instanceof String) {
234: namedStyle = (String) layerStyle;
235:
236: } else if (layerStyle instanceof Style) {
237: Style style = (Style) layerStyle;
238: namedStyle = style.getName();
239: }
240: return namedStyle;
241: }
242:
243: public void getMap() {
244: try {
245: Layer selected = (Layer) layers.getSelectedValue();
246: getMap(selected);
247: } catch (Exception e1) {
248: image = null;
249: }
250: }
251:
252: private void getMap(Layer layer) throws Exception {
253: panel.repaint();
254: }
255:
256: private void getMap(List layers) throws Exception {
257: if (layers == null || layers.isEmpty())
258: return;
259:
260: GetMapRequest mapRequest = wms.createGetMapRequest();
261: CRSEnvelope bounds = null;
262: for (Iterator i = layers.iterator(); i.hasNext();) {
263: Layer layer = (Layer) i.next();
264: String namedStyle = getNamedStyle(layer);
265: mapRequest.addLayer(layer, namedStyle);
266: CRSEnvelope box = layer.getLatLonBoundingBox();
267: box.setEPSGCode("EPSG:4326");
268: if (box != null) {
269: if (bounds != null) {
270: bounds.setMinX(Math.min(bounds.getMinX(), box
271: .getMinX()));
272: bounds.setMaxX(Math.max(bounds.getMaxX(), box
273: .getMaxX()));
274: bounds.setMinY(Math.min(bounds.getMinY(), box
275: .getMinY()));
276: bounds.setMaxY(Math.max(bounds.getMaxY(), box
277: .getMaxY()));
278: } else {
279: bounds = box;
280: }
281: }
282: }
283: if (bounds == null) {
284: bounds = new CRSEnvelope();
285: bounds.setEPSGCode("EPSG:4326");
286: }
287: mapRequest.setFormat(getImageFormat(wms));
288:
289: mapRequest.setSRS(bounds.getEPSGCode());
290: mapRequest.setBBox(bounds);
291: mapRequest.setDimensions(panel.getWidth(), panel.getHeight());
292:
293: URL url = mapRequest.getFinalURL();
294: ImageIcon load = new ImageIcon(url);
295: image = load.getImage();
296: panel.repaint();
297: }
298:
299: /**
300: * Some WMS Servers like GeoServer support strange formats like KML and PDF
301: *
302: * @return
303: */
304: String getImageFormat(WebMapServer wms) {
305: OperationType description = wms.getCapabilities().getRequest()
306: .getGetMap();
307:
308: List formats = description.getFormats();
309: for (Iterator i = formats.iterator(); i.hasNext();) {
310: String format = (String) i.next();
311: if (format.indexOf("pdf") != -1)
312: continue;
313:
314: return format;
315: }
316: return "image/jpeg";
317: }
318:
319: /**
320: * Search through the layer data structure for bounds for the provided srs
321: * (if null we will return the first bounds).
322: *
323: * @param srs
324: * @return CRSEnvelope
325: */
326: CRSEnvelope getCRSEnvelope(Layer layer, String srs) {
327:
328: if (layer == null)
329: return null;
330: Map boundingBoxes = layer.getBoundingBoxes();
331: if (boundingBoxes != null && !boundingBoxes.isEmpty()) {
332: for (Iterator i = boundingBoxes.entrySet().iterator(); i
333: .hasNext();) {
334: Map.Entry entry = (Entry) i.next();
335: String layerSrs = (String) entry.getKey();
336: CRSEnvelope box = (CRSEnvelope) entry.getValue();
337: if (srs == null || srs.equals(layerSrs)) {
338: return box;
339: }
340: }
341: }
342: return getCRSEnvelope(layer.getParent(), srs);
343: }
344:
345: class CoveragePanel extends JPanel {
346: private static final long serialVersionUID = -4755270758709990530L;
347:
348: CoveragePanel() {
349: setBackground(Color.WHITE);
350: }
351:
352: public Dimension getPreferredSize() {
353: return new Dimension(640, 400);
354: }
355:
356: public void paintComponent(Graphics graphics) {
357: super .paintComponents(graphics);
358: if (image != null) {
359: Graphics2D g = (Graphics2D) graphics;
360: g.drawImage(image, 0, 0, null);
361: }
362: }
363: }
364:
365: /**
366: * Prompt the user for a file and open up ImageLab.
367: *
368: * @param args
369: * filename of image
370: */
371: public static void main(String[] args) throws Exception {
372: URL server = getServerURL(args);
373: WebMapServer wms;
374:
375: System.out.println("Connecting to " + server);
376: wms = new WebMapServer(server);
377:
378: System.out.println("Welcome");
379: WMSLab wmsLab = new WMSLab(wms);
380: wmsLab.setVisible(true);
381: }
382:
383: public static String[] getLayerNames(WebMapServer wms) {
384: Layer[] namedLayers = WMSUtils.getNamedLayers(wms
385: .getCapabilities());
386: String[] names = new String[namedLayers.length];
387: for (int i = 0; i < namedLayers.length; i++) {
388: Layer layer = namedLayers[i];
389: names[i] = layer.getName();
390: }
391: return names;
392: }
393:
394: public static URL getServerURL(String[] args)
395: throws MalformedURLException {
396: if (args.length == 0) {
397: Object[] servers = new Object[] {
398: "http://localhost:8080/geoserver/wms?service=WMS&request=GetCapabilities",
399: "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?Service=WMS&VERSION=1.1.0&REQUEST=GetCapabilities",
400: "http://wms.jpl.nasa.gov/wms.cgi?Service=WMS&Version=1.1.1&Request=GetCapabilities",
401: "http://giswebservices.massgis.state.ma.us/geoserver/wms?service=WMS&request=GetCapabilities",
402: "http://wms.cits.rncan.gc.ca/cgi-bin/cubeserv.cgi?VERSION=1.1.0&REQUEST=GetCapabilities",
403: "http://atlas.gc.ca/cgi-bin/atlaswms_en?VERSION=1.1.1&Request=GetCapabilities&Service=WMS", };
404: Object selected = JOptionPane.showInputDialog(null,
405: "WMS GetCapabilities URL", "Choose a WMS Server",
406: JOptionPane.QUESTION_MESSAGE, null, servers, null);
407:
408: if (selected == null)
409: System.exit(0);
410:
411: return new URL((String) selected);
412: } else {
413: return new URL(args[0]);
414: }
415: }
416: }
|