Statistics
| Revision:

root / trunk / extensions / extWCS / src / com / iver / cit / gvsig / fmap / layers / FMapWCSAdaptor.java @ 2003

History | View | Annotate | Download (12.2 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2005 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.Dimension;
44
import java.awt.Graphics2D;
45
import java.awt.Image;
46
import java.awt.geom.Point2D;
47
import java.awt.geom.Rectangle2D;
48
import java.awt.image.BufferedImage;
49
import java.io.File;
50

    
51
import javax.swing.JOptionPane;
52

    
53
import org.cresques.geo.ViewPortData;
54
import org.cresques.io.GdalFile;
55
import org.cresques.io.GeoRasterFile;
56
import org.cresques.io.rasterOld.ComputeMinMaxFilter;
57
import org.cresques.io.rasterOld.GreyscaleRasterToImageFilter;
58
import org.cresques.io.rasterOld.LinearEnhancementFilter;
59
import org.cresques.io.rasterOld.RasterBuf;
60
import org.cresques.io.rasterOld.RasterStats;
61
import org.cresques.io.rasterOld.RasterToImageFilter;
62
import org.cresques.px.Extent;
63
import org.cresques.px.PxRaster;
64

    
65
import com.hardcode.driverManager.Driver;
66
import com.iver.cit.gvsig.fmap.DriverException;
67
import com.iver.cit.gvsig.fmap.ViewPort;
68
import com.iver.cit.gvsig.fmap.drivers.WCSDriver;
69
import com.iver.cit.gvsig.fmap.drivers.wcs.FMapWCSDriver;
70
import com.iver.cit.gvsig.fmap.operations.Cancellable;
71

    
72
import es.gva.cit.jgdal.Gdal;
73
import es.gva.cit.jgdal.GdalBuffer;
74
import es.gva.cit.jgdal.GdalException;
75
import es.gva.cit.jgdal.GdalRasterBand;
76
import es.gva.cit.jgdal.GeoTransform;
77
import es.uji.lsi.wcs.client.ServerErrorResponseException;
78

    
79
/**
80
 * @author jaume - jaume.dominguez@iver.es
81
 *
82
 */
83
public class FMapWCSAdaptor {
84
        private boolean driverInitialized = false;
85
        private WCSDriver driver;
86
        private Rectangle2D fullExtent, bbox;
87
        
88
        private static final double METROSXGRADO = 111120D;
89
        private String coverageName;
90
        private String SRS;
91
        private String format;
92
        private String time;
93
        private String parameter;
94
        
95
        private String coverageQuery;
96
        private String lastCoverageQuery = "";
97
        private File fCoverage = null;
98
        
99
        /**
100
         * Establece el driver sobre el que act?a el adaptador 
101
         */
102
        public void setDriver(Driver d) {
103
                driver = (WCSDriver) d;
104
        }
105
        
106
        /**
107
         * Obtiene una referencia al objeto que implementa la interfaz vectorial con
108
         *  el fin de que las Strategy puedan optimizar en funci?n del driver.
109
         */
110
        public Driver getDriver(){
111
                return driver;
112
        }
113
        
114
        /**
115
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#draw(java.awt.image.BufferedImage, java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort)
116
         */
117
        public void draw(BufferedImage image, Graphics2D g,
118
                        ViewPort viewPort, Cancellable cancel) throws DriverException {
119
                if (viewPort.getExtent().getMinX() > fullExtent.getMaxX())
120
                        return;
121
                if (viewPort.getExtent().getMinY() > fullExtent.getMaxY())
122
                        return;
123
                if (viewPort.getExtent().getMaxX() < fullExtent.getMinX())
124
                        return;
125
                if (viewPort.getExtent().getMaxY() < fullExtent.getMinY())
126
                        return;
127
                setBBox(viewPort.getAdjustedExtent());
128
                
129
                double x = bbox.getMinX();
130
                double y = bbox.getMinY();
131
                double w = bbox.getWidth();
132
                double h = bbox.getHeight();
133
                
134
                double scalex = viewPort.getAffineTransform().getScaleX()        /* g.getTransform().getScaleX()*/ ,
135
                scaley = viewPort.getAffineTransform().getScaleY()                /* g.getTransform().getScaleY() */;
136
                int wImg = (int) Math.abs(w*scalex)+1, hImg = (int) Math.abs(h*scaley)+1;
137
                if (wImg <= 0 || hImg <= 0) return;
138
                
139
                setCoverageQuery(bbox, new Dimension(wImg, hImg));
140
                
141
                try {
142
                        if (lastCoverageQuery.compareTo(coverageQuery) != 0) {
143
                                setWCSClientCoverageQuery(coverageQuery);
144
                                fCoverage = driver.getCoverage();
145
                        }
146
                        
147
                        if (fCoverage != null) {
148
                                //drawJaume(g, viewPort, fCoverage);
149
                                drawLWS(g, viewPort, fCoverage);
150
                        }
151
                } catch (ServerErrorResponseException e) {
152
                        JOptionPane.showMessageDialog(null, e.getMessage(), "Error",
153
                                        JOptionPane.ERROR_MESSAGE);
154
                        //throw new DriverException(e);
155
                }
156
        }
157
                
158
        /**
159
         * Pinta usando PxRaster
160
         */        
161
        private void drawLWS(Graphics2D g, ViewPort viewPort, File fCoverage) {
162
                GeoRasterFile rasterFile = new GdalFile(viewPort.getProjection(), fCoverage.getAbsolutePath());
163
                Extent e = new Extent(bbox);
164
                PxRaster raster = new PxRaster(rasterFile, null, rasterFile.getExtent());
165
                // ? PxRaster raster = new PxRaster(rasterFile, null, e);
166
                raster.setTransparency(false);
167
                ViewPortData vpData = new ViewPortData(viewPort.getProjection(), e, viewPort.getImageSize() );
168
                vpData.setMat(viewPort.getAffineTransform());
169
                
170
                raster.draw(g, vpData);
171
        }
172
        
173
        public void setBBox(Rectangle2D rect) {
174
                double x1 = rect.getMinX();
175
                double y1 = rect.getMinY();
176
                double x2 = rect.getMaxX();
177
                double y2 = rect.getMaxY();
178
                if (x1 < fullExtent.getMinX())
179
                        x1 = fullExtent.getMinX();
180
                if (y1 < fullExtent.getMinY())
181
                        y1 = fullExtent.getMinY();
182
                if (x2 > fullExtent.getMaxX())
183
                        x2 = fullExtent.getMaxX();
184
                if (y2 > fullExtent.getMaxY())
185
                        y2 = fullExtent.getMaxY();
186
                
187
                if (bbox == null)
188
                        bbox = new Rectangle2D.Double();
189
                
190
                bbox.setRect(x1, y1, x2 - x1, y2 - y1);
191
        }
192
        /**
193
         * Para establecer los valores iniciales que se incluiran en la consulta.
194
         * 
195
         * @param layersRectangle
196
         * @param srs
197
         * @param format
198
         * @param parametro
199
         * @param times
200
         */
201
        public void setCoverageQuery(Rectangle2D bBox, Dimension sz) {
202
                String coverage = "COVERAGE=" + coverageName;
203
                String crs = "&CRS=" + SRS;
204
                String boundingBox = "&BBOX=" + bBox.getMinX() + "," + bBox.getMinY()
205
                + "," + bBox.getMaxX() + "," + bBox.getMaxY();
206
                String time = this.time != null ? "&" + this.time : "";
207
                String param = parameter != null ? "&" + parameter : "";
208
                double res = bBox.getWidth() / sz.getWidth();
209
                // Calculo cutre para ver si son grados (o metros). Si da menos de 180
210
                // es que son grados y lo paso a metros. (LWS)
211
                if (bBox.getMaxX() < 181D)
212
                        res *= METROSXGRADO;
213
                System.out.println(" resolucion = " + res);
214
                String resX = "&RESX=" + res;
215
                String resY = "&RESY=" + res;
216
                
217
                //                String width = "&WIDTH="+ (int) sz.getWidth();
218
                //                String height = "&HEIGHT="+ (int) sz.getHeight();
219
                
220
                String format = "&FORMAT=" + this.format;
221
                coverageQuery = coverage + crs + boundingBox + time + param + resX        + resY + format;
222
        }
223
        
224
        /**
225
         * Recoge los par?metros de la capa y los pasa al cliente WCS. Despu?s de
226
         * esto, ya se puede lanzar una Getcoverage
227
         *  
228
         */
229
        private void setWCSClientCoverageQuery(String query) {
230
                lastCoverageQuery = query;
231
                ((FMapWCSDriver) driver).setGetCoverageParams(query);
232
        }
233
        
234
        public String getCoverageName() {
235
                return coverageName;
236
        }
237
        public void setCoverageName(String coverageName) {
238
                this.coverageName = coverageName;
239
        }
240
        public String getCoverageQuery() {
241
                return coverageQuery;
242
        }
243
        public void setCoverageQuery(String coverageQuery) {
244
                this.coverageQuery = coverageQuery;
245
        }
246
        public String getFormat() {
247
                return format;
248
        }
249
        public void setFormat(String format) {
250
                this.format = format;
251
        }
252
        public Rectangle2D getFullExtent() {
253
                return fullExtent;
254
        }
255
        public void setFullExtent(Rectangle2D fullExtent) {
256
                this.fullExtent = fullExtent;
257
        }
258
        public String getParameter() {
259
                return parameter;
260
        }
261
        public void setParameter(String parameter) {
262
                this.parameter = parameter;
263
        }
264
        public String getSRS() {
265
                return SRS;
266
        }
267
        public void setSRS(String srs) {
268
                SRS = srs;
269
        }
270
        public String getTime() {
271
                return time;
272
        }
273
        public void setTime(String time) {
274
                this.time = time;
275
        }
276
        
277
        public String getHost() {
278
                return ((FMapWCSDriver) driver).getHost();
279
        }
280
        
281
        public void setHost(String host) {
282
                ((FMapWCSDriver) driver).setHost(host);
283
        }
284
        
285
        private void drawJaume(Graphics2D g, ViewPort viewPort, File fCoverage) {
286
                Image coverage = renderizeRaster(getRaster(fCoverage));
287
                
288
                Point2D p1 = new Point2D.Double(bbox.getMinX(), bbox.getMaxY());
289
                //Point2D p2 = new Point2D.Double(bbox.getMaxX(), bbox.getMinY());
290
                
291
                viewPort.getAffineTransform().transform(p1, p1);
292
                //viewPort.getAffineTransform().transform(p2, p2);
293
                
294
                g.drawImage(coverage, (int) p1.getX(), (int) p1.getY(), null);
295
                /*g.setColor(Color.RED);
296
                 g.drawRect((int) p1.getX(), (int) p1.getY(),
297
                 ((int) (p2.getX() - p1.getX())), ((int) (p2.getY() - p1
298
                 .getY())));*/
299
        }
300
        
301
        /**
302
         * Computa el r?ster del fichero geogr?fico
303
         * 
304
         * @param coverage
305
         * @return RasterBuf
306
         */
307
        private RasterBuf getRaster(File coverage) {
308
                RasterBuf raster = null;
309
                
310
                Gdal migdal = new Gdal();
311
                GeoTransform gt = null;
312
                int ancho = 0, alto = 0;
313
                GdalRasterBand mirasterband = null;
314
                int rastercount = 0;
315
                
316
                try {
317
                        migdal.open(coverage.getAbsolutePath(), Gdal.GA_ReadOnly);
318
                } catch (Exception ge) {
319
                        ge.printStackTrace();
320
                }
321
                
322
                try {
323
                        gt = migdal.getGeoTransform();
324
                        //        System.out.println("Origin =
325
                        // ("+gt.adfgeotransform[0]+","+gt.adfgeotransform[3]+")");
326
                        //        System.out.println("Pixel Size =
327
                        // ("+gt.adfgeotransform[1]+","+gt.adfgeotransform[5]+")");
328
                } catch (GdalException e) {
329
                        System.out
330
                        .println("I can't obtain the array geoTransform for this image");
331
                }
332
                
333
                try {
334
                        rastercount = migdal.getRasterCount();
335
                        ancho = migdal.getRasterXSize();
336
                        alto = migdal.getRasterYSize();
337
                        int ngcp = migdal.getGCPCount();
338
                        //System.out.println("NGCP="+ngcp);
339
                } catch (GdalException ge) {
340
                        ge.printStackTrace();
341
                        //...
342
                }
343
                
344
                try {
345
                        int dataType = migdal.getRasterBand(1).getRasterDataType();
346
                        GdalBuffer buf = null;
347
                        
348
                        /*
349
                         * Evita el problema de que haya m?s de 3 bandas en el fichero esto
350
                         * deberia hacerse asignando a las 3 bandas del raster una banda
351
                         * distinta del fichero (no necesariamente 1->0, 2->1 y 3->2
352
                         */
353
                        
354
                        if (rastercount > 3)
355
                                rastercount = 3;
356
                        if (dataType == Gdal.GDT_Byte) {
357
                                raster = new RasterBuf(RasterBuf.TYPE_INT, ancho, alto,
358
                                                rastercount, null);
359
                                for (int iBand = 0; iBand < rastercount; iBand++) {
360
                                        mirasterband = migdal.getRasterBand(iBand + 1);
361
                                        buf = mirasterband.readRaster(0, 0, ancho, alto, ancho,
362
                                                        alto, dataType);
363
                                        for (int y = 0; y < alto; y++)
364
                                                for (int x = 0; x < ancho; x++)
365
                                                        raster.setPixelInt(x, y, iBand, buf.buffByte[y
366
                                                                                                                                                 * ancho + x] & 0xff);
367
                                }
368
                                migdal.close();
369
                        } else if (dataType == Gdal.GDT_CInt16
370
                                        || dataType == Gdal.GDT_UInt16
371
                                        || dataType == Gdal.GDT_Int16) {
372
                                raster = new RasterBuf(RasterBuf.TYPE_INT, ancho, alto,
373
                                                rastercount, null);
374
                                for (int iBand = 0; iBand < rastercount; iBand++) {
375
                                        // System.out.println("Banda:"+iBand);
376
                                        mirasterband = migdal.getRasterBand(iBand + 1);
377
                                        buf = mirasterband.readRaster(0, 0, ancho, alto, ancho,
378
                                                        alto, dataType);
379
                                        for (int y = 0; y < alto; y++)
380
                                                for (int x = 0; x < ancho; x++)
381
                                                        raster.setPixelInt(x, y, iBand, buf.buffShort[y
382
                                                                                                                                                  * ancho + x] & 0xffff);
383
                                }
384
                                migdal.close();
385
                        }
386
                } catch (GdalException e1) {
387
                        e1.printStackTrace();
388
                }
389
                return raster;
390
        }
391
        
392
        /**
393
         * Construye un objeto Image a partir de un RasterBuf
394
         * 
395
         * @param raster
396
         * @return Image
397
         */
398
        public Image renderizeRaster(RasterBuf raster) {
399
                RasterStats stats = new RasterStats(raster.getBandNr());
400
                int alpha = 255; // transparencia
401
                boolean debug = false;
402
                ComputeMinMaxFilter filter = new ComputeMinMaxFilter(raster, stats);
403
                
404
                LinearEnhancementFilter lEFilter = new LinearEnhancementFilter(raster,
405
                                stats);
406
                Image image = null;
407
                if (raster.getBandNr() == 1)
408
                        image = new GreyscaleRasterToImageFilter(raster, alpha).getImage();
409
                else
410
                        image = new RasterToImageFilter(raster, alpha).getImage();
411
                
412
                if (debug)
413
                        stats.pinta();
414
                return image;
415
        }        
416
}