/****************************************************************************** * * File : pgchipdataset.cpp * Project: PGCHIP Driver * Purpose: GDALDataset code for POSTGIS CHIP/GDAL Driver * Author: Benjamin Simon, noumayoss@gmail.com * ****************************************************************************** * Copyright (c) 2005, Benjamin Simon, noumayoss@gmail.com * Copyright (c) 2008, Even Rouault * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * Revision 1.1 2005/08/29 bsimon * New * */ #include "pgchip.h" /* Define to enable debugging info */ /*#define PGCHIP_DEBUG 1*/ CPL_C_START void GDALRegister_PGCHIP(void); CPL_C_END /************************************************************************/ /* ==================================================================== */ /* PGCHIPDataset */ /* ==================================================================== */ /************************************************************************/ /************************************************************************/ /* PGCHIPDataset() */ /************************************************************************/ PGCHIPDataset::PGCHIPDataset(){ hPGConn = NULL; pszTableName = NULL; pszDSName = NULL; PGCHIP = NULL; bGeoTransformValid = FALSE; adfGeoTransform[0] = 0.0; adfGeoTransform[1] = 1.0; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = 0.0; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = 1.0; SRID = -1; pszProjection = CPLStrdup(""); bHaveNoData = FALSE; dfNoDataValue = -1; } /************************************************************************/ /* ~PGCHIPDataset() */ /************************************************************************/ PGCHIPDataset::~PGCHIPDataset(){ if( hPGConn != NULL ) { /* XXX - mloskot: After the connection is closed, valgrind still * reports 36 bytes definitely lost, somewhere in the libpq. */ PQfinish( hPGConn ); hPGConn = NULL; } CPLFree(pszProjection); CPLFree(pszTableName); CPLFree(pszDSName); CPLFree(PGCHIP); } /************************************************************************/ /* GetGeoTransform() */ /************************************************************************/ CPLErr PGCHIPDataset::GetGeoTransform( double * padfTransform ){ memcpy( padfTransform, adfGeoTransform, sizeof(adfGeoTransform[0]) * 6 ); if( bGeoTransformValid ) return CE_None; else return CE_Failure; } /************************************************************************/ /* GetProjectionRef() */ /************************************************************************/ const char *PGCHIPDataset::GetProjectionRef(){ char szCommand[1024]; PGresult *hResult; if(SRID == -1) { return ""; } /* -------------------------------------------------------------------- */ /* Reading proj */ /* -------------------------------------------------------------------- */ sprintf( szCommand,"SELECT srtext FROM spatial_ref_sys where SRID=%d",SRID); hResult = PQexec(hPGConn,szCommand); if( hResult && PQresultStatus(hResult) == PGRES_TUPLES_OK && PQntuples(hResult) > 0 ) { CPLFree(pszProjection); pszProjection = CPLStrdup(PQgetvalue(hResult,0,0)); } if( hResult ) PQclear( hResult ); return pszProjection; } /************************************************************************/ /* PGChipOpenConnection() */ /************************************************************************/ static PGconn* PGChipOpenConnection(const char* pszFilename, char** ppszTableName, const char** ppszDSName, int bExitOnMissingTable, int* pbExistTable, int *pbHasNameCol) { char *pszConnectionString; PGconn *hPGConn; PGresult *hResult = NULL; int i=0; int bHavePostGIS; char *pszTableName; char szCommand[1024]; if( pszFilename == NULL || !EQUALN(pszFilename,"PG:",3)) return NULL; pszConnectionString = CPLStrdup(pszFilename); /* -------------------------------------------------------------------- */ /* Try to establish connection. */ /* -------------------------------------------------------------------- */ while(pszConnectionString[i] != '\0') { if(pszConnectionString[i] == '#') pszConnectionString[i] = ' '; else if(pszConnectionString[i] == '%') { pszConnectionString[i] = '\0'; break; } i++; } hPGConn = PQconnectdb( pszConnectionString + 3 ); if( hPGConn == NULL || PQstatus(hPGConn) == CONNECTION_BAD ) { CPLError( CE_Failure, CPLE_AppDefined, "PGconnectcb failed.\n%s", PQerrorMessage(hPGConn) ); PQfinish(hPGConn); CPLFree(pszConnectionString); return NULL; } /* -------------------------------------------------------------------- */ /* Test to see if this database instance has support for the */ /* PostGIS Geometry type. If so, disable sequential scanning */ /* so we will get the value of the gist indexes. */ /* -------------------------------------------------------------------- */ hResult = PQexec(hPGConn, "SELECT oid FROM pg_type WHERE typname = 'geometry'" ); if( hResult && PQresultStatus(hResult) == PGRES_TUPLES_OK && PQntuples(hResult) > 0 ) { bHavePostGIS = TRUE; } if( hResult ) PQclear( hResult ); if(!bHavePostGIS){ CPLError( CE_Failure, CPLE_AppDefined, "Can't find geometry type, is Postgis correctly installed ?\n"); PQfinish(hPGConn); CPLFree(pszConnectionString); return NULL; } /* -------------------------------------------------------------------- */ /* Try opening the layer */ /* -------------------------------------------------------------------- */ if( strstr(pszFilename, "layer=") != NULL ) { pszTableName = CPLStrdup( strstr(pszFilename, "layer=") + 6 ); } else { pszTableName = CPLStrdup("unknown_layer"); } char* pszDSName = strstr(pszTableName, "%name="); if (pszDSName) { *pszDSName = '\0'; pszDSName += 6; } else pszDSName = "unknown_name"; sprintf( szCommand, "select b.attname from pg_class a,pg_attribute b where a.oid=b.attrelid and a.relname='%s' and b.attname='raster';", pszTableName); hResult = PQexec(hPGConn,szCommand); if( ! (hResult && PQresultStatus(hResult) == PGRES_TUPLES_OK && PQntuples(hResult) > 0) ) { if (pbExistTable) *pbExistTable = FALSE; if (bExitOnMissingTable) { if (hResult) PQclear( hResult ); CPLFree(pszConnectionString); CPLFree(pszTableName); PQfinish(hPGConn); return NULL; } } else { if (pbExistTable) *pbExistTable = TRUE; sprintf( szCommand, "select b.attname from pg_class a,pg_attribute b where a.oid=b.attrelid and a.relname='%s' and b.attname='name';", pszTableName); if (hResult) PQclear( hResult ); hResult = PQexec(hPGConn,szCommand); if (PQresultStatus(hResult) == PGRES_TUPLES_OK && PQntuples(hResult) > 0) { if (pbHasNameCol) *pbHasNameCol = TRUE; } else { if (pbHasNameCol) *pbHasNameCol = FALSE; } } if (hResult) PQclear( hResult ); if (ppszTableName) *ppszTableName = pszTableName; else CPLFree(pszTableName); if (ppszDSName) *ppszDSName = pszDSName; CPLFree(pszConnectionString); return hPGConn; } /************************************************************************/ /* Open() */ /************************************************************************/ GDALDataset *PGCHIPDataset::Open( GDALOpenInfo * poOpenInfo ){ char szCommand[1024]; PGresult *hResult = NULL; PGCHIPDataset *poDS = NULL; char *chipStringHex; unsigned char *chipdata; int t; char *pszTableName = NULL; const char *pszDSName = NULL; int bHasNameCol = FALSE; PGconn* hPGConn = PGChipOpenConnection(poOpenInfo->pszFilename, &pszTableName, &pszDSName, TRUE, NULL, &bHasNameCol); if( hPGConn == NULL) return NULL; poDS = new PGCHIPDataset(); poDS->hPGConn = hPGConn; poDS->pszTableName = pszTableName; poDS->pszDSName = CPLStrdup(pszDSName); /* -------------------------------------------------------------------- */ /* Read the chip */ /* -------------------------------------------------------------------- */ hResult = PQexec(poDS->hPGConn, "BEGIN"); if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) { PQclear( hResult ); if (bHasNameCol) sprintf( szCommand, "SELECT raster FROM %s WHERE name = '%s' LIMIT 1 ", poDS->pszTableName, poDS->pszDSName); else sprintf( szCommand, "SELECT raster FROM %s LIMIT 1", poDS->pszTableName); hResult = PQexec(poDS->hPGConn,szCommand); } if( !hResult || PQresultStatus(hResult) != PGRES_TUPLES_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "%s", PQerrorMessage(poDS->hPGConn) ); if (hResult) PQclear( hResult ); delete poDS; return NULL; } if (PQntuples(hResult) == 0) { PQclear( hResult ); delete poDS; return NULL; } chipStringHex = PQgetvalue(hResult, 0, 0); if (chipStringHex == NULL) { PQclear( hResult ); delete poDS; return NULL; } int stringlen = strlen((char *)chipStringHex); // Allocating memory for chip chipdata = (unsigned char *) CPLMalloc(stringlen/2); for (t=0;tPGCHIP = (CHIP *)chipdata; poDS->SRID = poDS->PGCHIP->SRID; if (poDS->PGCHIP->bvol.xmin != 0 && poDS->PGCHIP->bvol.ymin != 0 & poDS->PGCHIP->bvol.xmax != 0 && poDS->PGCHIP->bvol.ymax != 0) { poDS->bGeoTransformValid = TRUE; poDS->adfGeoTransform[0] = poDS->PGCHIP->bvol.xmin; poDS->adfGeoTransform[3] = poDS->PGCHIP->bvol.ymax; poDS->adfGeoTransform[1] = (poDS->PGCHIP->bvol.xmax - poDS->PGCHIP->bvol.xmin) / poDS->PGCHIP->width; poDS->adfGeoTransform[5] = - (poDS->PGCHIP->bvol.ymax - poDS->PGCHIP->bvol.ymin) / poDS->PGCHIP->height; } #ifdef PGCHIP_DEBUG poDS->printChipInfo(*(poDS->PGCHIP)); #endif PQclear( hResult ); hResult = PQexec(poDS->hPGConn, "COMMIT"); PQclear( hResult ); /* -------------------------------------------------------------------- */ /* Verify that there's no unknown field set. */ /* -------------------------------------------------------------------- */ if ( poDS->PGCHIP->future[0] != 0 || poDS->PGCHIP->future[1] != 0 || poDS->PGCHIP->future[2] != 0 || poDS->PGCHIP->future[3] != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Unsupported CHIP format (future field bytes != 0)\n"); delete poDS; return NULL; } if ( poDS->PGCHIP->compression != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Compressed CHIP unsupported\n"); delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Set some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = poDS->PGCHIP->width; poDS->nRasterYSize = poDS->PGCHIP->height; poDS->nBands = 1; // (int)poDS->PGCHIP->future[0]; //poDS->nBitDepth = (int)poDS->PGCHIP->future[1]; poDS->nColorType = PGCHIP_COLOR_TYPE_GRAY; //(int)poDS->PGCHIP->future[2]; switch (poDS->PGCHIP->datatype) { case 5: // 24bit integer poDS->nBitDepth = 24; break; case 6: // 16bit integer poDS->nBitDepth = 16; break; case 8: poDS->nBitDepth = 8; break; case 1: // float32 case 7: // 16bit ??? case 101: // float32 (NDR) case 105: // 24bit integer (NDR) case 106: // 16bit integer (NDR) case 107: // 16bit ??? (NDR) case 108: // 8bit ??? (NDR) [ doesn't make sense ] default : CPLError( CE_Failure, CPLE_AppDefined, "Under development : CHIP datatype %d unsupported.\n", poDS->PGCHIP->datatype); break; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; iBand < poDS->nBands; iBand++ ) poDS->SetBand( iBand+1, new PGCHIPRasterBand( poDS, iBand+1 ) ); /* -------------------------------------------------------------------- */ /* Is there a palette? Note: we should also read back and */ /* apply transparency values if available. */ /* -------------------------------------------------------------------- */ CPLAssert (poDS->nColorType != PGCHIP_COLOR_TYPE_PALETTE); if( poDS->nColorType == PGCHIP_COLOR_TYPE_PALETTE ) { unsigned char *pPalette; int nColorCount = 0; int sizePalette = 0; int offsetColor = -1; GDALColorEntry oEntry; nColorCount = (int)poDS->PGCHIP->compression; pPalette = (unsigned char *)chipdata + sizeof(CHIP); sizePalette = nColorCount * sizeof(pgchip_color); poDS->poColorTable = new GDALColorTable(); for( int iColor = 0; iColor < nColorCount; iColor++ ) { oEntry.c1 = pPalette[offsetColor++]; oEntry.c2 = pPalette[offsetColor++]; oEntry.c3 = pPalette[offsetColor++]; oEntry.c4 = pPalette[offsetColor++]; poDS->poColorTable->SetColorEntry( iColor, &oEntry ); } } return( poDS ); } /************************************************************************/ /* PGCHIPCreateCopy() */ /************************************************************************/ static GDALDataset * PGCHIPCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ){ PGconn *hPGConn; char *pszTableName = NULL; const char *pszDSName = NULL; char* pszCommand; PGresult *hResult; char *pszProjection; int SRID; GDALColorTable *poCT= NULL; int bTableExists = FALSE; int bHasNameCol = FALSE; int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); int nBands = poSrcDS->GetRasterCount(); /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ /* check number of bands */ if( nBands != 1 && nBands != 4) { CPLError( CE_Failure, CPLE_NotSupported, "Under development : PGCHIP driver doesn't support %d bands. Must be 1 or 4\n", nBands ); return NULL; } if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Byte && poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_UInt16) { CPLError( CE_Failure, CPLE_NotSupported, "Under development : PGCHIP driver doesn't support data type %s. " "Only eight bit (Byte) and sixteen bit (UInt16) bands supported.\n", GDALGetDataTypeName( poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); return NULL; } hPGConn = PGChipOpenConnection(pszFilename, &pszTableName, &pszDSName, FALSE, &bTableExists, &bHasNameCol); /* Check Postgis connection string */ if( hPGConn == NULL){ CPLError( CE_Failure, CPLE_NotSupported, "Cannont connect to %s.\n", pszFilename); return NULL; } /* -------------------------------------------------------------------- */ /* Setup some parameters. */ /* -------------------------------------------------------------------- */ int nBitDepth; GDALDataType eType; int storageChunk; int nColorType=0; if( nBands == 1 && poSrcDS->GetRasterBand(1)->GetColorTable() == NULL ){ nColorType = PGCHIP_COLOR_TYPE_GRAY; } else if( nBands == 1 ){ nColorType = PGCHIP_COLOR_TYPE_PALETTE; } else if( nBands == 4 ){ nColorType = PGCHIP_COLOR_TYPE_RGB_ALPHA; } if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_UInt16 ) { eType = GDT_Byte; nBitDepth = 8; } else { eType = GDT_UInt16; nBitDepth = 16; } storageChunk = nBitDepth/8; //printf("nBands = %d, nBitDepth = %d\n",nBands,nBitDepth); pszCommand = (char*)CPLMalloc(1024); if(!bTableExists){ sprintf( pszCommand, "CREATE TABLE %s(raster chip, name varchar)", pszTableName); hResult = PQexec(hPGConn,pszCommand); bHasNameCol = TRUE; } else { if (bHasNameCol) sprintf( pszCommand, "DELETE FROM %s WHERE name = '%s'", pszTableName, pszDSName); else sprintf( pszCommand, "DELETE FROM %s", pszTableName); hResult = PQexec(hPGConn,pszCommand); } if( hResult && (PQresultStatus(hResult) == PGRES_COMMAND_OK || PQresultStatus(hResult) == PGRES_TUPLES_OK)){ PQclear( hResult ); } else { CPLError( CE_Failure, CPLE_AppDefined, "%s", PQerrorMessage(hPGConn) ); PQfinish( hPGConn ); hPGConn = NULL; return NULL; } /* -------------------------------------------------------------------- */ /* Projection, finding SRID */ /* -------------------------------------------------------------------- */ pszProjection = (char *)poSrcDS->GetProjectionRef(); SRID = -1; if( !EQUALN(pszProjection,"GEOGCS",6) && !EQUALN(pszProjection,"PROJCS",6) && !EQUALN(pszProjection,"+",6) && !EQUAL(pszProjection,"") ) { CPLError( CE_Failure, CPLE_AppDefined, "Only OGC WKT Projections supported for writing to Postgis.\n" "%s not supported.", pszProjection ); } if( pszProjection[0]=='+') sprintf( pszCommand,"SELECT SRID FROM spatial_ref_sys where proj4text=%s",pszProjection); else sprintf( pszCommand,"SELECT SRID FROM spatial_ref_sys where srtext=%s",pszProjection); hResult = PQexec(hPGConn,pszCommand); if( hResult && PQresultStatus(hResult) == PGRES_TUPLES_OK && PQntuples(hResult) > 0 ){ SRID = atoi(PQgetvalue(hResult,0,0)); } // Try to find SRID via EPSG number if (SRID == -1 && strcmp(pszProjection,"") != 0){ char *buf; char epsg[16]; memset(epsg,0,16); const char *workingproj = pszProjection; while( (buf = strstr(workingproj,"EPSG")) != 0){ workingproj = buf+4; } int iChar = 0; workingproj = workingproj + 3; while(workingproj[iChar] != '"' && iChar < 15){ epsg[iChar] = workingproj[iChar]; iChar++; } if(epsg[0] != 0){ SRID = atoi(epsg); } } else{ CPLError( CE_Failure, CPLE_AppDefined, "Projection %s not found in spatial_ref_sys table. SRID will be set to -1.\n", pszProjection ); SRID = -1; } if( hResult ) PQclear( hResult ); /* -------------------------------------------------------------------- */ /* Write palette if there is one. Technically, I think it is */ /* possible to write 16bit palettes for PNG, but we will omit */ /* this for now. */ /* -------------------------------------------------------------------- */ unsigned char *pPalette = NULL; int bHaveNoData = FALSE; double dfNoDataValue = -1; int nbColors = 0,bFoundTrans = FALSE; size_t sizePalette = 0; if( nColorType == PGCHIP_COLOR_TYPE_PALETTE ) { GDALColorEntry sEntry; int iColor; int offsetColor = -1; poCT = poSrcDS->GetRasterBand(1)->GetColorTable(); nbColors = poCT->GetColorEntryCount(); sizePalette += sizeof(pgchip_color) * poCT->GetColorEntryCount(); pPalette = (unsigned char *) CPLMalloc(sizePalette); for( iColor = 0; iColor < poCT->GetColorEntryCount(); iColor++ ) { poCT->GetColorEntryAsRGB( iColor, &sEntry ); if( sEntry.c4 != 255 ) bFoundTrans = TRUE; pPalette[offsetColor++] = (unsigned char) sEntry.c1; pPalette[offsetColor++] = (unsigned char) sEntry.c2; pPalette[offsetColor++] = (unsigned char) sEntry.c3; if( bHaveNoData && iColor == (int) dfNoDataValue ){ pPalette[offsetColor++] = 0; } else{ pPalette[offsetColor++] = (unsigned char) sEntry.c4; } } } /* -------------------------------------------------------------------- */ /* Initialize CHIP Structure */ /* -------------------------------------------------------------------- */ CHIP PGCHIP; memset(&PGCHIP,0,sizeof(PGCHIP)); PGCHIP.factor = 1.0; PGCHIP.endian_hint = 1; PGCHIP.compression = 0; // nbColors; // To cope with palette extra information :
PGCHIP.height = nYSize; PGCHIP.width = nXSize; PGCHIP.SRID = SRID; PGCHIP.future[0] = 0; // nBands; //nBands is stored in future variable PGCHIP.future[1] = 0; // nBitDepth; //nBitDepth is stored in future variable PGCHIP.future[2] = 0; // nColorType; //nBitDepth is stored in future variable PGCHIP.future[3] = 0; // nbColors; // Useless as we store nbColors in the "compression" integer PGCHIP.data = NULL; // Serialized Form double adfGeoTransform[6]; if (GDALGetGeoTransform(poSrcDS, adfGeoTransform) == CE_None) { if (adfGeoTransform[2] == 0 && adfGeoTransform[4] == 0 && adfGeoTransform[5] < 0) { PGCHIP.bvol.xmin = adfGeoTransform[0]; PGCHIP.bvol.ymax = adfGeoTransform[3]; PGCHIP.bvol.xmax = adfGeoTransform[0] + nXSize * adfGeoTransform[1]; PGCHIP.bvol.ymin = adfGeoTransform[3] + nYSize * adfGeoTransform[5]; } else { CPLError( CE_Warning, CPLE_AppDefined, "Could not write geotransform.\n" ); } } // PGCHIP.size changes if there is a palette. // Is calculated by Postgis when inserting anyway PGCHIP.size = sizeof(CHIP) - sizeof(void*) + (nYSize * nXSize * storageChunk * nBands) + sizePalette; switch(nBitDepth) { case 8: PGCHIP.datatype = 8; // NDR|XDR ? break; case 16: PGCHIP.datatype = 6; // NDR|XDR ? break; case 24: PGCHIP.datatype = 5; // NDR|XDR ? break; default: CPLError( CE_Failure, CPLE_AppDefined,"Under development : ERROR STORAGE CHUNK SIZE NOT SUPPORTED\n"); break; } #ifdef PGCHIP_DEBUG PGCHIPDataset::printChipInfo(PGCHIP); #endif /* -------------------------------------------------------------------- */ /* Loop over image */ /* -------------------------------------------------------------------- */ CPLErr eErr; size_t lineSize = nXSize * storageChunk * nBands; // allocating data buffer GByte *data = (GByte *) CPLMalloc( nYSize * lineSize); for( int iLine = 0; iLine < nYSize; iLine++ ){ for( int iBand = 0; iBand < nBands; iBand++ ){ GDALRasterBand * poBand = poSrcDS->GetRasterBand( iBand+1 ); eErr = poBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, data + (iBand*storageChunk) + iLine * lineSize, nXSize, 1, eType, nBands * storageChunk, lineSize ); } } /* -------------------------------------------------------------------- */ /* Write Header, Palette and Data */ /* -------------------------------------------------------------------- */ char *result; size_t j=0; // Calculating result length (*2 -> Hex form, +1 -> end string) size_t size_result = (PGCHIP.size * 2) + 1; // memory allocation result = (char *) CPLMalloc( size_result * sizeof(char)); // Assign chip GByte *header = (GByte *)&PGCHIP; // Copy header into result string for(j=0; j0){ for(j=0;jPGCHIP != NULL){ printf("\n---< CHIP INFO >----\n"); printf("CHIP.datatype = %d\n", c.datatype); printf("CHIP.compression = %d\n", c.compression); printf("CHIP.size = %d\n", c.size); printf("CHIP.factor = %f\n", c.factor); printf("CHIP.width = %d\n", c.width); printf("CHIP.height = %d\n", c.height); //printf("CHIP.future[0] (nBands?) = %d\n", (int)c.future[0]); //printf("CHIP.future[1] (nBitDepth?) = %d\n", (int)c.future[1]); printf("--------------------\n"); //} } /************************************************************************/ /* PGCHIPDelete */ /************************************************************************/ static CPLErr PGCHIPDelete(const char* pszFilename) { return CE_None; } /************************************************************************/ /* GDALRegister_PGCHIP() */ /************************************************************************/ void GDALRegister_PGCHIP(){ GDALDriver *poDriver; if( GDALGetDriverByName( "PGCHIP" ) == NULL ) { poDriver = new GDALDriver(); poDriver->SetDescription( "PGCHIP" ); poDriver->SetMetadataItem( GDAL_DCAP_RASTER, "YES" ); poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, "Postgis CHIP raster" ); poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, "Byte UInt16" ); poDriver->pfnOpen = PGCHIPDataset::Open; poDriver->pfnCreateCopy = PGCHIPCreateCopy; poDriver->pfnDelete = PGCHIPDelete; GetGDALDriverManager()->RegisterDriver( poDriver ); } }