Statistics
| Revision:

root / trunk / extensions / extWMS / src / com / iver / cit / gvsig / fmap / layers / FLyrWMS.java @ 3430

History | View | Annotate | Download (13.1 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.NoRouteToHostException;
54
import java.net.URL;
55

    
56
import javax.imageio.ImageIO;
57

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

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

    
74

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

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

    
98
        /**
99
         * Inicializa una capa WMS con el driver que se le pasa como par?metro y
100
         * guard?ndose el nombre del fichero para realizar los accesos, la capa
101
         * tendr? asociada la proyecci?n que se pasa como parametro tambi?n
102
         *
103
         * @param layerName Nombre de la capa.
104
         * @param rect extent
105
         * @param host URL.
106
         * @param format Formato
107
         * @param query Consulta.
108
         * @param infoQuery inforamci?n de la consulta.
109
         * @param srs SRS.
110
         */
111
        public void init(String layerName, Rectangle2D rect,
112
                                URL host, String format, String query, String infoQuery, String srs) {
113
                FLyrWMS layer = this;
114
                layer.setHost(host);
115
                layer.setFullExtent(rect);
116
                layer.setFormat(format);
117
                layer.setLayerQuery(query);
118
                layer.setInfoLayerQuery(infoQuery);
119
                layer.setSRS(srs);
120
                layer.setName(layerName);
121
        }
122
        
123
        /**
124
         * Slecciona el formato del WMS.
125
         *
126
         * @return formato seleccionado.
127
         *
128
         * @throws WMSException
129
         * @throws IllegalStateException
130
         * @throws ValidationException
131
         * @throws UnsupportedVersionException
132
         * @throws IOException
133
         */
134
        private String selectFormat()
135
                throws WMSException, IllegalStateException, ValidationException, 
136
                        UnsupportedVersionException, IOException {
137
                String[] formats;
138
                formats = getWmsClient().getInfoFormats();
139

    
140
                for (int i = 0; i < formats.length; i++) {
141
                        if (formats[i].equals("GML.1")) {
142
                                return formats[i];
143
                        }
144

    
145
                        if (formats[i].equals("GML.2")) {
146
                                return formats[i];
147
                        }
148

    
149
                        if (formats[i].equals("GML.3")) {
150
                                return formats[i];
151
                        }
152

    
153
                        if (formats[i].equals("application/vnd.ogc.gml")) {
154
                                return formats[i];
155
                        }
156

    
157
                        if (formats[i].indexOf("XML") != -1) {
158
                                return formats[i];
159
                        }
160
                }
161

    
162
                throw new WMSException("No format supported");
163
        }
164

    
165
        /**
166
         * Devuelve el XMLEntity con la informaci?n necesaria para reproducir la
167
         * capa.
168
         *
169
         * @return XMLEntity.
170
         * @throws XMLException
171
         */
172
        public XMLEntity getXMLEntity() throws XMLException {
173
                XMLEntity xml = super.getXMLEntity();
174

    
175
                xml.putProperty("fullExtent", StringUtilities.rect2String(fullExtent));
176
                xml.putProperty("host", host.toExternalForm());
177
                xml.putProperty("infoLayerQuery", infoLayerQuery);
178
                xml.putProperty("layerQuery", layerQuery);
179
                xml.putProperty("format", m_Format);
180
                xml.putProperty("srs", m_SRS);
181

    
182
                return xml;
183
        }
184

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

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

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

    
212
        /**
213
         * A partir del XMLEntity reproduce la capa.
214
         *
215
         * @param xml XMLEntity
216
         *
217
         * @throws XMLException
218
         * @throws DriverException
219
         * @throws DriverIOException
220
         */
221
        public void setXMLEntity(XMLEntity xml)
222
                throws XMLException {
223
                super.setXMLEntity(xml);
224
                fullExtent = StringUtilities.string2Rect(xml.getStringProperty(
225
                                        "fullExtent"));
226

    
227
                try {
228
                        host = new URL(xml.getStringProperty("host"));
229
                } catch (MalformedURLException e) {
230
                        throw new XMLException(e);
231
                }
232

    
233
                infoLayerQuery = xml.getStringProperty("infoLayerQuery");
234
                layerQuery = xml.getStringProperty("layerQuery");
235
                m_Format = xml.getStringProperty("format");
236
                m_SRS = xml.getStringProperty("srs");
237
        }
238

    
239
        /**
240
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint#queryByPoint(com.iver.cit.gvsig.fmap.operations.QueriedPoint)
241
         */
242
        public String queryByPoint(Point p) throws DriverException {
243
                FeatureInfoQuery query = new FeatureInfoQuery(lastMapQuery);
244
                query.setFeatureCount(Integer.MAX_VALUE);
245
                query.setX((int) p.getX());
246
                query.setY((int) p.getY());
247
                query.setInfoQuery(infoLayerQuery);
248
                
249
                try {
250
                        query.setInfoFormat(selectFormat());
251

    
252
                        return new String(getWmsClient().doFeatureInfo(query));
253
                } catch (WMSException e) {
254
                        return "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><exception>" +
255
                        e.getMessage() + "</exception>";
256
                } catch (ValidationException e) {
257
                        /*
258
                         * TODO Las traducciones en este m?todo han de ser
259
                         * las mismas que en el m?todo de dibujado
260
                         */
261
                        throw new DriverException("No se reconoce el formato de la respuesta",
262
                                e);
263
                } catch (UnsupportedVersionException e) {
264
                        throw new DriverException("Conflicto de versiones", e);
265
                } catch (IOException e) {
266
                        throw new DriverException("Error en la conexi?n", e);
267
                } catch (com.iver.wmsclient.WMSException e) {
268
                        throw new DriverException(e.getMessage(), e);
269
                } catch (NoSuchFieldException e) {
270
                        throw new RuntimeException(
271
                                "No se rellenaron todos los campos de la petici?n");
272
                }
273
        }
274

    
275
        /**
276
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getFullExtent()
277
         */
278
        public Rectangle2D getFullExtent() throws DriverException {
279
                return fullExtent;
280
        }
281

    
282
        /**
283
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#draw(java.awt.image.BufferedImage,
284
         *                 java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort,
285
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
286
         */
287
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
288
                        Cancellable cancel,double scale) throws DriverException {
289
                if (isWithinScale(scale)){        
290
                        try {
291
                                MapQuery mapQuery = getWmsClient().createQuery();
292
                                mapQuery.setBBOX(viewPort.getAdjustedExtent());
293
                                mapQuery.setFormat(m_Format);
294
                                mapQuery.setHeight(viewPort.getImageHeight());
295
                                
296
                                // System.err.println("m_Mapa.getHeight() = " + m_Mapa.getHeight());
297
                                mapQuery.setLayers(layerQuery);
298
                                mapQuery.setSRS(m_SRS);
299
                                mapQuery.setStyles("");
300
                                mapQuery.setWidth(viewPort.getImageWidth());
301
                                mapQuery.setExceptions("application/vnd.ogc.se_xml");
302
                                
303
                                byte[] bytes;
304
                                lastMapQuery = mapQuery;
305
                                bytes = getWmsClient().doMapQuery(lastMapQuery);
306
                                
307
                                ByteArrayInputStream inbytes = new ByteArrayInputStream(bytes);
308
                                BufferedImage tempImg = ImageIO.read(inbytes);
309
                                // LWS Cambio de estrategia en el posicionado para la impresi?n.
310
                                Point2D p2=new Point2D.Double(viewPort.getAdjustedExtent().getX(), viewPort.getAdjustedExtent().getMaxY()); //viewPort.getOffset();
311
                                viewPort.getAffineTransform().transform(p2, p2);
312
                                g.drawImage(tempImg,(int)p2.getX(),(int)p2.getY(), null);
313
                        } catch (ValidationException e) {
314
                                throw new DriverException("No se reconoce el formato de la respuesta",
315
                                                e);
316
                        } catch (UnsupportedVersionException e) {
317
                                throw new DriverException("Conflicto de versiones", e);
318
                        } catch (IOException e) {
319
                                this.setActive(false);
320
                                this.setVisible(false);
321
                                throw new DriverException("Error en la conexi?n", e);
322
                        } catch (com.iver.wmsclient.WMSException e) {
323
                                throw new DriverException(e.getMessage(), e);
324
                        } catch (NoSuchFieldException e) {
325
                                throw new RuntimeException(
326
                                "No se rellenaron todos los campos de la petici?n");
327
                        } catch (RuntimeException e) {
328
                                this.setActive(false);
329
                                this.setVisible(false);
330
                                throw new DriverException("Error en la conexi?n", e);
331
                        }
332
                }
333
        }
