Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / FLyrWMS.java @ 2183

History | View | Annotate | Download (11.9 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap.layers;
42

    
43
import java.awt.Graphics2D;
44
import java.awt.Point;
45
import java.awt.geom.AffineTransform;
46
import java.awt.geom.NoninvertibleTransformException;
47
import java.awt.geom.Point2D;
48
import java.awt.geom.Rectangle2D;
49
import java.awt.image.BufferedImage;
50
import java.io.ByteArrayInputStream;
51
import java.io.IOException;
52
import java.net.MalformedURLException;
53
import java.net.URL;
54

    
55
import javax.imageio.ImageIO;
56

    
57
import org.exolab.castor.xml.ValidationException;
58

    
59
import com.iver.cit.gvsig.fmap.DriverException;
60
import com.iver.cit.gvsig.fmap.ViewPort;
61
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
62
import com.iver.cit.gvsig.fmap.drivers.WMSException;
63
import com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint;
64
import com.iver.cit.gvsig.fmap.operations.Cancellable;
65
import com.iver.utiles.StringUtilities;
66
import com.iver.utiles.XMLEntity;
67
import com.iver.wmsclient.FeatureInfoQuery;
68
import com.iver.wmsclient.MapQuery;
69
import com.iver.wmsclient.UnsupportedVersionException;
70
import com.iver.wmsclient.WMSClient;
71
import com.iver.wmsclient.WMSClientFactory;
72

    
73

    
74
/**
75
 * Capa WMS.
76
 *
77
 * @author Fernando Gonz?lez Cort?s
78
 */
79
public class FLyrWMS extends FLyrDefault implements InfoByPoint {
80
        boolean isPrinting = false;
81
        boolean mustTileDraw = false;
82
        boolean mustTilePrint = true;
83
        int maxTileDrawWidth = -1;
84
        int maxTileDrawHeight = -1;
85
        int maxTilePrintWidth = 1500;
86
        int maxTilePrintHeight = 1500;
87

    
88
        private String m_SRS;
89
        private String m_Format;
90
        private String layerQuery;
91
        private String infoLayerQuery;
92
        private URL host;
93
        private WMSClient wmsClient;
94
        private MapQuery lastMapQuery;
95
        private Rectangle2D fullExtent;
96

    
97
        /**
98
         * Slecciona el formato del WMS.
99
         *
100
         * @return formato seleccionado.
101
         *
102
         * @throws WMSException
103
         * @throws IllegalStateException
104
         * @throws ValidationException
105
         * @throws UnsupportedVersionException
106
         * @throws IOException
107
         */
108
        private String selectFormat()
109
                throws WMSException, IllegalStateException, ValidationException, 
110
                        UnsupportedVersionException, IOException {
111
                String[] formats;
112
                formats = getWmsClient().getInfoFormats();
113

    
114
                for (int i = 0; i < formats.length; i++) {
115
                        if (formats[i].equals("GML.1")) {
116
                                return formats[i];
117
                        }
118

    
119
                        if (formats[i].equals("GML.2")) {
120
                                return formats[i];
121
                        }
122

    
123
                        if (formats[i].equals("GML.3")) {
124
                                return formats[i];
125
                        }
126

    
127
                        if (formats[i].equals("application/vnd.ogc.gml")) {
128
                                return formats[i];
129
                        }
130

    
131
                        if (formats[i].indexOf("XML") != -1) {
132
                                return formats[i];
133
                        }
134
                }
135

    
136
                throw new WMSException("No format supported");
137
        }
138

    
139
        /**
140
         * Devuelve el XMLEntity con la informaci?n necesaria para reproducir la
141
         * capa.
142
         *
143
         * @return XMLEntity.
144
         * @throws XMLException
145
         */
146
        public XMLEntity getXMLEntity() throws XMLException {
147
                XMLEntity xml = super.getXMLEntity();
148

    
149
                xml.putProperty("fullExtent", StringUtilities.rect2String(fullExtent));
150
                xml.putProperty("host", host.toExternalForm());
151
                xml.putProperty("infoLayerQuery", infoLayerQuery);
152
                xml.putProperty("layerQuery", layerQuery);
153
                xml.putProperty("format", m_Format);
154
                xml.putProperty("srs", m_SRS);
155

    
156
                return xml;
157
        }
158

    
159
        /**
160
         * A partir del XMLEntity reproduce la capa.
161
         *
162
         * @param xml XMLEntity
163
         *
164
         * @throws XMLException
165
         * @throws DriverException
166
         * @throws DriverIOException
167
         */
168
        public void setXMLEntity03(XMLEntity xml)
169
                throws XMLException {
170
                super.setXMLEntity(xml);
171
                fullExtent = StringUtilities.string2Rect(xml.getStringProperty(
172
                                        "fullExtent"));
173

    
174
                try {
175
                        host = new URL(xml.getStringProperty("host"));
176
                } catch (MalformedURLException e) {
177
                        throw new XMLException(e);
178
                }
179

    
180
                infoLayerQuery = xml.getStringProperty("infoLayerQuery");
181
                layerQuery = xml.getStringProperty("layerQuery");
182
                m_Format = xml.getStringProperty("format");
183
                m_SRS = xml.getStringProperty("srs");
184
        }
185

    
186
        /**
187
         * A partir del XMLEntity reproduce la capa.
188
         *
189
         * @param xml XMLEntity
190
         *
191
         * @throws XMLException
192
         * @throws DriverException
193
         * @throws DriverIOException
194
         */
195
        public void setXMLEntity(XMLEntity xml)
196
                throws XMLException {
197
                super.setXMLEntity(xml);
198
                fullExtent = StringUtilities.string2Rect(xml.getStringProperty(
199
                                        "fullExtent"));
200

    
201
                try {
202
                        host = new URL(xml.getStringProperty("host"));
203
                } catch (MalformedURLException e) {
204
                        throw new XMLException(e);
205
                }
206

    
207
                infoLayerQuery = xml.getStringProperty("infoLayerQuery");
208
                layerQuery = xml.getStringProperty("layerQuery");
209
                m_Format = xml.getStringProperty("format");
210
                m_SRS = xml.getStringProperty("srs");
211
        }
212

    
213
        /**
214
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint#queryByPoint(com.iver.cit.gvsig.fmap.operations.QueriedPoint)
215
         */
216
        public String queryByPoint(Point p) throws DriverException {
217
                FeatureInfoQuery query = new FeatureInfoQuery(lastMapQuery);
218
                query.setFeatureCount(Integer.MAX_VALUE);
219
                query.setX((int) p.getX());
220
                query.setY((int) p.getY());
221
                query.setInfoQuery(infoLayerQuery);
222
                
223
                try {
224
                        query.setInfoFormat(selectFormat());
225

    
226
                        return new String(getWmsClient().doFeatureInfo(query));
227
                } catch (WMSException e) {
228
                        return "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><exception>" +
229
                        e.getMessage() + "</exception>";
230
                } catch (ValidationException e) {
231
                        /*
232
                         * TODO Las traducciones en este m?todo han de ser
233
                         * las mismas que en el m?todo de dibujado
234
                         */
235
                        throw new DriverException("No se reconoce el formato de la respuesta",
236
                                e);
237
                } catch (UnsupportedVersionException e) {
238
                        throw new DriverException("Conflicto de versiones", e);
239
                } catch (IOException e) {
240
                        throw new DriverException("Error en la conexi?n", e);
241
                } catch (com.iver.wmsclient.WMSException e) {
242
                        throw new DriverException(e.getMessage(), e);
243
                } catch (NoSuchFieldException e) {
244
                        throw new RuntimeException(
245
                                "No se rellenaron todos los campos de la petici?n");
246
                }
247
        }
248

    
249
        /**
250
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getFullExtent()
251
         */
252
        public Rectangle2D getFullExtent() throws DriverException {
253
                return fullExtent;
254
        }
255

    
256
        /**
257
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#draw(java.awt.image.BufferedImage,
258
         *                 java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort,
259
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
260
         */
261
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
262
                Cancellable cancel) throws DriverException {
263
                try {
264
                        MapQuery mapQuery = getWmsClient().createQuery();
265
                        mapQuery.setBBOX(viewPort.getAdjustedExtent());
266
                        mapQuery.setFormat(m_Format);
267
                        mapQuery.setHeight(viewPort.getImageHeight());
268

    
269
                        // System.err.println("m_Mapa.getHeight() = " + m_Mapa.getHeight());
270
                        mapQuery.setLayers(layerQuery);
271
                        mapQuery.setSRS(m_SRS);
272
                        mapQuery.setStyles("");
273
                        mapQuery.setWidth(viewPort.getImageWidth());
274
                        mapQuery.setExceptions("application/vnd.ogc.se_xml");
275

    
276
                        byte[] bytes;
277
                        lastMapQuery = mapQuery;
278
                        bytes = getWmsClient().doMapQuery(lastMapQuery);
279

    
280
                        ByteArrayInputStream inbytes = new ByteArrayInputStream(bytes);
281
                        BufferedImage tempImg = ImageIO.read(inbytes);
282
                        // LWS Cambio de estrategia en el posicionado para la impresi?n.
283
                        Point2D p2=new Point2D.Double(viewPort.getAdjustedExtent().getX(), viewPort.getAdjustedExtent().getMaxY()); //viewPort.getOffset();
284
                        viewPort.getAffineTransform().transform(p2, p2);
285
                        g.drawImage(tempImg,(int)p2.getX(),(int)p2.getY(), null);
286
                } catch (ValidationException e) {
287
                        throw new DriverException("No se reconoce el formato de la respuesta",
288
                                e);
289
                } catch (UnsupportedVersionException e) {
290
                        throw new DriverException("Conflicto de versiones", e);
291
                } catch (IOException e) {
292
                        throw new DriverException("Error en la conexi?n", e);
293
                } catch (com.iver.wmsclient.WMSException e) {
294
                        throw new DriverException(e.getMessage(), e);
295
                } catch (NoSuchFieldException e) {
296
                        throw new RuntimeException(
297
                                "No se rellenaron todos los campos de la petici?n");
298
                }
299
        }
300

    
301
        /**
302
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
303
         *                 com.iver.cit.gvsig.fmap.ViewPort,
304
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
305
         */
306
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel)
307
                throws DriverException {
308
                isPrinting = true;
309
                if (!mustTilePrint) {
310
                        draw(null, g, viewPort, cancel);
311
                } else {
312
                // Para no pedir imagenes demasiado grandes, vamos
313
                // a hacer lo mismo que hace EcwFile: chunkear.
314
                // Llamamos a drawView con cuadraditos m?s peque?os
315
                // del BufferedImage ni caso, cuando se imprime viene con null
316
                        Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, g.getClipRect());
317
                        tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
318
                        for (int tileNr=0; tileNr < tiles.getNumTiles(); tileNr++) {
319
                            // Parte que dibuja
320
                            try {
321
                                ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
322
                                draw(null, g, vp, cancel);
323
                                } catch (NoninvertibleTransformException e) {
324
                                        // TODO Auto-generated catch block
325
                                        e.printStackTrace();
326
                                }
327
                }
328
                }
