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