Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster.2.4 / org.gvsig.raster.wms2 / org.gvsig.raster.wms2.provider / src / main / java / org / gvsig / raster / wms / provider / WMSRasterProvider.java @ 6665

History | View | Annotate | Download (15.2 KB)

1
package org.gvsig.raster.wms.provider;
2

    
3
import java.awt.Image;
4
import java.awt.geom.Rectangle2D;
5
import java.awt.image.BufferedImage;
6
import java.io.File;
7
import java.io.IOException;
8
import java.net.URL;
9
import java.util.HashMap;
10
import java.util.Iterator;
11
import java.util.List;
12
import java.util.Map;
13
import java.util.Vector;
14

    
15
import javax.imageio.ImageIO;
16

    
17
import org.cresques.cts.IProjection;
18
import org.slf4j.Logger;
19
import org.slf4j.LoggerFactory;
20

    
21
import org.gvsig.compat.CompatLocator;
22
import org.gvsig.compat.net.Downloader;
23
import org.gvsig.fmap.dal.DALLocator;
24
import org.gvsig.fmap.dal.DataManager;
25
import org.gvsig.fmap.dal.DataServerExplorer;
26
import org.gvsig.fmap.dal.DataServerExplorerParameters;
27
import org.gvsig.fmap.dal.DataStore;
28
import org.gvsig.fmap.dal.DataStoreParameters;
29
import org.gvsig.fmap.dal.FileHelper;
30
import org.gvsig.fmap.dal.exception.InitializeException;
31
import org.gvsig.fmap.dal.exception.OpenException;
32
import org.gvsig.fmap.dal.exception.ReadException;
33
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
34
import org.gvsig.fmap.dal.raster.api.BandQuery;
35
import org.gvsig.fmap.dal.raster.api.RasterQuery;
36
import org.gvsig.fmap.dal.raster.spi.AbstractRasterStoreProvider;
37
import org.gvsig.fmap.dal.raster.spi.BandDescriptorServices;
38
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
39
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
40
import org.gvsig.fmap.geom.Geometry.DIMENSIONS;
41
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
42
import org.gvsig.fmap.geom.GeometryLocator;
43
import org.gvsig.fmap.geom.GeometryManager;
44
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
45
import org.gvsig.fmap.geom.primitive.Envelope;
46
import org.gvsig.metadata.MetadataLocator;
47
import org.gvsig.metadata.MetadataManager;
48
import org.gvsig.metadata.exceptions.MetadataException;
49
import org.gvsig.raster.lib.buffer.api.BandInfo;
50
import org.gvsig.raster.lib.buffer.api.Buffer;
51
import org.gvsig.raster.lib.buffer.api.BufferLocator;
52
import org.gvsig.raster.lib.buffer.api.BufferManager;
53
import org.gvsig.raster.lib.buffer.api.NoData;
54
import org.gvsig.raster.lib.buffer.api.TileStruct;
55
import org.gvsig.raster.lib.buffer.api.exceptions.BufferException;
56
import org.gvsig.raster.lib.buffer.spi.DefaultTileStruct;
57
import org.gvsig.remoteclient.exceptions.ServerErrorException;
58
import org.gvsig.remoteclient.exceptions.WMSException;
59
import org.gvsig.remoteclient.wms.WMSClient;
60
import org.gvsig.remoteclient.wms.WMSStatus;
61
import org.gvsig.remoteclient.wms.WMSStyle;
62
import org.gvsig.tools.dataTypes.DataTypes;
63
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
64
import org.gvsig.tools.locator.LocatorException;
65

    
66
/**
67
 * @author fdiaz
68
 *
69
 */
70
public class WMSRasterProvider extends AbstractRasterStoreProvider {
71

    
72
    private static final Logger logger = LoggerFactory.getLogger(WMSRasterProvider.class);
73

    
74
    public static String NAME = "WMSRaster";
75
    public static String DESCRIPTION = "WMS Raster Provider";
76
    public static final String METADATA_DEFINITION_NAME = "WMSRaster";
77

    
78
    public static final int DEFAULT_BUFFER_SIZE = 1024;
79
    public static final int MAX_ZOOM_LEVEL = 22;
80

    
81
    // WMS Parameters
82
    private WMSClient wmsClient;
83
    private WMSStatus wmsStatus;
84

    
85
    private Envelope envelope = null;
86

    
87
    private IProjection projection = null;
88

    
89
    protected WMSRasterProvider(DataStoreParameters params, DataStoreProviderServices storeServices) throws InitializeException {
90
        super(params, storeServices, FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME));
91
        initParams();
92
    }