329
            isPrinting = false;
330
        }
331
        
332
        public void _print(Graphics2D g, ViewPort viewPort, Cancellable cancel)
333
                throws DriverException {
334
                draw(null, g, viewPort, cancel);
335
        }
336

    
337
        /**
338
         * Devuelve el WMSClient.
339
         *
340
         * @return WMSClient
341
         *
342
         * @throws IllegalStateException
343
         * @throws ValidationException
344
         * @throws UnsupportedVersionException
345
         * @throws IOException
346
         */
347
        private WMSClient getWmsClient()
348
                throws IllegalStateException, ValidationException, 
349
                        UnsupportedVersionException, IOException {
350
                if (wmsClient == null) {
351
                        wmsClient = WMSClientFactory.getClient(host);
352
                }
353

    
354
                return wmsClient;
355
        }
356

    
357
        /**
358
         * Devuelve el URL.
359
         *
360
         * @return URL.
361
         */
362
        public URL getHost() {
363
                return host;
364
        }
365

    
366
        /**
367
         * Inserta el URL.
368
         *
369
         * @param host URL.
370
         */
371
        public void setHost(URL host) {
372
                this.host = host;
373
        }
374

    
375
        /**
376
         * Devuelve la informaci?n de la consulta.
377
         *
378
         * @return String.
379
         */
