Changes between Version 50 and Version 51 of WKTRaster/GDALDriverSpecificationWorking


Ignore:
Timestamp:
Oct 3, 2012, 8:57:47 AM (12 years ago)
Author:
jorgearevalo
Comment:

Updated to new changes introduced in the driver on August 2012

Legend:

Unmodified
Added
Removed
Modified
  • WKTRaster/GDALDriverSpecificationWorking

    v50 v51  
    1414}}}
    1515
    16 == '''Current status of the driver (July 2012)''' ==
     16== '''Current status of the driver (September 2012)''' ==
    1717
    1818The driver is:
    19  * Able to read in-db evenly blocked rasters (all blocks with same size)
     19 * Able to read regularly/irregularly tiled raster, each tile with same/different pixel size
    2020
    2121 * Able to generate two kind of raster object based on two modes:
     
    2323   - ONE_RASTER_PER_TABLE ('mode = 2' in connection string): Each table is considered as a raster coverage, and each row is a raster tile.
    2424
    25  * Slow (Needs one server round per [http://www.gdal.org/classGDALRasterBand.html GDALRasterBand::IReadBlock] call)
     25 * Faster than previous version (GDAL 1.9.x and below)
    2626 * Able to manage B, C, D, and F (partially) [http://trac.osgeo.org/postgis/raw-attachment/wiki/WKTRaster/Documentation01/WKTRasterArrangements.gif PostGIS Raster arrangements].
     27 * (Theoretically) able to manage A [http://trac.osgeo.org/postgis/raw-attachment/wiki/WKTRaster/Documentation01/WKTRasterArrangements.gif PostGIS Raster arrangement] (it uses VRT driver under the courtain, but need more testing)
     28* Able to provide a color interpretation for bands
    2729The driver is not:
    2830 * Able to read out-db rasters
    2931 * Able to create new rasters
    30  * Able to manage A, E, and F (fully) [http://trac.osgeo.org/postgis/raw-attachment/wiki/WKTRaster/Documentation01/WKTRasterArrangements.gif PostGIS Raster arrangements]
    31  * Able to provide a color interpretation for bands
     32 * Able to manage E, and F (fully) [http://trac.osgeo.org/postgis/raw-attachment/wiki/WKTRaster/Documentation01/WKTRasterArrangements.gif PostGIS Raster arrangements]
    3233
    3334
     
    4546Take into account a raster can contain only 1 tile. In that case, 1 GDALDataset = 1 PostGIS Raster object (= 1 PostGIS Raster table row). Otherwise, 1 GDALDataset = Several PostGIS Raster objects (= several PostGIS Raster rows). For this reason, the GDAL PostGIS Raster driver has '''2 working modes''': ONE_RASTER_PER_TABLE, ONE_RASTER_PER_ROW.
    4647
    47 However, currently the driver only deals with continuous tiled raster layers, when all the raster tiles are the same size, snap to the same grid and do not overlap (the ideal case).
     48The driver deals with regulary and irregularly tiled rasters, and each tile can has its own pixel size. It uses VRT + MEM drivers to allow this.
    4849
    49 '''UPDATE'''
    50 The driver supports any raster arrangement on a regular grid. This means that tiles on the grid may be missing or sparse. The driver supports many rasters in one table if they are on different grids, and the "where" clause to the driver limits the selection to rasters that are on the same grid at one time.
    5150
    5251'''Question''': Are 2 working modes enough to manage all the raster arrangements? '''[SOLVED]: YES'''
     
    7170 
    7271----
    73 
    74 
    75 ----
    7672=== Topic: Constructing the GDALDataset object ===
    7773
     
    9187=== Topic: !Reading/Writing raster data ===
    9288
    93 Once constructed the basic structure (GDALDataset object and related GDALRasterBand objects), we can read/write the data, following this general method: Fetch, in a long query, all the rasters along with their world georeferences (upperleftx and upperlefy, width and height) and burn them in the GDAL buffer by converting their world coordinates to the raster coordinates of the buffer.
     89Once constructed the basic structure (GDALDataset object and related GDALRasterBand objects), we read/write the data, following this general method in PostGISRasterBand::IRasterIO: Fetch, in a long query, all the rasters along with their world georeferences (upperleftx and upperlefy, width and height), create MEM datasets with them, create a VRTDataset with the MEMDatasets and call IRasterIO on VRT raster band.
    9490
    95 More specific:
    96 
    97 {{{
    98 #!c
    99 /* Perform all read & write operations */
    100 CPLErr PostGISRasterDataset::IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, void * pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, int nBandCount, int *panBandMap, int nPixelSpace, int nLineSpace, int nBandSpace)
    101 {
    102   // Deduce a world coordinate rectangle which four corners are the center of the upper left, lower left, lower right, upper right pixels of the area requested.
    103  
    104   // Fetch, in a unique SQL query, every rasters intersecting this area along with the upper left X & Y, width, height, scalex, scaleY, skewX and skewY
    105  
    106   // If the blocks are not cached, cache them with this strategy:
    107   if (!bBlocksCached) {
    108     // If the raster arrangement is a regular grid
    109     if (ST_IsRegularlyTiled()) {
    110 
    111       // Delegate to PostGISRasterBand->RasterIO(), which passes down to PostGISRasterBand::ReadBlock (see below)
    112     }
    113    
    114     // If the raster arrangement is not on a regular grid
    115     else {
    116 
    117       // memcpy rows one by one from each pixel line that lies within the intersecting area (that means if there is overlaps, only the pixel lines of the last raster fetched is burned. We can enhance this later by providing a BLENDING_MODE with the driver)
    118     }
    119 
    120     bBlocksCached = TRUE;
    121   }
    122 
    123   // Once everything is cached, delegate reading of cached blocks with GDALDataSet->RasterIO()
    124 }
    125 }}}
    126 
    127 This algorithm must be developed in the implementation of IRasterIO method of the rasterband class. In the best case the required blocks fits what is in the table and everything is optimized. If not it is slower. We don't have to know in advance whether the table is regularly tiled or not.
    128 
    129 About the IReadBlock method (to be implemented in the rasterband class):
    130 
    131 {{{
    132 #!c
    133 /* This will only be called if the PostGISDataset detects that the raster is a regularly tiled table. */
    134 CPLErr PostGISRasterRasterBand::IReadBlock(int nBlockXOff, int nBlockYOff, void* pImage)
    135 {
    136   // Deduce IRasterIO required tile metadata
    137 
    138   // memcpy raster binary data into the pImage
    139 }
    140 }}}
     91About the IReadBlock method (implemented in the rasterband class too), it just call IRasterIO with proper block parameters.
    14192
    14293----
     
    14495=== Topic: Some general thoughts ===
    14596
    146  '''Open Question (Pierre, july 2012)''': In the worst case, a VRT is basically the same thing as a PostGIS raster table (just a bunch of non aligned rasters) and I was wondering if we could not simply copy the code of the VRT driver and adjust it so it reads all the rasters of a PostGIS query instead of reading them from the file system. Basically the VRT file resume to all the rasters returned by a where query whatever their alignment are. If I'm right then we would benefit from any smart optimization implemented by Frank in the VRT driver...
     97 '''Question (Pierre, july 2012) - SOLVED (Implemented using VRT driver, as suggested)''': In the worst case, a VRT is basically the same thing as a PostGIS raster table (just a bunch of non aligned rasters) and I was wondering if we could not simply copy the code of the VRT driver and adjust it so it reads all the rasters of a PostGIS query instead of reading them from the file system. Basically the VRT file resume to all the rasters returned by a where query whatever their alignment are. If I'm right then we would benefit from any smart optimization implemented by Frank in the VRT driver...
     98 
    14799
    148100 * The driver should not be dependent on a "rid" column nor request for it. Currently, the 'rid' attribute is hardcoded in some queries. A better approach would  be looking for a primary/unique key. This is useful when getting subdatasets (each subdataset should be identified by its primary key). But just when write ability exists. In case of reading, you could always create a GDAL-internal key for each tile loaded assuming there is a "management" structure for the set of tiles. Pierre says that, if there’s no primary key, you could use a query with “where ST_UpperLeftX(rast) = XXX AND ST_UpperLeftY(rast) = YYY".