93

    
94
    private void initParams() throws InitializeException {
95
        WMSRasterProviderParameters parameters = (WMSRasterProviderParameters) getParameters();
96

    
97
        URL service = parameters.getService();
98
        try {
99
            wmsClient = new WMSClient(service.toString());
100
        } catch (IOException e) {
101
            throw new InitializeException("Can't create WMSClient with host '"+service+"'", e);
102
        }
103
        wmsStatus = new WMSStatus();
104

    
105
        // Setting the envelope for the layer
106
        wmsClient.getCapabilities(wmsStatus, false, null);
107

    
108
        @SuppressWarnings("unchecked")
109
        List<String> layerNames =
110
            (List<String>) parameters.getDynValue(WMSRasterProviderParameters.WMS_LAYERS_PARAMETER_NAME);
111
        for (Iterator<String> iterator = layerNames.iterator(); iterator.hasNext();) {
112
            String layerName = (String) iterator.next();
113
            wmsStatus.addLayerName(layerName);
114
        }
115

    
116
        Rectangle2D extent = wmsClient.getLayersExtent(layerNames.toArray(new String[0]), getProjection().getAbrev());
117
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
118
        try {
119
            this.envelope =
120
                geomManager.createEnvelope(extent.getMinX(), extent.getMinY(), extent.getMaxX(), extent.getMaxY(),
121
                    SUBTYPES.GEOM2D);
122
        } catch (CreateEnvelopeException e) {
123
            throw new InitializeException("Can't create envenlope.", e);
124

    
125
        }
126

    
127
        @SuppressWarnings("unchecked")
128
        List<WMSStyle> wmsStyles =
129
            (List<WMSStyle>) parameters.getDynValue(WMSRasterProviderParameters.WMS_STYLES_PARAMETER_NAME);
130
        wmsStatus.setStyles(new Vector<WMSStyle>(wmsStyles));
131
        wmsStatus.setFormat((String) parameters.getDynValue(WMSRasterProviderParameters.WMS_FORMAT_PARAMETER_NAME));
132
        wmsStatus.setInfoFormat((String) parameters.getDynValue(WMSRasterProviderParameters.WMS_INFO_FORMAT_PARAMETER_NAME));
133
        Boolean xyAxisOrder = (Boolean) parameters.getDynValue(WMSRasterProviderParameters.WMS_XYAXISORDER_PARAMETER_NAME);
134
        if(xyAxisOrder!=null && xyAxisOrder.booleanValue()){
135
            wmsStatus.setXyAxisOrder(xyAxisOrder);
136
        }
137
        projection  = (IProjection) (parameters.getDynValue(WMSRasterProviderParameters.WMS_CRS_PARAMETER_NAME));
138
        wmsStatus.setSrs(projection.getAbrev());
139
        Boolean transparency = (Boolean) parameters.getDynValue(WMSRasterProviderParameters.WMS_TRANSPARENCY_PARAMETER_NAME);
140
        if(transparency!=null && transparency.booleanValue()){
141
            wmsStatus.setTransparency(transparency);
142
        }
143

    
144
    }
145

    
146
    protected static void registerMetadataDefinition() throws MetadataException {
147
        MetadataManager manager = MetadataLocator.getMetadataManager();
148
        if (manager.getDefinition(METADATA_DEFINITION_NAME) == null) {
149
            manager.addDefinition(METADATA_DEFINITION_NAME,
150
                WMSRasterProviderParameters.class.getResourceAsStream("WMSRasterMetadata.xml"),
151
                WMSRasterProviderParameters.class.getClassLoader());
152
        }
153
    }
154

    
155
    @Override
