Statistics
| Revision:

gvsig-raster / org.gvsig.raster.postgis / trunk / org.gvsig.raster.postgis / org.gvsig.raster.postgis.io / src / main / java / org / gvsig / raster / postgis / io / PostGISRasterProvider.java @ 951

History | View | Annotate | Download (16.1 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
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 2
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
 */
22
package org.gvsig.raster.postgis.io;
23

    
24
import java.awt.geom.AffineTransform;
25
import java.util.ArrayList;
26
import java.util.Collections;
27
import java.util.Iterator;
28
import java.util.List;
29

    
30
import org.gvsig.fmap.dal.DALLocator;
31
import org.gvsig.fmap.dal.DataManager;
32
import org.gvsig.fmap.dal.DataStore;
33
import org.gvsig.fmap.dal.coverage.RasterLocator;
34
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
35
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
36
import org.gvsig.fmap.dal.coverage.datastruct.DatasetBand;
37
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
38
import org.gvsig.fmap.dal.coverage.exception.BandNotFoundInListException;
39
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
40
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
41
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
42
import org.gvsig.fmap.dal.coverage.store.parameter.RasterDataParameters;
43
import org.gvsig.fmap.dal.exception.DataException;
44
import org.gvsig.fmap.dal.exception.InitializeException;
45
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
46
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
47
import org.gvsig.fmap.dal.serverexplorer.db.DBServerExplorer;
48
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
49
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
50
import org.gvsig.fmap.dal.store.db.DBStoreParameters;
51
import org.gvsig.metadata.MetadataLocator;
52
import org.gvsig.raster.cache.tile.provider.TileListener;
53
import org.gvsig.raster.gdal.io.GdalDataParameters;
54
import org.gvsig.raster.gdal.io.GdalProvider;
55
import org.gvsig.raster.impl.datastruct.BandListImpl;
56
import org.gvsig.raster.impl.datastruct.DatasetBandImpl;
57
import org.gvsig.raster.impl.provider.DefaultRasterProvider;
58
import org.gvsig.raster.impl.store.AbstractRasterDataParameters;
59
import org.gvsig.raster.impl.store.DefaultStoreFactory;
60
import org.gvsig.tools.ToolsLocator;
61
import org.gvsig.tools.extensionpoint.ExtensionPoint;
62
import org.gvsig.tools.extensionpoint.ExtensionPointManager;
63
/**
64
 * This class represents the data access just for PostGIS raster databases.
65
 * @author Nacho Brodin (nachobrodin@gmail.com)
66
 */
67
public class PostGISRasterProvider extends GdalProvider {
68
        public static String           NAME                     = "PostGIS Raster Store";
69
        public static String           DESCRIPTION              = "PostGIS Raster file";
70
        public static final String     METADATA_DEFINITION_NAME = "PostGISRasterStore";
71
        private static final String    OVERVIEW_PREFIX          = "o_";
72
        
73
        private DBServerExplorer       dbServerExplorer         = null;
74
        private DBStoreParameters      dbParameters             = null;
75
        private ArrayList<Overview>    overviews                = null;
76
        private DataManager            dataManager              = DALLocator.getDataManager();
77
        private DefaultRasterProvider  selectedProvider         = null;
78
        private Overview               mainOverview             = null;
79
        
80
        class Overview implements Comparable<Overview> {
81
                public int                         width               = 0;
82
                public int                         height              = 0;
83
                public int                         factor              = 0;
84
                public double                      pxSizeOverview      = 0;
85
                public DefaultRasterProvider       provider            = null;
86
                
87
                public Overview() {
88
                        
89
                }
90
                
91
                public Overview(int f, int w, int h, PostGISRasterDataParameters p) throws NotSupportedExtensionException {
92
                        this.width = w;
93
                        this.height = h;
94
                        this.factor = f;
95
                        if(p != null)
96
                                createProvider(p);
97
                        this.pxSizeOverview = getExtent().width() / (double)w;
98
                }
99
                
100
                public void createProvider(PostGISRasterDataParameters p) throws NotSupportedExtensionException {
101
                        GdalDataParameters gdalParams = new GdalDataParameters();
102
                        gdalParams.setURI(p.getURI());
103
                        this.provider = new GdalProvider(gdalParams, storeServices);
104
                        this.width = (int)provider.getWidth();
105
                        this.height = (int)provider.getHeight();
106
                        this.pxSizeOverview = provider.getExtent().width() / (double)this.width;
107
                }
108
                
109
                public int compareTo(Overview o) {
110
                        if(factor < o.factor)
111
                                return -1;
112
                        if(factor > o.factor)
113
                                return 1;
114
                        return 0;
115
                }
116
        }
117
        
118
        public static void register() {
119
                ExtensionPointManager extensionPoints = ToolsLocator.getExtensionPointManager();
120
                ExtensionPoint point = extensionPoints.get("DefaultDriver");
121
                point.append("reader", PostGISRasterProvider.NAME, PostGISRasterProvider.class);
122
                
123
                RasterLocator.getManager().registerFileProvidersTiled(PostGISRasterProvider.class);
124
                
125
                DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager();
126
                if (dataman != null && !dataman.getStoreProviders().contains(NAME)) {
127
                        dataman.registerStoreProvider(NAME,
128
                                        PostGISRasterProvider.class, PostGISRasterDataParameters.class);
129
                }
130

    
131
                if (!dataman.getExplorerProviders().contains(PostGISRasterProvider.NAME)) {
132
                        dataman.registerExplorerProvider(PostGISRasterServerExplorer.NAME, PostGISRasterServerExplorer.class, PostGISRasterServerExplorerParameters.class);
133
                }
134
                dataman.registerStoreFactory(NAME, DefaultStoreFactory.class);
135
        }
136
        
137
        public PostGISRasterProvider() {
138
                
139
        }
140
        
141
        public PostGISRasterProvider (PostGISRasterDataParameters params,
142
                        DataStoreProviderServices storeServices) throws NotSupportedExtensionException {
143
                super(params, storeServices, ToolsLocator.getDynObjectManager()
144
                                .createDynObject(
145
                                                MetadataLocator.getMetadataManager().getDefinition(
146
                                                                DataStore.METADATA_DEFINITION_NAME)));
147
                init(params, storeServices);
148
        }
149
        
150
        /**
151
         * Creates data base references and loads structures with the information and metadata
152
         * @param params load parameters
153
         * @throws NotSupportedExtensionException
154
         */
155
        public void init (AbstractRasterDataParameters params,
156
                        DataStoreProviderServices storeServices) throws NotSupportedExtensionException {
157
                try {
158
                        setParam(storeServices, params);
159
                        mainOverview = new Overview();
160
                        mainOverview.createProvider((PostGISRasterDataParameters)param);
161
                        mainOverview.factor = 1;
162
                        file = ((GdalProvider)mainOverview.provider).getNative();
163
                        setColorInterpretation(file.getColorInterpretation());
164
                        setColorTable(file.getColorTable());
165
                        noData = file.getNoDataValue();
166
                        wktProjection = file.getProjectionRef();
167
                        //CrsWkt crs = new CrsWkt(wktProjection);
168
                        //IProjection proj = CRSFactory.getCRS("EPSG:23030");
169
                        ownTransformation = file.getOwnTransformation();
170
                        externalTransformation = (AffineTransform)ownTransformation.clone();
171
                        bandCount = file.getRasterCount();
172
                        load();
173
                } catch (Exception e) {
174
                        throw new NotSupportedExtensionException("Gdal library can't be initialized with this PostGIS raster parameters", e);
175
                } 
176

    
177
                //Obtenemos el tipo de dato de gdal y lo convertimos el de RasterBuf
178
                int[] dt = new int[file.getDataType().length];
179
                for (int i = 0; i < dt.length; i++)
180
                        dt[i] = rasterUtil.getRasterBufTypeFromGdalType(file.getDataType()[i]);
181
                setDataType(dt);
182
                
183
                PostGISRasterDataParameters p = (PostGISRasterDataParameters)params;
184
                //Object obj = p.getDynValue(PostGISRasterDataParameters.FIELD_DBPARAMS);
185
                dbParameters = (DBStoreParameters)p.getDynValue(PostGISRasterDataParameters.FIELD_DBPARAMS);
186
                dbServerExplorer = (DBServerExplorer)p.getDynValue(PostGISRasterDataParameters.FIELD_DBEXPLORER);
187
        }
188
        
189
        /*
190
         * (non-Javadoc)
191
         * @see org.gvsig.raster.impl.provider.RasterProvider#getRMFFile()
192
         */
193
        public String getRMFFile() {
194
                if(uri.startsWith("PG:host=")) {
195
                        String uri = getURI().replace("'", "");
196
                        return uri + ".rmf";
197
                } else 
198
                        return fileUtil.getNameWithoutExtension(uri) + ".rmf";
199
        }
200
        
201
        /**
202
         * Reads overviews from database. The overviews in PostGIS raster are loaded 
203
         * in separated tables. The name of those tables is the same that the original table
204
         * with a overview prefix. Now this prefix is "o_X_" where the X is a factor scale.
205
         * 
206
         * For that reason the overview object contains the DataParameter which correspond
207
         * to each table.
208
         * @throws DataException 
209
         * @throws DataException
210
         */
211
        @SuppressWarnings("unchecked")
212
        private void readOverviews() throws DataException  {
213
                if(overviews == null) {
214
                        overviews = new ArrayList<Overview>();
215
                        String mainHost = ((PostGISRasterDataParameters)param).getURI();
216

    
217
                        String mainTable = dbParameters.getTable();
218
                        List parameters = dbServerExplorer.list();
219

    
220
                        int mainFactor = 1; 
221
                                
222
                        if(isOverview(mainTable, mainTable)) {
223
                                mainFactor = getFactor(mainTable);
224
                        }
225
                        overviews.add(mainOverview);
226
                        
227
                        Iterator iter = parameters.iterator();
228
                        while (iter.hasNext()) {
229
                                DBStoreParameters p = (DBStoreParameters) iter.next();
230
                                String tname = p.getTable();
231

    
232
                                try {
233
                                        if(isOverview(mainTable, tname)) {
234
                                                Overview o = new Overview();
235
                                                o.factor = (getFactor(tname) / mainFactor);
236
                                                o.width = (int)(getWidth() / o.factor);
237
                                                o.height = (int)(getHeight() / o.factor);
238
                                                o.pxSizeOverview = getExtent().width() / (double)o.width;
239
                                                o.createProvider(createParameters(mainHost, mainTable, tname));
240
                                                overviews.add(o);
241
                                        }
242
                                } catch (NumberFormatException e) {
243
                                } catch (PostGISRasterCoreException e) {
244
                                } catch (ValidateDataParametersException e) {
245
                                } catch (NotSupportedExtensionException e) {
246
                                }
247
                        }
248
                        Collections.sort(overviews);
249
                }
250
        }
251
        
252
        /**
253
         * Returns true if tname is an overview of mainTable
254
         * @param mainTable
255
         * @param tname
256
         * @return
257
         */
258
        private boolean isOverview(String mainTable, String tname) throws NumberFormatException {
259
                if(mainTable.compareTo(tname) != 0) {
260
                        return ((tname.endsWith(mainTable) && tname.startsWith(OVERVIEW_PREFIX)) ||
261
                                        (tname.startsWith(OVERVIEW_PREFIX) && mainTable.startsWith(OVERVIEW_PREFIX) && getFactor(tname) > getFactor(mainTable)));
262
                }
263
                return false;
264
        }
265
        
266
        /**
267
         * Gets the overview factor number reading the name of the table
268
         * @param tname
269
         * @return
270
         * @throws NumberFormatException
271
         */
272
        private int getFactor(String tname) throws NumberFormatException {
273
                String factor = tname.substring(tname.indexOf('_') + 1);
274
                factor = factor.substring(0, factor.indexOf('_'));
275
                return new Integer(factor);
276
        }
277
        
278
        /**
279
         * Creates the list of parameters
280
         * @param mainHost
281
         * @param mainTable
282
         * @param tableName
283
         * @return
284
         * @throws PostGISRasterCoreException 
285
         * @throws PostGISRasterCoreException
286
         * @throws ProviderNotRegisteredException 
287
         * @throws InitializeException 
288
         * @throws ValidateDataParametersException 
289
         */
290
        @SuppressWarnings("deprecation")
291
        private PostGISRasterDataParameters createParameters(String mainHost, String mainTable, String tableName) throws PostGISRasterCoreException, ValidateDataParametersException, InitializeException, ProviderNotRegisteredException {
292
                String newHost = mainHost.replaceFirst(mainTable, tableName);
293
                
294
                PostGISRasterServerExplorerParameters explorerParams = (PostGISRasterServerExplorerParameters) dataManager.createServerExplorerParameters(PostGISRasterServerExplorer.NAME);
295
                explorerParams.setHost(newHost);
296
                PostGISRasterServerExplorer explorer = (PostGISRasterServerExplorer) dataManager.createServerExplorer(explorerParams);
297
                RasterDataParameters storeParameters = (RasterDataParameters)explorer.getStoreParameters();
298
                storeParameters.setURI(newHost);
299
                return (PostGISRasterDataParameters)storeParameters;
300
        }
301
        
302
        /**
303
         * Selects the right overview. The right overview means the first 
304
         * one with a pixel size lesser or equals than the original. 
305
         * @param pixels
306
         * @param mts
307
         */
308
        private void overviewSelector(int pixels, double mts) {
309
                this.selectedProvider = overviews.get(overviews.size() - 1).provider;
310
                //System.out.println("*************" + overviews.get(overviews.size() - 1).pxSizeOverview + "**************");
311
                double pxSizeRequest = mts / (double)pixels;
312
                for (int i = overviews.size() - 1; i > 0; i--) {
313
                        Overview ovb = overviews.get(i);
314
                        if(pxSizeRequest <= ovb.pxSizeOverview) {
315
                                this.selectedProvider = ovb.provider;
316
                                System.out.println(ovb.pxSizeOverview);
317
                        }
318
                }
319
                //System.out.println("***************************");
320
        }
321
        
322
        /*
323
         * (non-Javadoc)
324
         * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(double, double, double, double, int, int, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.raster.cache.tile.provider.TileListener)
325
         */
326
        public void getWindow(Extent ex, int bufWidth, int bufHeight, 
327
                        BandList bandList, TileListener listener) throws ProcessInterruptedException, RasterDriverException {
328
                 super.getWindow(ex, bufWidth, bufHeight, bandList, listener);
329
        }
330

    
331
        /*
332
         * (non-Javadoc)
333
         * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(org.gvsig.fmap.dal.coverage.datastruct.Extent, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer)
334
         */
335
        public Buffer getWindow(Extent ex, BandList bandList, Buffer rasterBuf) 
336
                throws ProcessInterruptedException, RasterDriverException {
337
                return super.getWindow(ex, bandList, rasterBuf);
338
        }
339

    
340
        /*
341
         * (non-Javadoc)
342
         * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(double, double, double, double, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer, boolean)
343
         */
344
        public Buffer getWindow(double ulx, double uly, double w, double h, 
345
                        BandList bandList, Buffer rasterBuf, boolean adjustToExtent) throws ProcessInterruptedException, RasterDriverException {
346
                return super.getWindow(ulx, uly, w, h, bandList, rasterBuf, adjustToExtent);
347
        }
348

    
349
        /*
350
         * (non-Javadoc)
351
         * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(double, double, double, double, int, int, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer, boolean)
352
         */
353
        public Buffer getWindow(Extent extent, 
354
                        int bufWidth, int bufHeight, BandList bandList, Buffer rasterBuf, boolean adjustToExtent) throws ProcessInterruptedException, RasterDriverException {
355
                try {
356
                        readOverviews();
357
                } catch (DataException e) {
358
                        throw new RasterDriverException("Overviews can't be read", e);
359
                }
360
                overviewSelector(bufWidth, extent.width());
361
                //Creamos un BandList con todas las bandas del fichero
362
                BandList bl = new BandListImpl();
363
                for(int i = 0; i < getBandCount(); i++) {
364
                        try {
365
                                DatasetBand band = new DatasetBandImpl(selectedProvider.getURIOfFirstProvider(), i, getDataType()[i], getBandCount());
366
                                bl.addBand(band, i);
367
                        } catch(BandNotFoundInListException e) {
368
                                //No a?adimos la banda
369
                        }
370
                }
371
                bl.setDrawableBands(bandList.getDrawableBands());
372
                
373
                return selectedProvider.getWindow(extent, bufWidth, bufHeight, bl, rasterBuf, adjustToExtent);
374
        }
375

    
376
        /*
377
         * (non-Javadoc)
378
         * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(int, int, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer)
379
         */
380
        public Buffer getWindow(int x, int y, 
381
                        BandList bandList, Buffer rasterBuf) throws ProcessInterruptedException, RasterDriverException {
382
                return super.getWindow(x, y, bandList, rasterBuf);
383
        }
384

    
385
        /*
386
         * (non-Javadoc)
387
         * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(int, int, int, int, int, int, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer)
388
         */
389
        public Buffer getWindow(int x, int y, int w, int h, 
390
                        int bufWidth, int bufHeight, BandList bandList, Buffer rasterBuf) throws ProcessInterruptedException, RasterDriverException {
391
                return super.getWindow(x, y, w, h, bufWidth, bufHeight, bandList, rasterBuf);
392
        }
393

    
394

    
395
}