380
        public String getInfoLayerQuery() {
381
                return infoLayerQuery;
382
        }
383

    
384
        /**
385
         * Inserta la informaci?n de la consulta.
386
         *
387
         * @param infoLayerQuery String.
388
         */
389
        public void setInfoLayerQuery(String infoLayerQuery) {
390
                this.infoLayerQuery = infoLayerQuery;
391
        }
392

    
393
        /**
394
         * Devuelve la consulta.
395
         *
396
         * @return String.
397
         */
398
        public String getLayerQuery() {
399
                return layerQuery;
400
        }
401

    
402
        /**
403
         * Inserta la consulta.
404
         *
405
         * @param layerQuery consulta.
406
         */
407
        public void setLayerQuery(String layerQuery) {
408
                this.layerQuery = layerQuery;
409
        }
410

    
411
        /**
412
         * Devuelve el formato.
413
         *
414
         * @return Formato.
415
         */
416
        public String getFormat() {
417
                return m_Format;
418
        }
419

    
420
        /**
421
         * Inserta el formato.
422
         *
423
         * @param format Formato.
424
         */
425
        public void setFormat(String format) {
426
                m_Format = format;
427
        }
428

    
429
        /**
430
         * Devuelve el SRS.
431
         *
432
         * @return SRS.
433
         */
434
        public String getSRS() {
435
                return m_SRS;
436
        }
437

    
438
        /**
439
         * Inserta el SRS.
440
         *
441
         * @param m_srs SRS.
442
         */
443
        public void setSRS(String m_srs) {
444
                m_SRS = m_srs;
445
        }
446

    
447
        /**
448
         * Inserta la extensi?n total de la capa.
449
         *
450
         * @param fullExtent Rect?ngulo.
451
         */
452
        public void setFullExtent(Rectangle2D fullExtent) {
453
                this.fullExtent = fullExtent;
454
        }
455
}