156
    public Buffer createBuffer(RasterQuery rasterQuery) throws BufferException {
157

    
158
        BufferManager bufferManager = BufferLocator.getBufferManager();
159
        int[] bandDataTypes;
160
        NoData[] bandNoData;
161
        //
162
        if (!rasterQuery.getBands().isEmpty()) {
163
            List<BandQuery> bands;
164
            bands = rasterQuery.getBands();
165
            bandDataTypes = new int[bands.size()];
166
            bandNoData = new NoData[bands.size()];
167

    
168
            for (BandQuery bandQuery : bands) {
169
                int band = bandQuery.getBand();
170
                bandDataTypes[band] = this.getBandDescriptor(band).getDataType();
171
                bandNoData[band] = null;
172
            }
173
        } else {
174
            int bands = getBands();
175
            bandDataTypes = new int[bands];
176
            bandNoData = new NoData[bands];
177
            for (int i = 0; i < bands; i++) {
178
                bandDataTypes[i] = this.getBandDescriptor(i).getDataType();
179
                bandNoData[i] = null;
180
            }
181
        }
182
        Envelope envelope = getEnvelope();
183
        if (rasterQuery.getClip() != null) {
184
            envelope = rasterQuery.getClip();
185
        }
186
        wmsStatus.setExtent(
187
            new Rectangle2D.Double(
188
                envelope.getMinimum(DIMENSIONS.X),
189
                envelope.getMinimum(DIMENSIONS.Y),
190
                envelope.getLength(DIMENSIONS.X),
191
                envelope.getLength(DIMENSIONS.Y)));
192

    
193
        double ratio = Math.abs(envelope.getLength(DIMENSIONS.X)/envelope.getLength(DIMENSIONS.Y));
194

    
195
        double pixelSize = rasterQuery.getPixelSize();
196
        int columns = WMSRasterProvider.DEFAULT_BUFFER_SIZE;
197
        int rows = WMSRasterProvider.DEFAULT_BUFFER_SIZE;
198
        if(pixelSize == 0){
199
            if(ratio >= 1){
200
                wmsStatus.setWidth(columns);
201
                rows = (int)Math.round(WMSRasterProvider.DEFAULT_BUFFER_SIZE/ratio);
202
                wmsStatus.setHeight((int)Math.round(WMSRasterProvider.DEFAULT_BUFFER_SIZE/ratio));
203
            } else {
204
                columns = (int)Math.round(WMSRasterProvider.DEFAULT_BUFFER_SIZE/ratio);
205
                wmsStatus.setWidth(columns);
206
                wmsStatus.setHeight(rows);
207
            }
208
        } else {
209
            columns = (int)Math.round(envelope.getLength(DIMENSIONS.X)/pixelSize);
210
            wmsStatus.setWidth(columns);
211
            rows = (int)Math.round(envelope.getLength(DIMENSIONS.Y)/pixelSize);
212
            wmsStatus.setHeight(rows);
213
        }
214

    
215
        URL url;
216
        Downloader downloader = CompatLocator.getDownloader();
217
        BufferedImage img;
218
        try {
219
            url = wmsClient.getGetMapURL(wmsStatus, null);
220
            logger.info("URL: "+url.toString());
221
            File file = downloader.downloadFile(url, "WMS_map", null);
222
            img = ImageIO.read(file);
223
        } catch (Exception e) {
224
            throw new BufferException(e);
225
        }
226

    
227
        Buffer buffer = bufferManager.createRGBABuffer(img, projection, envelope);
228

    
229
        return buffer;
230
    }
231

    
232
    @Override
233
    public BandDescriptorServices getBandDescriptor(int band) {
234
        BandDescriptorServices descriptor = super.getBandDescriptor(band);
235
      switch (band) {
236
      case 0:
237
          descriptor.setName("RED");
238
          descriptor.setDescription("RED");
239
          descriptor.setDataType(BufferManager.TYPE_BYTE);
240
      case 1:
241
          descriptor.setName("GREEN");
242
          descriptor.setDescription("GREEN");
243
          descriptor.setDataType(BufferManager.TYPE_BYTE);
244
      case 2:
245
          descriptor.setName("BLUE");
246
          descriptor.setDescription("BLUE");
247
          descriptor.setDataType(BufferManager.TYPE_BYTE);
248
      case 3:
249
          descriptor.setName("ALPHA");
250
          descriptor.setDescription("ALPHA");
251
          descriptor.setDataType(BufferManager.TYPE_BYTE);
252
      }
253
      return descriptor;
254

    
255
    }
256

    
257
    @Override
258
    public int getBands() {
259
        return 4;
260
    }
261

    
262
    @Override
263
    public DataServerExplorer getExplorer() throws ReadException, ValidateDataParametersException {
264
        DataManager manager = DALLocator.getDataManager();
265
        WMSRasterServerExplorerParameters params;
266
        try {
267
            params =
268
                (WMSRasterServerExplorerParameters) manager
269
                    .createServerExplorerParameters(WMSRasterServerExplorer.NAME);
270
            params.setService(((WMSRasterProviderParameters) getParameters()).getService());
271
//            params.setXYAxisOrder(((WMSRasterProviderParameters) getParameters()).getXYAxisOrder());
272
            return manager.openServerExplorer(WMSRasterServerExplorer.NAME, (DataServerExplorerParameters) params);
273
        } catch (Exception e) {
274
            throw new ReadException(this.getName(), e);
275
        }
276
    }
277

    
278
    @Override
