Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.remoteclient / src / main / java / org / gvsig / remoteclient / wms / WMSClient.java @ 41285

History | View | Annotate | Download (10.6 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

    
25
package org.gvsig.remoteclient.wms;
26

    
27
import java.awt.geom.Rectangle2D;
28
import java.io.File;
29
import java.io.IOException;
30
import java.net.ConnectException;
31
import java.net.URL;
32
import java.util.TreeMap;
33
import java.util.Vector;
34
import org.apache.commons.lang3.StringUtils;
35

    
36
import org.gvsig.compat.net.ICancellable;
37
import org.gvsig.remoteclient.exceptions.ServerErrorException;
38
import org.gvsig.remoteclient.exceptions.WMSException;
39
import org.gvsig.remoteclient.utils.BoundaryBox;
40
import org.slf4j.Logger;
41
import org.slf4j.LoggerFactory;
42

    
43

    
44
/**
45
 * <p>Represents the class the with the necessary logic to connect to a OGCWMS and interpretate the data </p>
46
 * 
47
 */
48
public class WMSClient extends org.gvsig.remoteclient.RasterClient {
49
    
50
    private static final Logger logger = LoggerFactory.getLogger(WMSClient.class);
51
    private org.gvsig.remoteclient.wms.WMSProtocolHandler handler;
52
//    private TreeMap layers = new TreeMap();
53
//    private WMSLayer rootLayer;
54
    
55
    /**
56
     * @return Returns the rootLayer.
57
     */
58
    public WMSLayer getRootLayer() {
59
        return handler.rootLayer;
60
    }
61

    
62
    /**
63
     * Constructor.
64
     * the parameter host, indicates the WMS host to connect.
65
     * */
66
    public WMSClient(String host) throws ConnectException, IOException 
67
    {
68
            setHost(host);
69
        try {                
70
                handler = WMSProtocolHandlerFactory.negotiate(host);
71
                handler.setHost(host);        
72
        } catch(ConnectException conE) {
73
                logger.warn("Can't create WMS protocol handler for host '"+host+"'.",conE);
74
                throw conE; 
75
        } catch(IOException ioE) {
76
                logger.warn("Can't create WMS protocol handler for host '"+host+"'.",ioE);
77
                throw ioE; 
78
        } catch(Exception e) {
79
                logger.warn("Can't create WMS protocol handler for host '"+host+"'.",e);
80
        }
81
    }
82
    
83
    public String getVersion()
84
    {
85
        return handler.getVersion();
86
    }
87
    /**
88
     * <p>One of the three interfaces that OGC WMS defines. Request a map.</p> 
89
     * @throws ServerErrorException 
90
     */
91
    public File getMap(WMSStatus status, ICancellable cancel) throws WMSException, ServerErrorException{   
92
        return handler.getMap(status, cancel);
93
    } 
94
    
95
    /**
96
     * <p>Gets the GetMap URL. The final client should download the file</p> 
97
     * @throws ServerErrorException 
98
     */
99
    public URL getGetMapURL(WMSStatus status, ICancellable cancel) throws WMSException, ServerErrorException{   
100
       return handler.getMapURL(status, cancel);
101
    } 
102
    
103
    /**
104
     * Returns the exception message if the file is a XML instead of a image.
105
     * @param file
106
     * @return
107
     * @throws IOException 
108
     */
109
    public String getExceptionMessage(File file) throws IOException {
110
            return handler.getExceptionMessage(file);
111
    }
112
    
113
    /**
114
     * <p>One of the three interfaces defined by OGC WMS, it gets the service capabilities</p>
115
     * @param override, if true the previous downloaded data will be overridden
116
     */
117
    public void getCapabilities(WMSStatus status, boolean override, ICancellable cancel) {        
118
        handler.getCapabilities(status, override, cancel);
119
    } 
120
    
121
    /**
122
     * <p>One of the three interfaces defined by the OGC WMS, it gets the information about a feature requested</p>
123
     * @return 
124
     */
125
    public String getFeatureInfo(WMSStatus status, int x, int y, int featureCount, ICancellable cancel) throws WMSException{        
126
        return handler.getFeatureInfo(status, x, y, featureCount, cancel);
127
    } 
128
    
129
    /**
130
     * <p>One of the three interfaces defined by the OGC WMS, it gets legend of a layer</p>
131
     * @return 
132
     */
133
    public File getLegendGraphic(WMSStatus status, String layerName, ICancellable cancel) throws WMSException, ServerErrorException{        
134
        return handler.getLegendGraphic(status, layerName, cancel);
135
    } 
136
    
137
    /**
138
     * <p> Reads from the WMS Capabilities, the layers available in the service</p>
139
     * @return a TreeMap with the available layers in the WMS 
140
     */
141
    public TreeMap getLayers() {        
142
        return handler.layers;
143
    } 
144
    
145
    /**
146
     * <p>Reads from the WMS Capabilities the number if layers available in the service</p>
147
     * @return, number of layers available
148
     */
149
    public int getNumberOfLayers() {        
150
        if (handler.layers != null)
151
        {
152
            return handler.layers.size();
153
        }
154
        return 0;
155
    } 
156
    
157
    /**
158
     * <p>Gets the WMSLayer with this name</p>
159
     * 
160
     * @param _name, layer name
161
     * @return the layer with this name
162
     */
163
    public WMSLayer getLayer(String _name) {        
164
        if (handler.layers.get(_name) != null)
165
        {
166
            return (WMSLayer)handler.layers.get(_name);
167
        }
168
        
169
        return null;
170
    } 
171
    
172
    public String[] getLayerNames()
173
    {            
174
        WMSLayer[] lyrs;
175
        
176
        lyrs = (WMSLayer[])handler.layers.values().toArray(new WMSLayer[0]);
177
        
178
        String[] names = new String[lyrs.length];
179
        
180
        for(int i = 0; i<lyrs.length; i++)
181
        {
182
            names[i] = ((WMSLayer)lyrs[i]).getName();
183
        }
184
        return names;
185
    }
186
    
187
    public String[] getLayerTitles()
188
    {            
189
        WMSLayer[] lyrs;
190
        
191
        lyrs = (WMSLayer[])handler.layers.values().toArray(new WMSLayer[0]);
192
        
193
        String[] titles = new String[lyrs.length];
194
        
195
        for(int i = 0; i<lyrs.length; i++)
196
        {
197
            titles[i] = ((WMSLayer)lyrs[i]).getTitle();
198
        }
199
        return titles;
200
    }
201
    /**
202
     * <p>Gets the image formats available in the Service to retrieve the maps</p>
203
     * @return a vector with all the available formats
204
     */
205
    public Vector getFormats() {        
206
        return ((WMSServiceInformation)handler.getServiceInformation()).formats;         
207
    } 
208
    
209
    /**
210
     * <p>Gets the information by point formats available in the Service</p>
211
     * @return a vector with all the available formats
212
     */
213
    public Vector getInfoFormats() {        
214
        return ((WMSServiceInformation)handler.getServiceInformation()).infoformats;
215
    } 
216
    
217
    public boolean isQueryable()
218
    {
219
            return ((WMSServiceInformation)handler.getServiceInformation()).isQueryable();  
220
    }
221
    public boolean hasLegendGraphic()
222
    {
223
            return ((WMSServiceInformation)handler.getServiceInformation()).hasLegendGraphic();  
224
    }
225
    
226
    public void close() {        
227
        // your code here
228
    } 
229
    
230
    
231
    /**
232
     * Returns the max extent that envolves the requested layers
233
     * */
234
    public Rectangle2D getLayersExtent(String[]layerNames, String srs) {
235
        try {
236
                if (layerNames == null) {
237
                        return null;
238
                }
239
                
240
            BoundaryBox bbox = null;
241
            WMSLayer layer = getLayer(layerNames[0]);
242
            
243
            bbox = layer.getBbox(srs);
244
            if (bbox == null) {
245
                    return null;
246
            }
247
            double xmin = bbox.getXmin();
248
            double xmax = bbox.getXmax();
249
            double ymin = bbox.getYmin();
250
            double ymax = bbox.getYmax();
251
            
252
            for(int i = 1; i < layerNames.length; i++) {
253
                layer = getLayer(layerNames[i]);
254
                bbox = layer.getBbox(srs);
255
                if (bbox == null) return null;
256
                if (bbox.getXmin() < xmin) {
257
                    xmin = bbox.getXmin();
258
                }
259
                if (bbox.getYmin() < ymin) {
260
                    ymin = bbox.getYmin();
261
                }
262
                if (bbox.getXmax() > xmax) {
263
                    xmax = bbox.getXmax();
264
                }
265
                if (bbox.getYmax() > ymax) {
266
                    ymax = bbox.getYmax();
267
                }
268
            }        
269
            
270
            Rectangle2D extent = new Rectangle2D.Double(xmin, ymin, Math.abs(xmax-xmin), Math.abs(ymax-ymin));
271
            return extent;
272
        } catch(Exception e) {
273
            String msg = null;
274
            try {
275
                msg = "Can't get layers extent, layers='"+StringUtils.join(layerNames, ",")+"', srs='"+srs+"'.";
276
            } catch(Exception ex) {
277
                msg = "Can't get layers extent.";
278
            }
279
            logger.warn(msg,e);
280
            return null;
281
        }
282
    }
283
    
284
    
285
    /**
286
     * Gets the Service information included in the Capabilities
287
     * */    
288
    public WMSServiceInformation getServiceInformation()
289
    {
290
        return ((WMSServiceInformation)handler.getServiceInformation());
291
    }
292
    
293
    
294
    /**
295
     * <p>Checks the connection to de remote WMS and requests its capabilities.</p>
296
     * @param override, if true the previous downloaded data will be overridden
297
     */
298
    public boolean connect(boolean override, ICancellable cancel) 
299
    {
300
        String host = getHost();
301
        try {            
302
            if (handler == null)
303
            {
304
                if (host.trim().length() > 0)
305
                {                                        
306
                    //TODO: Implement correctly the negotiate algorithm
307
                    handler = WMSProtocolHandlerFactory.negotiate(host);
308
                    //handler = new WMSProtocolHandler1_1_1();
309
                    handler.setHost(host);
310
                }
311
                else
312
                {
313
                    //must to specify host first!!!!
314
                    return false;
315
                }                
316
            }
317
            getCapabilities(null, override, cancel);
318
            return true;
319
            
320
        } catch (Exception e) {
321
            logger.warn("Can't connect to host '"+host+"'.",e);
322
            return false;
323
        }
324
    }
325
    
326
    //TODO Check this out: Always 1 layer at first level...
327
    public WMSLayer getLayersRoot() {
328
        return handler.rootLayer;
329
    }
330

    
331
        public boolean connect(ICancellable cancel) {
332
                return connect(false, cancel);
333
        }
334
}