334

    
335
        /**
336
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
337
         *                 com.iver.cit.gvsig.fmap.ViewPort,
338
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
339
         */
340
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,double scale)
341
                throws DriverException {
342
                if (isVisible() && isWithinScale(scale)){        
343
                isPrinting = true;
344
                if (!mustTilePrint) {
345
                        draw(null, g, viewPort, cancel,scale);
346
                } else {
347
                // Para no pedir imagenes demasiado grandes, vamos
348
                // a hacer lo mismo que hace EcwFile: chunkear.
349
                // Llamamos a drawView con cuadraditos m?s peque?os
350
                // del BufferedImage ni caso, cuando se imprime viene con null
351
                        Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, g.getClipBounds());
352
                        tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
353
                        for (int tileNr=0; tileNr < tiles.getNumTiles(); tileNr++) {
354
                            // Parte que dibuja
355
                            try {
356
                                ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
357
                                draw(null, g, vp, cancel,scale);
358
                                } catch (NoninvertibleTransformException e) {
359
                                        // TODO Auto-generated catch block
360
                                        e.printStackTrace();
361
                                }
362
                }
363
                }
364
            isPrinting = false;
365
                }
366
        }
367
        
368
        public void _print(Graphics2D g, ViewPort viewPort, Cancellable cancel,double scale)