279
    public void open() throws OpenException {
280
        for(int i=0; i<getBands(); i++){
281
            this.getBandDescriptor(i).setDataType(DataTypes.BYTE);
282
        }
283
    }
284

    
285
    @Override
286
    public ResourceProvider getResource() {
287
        return null;
288
    }
289

    
290
    @Override
291
    public Object getSourceId() {
292
        return getParameters().getDynValue(WMSRasterProviderParameters.WMS_SERVICE_PARAMETER_NAME);
293
    }
294

    
295
    @Override
296
    public String getProviderName() {
297
        return NAME;
298
    }
299

    
300
    @Override
301
    public String getName() { //lista de capas
302
        @SuppressWarnings("unchecked")
303
        List<String> layers = (List<String>) getParameters().getDynValue("layers");
304
        StringBuilder builder = new StringBuilder();
305
        for (int i = 0; i < layers.size(); i++) {
306
            if (i != 0) {
307
                builder.append(",");
308
            }
309
            builder.append(layers.get(i));
310
        }
311
        return builder.toString();
312
    }
313

    
314
    @Override
315
    public String getFullName() { // host:port - lista de capas
316

    
317
        StringBuilder builder = new StringBuilder();
318
        URL service = (URL)this.getParameters().getDynValue(WMSRasterProviderParameters.WMS_SERVICE_PARAMETER_NAME);
319
        builder.append(service.getHost());
320
        int port = service.getPort();
321
        if(port < 0){
322
            int defaultPort = service.getDefaultPort();
323
            if(defaultPort>=0){
324
                builder.append(":");
325
                builder.append(service.getDefaultPort());
326
            }
327
        } else {
328
            builder.append(":");
329
            builder.append(port);
330
        }
331
        builder.append(" - ");
332
        builder.append(getName());
333
        return builder.toString();
334
    }
335

    
336
    @Override
337
    public Object getDynValue(String name) throws DynFieldNotFoundException {
338
        if (DataStore.METADATA_CRS.equalsIgnoreCase(name)) {
339
            return this.getParameters().getDynValue(name);
340
        }
341
        if (DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name)) {
342
            return this.getEnvelope();
343
        }
344
        return super.getDynValue(name);
345
    }
346

    
347
    private Envelope getEnvelope() {
348
        return this.envelope;
349
    }
350

    
351
    private IProjection getProjection() {
352
        return (IProjection) this.getParameters().getDynValue(WMSRasterProviderParameters.WMS_CRS_PARAMETER_NAME);
353
    }
354

    
355
    @Override
356
    public TileStruct getTileStruct() {
357
        TileStruct tileStruct = new DefaultTileStruct();
358
        tileStruct.setColumnsPerTile(DEFAULT_BUFFER_SIZE);
359
        tileStruct.setRowsPerTile(DEFAULT_BUFFER_SIZE);
360

    
361
        try {
362
            Envelope envelope = getEnvelope();
363
            tileStruct.setEnvelope(envelope);
364

    
365
            Map<Integer, Double> zoomLevels = new HashMap<Integer, Double>();
366
            double pixelSize;
367
            double length;
368
            if (envelope.getLength(DIMENSIONS.X) >= envelope.getLength(DIMENSIONS.Y)) {
369
                length = envelope.getLength(DIMENSIONS.X);
370
            } else {
371
                length = envelope.getLength(DIMENSIONS.Y);
372
            }
373
            pixelSize = length / DEFAULT_BUFFER_SIZE;
374
            for (int zoomLevel = 0; (zoomLevel <= MAX_ZOOM_LEVEL) && ((length/pixelSize)<Integer.MAX_VALUE); zoomLevel++) {
375
                zoomLevels.put(zoomLevel, pixelSize);
376
                pixelSize = pixelSize / 2;
377
            }
378

    
379
            tileStruct.setPixelSizePerZoomLevel(zoomLevels);
380
        } catch (LocatorException e) {
381
            logger.warn("Can't create world extent of GoogleMaps", e);
382
        }
383
        return tileStruct;
384
    }
385

    
386
    @Override
387
    public Image getImageLegend() {
388
        Vector layerNames = wmsStatus.getLayerNames();
389
        if(layerNames.size()>1){
390
            return null;
391
        }
392

    
393
        File file;
394
        BufferedImage img=null;
395
        try {
396
            file = wmsClient.getLegendGraphic(wmsStatus, layerNames.get(0).toString(), null);
397
            img = ImageIO.read(file);
398
        } catch (WMSException | ServerErrorException | IOException e) {
399
            logger.warn("Can't read image legend of WMS Provider", e);
400
        }
401
        return img;
402
    }
403

    
404
}