Changes between Version 50 and Version 51 of WKTRaster/GDALDriverSpecificationWorking
- Timestamp:
- 10/03/12 08:57:47 (12 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
WKTRaster/GDALDriverSpecificationWorking
v50 v51 14 14 }}} 15 15 16 == '''Current status of the driver ( July2012)''' ==16 == '''Current status of the driver (September 2012)''' == 17 17 18 18 The 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 20 20 21 21 * Able to generate two kind of raster object based on two modes: … … 23 23 - ONE_RASTER_PER_TABLE ('mode = 2' in connection string): Each table is considered as a raster coverage, and each row is a raster tile. 24 24 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) 26 26 * 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 27 29 The driver is not: 28 30 * Able to read out-db rasters 29 31 * 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] 32 33 33 34 … … 45 46 Take 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. 46 47 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).48 The 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. 48 49 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.51 50 52 51 '''Question''': Are 2 working modes enough to manage all the raster arrangements? '''[SOLVED]: YES''' … … 71 70 72 71 ---- 73 74 75 ----76 72 === Topic: Constructing the GDALDataset object === 77 73 … … 91 87 === Topic: !Reading/Writing raster data === 92 88 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.89 Once 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. 94 90 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 }}} 91 About the IReadBlock method (implemented in the rasterband class too), it just call IRasterIO with proper block parameters. 141 92 142 93 ---- … … 144 95 === Topic: Some general thoughts === 145 96 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 147 99 148 100 * 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".