369
                throws DriverException {
370
                draw(null, g, viewPort, cancel,scale);
371
        }
372

    
373
        /**
374
         * Devuelve el WMSClient.
375
         *
376
         * @return WMSClient
377
         *
378
         * @throws IllegalStateException
379
         * @throws ValidationException
380
         * @throws UnsupportedVersionException
381
         * @throws IOException
382
         */
383
        private WMSClient getWmsClient()
384
                throws IllegalStateException, ValidationException, 
385
                        UnsupportedVersionException, IOException {
386
                if (wmsClient == null) {
387
                        wmsClient = WMSClientFactory.getClient(host);
388
                }
389

    
390
                return wmsClient;
391
        }
392

    
393
        /**
394
         * Devuelve el URL.
395
         *
396
         * @return URL.
397
         */
398
        public URL getHost() {
399
                return host;
400
        }
401

    
402
        /**
403
         * Inserta el URL.
404
         *
405
         * @param host URL.
406
         */
407
        public void setHost(URL host) {
408
                this.host = host;
409
        }
410

    
411
        /**
412
         * Devuelve la informaci?n de la consulta.
413
         *
414
         * @return String.
415
         */
416
        public String getInfoLayerQuery() {
417
                return infoLayerQuery;
418
        }
419

    
420
        /**
421
         * Inserta la informaci?n de la consulta.
422
         *
423
         * @param infoLayerQuery String.
424
         */
425
        public void setInfoLayerQuery(String infoLayerQuery) {
426
                this.infoLayerQuery = infoLayerQuery;
427
        }
428

    
429
        /**
430
         * Devuelve la consulta.
431
         *
432
         * @return String.
433
         */
434
        public String getLayerQuery() {
435
                return layerQuery;
436
        }
437

    
438
        /**
439
         * Inserta la consulta.
440
         *
441
         * @param layerQuery consulta.
442
         */
443
        public void setLayerQuery(String layerQuery) {
444
                this.layerQuery = layerQuery;
445
        }
446

    
447
        /**
448
         * Devuelve el formato.
449
         *
450
         * @return Formato.
451
         */
452
        public String getFormat() {
453
                return m_Format;
454
        }
455

    
456
        /**
457
         * Inserta el formato.
458
         *
459
         * @param format Formato.
460
         */
461
        public void setFormat(String format) {
462
                m_Format = format;
463
        }
464

    
465
        /**
466
         * Devuelve el SRS.
467
         *
468
         * @return SRS.
469
         */
470
        public String getSRS() {
471
                return m_SRS;
472
        }
473

    
474
        /**
475
         * Inserta el SRS.
476
         *
477
         * @param m_srs SRS.
478
         */
479
        public void setSRS(String m_srs) {
480
                m_SRS = m_srs;
481
        }
482

    
483
        /**
484
         * Inserta la extensi?n total de la capa.
485
         *
486
         * @param fullExtent Rect?ngulo.
487
         */
488
        public void setFullExtent(Rectangle2D fullExtent) {
489
                this.fullExtent = fullExtent;
490
        }
491
}