/*! \brief Load data records (&D) Call VFKReader::OpenFile() before this function. \param poDataBlock limit to selected data block or NULL for all \return number of data records or -1 on error */ int VFKReaderSQLite::ReadDataRecords(IVFKDataBlock *poDataBlock) { int nDataRecords; int iDataBlock; const char *pszName; CPLString osSQL; IVFKDataBlock *poDataBlockCurrent; sqlite3_stmt *hStmt; pszName = NULL; if (poDataBlock) { /* read records only for selected data block */ /* table name */ pszName = poDataBlock->GetName(); /* check for existing records (re-use already inserted data) */ osSQL.Printf("SELECT num_records FROM %s WHERE " "table_name = '%s'", VFK_DB_TABLE, pszName); hStmt = PrepareStatement(osSQL.c_str()); nDataRecords = -1; if (ExecuteSQL(hStmt) == OGRERR_NONE) { nDataRecords = sqlite3_column_int(hStmt, 0); } sqlite3_finalize(hStmt); } else { /* read all data blocks */ /* check for existing records (re-use already inserted data) */ osSQL.Printf("SELECT COUNT(*) FROM %s WHERE num_records = -1", VFK_DB_TABLE); hStmt = PrepareStatement(osSQL.c_str()); if (ExecuteSQL(hStmt) == OGRERR_NONE && sqlite3_column_int(hStmt, 0) == 0) nDataRecords = 0; /* -> read from DB */ else nDataRecords = -1; /* -> read from VFK file */ sqlite3_finalize(hStmt); } if (nDataRecords > -1) { /* read records from DB */ /* read from DB */ long iFID; int iRowId; VFKFeatureSQLite *poNewFeature = NULL; poDataBlockCurrent = NULL; for (iDataBlock = 0; iDataBlock < GetDataBlockCount(); iDataBlock++) { poDataBlockCurrent = GetDataBlock(iDataBlock); if (poDataBlock && poDataBlock != poDataBlockCurrent) continue; poDataBlockCurrent->SetFeatureCount(0); /* avoid recursive call */ pszName = poDataBlockCurrent->GetName(); CPLAssert(NULL != pszName); osSQL.Printf("SELECT %s,_rowid_ FROM %s ", FID_COLUMN, pszName); if (EQUAL(pszName, "SBP")) osSQL += "WHERE PORADOVE_CISLO_BODU = 1 "; osSQL += "ORDER BY "; osSQL += FID_COLUMN; hStmt = PrepareStatement(osSQL.c_str()); nDataRecords = 0; while (ExecuteSQL(hStmt) == OGRERR_NONE) { iFID = sqlite3_column_int(hStmt, 0); iRowId = sqlite3_column_int(hStmt, 1); poNewFeature = new VFKFeatureSQLite(poDataBlockCurrent, iRowId, iFID); poDataBlockCurrent->AddFeature(poNewFeature); nDataRecords++; } /* check DB consistency */ osSQL.Printf("SELECT num_features FROM %s WHERE table_name = '%s'", VFK_DB_TABLE, pszName); hStmt = PrepareStatement(osSQL.c_str()); if (ExecuteSQL(hStmt) == OGRERR_NONE) { int nFeatDB; nFeatDB = sqlite3_column_int(hStmt, 0); if (nFeatDB > 0 && nFeatDB != poDataBlockCurrent->GetFeatureCount()) CPLError(CE_Failure, CPLE_AppDefined, "%s: Invalid number of features " CPL_FRMT_GIB " (should be %d)", pszName, poDataBlockCurrent->GetFeatureCount(), nFeatDB); } sqlite3_finalize(hStmt); } } else { /* read from VFK file and insert records into DB */ /* begin transaction */ ExecuteSQL("BEGIN"); /* INSERT ... */ nDataRecords = VFKReader::ReadDataRecords(poDataBlock); /* update VFK_DB_TABLE table */ poDataBlockCurrent = NULL; for (iDataBlock = 0; iDataBlock < GetDataBlockCount(); iDataBlock++) { poDataBlockCurrent = GetDataBlock(iDataBlock); if (poDataBlock && poDataBlock != poDataBlockCurrent) continue; osSQL.Printf("UPDATE %s SET num_records = %d WHERE " "table_name = '%s'", VFK_DB_TABLE, poDataBlockCurrent->GetRecordCount(), poDataBlockCurrent->GetName()); ExecuteSQL(osSQL); } /* commit transaction */ ExecuteSQL("COMMIT"); } return nDataRecords; }
GDALDataset *ARGDataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int /* bStrict */ , char ** /* papszOptions */ , GDALProgressFunc /* pfnProgress */ , void * /*pProgressData */ ) { const int nBands = poSrcDS->GetRasterCount(); if( nBands != 1 ) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver doesn't support %d bands. Must be 1 band.", nBands ); return NULL; } CPLString pszDataType; int nPixelOffset = 0; GDALDataType eType = poSrcDS->GetRasterBand(1)->GetRasterDataType(); if( eType == GDT_Unknown || eType == GDT_CInt16 || eType == GDT_CInt32 || eType == GDT_CFloat32 || eType == GDT_CFloat64 ) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver doesn't support data type %s.", GDALGetDataTypeName(eType) ); return NULL; } else if (eType == GDT_Int16) { pszDataType = "int16"; nPixelOffset = 2; } else if (eType == GDT_Int32) { pszDataType = "int32"; nPixelOffset = 4; } else if (eType == GDT_Byte) { pszDataType = "uint8"; nPixelOffset = 1; } else if (eType == GDT_UInt16) { pszDataType = "uint16"; nPixelOffset = 2; } else if (eType == GDT_UInt32) { pszDataType = "uint32"; nPixelOffset = 4; } else if (eType == GDT_Float32) { pszDataType = "float32"; nPixelOffset = 4; } else if (eType == GDT_Float64) { pszDataType = "float64"; nPixelOffset = 8; } double adfTransform[6]; poSrcDS->GetGeoTransform( adfTransform ); char *pszWKT = const_cast<char *>(poSrcDS->GetProjectionRef()); OGRSpatialReference oSRS; OGRErr nErr = oSRS.importFromWkt(&pszWKT); if (nErr != OGRERR_NONE) { CPLError( CE_Failure, CPLE_NotSupported, "Cannot import spatial reference WKT from source dataset."); return NULL; } int nSrs = 0; if (oSRS.GetAuthorityCode("PROJCS") != NULL) { nSrs = atoi(oSRS.GetAuthorityCode("PROJCS")); } else if (oSRS.GetAuthorityCode("GEOGCS") != NULL) { nSrs = atoi(oSRS.GetAuthorityCode("GEOGCS")); } else { // could not determine projected or geographic code // default to EPSG:3857 if no code could be found nSrs = 3857; } /********************************************************************/ /* Create JSON companion file. */ /********************************************************************/ const CPLString osJSONFilename = GetJsonFilename(pszFilename); json_object *poJSONObject = json_object_new_object(); char **pszTokens = poSrcDS->GetMetadata(); const char *pszLayer = CSLFetchNameValue(pszTokens, "LAYER"); if ( pszLayer == NULL) { // Set the layer json_object_object_add(poJSONObject, "layer", json_object_new_string( CPLGetBasename(osJSONFilename) )); } else { // Set the layer json_object_object_add(poJSONObject, "layer", json_object_new_string( pszLayer )); } // Set the type json_object_object_add(poJSONObject, "type", json_object_new_string("arg")); // Set the datatype json_object_object_add(poJSONObject, "datatype", json_object_new_string(pszDataType)); const int nXSize = poSrcDS->GetRasterXSize(); const int nYSize = poSrcDS->GetRasterYSize(); // Set the number of rows json_object_object_add(poJSONObject, "rows", json_object_new_int(nYSize)); // Set the number of columns json_object_object_add(poJSONObject, "cols", json_object_new_int(nXSize)); // Set the xmin json_object_object_add(poJSONObject, "xmin", json_object_new_double(adfTransform[0])); // Set the ymax json_object_object_add(poJSONObject, "ymax", json_object_new_double(adfTransform[3])); // Set the cellwidth json_object_object_add(poJSONObject, "cellwidth", json_object_new_double(adfTransform[1])); // Set the cellheight json_object_object_add(poJSONObject, "cellheight", json_object_new_double(-adfTransform[5])); // Set the xmax json_object_object_add(poJSONObject, "xmax", json_object_new_double(adfTransform[0] + nXSize * adfTransform[1])); // Set the ymin json_object_object_add(poJSONObject, "ymin", json_object_new_double(adfTransform[3] + nYSize * adfTransform[5])); // Set the xskew json_object_object_add(poJSONObject, "xskew", json_object_new_double(adfTransform[2])); // Set the yskew json_object_object_add(poJSONObject, "yskew", json_object_new_double(adfTransform[4])); if (nSrs > 0) { // Set the epsg json_object_object_add(poJSONObject, "epsg", json_object_new_int(nSrs)); } if (json_object_to_file(const_cast<char *>(osJSONFilename.c_str()), poJSONObject) < 0) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver can't write companion file."); json_object_put(poJSONObject); poJSONObject = NULL; return NULL; } json_object_put(poJSONObject); poJSONObject = NULL; VSILFILE *fpImage = VSIFOpenL(pszFilename, "wb"); if (fpImage == NULL) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver can't create data file %s.", pszFilename); // remove JSON file VSIUnlink( osJSONFilename.c_str() ); return NULL; } // only 1 raster band GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 ); #ifdef CPL_LSB int bNative = FALSE; #else int bNative = TRUE; #endif RawRasterBand *poDstBand = new RawRasterBand( fpImage, 0, nPixelOffset, nPixelOffset * nXSize, eType, bNative, nXSize, nYSize, TRUE, FALSE); int nXBlockSize, nYBlockSize; poSrcBand->GetBlockSize(&nXBlockSize, &nYBlockSize); void *pabyData = CPLMalloc(nXBlockSize * nPixelOffset); // convert any blocks into scanlines for (int nYBlock = 0; nYBlock * nYBlockSize < nYSize; nYBlock++) { for (int nYScanline = 0; nYScanline < nYBlockSize; nYScanline++) { if ((nYScanline+1) + nYBlock * nYBlockSize > poSrcBand->GetYSize() ) { continue; } for (int nXBlock = 0; nXBlock * nXBlockSize < nXSize; nXBlock++) { int nXValid; if( (nXBlock+1) * nXBlockSize > poSrcBand->GetXSize() ) nXValid = poSrcBand->GetXSize() - nXBlock * nXBlockSize; else nXValid = nXBlockSize; CPLErr eErr = poSrcBand->RasterIO(GF_Read, nXBlock * nXBlockSize, nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize, 1, eType, 0, 0, NULL); if (eErr != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "Error reading."); CPLFree( pabyData ); delete poDstBand; VSIFCloseL( fpImage ); return NULL; } eErr = poDstBand->RasterIO(GF_Write, nXBlock * nXBlockSize, nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize, 1, eType, 0, 0, NULL); if (eErr != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "Error writing."); CPLFree( pabyData ); delete poDstBand; VSIFCloseL( fpImage ); return NULL; } } } } CPLFree( pabyData ); delete poDstBand; VSIFCloseL( fpImage ); return reinterpret_cast<GDALDataset *>( GDALOpen( pszFilename, GA_ReadOnly ) ); }
int OGRGPSBabelDataSource::Open( const char * pszDatasourceName, const char* pszGPSBabelDriverNameIn, char** papszOpenOptionsIn ) { if (!STARTS_WITH_CI(pszDatasourceName, "GPSBABEL:")) { CPLAssert(pszGPSBabelDriverNameIn); pszGPSBabelDriverName = CPLStrdup(pszGPSBabelDriverNameIn); pszFilename = CPLStrdup(pszDatasourceName); } else { if( CSLFetchNameValue(papszOpenOptionsIn, "FILENAME") ) pszFilename = CPLStrdup(CSLFetchNameValue(papszOpenOptionsIn, "FILENAME")); if( CSLFetchNameValue(papszOpenOptionsIn, "GPSBABEL_DRIVER") ) { if( pszFilename == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Missing FILENAME"); return FALSE; } pszGPSBabelDriverName = CPLStrdup(CSLFetchNameValue(papszOpenOptionsIn, "DRIVER")); /* A bit of validation to avoid command line injection */ if (!IsValidDriverName(pszGPSBabelDriverName)) return FALSE; } } pszName = CPLStrdup( pszDatasourceName ); bool bExplicitFeatures = false; bool bWaypoints = true; bool bTracks = true; bool bRoutes = true; if (pszGPSBabelDriverName == NULL) { const char* pszSep = strchr(pszDatasourceName + 9, ':'); if (pszSep == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "Wrong syntax. Expected GPSBabel:driver_name:file_name"); return FALSE; } pszGPSBabelDriverName = CPLStrdup(pszDatasourceName + 9); *(strchr(pszGPSBabelDriverName, ':')) = '\0'; /* A bit of validation to avoid command line injection */ if (!IsValidDriverName(pszGPSBabelDriverName)) return FALSE; /* Parse optional features= option */ if (STARTS_WITH_CI(pszSep+1, "features=")) { const char* pszNextSep = strchr(pszSep+1, ':'); if (pszNextSep == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Wrong syntax. Expected " "GPSBabel:driver_name[,options]*:[" "features=waypoints,tracks,routes:]file_name"); return FALSE; } char* pszFeatures = CPLStrdup(pszSep+1+9); *strchr(pszFeatures, ':') = 0; char** papszTokens = CSLTokenizeString(pszFeatures); char** papszIter = papszTokens; bool bErr = false; bExplicitFeatures = true; bWaypoints = false; bTracks = false; bRoutes = false; while(papszIter && *papszIter) { if (EQUAL(*papszIter, "waypoints")) bWaypoints = true; else if (EQUAL(*papszIter, "tracks")) bTracks = true; else if (EQUAL(*papszIter, "routes")) bRoutes = true; else { CPLError( CE_Failure, CPLE_AppDefined, "Wrong value for 'features' options"); bErr = true; } papszIter++; } CSLDestroy(papszTokens); CPLFree(pszFeatures); if (bErr) return FALSE; pszSep = pszNextSep; } if( pszFilename == NULL ) pszFilename = CPLStrdup(pszSep+1); } const char* pszOptionUseTempFile = CPLGetConfigOption("USE_TEMPFILE", NULL); if (pszOptionUseTempFile && CPLTestBool(pszOptionUseTempFile)) osTmpFileName = CPLGenerateTempFilename(NULL); else osTmpFileName.Printf("/vsimem/ogrgpsbabeldatasource_%p", this); bool bRet = false; if (IsSpecialFile(pszFilename)) { /* Special file : don't try to open it */ char** argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, pszFilename); VSILFILE* tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); bRet = (CPLSpawn(argv, NULL, tmpfp, TRUE) == 0); VSIFCloseL(tmpfp); tmpfp = NULL; CSLDestroy(argv); argv = NULL; } else { VSILFILE* fp = VSIFOpenL(pszFilename, "rb"); if (fp == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open file %s", pszFilename); return FALSE; } char** argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, "-"); VSILFILE* tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); CPLPushErrorHandler(CPLQuietErrorHandler); bRet = (CPLSpawn(argv, fp, tmpfp, TRUE) == 0); CPLPopErrorHandler(); CSLDestroy(argv); argv = NULL; CPLErr nLastErrorType = CPLGetLastErrorType(); CPLErrorNum nLastErrorNo = CPLGetLastErrorNo(); CPLString osLastErrorMsg = CPLGetLastErrorMsg(); VSIFCloseL(tmpfp); tmpfp = NULL; VSIFCloseL(fp); fp = NULL; if (!bRet) { if ( strstr(osLastErrorMsg.c_str(), "This format cannot be used in piped commands") == NULL) { CPLError( nLastErrorType, nLastErrorNo, "%s", osLastErrorMsg.c_str()); } else { VSIStatBuf sStatBuf; if (VSIStat(pszFilename, &sStatBuf) != 0) { CPLError( CE_Failure, CPLE_NotSupported, "Driver %s only supports real (non virtual) " "files", pszGPSBabelDriverName ); return FALSE; } /* Try without piping in */ argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, pszFilename); tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); bRet = (CPLSpawn(argv, NULL, tmpfp, TRUE) == 0); VSIFCloseL(tmpfp); tmpfp = NULL; CSLDestroy(argv); argv = NULL; } } } if (bRet) { poGPXDS = static_cast<GDALDataset *>( GDALOpenEx( osTmpFileName.c_str(), GDAL_OF_VECTOR, NULL, NULL, NULL ) ); if (poGPXDS) { if (bWaypoints) { OGRLayer* poLayer = poGPXDS->GetLayerByName("waypoints"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } if (bRoutes) { OGRLayer* poLayer = poGPXDS->GetLayerByName("routes"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; poLayer = poGPXDS->GetLayerByName("route_points"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } if (bTracks) { OGRLayer* poLayer = poGPXDS->GetLayerByName("tracks"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; poLayer = poGPXDS->GetLayerByName("track_points"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } } } return nLayers > 0; }
CPLErr PostGISRasterRasterBand::IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, void * pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, int nPixelSpace, int nLineSpace) { PostGISRasterDataset * poRDS = (PostGISRasterDataset *)poDS; CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IRasterIO(): Table %s.%s (%s), Srid : %d", pszSchema, pszTable, pszColumn, poRDS->nSrid); if (eRWFlag == GF_Write) { /* ReportError(CE_Failure, CPLE_NotSupported, "Writing through PostGIS Raster band not supported yet"); return CE_Failure; */ // Delegate in generic IRasterIO to force IWriteBlock call. // TODO: This is not a solution for UPDATE scenario, but it works // for CREATE scenario. return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace); } /******************************************************************* * Do we have overviews that would be appropriate to satisfy this * request? ******************************************************************/ if( (nBufXSize < nXSize || nBufYSize < nYSize) && GetOverviewCount() > 0 && eRWFlag == GF_Read) { if(OverviewRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace) == CE_None) return CE_None; } int bSameWindowAsOtherBand = (nXOff == poRDS->nXOffPrev && nYOff == poRDS->nYOffPrev && nXSize == poRDS->nXSizePrev && nYSize == poRDS->nYSizePrev); poRDS->nXOffPrev = nXOff; poRDS->nYOffPrev = nYOff; poRDS->nXSizePrev = nXSize; poRDS->nYSizePrev = nYSize; /* Logic to determine if bands are read in order 1, 2, ... N */ /* If so, then use multi-band caching, otherwise do just single band caching */ if( poRDS->bAssumeMultiBandReadPattern ) { if( nBand != poRDS->nNextExpectedBand ) { CPLDebug("PostGIS_Raster", "Disabling multi-band caching since band access pattern does not match"); poRDS->bAssumeMultiBandReadPattern = false; poRDS->nNextExpectedBand = 1; } else { poRDS->nNextExpectedBand ++; if( poRDS->nNextExpectedBand > poRDS->GetRasterCount() ) poRDS->nNextExpectedBand = 1; } } else { if( nBand == poRDS->nNextExpectedBand ) { poRDS->nNextExpectedBand ++; if( poRDS->nNextExpectedBand > poRDS->GetRasterCount() ) { CPLDebug("PostGIS_Raster", "Re-enabling multi-band caching"); poRDS->bAssumeMultiBandReadPattern = true; poRDS->nNextExpectedBand = 1; } } } #ifdef DEBUG_VERBOSE CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IRasterIO: " "nBand = %d, nXOff = %d, nYOff = %d, nXSize = %d, nYSize = %d, nBufXSize = %d, nBufYSize = %d", nBand, nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize); #endif #ifdef notdef /******************************************************************* * Optimization: We just have one tile. So, we can read it with * IReadBlock * * TODO: Review it. It's not working (see comment in * PostGISRasterDataset::ConstructOneDatasetFromTiles) ******************************************************************/ if (poRDS->nTiles == 1) { return GDALRasterBand::IRasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace); } #endif /******************************************************************* * Several tiles: we first look in all our sources caches. Missing * blocks are queried ******************************************************************/ double adfProjWin[8]; int nFeatureCount = 0; CPLRectObj sAoi; poRDS->PolygonFromCoords(nXOff, nYOff, nXOff + nXSize, nYOff + nYSize, adfProjWin); // (p[6], p[7]) is the minimum (x, y), and (p[2], p[3]) the max sAoi.minx = adfProjWin[6]; sAoi.maxx = adfProjWin[2]; if( adfProjWin[7] < adfProjWin[3] ) { sAoi.miny = adfProjWin[7]; sAoi.maxy = adfProjWin[3]; } else { sAoi.maxy = adfProjWin[7]; sAoi.miny = adfProjWin[3]; } #ifdef DEBUG_VERBOSE CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IRasterIO: " "Intersection box: (%f, %f) - (%f, %f)", sAoi.minx, sAoi.miny, sAoi.maxx, sAoi.maxy); #endif if (poRDS->hQuadTree == NULL) { ReportError(CE_Failure, CPLE_AppDefined, "Could not read metadata index."); return CE_Failure; } NullBuffer(pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace); if( poRDS->bBuildQuadTreeDynamically && !bSameWindowAsOtherBand ) { if( !(poRDS->LoadSources(nXOff, nYOff, nXSize, nYSize, nBand)) ) return CE_Failure; } // Matching sources, to avoid a dumb for loop over the sources PostGISRasterTileDataset ** papsMatchingTiles = (PostGISRasterTileDataset **) CPLQuadTreeSearch(poRDS->hQuadTree, &sAoi, &nFeatureCount); // No blocks found. This is not an error (the raster may have holes) if (nFeatureCount == 0) { CPLFree(papsMatchingTiles); return CE_None; } int i; /** * We need to store the max, min coords for the missing tiles in * any place. This is as good as any other **/ sAoi.minx = 0.0; sAoi.miny = 0.0; sAoi.maxx = 0.0; sAoi.maxy = 0.0; GIntBig nMemoryRequiredForTiles = 0; CPLString osIDsToFetch; int nTilesToFetch = 0; int nBandDataTypeSize = GDALGetDataTypeSize(eDataType) / 8; // Loop just over the intersecting sources for(i = 0; i < nFeatureCount; i++) { PostGISRasterTileDataset *poTile = papsMatchingTiles[i]; PostGISRasterTileRasterBand* poTileBand = (PostGISRasterTileRasterBand *)poTile->GetRasterBand(nBand); nMemoryRequiredForTiles += poTileBand->GetXSize() * poTileBand->GetYSize() * nBandDataTypeSize; // Missing tile: we'll need to query for it if (!poTileBand->IsCached()) { // If we have a PKID, add the tile PKID to the list if (poTile->pszPKID != NULL) { if( osIDsToFetch.size() != 0 ) osIDsToFetch += ","; osIDsToFetch += "'"; osIDsToFetch += poTile->pszPKID; osIDsToFetch += "'"; } double dfTileMinX, dfTileMinY, dfTileMaxX, dfTileMaxY; poTile->GetExtent(&dfTileMinX, &dfTileMinY, &dfTileMaxX, &dfTileMaxY); /** * We keep the general max and min values of all the missing * tiles, to raise a query that intersect just that area. * * TODO: In case of just a few tiles and very separated, * this strategy is clearly suboptimal. We'll get our * missing tiles, but with a lot of other not needed tiles. * * A possible optimization will be to simply rely on the * I/O method of the source (must be implemented), in case * we have minus than a reasonable amount of tiles missing. * Another criteria to decide would be how separated the * tiles are. Two queries for just two adjacent tiles is * also a dumb strategy. **/ if( nTilesToFetch == 0 ) { sAoi.minx = dfTileMinX; sAoi.miny = dfTileMinY; sAoi.maxx = dfTileMaxX; sAoi.maxy = dfTileMaxY; } else { if (dfTileMinX < sAoi.minx) sAoi.minx = dfTileMinX; if (dfTileMinY < sAoi.miny) sAoi.miny = dfTileMinY; if (dfTileMaxX > sAoi.maxx) sAoi.maxx = dfTileMaxX; if (dfTileMaxY > sAoi.maxy) sAoi.maxy = dfTileMaxY; } nTilesToFetch ++; } } /* Determine caching strategy */ int bAllBandCaching = FALSE; if (nTilesToFetch > 0) { GIntBig nCacheMax = (GIntBig) GDALGetCacheMax64(); if( nMemoryRequiredForTiles > nCacheMax ) { CPLDebug("PostGIS_Raster", "For best performance, the block cache should be able to store " CPL_FRMT_GIB " bytes for the tiles of the requested window, " "but it is only " CPL_FRMT_GIB " byte large", nMemoryRequiredForTiles, nCacheMax ); nTilesToFetch = 0; } if( poRDS->GetRasterCount() > 1 && poRDS->bAssumeMultiBandReadPattern ) { GIntBig nMemoryRequiredForTilesAllBands = nMemoryRequiredForTiles * poRDS->GetRasterCount(); if( nMemoryRequiredForTilesAllBands <= nCacheMax ) { bAllBandCaching = TRUE; } else { CPLDebug("PostGIS_Raster", "Caching only this band, but not all bands. " "Cache should be " CPL_FRMT_GIB " byte large for that", nMemoryRequiredForTilesAllBands); } } } // Raise a query for missing tiles and cache them if (nTilesToFetch > 0) { /** * There are several options here, to raise the query. * - Get all the tiles which PKID is in a list of missing * PKIDs. * - Get all the tiles that intersect a polygon constructed * based on the (min - max) values calculated before. * - Get all the tiles with upper left pixel included in the * range (min - max) calculated before. * * The first option is the most efficient one when a PKID exists. * After that, the second one is the most efficient one when a * spatial index exists. * The third one is the only one available when neither a PKID or spatial * index exist. **/ CPLString osCommand; PGresult * poResult; CPLString osRasterToFetch; if (bAllBandCaching) osRasterToFetch = pszColumn; else osRasterToFetch.Printf("ST_Band(%s, %d)", pszColumn, nBand); int bHasWhere = FALSE; if (osIDsToFetch.size() && (poRDS->bIsFastPK || !(poRDS->HasSpatialIndex())) ) { osCommand.Printf("SELECT %s, " "ST_Metadata(%s), %s FROM %s.%s", osRasterToFetch.c_str(), pszColumn, poRDS->GetPrimaryKeyRef(), pszSchema, pszTable); if( nTilesToFetch < poRDS->nTiles || poRDS->bBuildQuadTreeDynamically ) { bHasWhere = TRUE; osCommand += " WHERE "; osCommand += poRDS->pszPrimaryKeyName; osCommand += " IN ("; osCommand += osIDsToFetch; osCommand += ")"; } } else { CPLLocaleC oCLocale; // Force C locale to avoid commas instead of decimal points (for QGIS e.g.) bHasWhere = TRUE; osCommand.Printf("SELECT %s, ST_Metadata(%s), %s FROM %s.%s WHERE ", osRasterToFetch.c_str(), pszColumn, (poRDS->GetPrimaryKeyRef()) ? poRDS->GetPrimaryKeyRef() : "'foo'", pszSchema, pszTable); if( poRDS->HasSpatialIndex() ) { osCommand += CPLSPrintf("%s && " "ST_GeomFromText('POLYGON((%.18f %.18f,%.18f %.18f,%.18f %.18f,%.18f %.18f,%.18f %.18f))')", pszColumn, adfProjWin[0], adfProjWin[1], adfProjWin[2], adfProjWin[3], adfProjWin[4], adfProjWin[5], adfProjWin[6], adfProjWin[7], adfProjWin[0], adfProjWin[1]); } else { #define EPS 1e-5 osCommand += CPLSPrintf("ST_UpperLeftX(%s)" " BETWEEN %f AND %f AND ST_UpperLeftY(%s) BETWEEN " "%f AND %f", pszColumn, sAoi.minx-EPS, sAoi.maxx+EPS, pszColumn, sAoi.miny-EPS, sAoi.maxy+EPS); } } if( poRDS->pszWhere != NULL ) { if( bHasWhere ) osCommand += " AND ("; else osCommand += " WHERE ("; osCommand += poRDS->pszWhere; osCommand += ")"; } poResult = PQexec(poRDS->poConn, osCommand.c_str()); #ifdef DEBUG_QUERY CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IRasterIO(): Query = \"%s\" --> number of rows = %d", osCommand.c_str(), poResult ? PQntuples(poResult) : 0 ); #endif if (poResult == NULL || PQresultStatus(poResult) != PGRES_TUPLES_OK || PQntuples(poResult) < 0) { if (poResult) PQclear(poResult); CPLError(CE_Failure, CPLE_AppDefined, "PostGISRasterRasterBand::IRasterIO(): %s", PQerrorMessage(poRDS->poConn)); // Free the object that holds pointers to matching tiles CPLFree(papsMatchingTiles); return CE_Failure; } /** * No data. Return the buffer filled with nodata values **/ else if (PQntuples(poResult) == 0) { PQclear(poResult); // Free the object that holds pointers to matching tiles CPLFree(papsMatchingTiles); return CE_None; } /** * Ok, we loop over the results **/ int nTuples = PQntuples(poResult); for(i = 0; i < nTuples; i++) { const char* pszMetadata = PQgetvalue(poResult, i, 1); const char* pszRaster = PQgetvalue(poResult, i, 0); const char *pszPKID = (poRDS->GetPrimaryKeyRef() != NULL) ? PQgetvalue(poResult, i, 2) : NULL; poRDS->CacheTile(pszMetadata, pszRaster, pszPKID, nBand, bAllBandCaching); } // All tiles have been added to cache PQclear(poResult); } // End missing tiles /* -------------------------------------------------------------------- */ /* Overlay each source in turn over top this. */ /* -------------------------------------------------------------------- */ CPLErr eErr = CE_None; /* Sort tiles by ascending PKID, so that the draw order is determinist */ if( poRDS->GetPrimaryKeyRef() != NULL ) { qsort(papsMatchingTiles, nFeatureCount, sizeof(PostGISRasterTileDataset*), SortTilesByPKID); } for(i = 0; i < nFeatureCount && eErr == CE_None; i++) { PostGISRasterTileDataset *poTile = papsMatchingTiles[i]; PostGISRasterTileRasterBand* poTileBand = (PostGISRasterTileRasterBand *)poTile->GetRasterBand(nBand); eErr = poTileBand->poSource->RasterIO( nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace); } // Free the object that holds pointers to matching tiles CPLFree(papsMatchingTiles); return eErr; }
void OGRDXFDataSource::ReadHeaderSection() { char szLineBuf[257]; int nCode; while( (nCode = ReadValue( szLineBuf, sizeof(szLineBuf) )) > -1 && !EQUAL(szLineBuf,"ENDSEC") ) { if( nCode != 9 ) continue; CPLString osName = szLineBuf; ReadValue( szLineBuf, sizeof(szLineBuf) ); CPLString osValue = szLineBuf; oHeaderVariables[osName] = osValue; } if (nCode != -1) { nCode = ReadValue( szLineBuf, sizeof(szLineBuf) ); UnreadValue(); } /* Unusual DXF files produced by dxflib */ /* such as http://www.ribbonsoft.com/library/architecture/plants/decd5.dxf */ /* where there is a spurious ENDSEC in the middle of the header variables */ if (nCode == 9 && EQUALN(szLineBuf,"$", 1) ) { while( (nCode = ReadValue( szLineBuf, sizeof(szLineBuf) )) > -1 && !EQUAL(szLineBuf,"ENDSEC") ) { if( nCode != 9 ) continue; CPLString osName = szLineBuf; ReadValue( szLineBuf, sizeof(szLineBuf) ); CPLString osValue = szLineBuf; oHeaderVariables[osName] = osValue; } } CPLDebug( "DXF", "Read %d header variables.", (int) oHeaderVariables.size() ); /* -------------------------------------------------------------------- */ /* Decide on what CPLRecode() name to use for the files */ /* encoding or allow the encoding to be overridden. */ /* -------------------------------------------------------------------- */ CPLString osCodepage = GetVariable( "$DWGCODEPAGE", "ANSI_1252" ); // not strictly accurate but works even without iconv. if( osCodepage == "ANSI_1252" ) osEncoding = CPL_ENC_ISO8859_1; else if( EQUALN(osCodepage,"ANSI_",5) ) { osEncoding = "CP"; osEncoding += osCodepage + 5; } else { // fallback to the default osEncoding = CPL_ENC_ISO8859_1; } if( CPLGetConfigOption( "DXF_ENCODING", NULL ) != NULL ) osEncoding = CPLGetConfigOption( "DXF_ENCODING", NULL ); if( osEncoding != CPL_ENC_ISO8859_1 ) CPLDebug( "DXF", "Treating DXF as encoding '%s', $DWGCODEPAGE='%s'", osEncoding.c_str(), osCodepage.c_str() ); }
OGRErr OGRGFTTableLayer::ICreateFeature( OGRFeature *poFeature ) { if (!poDS->IsReadWrite()) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode"); return OGRERR_FAILURE; } if (osTableId.size() == 0) { CreateTableIfNecessary(); if (osTableId.size() == 0) { CPLError(CE_Failure, CPLE_NotSupported, "Cannot add feature to non-created table"); return OGRERR_FAILURE; } } if (poDS->GetAccessToken().size() == 0) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in unauthenticated mode"); return OGRERR_FAILURE; } CPLString osCommand; osCommand += "INSERT INTO "; osCommand += osTableId; osCommand += " ("; int iField; int nFieldCount = poFeatureDefn->GetFieldCount(); for(iField = 0; iField < nFieldCount; iField++) { if (iField > 0) osCommand += ", "; const char* pszFieldName = poFeatureDefn->GetFieldDefn(iField)->GetNameRef(); osCommand += EscapeAndQuote(pszFieldName); } if (bHiddenGeometryField) { if (iField > 0) osCommand += ", "; osCommand += EscapeAndQuote(GetGeometryColumn()); } osCommand += ") VALUES ("; for(iField = 0; iField < nFieldCount + bHiddenGeometryField; iField++) { if (iField > 0) osCommand += ", "; OGRGeometry* poGeom = poFeature->GetGeometryRef(); /* If there's a geometry, let's use it in priority over the textual */ /* content of the field. */ if (iGeometryField != iLatitudeField && iField == iGeometryField && (iField == nFieldCount || poGeom != NULL || !poFeature->IsFieldSet( iField ))) { if (poGeom == NULL) osCommand += "''"; else { char* pszKML; if (poGeom->getSpatialReference() != NULL && !poGeom->getSpatialReference()->IsSame(poSRS)) { OGRGeometry* poGeom4326 = poGeom->clone(); poGeom4326->transformTo(poSRS); pszKML = poGeom4326->exportToKML(); delete poGeom4326; } else { pszKML = poGeom->exportToKML(); } osCommand += "'"; osCommand += pszKML; osCommand += "'"; CPLFree(pszKML); } continue; } if( !poFeature->IsFieldSet( iField ) ) { osCommand += "''"; } else { OGRFieldType eType = poFeatureDefn->GetFieldDefn(iField)->GetType(); if (eType != OFTInteger && eType != OFTReal) { CPLString osTmp; const char* pszVal = poFeature->GetFieldAsString(iField); if (!CPLIsUTF8(pszVal, -1)) { static int bFirstTime = TRUE; if (bFirstTime) { bFirstTime = FALSE; CPLError(CE_Warning, CPLE_AppDefined, "%s is not a valid UTF-8 string. Forcing it to ASCII.\n" "This warning won't be issued anymore", pszVal); } else { CPLDebug("OGR", "%s is not a valid UTF-8 string. Forcing it to ASCII", pszVal); } char* pszEscaped = CPLForceToASCII(pszVal, -1, '?'); osTmp = pszEscaped; CPLFree(pszEscaped); pszVal = osTmp.c_str(); } osCommand += EscapeAndQuote(pszVal); } else osCommand += poFeature->GetFieldAsString(iField); } } osCommand += ")"; //CPLDebug("GFT", "%s", osCommand.c_str()); if (bInTransaction) { nFeaturesInTransaction ++; if (nFeaturesInTransaction > 1) osTransaction += "; "; osTransaction += osCommand; return OGRERR_NONE; } CPLHTTPResult * psResult = poDS->RunSQL(osCommand); if (psResult == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed"); return OGRERR_FAILURE; } char* pszLine = (char*) psResult->pabyData; if (pszLine == NULL || strncmp(pszLine, "rowid", 5) != 0 || psResult->pszErrBuf != NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed"); CPLHTTPDestroyResult(psResult); return OGRERR_FAILURE; } pszLine = OGRGFTGotoNextLine(pszLine); if (pszLine == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed"); CPLHTTPDestroyResult(psResult); return OGRERR_FAILURE; } char* pszNextLine = OGRGFTGotoNextLine(pszLine); if (pszNextLine) pszNextLine[-1] = 0; CPLDebug("GFT", "Feature id = %s", pszLine); int nFID = atoi(pszLine); if (strcmp(CPLSPrintf("%d", nFID), pszLine) == 0) poFeature->SetFID(nFID); CPLHTTPDestroyResult(psResult); return OGRERR_NONE; }
/***************************************************** * \brief Read a natural block of raster band data *****************************************************/ CPLErr PostGISRasterRasterBand::IReadBlock(int nBlockXOff, int nBlockYOff, void * pImage) { PGresult * poResult = NULL; CPLString osCommand; int nXOff = 0; int nYOff = 0; int nNaturalBlockXSize = 0; int nNaturalBlockYSize = 0; double adfProjWin[8]; PostGISRasterDataset * poRDS = (PostGISRasterDataset *)poDS; int nPixelSize = GDALGetDataTypeSize(eDataType) / 8; // Construct a polygon to intersect with GetBlockSize(&nNaturalBlockXSize, &nNaturalBlockYSize); nXOff = nBlockXOff * nNaturalBlockXSize; nYOff = nBlockYOff * nNaturalBlockYSize; poRDS->PolygonFromCoords(nXOff, nYOff, nXOff + nNaturalBlockXSize, nYOff + nNaturalBlockYSize, adfProjWin); // Raise the query if (poRDS->pszWhere == NULL) { osCommand.Printf("SELECT st_band(%s, %d) FROM %s.%s " "WHERE st_intersects(%s, ST_PolygonFromText" "('POLYGON((%.17f %.17f, %.17f %.17f, %.17f %.17f, %.17f " "%.17f, %.17f %.17f))', %d))", pszColumn, nBand, pszSchema, pszTable, pszColumn, adfProjWin[0], adfProjWin[1], adfProjWin[2], adfProjWin[3], adfProjWin[4], adfProjWin[5], adfProjWin[6], adfProjWin[7], adfProjWin[0], adfProjWin[1], poRDS->nSrid); } else { osCommand.Printf("SELECT st_band(%s, %d) FROM %s.%s WHERE (%s) " "AND st_intersects(%s, ST_PolygonFromText" "('POLYGON((%.17f %.17f, %.17f %.17f, %.17f %.17f, %.17f " "%.17f, %.17f %.17f))', %d))", pszColumn, nBand, pszSchema, pszTable, poRDS->pszWhere, pszColumn, adfProjWin[0], adfProjWin[1], adfProjWin[2], adfProjWin[3], adfProjWin[4], adfProjWin[5], adfProjWin[6], adfProjWin[7], adfProjWin[0], adfProjWin[1], poRDS->nSrid); } #ifdef DEBUG_QUERY CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IReadBlock(): Query = %s", osCommand.c_str()); #endif poResult = PQexec(poRDS->poConn, osCommand.c_str()); if (poResult == NULL || PQresultStatus(poResult) != PGRES_TUPLES_OK || PQntuples(poResult) < 0) { if (poResult) PQclear(poResult); ReportError(CE_Failure, CPLE_AppDefined, "Error retrieving raster data FROM database"); CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IRasterIO(): %s", PQerrorMessage(poRDS->poConn)); return CE_Failure; } /** * No data. Return the buffer filled with nodata values **/ else if (PQntuples(poResult) == 0) { PQclear(poResult); CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IRasterIO(): Null block"); NullBlock(pImage); return CE_None; } /** * Ok, we get the data. Only data size, without payload * * TODO: Check byte order **/ int nExpectedDataSize = nNaturalBlockXSize * nNaturalBlockYSize * nPixelSize; int nWKBLength = 0; GByte * pbyData = CPLHexToBinary(PQgetvalue(poResult, 0, 0), &nWKBLength); char * pbyDataToRead = (char*)GET_BAND_DATA(pbyData,nBand, nPixelSize, nExpectedDataSize); memcpy(pImage, pbyDataToRead, nExpectedDataSize * sizeof(char)); CPLDebug("PostGIS_Raster", "IReadBlock: Copied %d bytes FROM block " "(%d, %d) to %p", nExpectedDataSize, nBlockXOff, nBlockYOff, pImage); CPLFree(pbyData); PQclear(poResult); return CE_None; }
void GDALPamProxyDB::SaveDB() { /* -------------------------------------------------------------------- */ /* Open the database relating original names to proxy .aux.xml */ /* file names. */ /* -------------------------------------------------------------------- */ CPLString osDBName = CPLFormFilename( osProxyDBDir, "gdal_pam_proxy", "dat" ); void *hLock = CPLLockFile( osDBName, 1.0 ); // proceed even if lock fails - we need CPLBreakLockFile()! if( hLock == NULL ) { CPLError( CE_Warning, CPLE_AppDefined, "GDALPamProxyDB::SaveDB() - Failed to lock %s file, proceeding anyways.", osDBName.c_str() ); } FILE *fpDB = VSIFOpenL( osDBName, "w" ); if( fpDB == NULL ) { if( hLock ) CPLUnlockFile( hLock ); CPLError( CE_Failure, CPLE_AppDefined, "Failed to save %s Pam Proxy DB.\n%s", osDBName.c_str(), VSIStrerror( errno ) ); return; } /* -------------------------------------------------------------------- */ /* Write header. */ /* -------------------------------------------------------------------- */ GByte abyHeader[100]; memset( abyHeader, ' ', sizeof(abyHeader) ); strncpy( (char *) abyHeader, "GDAL_PROXY", 10 ); sprintf( (char *) abyHeader + 10, "%9d", nUpdateCounter ); VSIFWriteL( abyHeader, 1, 100, fpDB ); /* -------------------------------------------------------------------- */ /* Write names. */ /* -------------------------------------------------------------------- */ unsigned int i; for( i = 0; i < aosOriginalFiles.size(); i++ ) { size_t nBytesWritten; const char *pszProxyFile; VSIFWriteL( aosOriginalFiles[i].c_str(), 1, strlen(aosOriginalFiles[i].c_str())+1, fpDB ); pszProxyFile = CPLGetFilename(aosProxyFiles[i]); nBytesWritten = VSIFWriteL( pszProxyFile, 1, strlen(pszProxyFile)+1, fpDB ); if( nBytesWritten != strlen(pszProxyFile)+1 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to write complete %s Pam Proxy DB.\n%s", osDBName.c_str(), VSIStrerror( errno ) ); VSIFCloseL( fpDB ); VSIUnlink( osDBName ); return; } } VSIFCloseL( fpDB ); if( hLock ) CPLUnlockFile( hLock ); }
void GDALPamProxyDB::LoadDB() { /* -------------------------------------------------------------------- */ /* Open the database relating original names to proxy .aux.xml */ /* file names. */ /* -------------------------------------------------------------------- */ CPLString osDBName = CPLFormFilename( osProxyDBDir, "gdal_pam_proxy", "dat" ); FILE *fpDB = VSIFOpenL( osDBName, "r" ); nUpdateCounter = 0; if( fpDB == NULL ) return; /* -------------------------------------------------------------------- */ /* Read header, verify and extract update counter. */ /* -------------------------------------------------------------------- */ GByte abyHeader[100]; if( VSIFReadL( abyHeader, 1, 100, fpDB ) != 100 || strncmp( (const char *) abyHeader, "GDAL_PROXY", 10 ) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Problem reading %s header - short or corrupt?", osDBName.c_str() ); return; } nUpdateCounter = atoi((const char *) abyHeader + 10); /* -------------------------------------------------------------------- */ /* Read the file in one gulp. */ /* -------------------------------------------------------------------- */ int nBufLength; char *pszDBData; VSIFSeekL( fpDB, 0, SEEK_END ); nBufLength = (int) (VSIFTellL(fpDB) - 100); pszDBData = (char *) CPLCalloc(1,nBufLength+1); VSIFSeekL( fpDB, 100, SEEK_SET ); VSIFReadL( pszDBData, 1, nBufLength, fpDB ); VSIFCloseL( fpDB ); /* -------------------------------------------------------------------- */ /* Parse the list of in/out names. */ /* -------------------------------------------------------------------- */ int iNext = 0; while( iNext < nBufLength ) { CPLString osOriginal, osProxy; osOriginal.assign( pszDBData + iNext ); for( ; iNext < nBufLength && pszDBData[iNext] != '\0'; iNext++ ) {} if( iNext == nBufLength ) break; iNext++; osProxy = osProxyDBDir; osProxy += "/"; osProxy += pszDBData + iNext; for( ; iNext < nBufLength && pszDBData[iNext] != '\0'; iNext++ ) {} iNext++; aosOriginalFiles.push_back( osOriginal ); aosProxyFiles.push_back( osProxy ); } CPLFree( pszDBData ); }
OGRErr OGRSQLiteTableLayer::CreateField( OGRFieldDefn *poFieldIn, int bApproxOK ) { OGRFieldDefn oField( poFieldIn ); ResetReading(); if (!poDS->GetUpdate()) { CPLError( CE_Failure, CPLE_NotSupported, "Can't create fields on a read-only layer."); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Do we want to "launder" the column names into SQLite */ /* friendly format? */ /* -------------------------------------------------------------------- */ if( bLaunderColumnNames ) { char *pszSafeName = poDS->LaunderName( oField.GetNameRef() ); oField.SetName( pszSafeName ); CPLFree( pszSafeName ); } /* -------------------------------------------------------------------- */ /* How much space do we need for the list of fields. */ /* -------------------------------------------------------------------- */ int iField, nFieldListLen = 100; char *pszOldFieldList, *pszNewFieldList; for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ ) { nFieldListLen += strlen(poFeatureDefn->GetFieldDefn(iField)->GetNameRef()) + 50; } nFieldListLen += strlen( oField.GetNameRef() ); pszOldFieldList = (char *) CPLCalloc(1,nFieldListLen); pszNewFieldList = (char *) CPLCalloc(1,nFieldListLen); /* -------------------------------------------------------------------- */ /* Build list of old fields, and the list of new fields. */ /* -------------------------------------------------------------------- */ const char *pszType; sprintf( pszOldFieldList, "%s", "OGC_FID" ); sprintf( pszNewFieldList, "%s", "OGC_FID INTEGER PRIMARY KEY" ); int iNextOrdinal = 3; /* _rowid_ is 1, OGC_FID is 2 */ if( poFeatureDefn->GetGeomType() != wkbNone ) { strcat( pszOldFieldList, "," ); strcat( pszNewFieldList, "," ); strcat( pszOldFieldList, osGeomColumn ); strcat( pszNewFieldList, osGeomColumn ); if ( eGeomFormat == OSGF_WKT ) strcat( pszNewFieldList, " VARCHAR" ); else strcat( pszNewFieldList, " BLOB" ); iNextOrdinal++; } for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ ) { OGRFieldDefn *poFldDefn = poFeatureDefn->GetFieldDefn(iField); // we already added OGC_FID so don't do it again if( EQUAL(poFldDefn->GetNameRef(),"OGC_FID") ) continue; if( poFldDefn->GetType() == OFTInteger ) pszType = "INTEGER"; else if( poFldDefn->GetType() == OFTReal ) pszType = "FLOAT"; else if( poFldDefn->GetType() == OFTBinary ) pszType = "BLOB"; else pszType = "VARCHAR"; sprintf( pszOldFieldList+strlen(pszOldFieldList), ", '%s'", poFldDefn->GetNameRef() ); sprintf( pszNewFieldList+strlen(pszNewFieldList), ", '%s' %s", poFldDefn->GetNameRef(), pszType ); iNextOrdinal++; } /* -------------------------------------------------------------------- */ /* Add the new field. */ /* -------------------------------------------------------------------- */ if( oField.GetType() == OFTInteger ) pszType = "INTEGER"; else if( oField.GetType() == OFTReal ) pszType = "FLOAT"; else if( oField.GetType() == OFTBinary ) pszType = "BLOB"; else pszType = "VARCHAR"; sprintf( pszNewFieldList+strlen(pszNewFieldList), ", '%s' %s", oField.GetNameRef(), pszType ); /* ==================================================================== */ /* Backup, destroy, recreate and repopulate the table. SQLite */ /* has no ALTER TABLE so we have to do all this to add a */ /* column. */ /* ==================================================================== */ /* -------------------------------------------------------------------- */ /* Do this all in a transaction. */ /* -------------------------------------------------------------------- */ poDS->SoftStartTransaction(); /* -------------------------------------------------------------------- */ /* Save existing related triggers and index */ /* -------------------------------------------------------------------- */ int rc; char *pszErrMsg = NULL; sqlite3 *hDB = poDS->GetDB(); CPLString osSQL; osSQL.Printf( "SELECT sql FROM sqlite_master WHERE type IN ('trigger','index') AND tbl_name='%s'", pszEscapedTableName ); int nRowTriggerIndexCount, nColTriggerIndexCount; char **papszTriggerIndexResult = NULL; rc = sqlite3_get_table( hDB, osSQL.c_str(), &papszTriggerIndexResult, &nRowTriggerIndexCount, &nColTriggerIndexCount, &pszErrMsg ); /* -------------------------------------------------------------------- */ /* Make a backup of the table. */ /* -------------------------------------------------------------------- */ if( rc == SQLITE_OK ) rc = sqlite3_exec( hDB, CPLSPrintf( "CREATE TEMPORARY TABLE t1_back(%s)", pszOldFieldList ), NULL, NULL, &pszErrMsg ); if( rc == SQLITE_OK ) rc = sqlite3_exec( hDB, CPLSPrintf( "INSERT INTO t1_back SELECT %s FROM '%s'", pszOldFieldList, pszEscapedTableName ), NULL, NULL, &pszErrMsg ); /* -------------------------------------------------------------------- */ /* Drop the original table, and recreate with new field. */ /* -------------------------------------------------------------------- */ if( rc == SQLITE_OK ) rc = sqlite3_exec( hDB, CPLSPrintf( "DROP TABLE '%s'", pszEscapedTableName ), NULL, NULL, &pszErrMsg ); if( rc == SQLITE_OK ) { const char *pszCmd = CPLSPrintf( "CREATE TABLE '%s' (%s)", pszEscapedTableName, pszNewFieldList ); rc = sqlite3_exec( hDB, pszCmd, NULL, NULL, &pszErrMsg ); CPLDebug( "OGR_SQLITE", "exec(%s)", pszCmd ); } /* -------------------------------------------------------------------- */ /* Copy backup field values into new table. */ /* -------------------------------------------------------------------- */ if( rc == SQLITE_OK ) rc = sqlite3_exec( hDB, CPLSPrintf( "INSERT INTO '%s' SELECT %s, NULL FROM t1_back", pszEscapedTableName, pszOldFieldList ), NULL, NULL, &pszErrMsg ); CPLFree( pszOldFieldList ); CPLFree( pszNewFieldList ); /* -------------------------------------------------------------------- */ /* Cleanup backup table. */ /* -------------------------------------------------------------------- */ if( rc == SQLITE_OK ) rc = sqlite3_exec( hDB, CPLSPrintf( "DROP TABLE t1_back" ), NULL, NULL, &pszErrMsg ); /* -------------------------------------------------------------------- */ /* Recreate existing related tables, triggers and index */ /* -------------------------------------------------------------------- */ if( rc == SQLITE_OK ) { int i; for(i = 1; i <= nRowTriggerIndexCount && nColTriggerIndexCount == 1 && rc == SQLITE_OK; i++) { if (papszTriggerIndexResult[i] != NULL && papszTriggerIndexResult[i][0] != '\0') rc = sqlite3_exec( hDB, papszTriggerIndexResult[i], NULL, NULL, &pszErrMsg ); } } /* -------------------------------------------------------------------- */ /* COMMIT on success or ROLLBACK on failuire. */ /* -------------------------------------------------------------------- */ sqlite3_free_table( papszTriggerIndexResult ); if( rc == SQLITE_OK ) { poDS->SoftCommit(); } else { CPLError( CE_Failure, CPLE_AppDefined, "Failed to add field %s to table %s:\n %s", oField.GetNameRef(), poFeatureDefn->GetName(), pszErrMsg ); sqlite3_free( pszErrMsg ); poDS->SoftRollback(); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Add the field to the OGRFeatureDefn. */ /* -------------------------------------------------------------------- */ int iNewField; poFeatureDefn->AddFieldDefn( &oField ); iNewField = poFeatureDefn->GetFieldCount() - 1; panFieldOrdinals = (int *) CPLRealloc(panFieldOrdinals, (iNewField+1) * sizeof(int) ); panFieldOrdinals[iNewField] = iNextOrdinal; return OGRERR_NONE; }
OGRErr OGRSQLiteTableLayer::CreateFeature( OGRFeature *poFeature ) { sqlite3 *hDB = poDS->GetDB(); CPLString osCommand; CPLString osValues; int bNeedComma = FALSE; if (bSpatialiteReadOnly || !poDS->GetUpdate()) { CPLError( CE_Failure, CPLE_NotSupported, "Can't create feature on a read-only layer."); return OGRERR_FAILURE; } ResetReading(); /* -------------------------------------------------------------------- */ /* Form the INSERT command. */ /* -------------------------------------------------------------------- */ osCommand += CPLSPrintf( "INSERT INTO '%s' (", pszEscapedTableName ); /* -------------------------------------------------------------------- */ /* Add FID if we have a cleartext FID column. */ /* -------------------------------------------------------------------- */ if( pszFIDColumn != NULL // && !EQUAL(pszFIDColumn,"OGC_FID") && poFeature->GetFID() != OGRNullFID ) { osCommand += pszFIDColumn; osValues += CPLSPrintf( "%ld", poFeature->GetFID() ); bNeedComma = TRUE; } /* -------------------------------------------------------------------- */ /* Add geometry. */ /* -------------------------------------------------------------------- */ OGRGeometry *poGeom = poFeature->GetGeometryRef(); if( osGeomColumn.size() != 0 && poGeom != NULL && eGeomFormat != OSGF_FGF ) { if( bNeedComma ) { osCommand += ","; osValues += ","; } osCommand += osGeomColumn; osValues += "?"; bNeedComma = TRUE; } /* -------------------------------------------------------------------- */ /* Add field values. */ /* -------------------------------------------------------------------- */ int iField; int nFieldCount = poFeatureDefn->GetFieldCount(); for( iField = 0; iField < nFieldCount; iField++ ) { if( !poFeature->IsFieldSet( iField ) ) continue; if( bNeedComma ) { osCommand += ","; osValues += ","; } osCommand += "'"; osCommand +=poFeatureDefn->GetFieldDefn(iField)->GetNameRef(); osCommand += "'"; osValues += "?"; bNeedComma = TRUE; } /* -------------------------------------------------------------------- */ /* Merge final command. */ /* -------------------------------------------------------------------- */ osCommand += ") VALUES ("; osCommand += osValues; osCommand += ")"; /* -------------------------------------------------------------------- */ /* Prepare the statement. */ /* -------------------------------------------------------------------- */ int rc; sqlite3_stmt *hInsertStmt; #ifdef DEBUG CPLDebug( "OGR_SQLITE", "prepare(%s)", osCommand.c_str() ); #endif rc = sqlite3_prepare( hDB, osCommand, -1, &hInsertStmt, NULL ); if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "In CreateFeature(): sqlite3_prepare(%s):\n %s", osCommand.c_str(), sqlite3_errmsg(hDB) ); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Bind the geometry */ /* -------------------------------------------------------------------- */ int nBindField = 1; if( osGeomColumn.size() != 0 && poGeom != NULL && eGeomFormat != OSGF_FGF ) { if ( eGeomFormat == OSGF_WKT ) { char *pszWKT = NULL; poGeom->exportToWkt( &pszWKT ); rc = sqlite3_bind_text( hInsertStmt, nBindField++, pszWKT, -1, CPLFree ); } else if( eGeomFormat == OSGF_WKB ) { int nWKBLen = poGeom->WkbSize(); GByte *pabyWKB = (GByte *) CPLMalloc(nWKBLen + 1); poGeom->exportToWkb( wkbNDR, pabyWKB ); rc = sqlite3_bind_blob( hInsertStmt, nBindField++, pabyWKB, nWKBLen, CPLFree ); } else if ( eGeomFormat == OSGF_SpatiaLite ) { int nBLOBLen; GByte *pabySLBLOB; ExportSpatiaLiteGeometry( poGeom, nSRSId, wkbNDR, bHasM, bSpatialite2D, &pabySLBLOB, &nBLOBLen ); rc = sqlite3_bind_blob( hInsertStmt, nBindField++, pabySLBLOB, nBLOBLen, CPLFree ); } else { CPLAssert(0); } if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "sqlite3_bind_blob/text() failed:\n %s", sqlite3_errmsg(hDB) ); sqlite3_finalize( hInsertStmt ); return OGRERR_FAILURE; } } /* -------------------------------------------------------------------- */ /* Bind field values. */ /* -------------------------------------------------------------------- */ for( iField = 0; iField < nFieldCount; iField++ ) { const char *pszRawValue; if( !poFeature->IsFieldSet( iField ) ) continue; switch( poFeatureDefn->GetFieldDefn(iField)->GetType() ) { case OFTInteger: { int nFieldVal = poFeature->GetFieldAsInteger( iField ); rc = sqlite3_bind_int(hInsertStmt, nBindField++, nFieldVal); break; } case OFTReal: { double dfFieldVal = poFeature->GetFieldAsDouble( iField ); rc = sqlite3_bind_double(hInsertStmt, nBindField++, dfFieldVal); break; } case OFTBinary: { int nDataLength = 0; GByte* pabyData = poFeature->GetFieldAsBinary( iField, &nDataLength ); rc = sqlite3_bind_blob(hInsertStmt, nBindField++, pabyData, nDataLength, SQLITE_TRANSIENT); break; } default: { pszRawValue = poFeature->GetFieldAsString( iField ); rc = sqlite3_bind_text(hInsertStmt, nBindField++, pszRawValue, -1, SQLITE_TRANSIENT); break; } } if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "sqlite3_bind_() for column %s failed:\n %s", poFeatureDefn->GetFieldDefn(iField)->GetNameRef(), sqlite3_errmsg(hDB) ); sqlite3_finalize( hInsertStmt ); return OGRERR_FAILURE; } } /* -------------------------------------------------------------------- */ /* Execute the insert. */ /* -------------------------------------------------------------------- */ rc = sqlite3_step( hInsertStmt ); if( rc != SQLITE_OK && rc != SQLITE_DONE ) { CPLError( CE_Failure, CPLE_AppDefined, "sqlite3_step() failed:\n %s", sqlite3_errmsg(hDB) ); sqlite3_finalize( hInsertStmt ); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Capture the FID/rowid. */ /* -------------------------------------------------------------------- */ const sqlite_int64 nFID = sqlite3_last_insert_rowid( hDB ); if(nFID > 0) { poFeature->SetFID( (long)nFID ); /* Possible truncation if nFID is 64bit */ } sqlite3_finalize( hInsertStmt ); return OGRERR_NONE; }
void OGRSQLiteTableLayer::BuildWhere() { osWHERE = ""; if( m_poFilterGeom != NULL && bHasSpatialIndex ) { OGREnvelope sEnvelope; m_poFilterGeom->getEnvelope( &sEnvelope ); /* We first check that the spatial index table exists */ if (!bHasCheckedSpatialIndexTable) { bHasCheckedSpatialIndexTable = TRUE; char **papszResult; int nRowCount, nColCount; char *pszErrMsg = NULL; CPLString osSQL; osSQL.Printf("SELECT name FROM sqlite_master " "WHERE name='idx_%s_%s'", pszEscapedTableName, osGeomColumn.c_str()); int rc = sqlite3_get_table( poDS->GetDB(), osSQL.c_str(), &papszResult, &nRowCount, &nColCount, &pszErrMsg ); if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "Error: %s", pszErrMsg ); sqlite3_free( pszErrMsg ); bHasSpatialIndex = FALSE; } else { if (nRowCount != 1) { bHasSpatialIndex = FALSE; } sqlite3_free_table(papszResult); } } if (bHasSpatialIndex) { osWHERE.Printf("WHERE ROWID IN ( SELECT pkid FROM 'idx_%s_%s' WHERE " "xmax > %.12f AND xmin < %.12f AND ymax > %.12f AND ymin < %.12f) ", pszEscapedTableName, osGeomColumn.c_str(), sEnvelope.MinX - 1e-11, sEnvelope.MaxX + 1e-11, sEnvelope.MinY - 1e-11, sEnvelope.MaxY + 1e-11); } else { CPLDebug("SQLITE", "Count not find idx_%s_%s layer. Disabling spatial index", pszEscapedTableName, osGeomColumn.c_str()); } } if( m_poFilterGeom != NULL && bSpatialiteLoaded && !bHasSpatialIndex) { OGREnvelope sEnvelope; m_poFilterGeom->getEnvelope( &sEnvelope ); /* A bit inefficient but still faster than OGR filtering */ osWHERE.Printf("WHERE MBRIntersects(\"%s\", BuildMBR(%.12f, %.12f, %.12f, %.12f, %d)) ", osGeomColumn.c_str(), sEnvelope.MinX - 1e-11, sEnvelope.MinY - 1e-11, sEnvelope.MaxX + 1e-11, sEnvelope.MaxY + 1e-11, nSRSId); } if( strlen(osQuery) > 0 ) { if( strlen(osWHERE) == 0 ) { osWHERE.Printf( "WHERE %s ", osQuery.c_str() ); } else { osWHERE += "AND "; osWHERE += osQuery; } } }
/*! \brief Add feature \param poDataBlock pointer to VFKDataBlock instance \param poFeature pointer to VFKFeature instance */ OGRErr VFKReaderSQLite::AddFeature(IVFKDataBlock *poDataBlock, VFKFeature *poFeature) { CPLString osCommand; CPLString osValue; const char *pszBlockName; OGRFieldType ftype; const VFKProperty *poProperty; VFKFeatureSQLite *poNewFeature; pszBlockName = poDataBlock->GetName(); osCommand.Printf("INSERT INTO '%s' VALUES(", pszBlockName); for (int i = 0; i < poDataBlock->GetPropertyCount(); i++) { ftype = poDataBlock->GetProperty(i)->GetType(); poProperty = poFeature->GetProperty(i); if (i > 0) osCommand += ","; if (poProperty->IsNull()) osValue.Printf("NULL"); else { switch (ftype) { case OFTInteger: osValue.Printf("%d", poProperty->GetValueI()); break; case OFTReal: osValue.Printf("%f", poProperty->GetValueD()); break; case OFTString: if (poDataBlock->GetProperty(i)->IsIntBig()) osValue.Printf("%s", poProperty->GetValueS()); else osValue.Printf("'%s'", poProperty->GetValueS(TRUE)); break; default: osValue.Printf("'%s'", poProperty->GetValueS()); break; } } osCommand += osValue; } osValue.Printf("," CPL_FRMT_GIB, poFeature->GetFID()); if (poDataBlock->GetGeometryType() != wkbNone) { osValue += ",NULL"; } osValue += ")"; osCommand += osValue; if (ExecuteSQL(osCommand.c_str(), TRUE) != OGRERR_NONE) return OGRERR_FAILURE; if (EQUAL(pszBlockName, "SBP")) { poProperty = poFeature->GetProperty("PORADOVE_CISLO_BODU"); if( poProperty == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find property PORADOVE_CISLO_BODU"); return OGRERR_FAILURE; } if (!EQUAL(poProperty->GetValueS(), "1")) return OGRERR_NONE; } poNewFeature = new VFKFeatureSQLite(poDataBlock, poDataBlock->GetRecordCount(RecordValid) + 1, poFeature->GetFID()); poDataBlock->AddFeature(poNewFeature); return OGRERR_NONE; }
/*! \brief VFKReaderSQLite constructor */ VFKReaderSQLite::VFKReaderSQLite(const char *pszFilename) : VFKReader(pszFilename) { const char *pszDbNameConf; CPLString osDbName; CPLString osCommand; VSIStatBufL sStatBufDb, sStatBufVfk; /* open tmp SQLite DB (re-use DB file if already exists) */ pszDbNameConf = CPLGetConfigOption("OGR_VFK_DB_NAME", NULL); if (pszDbNameConf) { osDbName = pszDbNameConf; } else { osDbName = CPLResetExtension(m_pszFilename, "db"); } size_t nLen = osDbName.length(); if( nLen > 2048 ) { nLen = 2048; osDbName.resize(nLen); } m_pszDBname = new char [nLen+1]; std::strncpy(m_pszDBname, osDbName.c_str(), nLen); m_pszDBname[nLen] = 0; CPLDebug("OGR-VFK", "Using internal DB: %s", m_pszDBname); if (CPLTestBool(CPLGetConfigOption("OGR_VFK_DB_SPATIAL", "YES"))) m_bSpatial = TRUE; /* build geometry from DB */ else m_bSpatial = FALSE; /* store also geometry in DB */ m_bNewDb = TRUE; if (VSIStatL(osDbName, &sStatBufDb) == 0) { if (CPLTestBool(CPLGetConfigOption("OGR_VFK_DB_OVERWRITE", "NO"))) { m_bNewDb = TRUE; /* overwrite existing DB */ CPLDebug("OGR-VFK", "Internal DB (%s) already exists and will be overwritten", m_pszDBname); VSIUnlink(osDbName); } else { if (VSIStatL(pszFilename, &sStatBufVfk) == 0 && sStatBufVfk.st_mtime > sStatBufDb.st_mtime) { CPLDebug("OGR-VFK", "Found %s but ignoring because it appears\n" "be older than the associated VFK file.", osDbName.c_str()); m_bNewDb = TRUE; VSIUnlink(osDbName); } else { m_bNewDb = FALSE; /* re-use existing DB */ } } } /* if (m_bNewDb) { CPLError(CE_Warning, CPLE_AppDefined, "INFO: No internal SQLite DB found. Reading VFK data may take some time..."); } */ CPLDebug("OGR-VFK", "New DB: %s Spatial: %s", m_bNewDb ? "yes" : "no", m_bSpatial ? "yes" : "no"); if (SQLITE_OK != sqlite3_open(osDbName, &m_poDB)) { CPLError(CE_Failure, CPLE_AppDefined, "Creating SQLite DB failed"); } else { char* pszErrMsg = NULL; CPL_IGNORE_RET_VAL(sqlite3_exec(m_poDB, "PRAGMA synchronous = OFF", NULL, NULL, &pszErrMsg)); sqlite3_free(pszErrMsg); } if (m_bNewDb) { /* new DB, create support metadata tables */ osCommand.Printf("CREATE TABLE %s (file_name text, table_name text, num_records integer, " "num_features integer, num_geometries integer, table_defn text)", VFK_DB_TABLE); ExecuteSQL(osCommand.c_str()); /* header table */ osCommand.Printf("CREATE TABLE %s (key text, value text)", VFK_DB_HEADER); ExecuteSQL(osCommand.c_str()); } }
int OGRSelafinDataSource::Open( const char * pszFilename, int bUpdateIn, int bCreate ) { // Check if a range is set and extract it and the filename. const char *pszc = pszFilename; if (*pszFilename==0) return FALSE; while (*pszc) ++pszc; if (*(pszc-1)==']') { --pszc; while (pszc!=pszFilename && *pszc!='[') pszc--; if (pszc==pszFilename) return FALSE; poRange.setRange(pszc); } pszName = CPLStrdup( pszFilename ); pszName[pszc-pszFilename]=0; bUpdate = CPL_TO_BOOL(bUpdateIn); if (bCreate && EQUAL(pszName, "/vsistdout/")) return TRUE; /* For writable /vsizip/, do nothing more */ if (bCreate && STARTS_WITH(pszName, "/vsizip/")) return TRUE; CPLString osFilename(pszName); CPLString osBaseFilename = CPLGetFilename(pszName); // Determine what sort of object this is. VSIStatBufL sStatBuf; if (VSIStatExL( osFilename, &sStatBuf, VSI_STAT_NATURE_FLAG ) != 0) return FALSE; // Is this a single Selafin file? if (VSI_ISREG(sStatBuf.st_mode)) return OpenTable( pszName ); // Is this a single a ZIP file with only a Selafin file inside ? if( STARTS_WITH(osFilename, "/vsizip/") && VSI_ISREG(sStatBuf.st_mode) ) { char** papszFiles = VSIReadDir(osFilename); if (CSLCount(papszFiles) != 1) { CSLDestroy(papszFiles); return FALSE; } osFilename = CPLFormFilename(osFilename, papszFiles[0], nullptr); CSLDestroy(papszFiles); return OpenTable( osFilename ); } #ifdef notdef // Otherwise it has to be a directory. if( !VSI_ISDIR(sStatBuf.st_mode) ) return FALSE; // Scan through for entries which look like Selafin files int nNotSelafinCount = 0, i; char **papszNames = VSIReadDir( osFilename ); for( i = 0; papszNames != NULL && papszNames[i] != NULL; i++ ) { CPLString oSubFilename = CPLFormFilename( osFilename, papszNames[i], NULL ); if( EQUAL(papszNames[i],".") || EQUAL(papszNames[i],"..") ) continue; if( VSIStatL( oSubFilename, &sStatBuf ) != 0 || !VSI_ISREG(sStatBuf.st_mode) ) { nNotSelafinCount++; continue; } if( !OpenTable( oSubFilename ) ) { CPLDebug("Selafin", "Cannot open %s", oSubFilename.c_str()); nNotSelafinCount++; continue; } } CSLDestroy( papszNames ); // We presume that this is indeed intended to be a Selafin datasource if over half the files were Selafin files. return nNotSelafinCount < nLayers; #else return FALSE; #endif }
CPLErr RasterliteDataset::CreateOverviewLevel(int nOvrFactor, GDALProgressFunc pfnProgress, void * pProgressData) { double dfXResolution = padfXResolutions[0] * nOvrFactor; double dfYResolution = padfXResolutions[0] * nOvrFactor; CPLString osSQL; int nBlockXSize = 256; int nBlockYSize = 256; int nOvrXSize = nRasterXSize / nOvrFactor; int nOvrYSize = nRasterYSize / nOvrFactor; if (nOvrXSize == 0 || nOvrYSize == 0) return CE_Failure; int nXBlocks = (nOvrXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nOvrYSize + nBlockYSize - 1) / nBlockYSize; const char* pszDriverName = "GTiff"; GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName); if (hTileDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName); return CE_Failure; } GDALDriverH hMemDriver = GDALGetDriverByName("MEM"); if (hMemDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver"); return CE_Failure; } GDALDataType eDataType = GetRasterBand(1)->GetRasterDataType(); int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8; GByte* pabyMEMDSBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize); if (pabyMEMDSBuffer == NULL) { return CE_Failure; } char** papszTileDriverOptions = NULL; CPLString osTempFileName; osTempFileName.Printf("/vsimem/%p", hDS); int nTileId = 0; int nBlocks = 0; int nTotalBlocks = nXBlocks * nYBlocks; CPLString osRasterLayer; osRasterLayer.Printf("%s_rasters", osTableName.c_str()); CPLString osMetatadataLayer; osMetatadataLayer.Printf("%s_metadata", osTableName.c_str()); OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str()); OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str()); CPLString osSourceName = "unknown"; osSQL.Printf("SELECT source_name FROM \"%s\" WHERE " "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f LIMIT 1", osMetatadataLayer.c_str(), padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15, padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15); OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr); if (hFeat) { const char* pszVal = OGR_F_GetFieldAsString(hFeat, 0); if (pszVal) osSourceName = pszVal; OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); } /* -------------------------------------------------------------------- */ /* Compute up to which existing overview level we can use for */ /* computing the requested overview */ /* -------------------------------------------------------------------- */ int iLev; nLimitOvrCount = 0; for(iLev=1;iLev<nResolutions;iLev++) { if (!(padfXResolutions[iLev] < dfXResolution - 1e-10 && padfYResolutions[iLev] < dfYResolution - 1e-10)) { break; } nLimitOvrCount++; } /* -------------------------------------------------------------------- */ /* Iterate over blocks to add data into raster and metadata tables */ /* -------------------------------------------------------------------- */ OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL); CPLErr eErr = CE_None; int nBlockXOff, nBlockYOff; for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++) { for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++) { /* -------------------------------------------------------------------- */ /* Create in-memory tile */ /* -------------------------------------------------------------------- */ int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize; if ((nBlockXOff+1) * nBlockXSize > nOvrXSize) nReqXSize = nOvrXSize - nBlockXOff * nBlockXSize; if ((nBlockYOff+1) * nBlockYSize > nOvrYSize) nReqYSize = nOvrYSize - nBlockYOff * nBlockYSize; eErr = RasterIO(GF_Read, nBlockXOff * nBlockXSize * nOvrFactor, nBlockYOff * nBlockYSize * nOvrFactor, nReqXSize * nOvrFactor, nReqYSize * nOvrFactor, pabyMEMDSBuffer, nReqXSize, nReqYSize, eDataType, nBands, NULL, 0, 0, 0); if (eErr != CE_None) { break; } GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::", nReqXSize, nReqYSize, 0, eDataType, NULL); if (hMemDS == NULL) { eErr = CE_Failure; break; } int iBand; for(iBand = 0; iBand < nBands; iBand ++) { char** papszOptions = NULL; char szTmp[64]; memset(szTmp, 0, sizeof(szTmp)); CPLPrintPointer(szTmp, pabyMEMDSBuffer + iBand * nDataTypeSize * nReqXSize * nReqYSize, sizeof(szTmp)); papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp); GDALAddBand(hMemDS, eDataType, papszOptions); CSLDestroy(papszOptions); } GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver, osTempFileName.c_str(), hMemDS, FALSE, papszTileDriverOptions, NULL, NULL); GDALClose(hMemDS); if (hOutDS) GDALClose(hOutDS); else { eErr = CE_Failure; break; } /* -------------------------------------------------------------------- */ /* Insert new entry into raster table */ /* -------------------------------------------------------------------- */ vsi_l_offset nDataLength; GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(), &nDataLength, FALSE); OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) ); OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData); OGR_L_CreateFeature(hRasterLayer, hFeat); /* Query raster ID to set it as the ID of the associated metadata */ int nRasterID = (int)OGR_F_GetFID(hFeat); OGR_F_Destroy(hFeat); VSIUnlink(osTempFileName.c_str()); /* -------------------------------------------------------------------- */ /* Insert new entry into metadata table */ /* -------------------------------------------------------------------- */ hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) ); OGR_F_SetFID(hFeat, nRasterID); OGR_F_SetFieldString(hFeat, 0, osSourceName); OGR_F_SetFieldInteger(hFeat, 1, nTileId ++); OGR_F_SetFieldInteger(hFeat, 2, nReqXSize); OGR_F_SetFieldInteger(hFeat, 3, nReqYSize); OGR_F_SetFieldDouble(hFeat, 4, dfXResolution); OGR_F_SetFieldDouble(hFeat, 5, dfYResolution); double minx, maxx, maxy, miny; minx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff) * dfXResolution; maxx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff + nReqXSize) * dfXResolution; maxy = adfGeoTransform[3] + (nBlockYSize * nBlockYOff) * (-dfYResolution); miny = adfGeoTransform[3] + (nBlockYSize * nBlockYOff + nReqYSize) * (-dfYResolution); OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon); OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddGeometryDirectly(hRectangle, hLinearRing); OGR_F_SetGeometryDirectly(hFeat, hRectangle); OGR_L_CreateFeature(hMetadataLayer, hFeat); OGR_F_Destroy(hFeat); nBlocks++; if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks, NULL, pProgressData)) eErr = CE_Failure; } } nLimitOvrCount = -1; if (eErr == CE_None) OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL); else OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL); VSIFree(pabyMEMDSBuffer); /* -------------------------------------------------------------------- */ /* Update raster_pyramids table */ /* -------------------------------------------------------------------- */ if (eErr == CE_None) { OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids"); if (hRasterPyramidsLyr == NULL) { osSQL.Printf ("CREATE TABLE raster_pyramids (" "table_prefix TEXT NOT NULL," "pixel_x_size DOUBLE NOT NULL," "pixel_y_size DOUBLE NOT NULL," "tile_count INTEGER NOT NULL)"); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); /* Re-open the DB to take into account the new tables*/ OGRReleaseDataSource(hDS); CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE"); CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE"); hDS = OGROpen(osFileName.c_str(), TRUE, NULL); CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str()); } /* Insert base resolution into raster_pyramids if not already done */ int bHasBaseResolution = FALSE; osSQL.Printf("SELECT * FROM raster_pyramids WHERE " "table_prefix = '%s' AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f", osTableName.c_str(), padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15, padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15); hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr); if (hFeat) { bHasBaseResolution = TRUE; OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); } if (!bHasBaseResolution) { osSQL.Printf("SELECT COUNT(*) FROM \"%s\" WHERE " "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f", osMetatadataLayer.c_str(), padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15, padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15); int nBlocksMainRes = 0; hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr); if (hFeat) { nBlocksMainRes = OGR_F_GetFieldAsInteger(hFeat, 0); OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); } osSQL.Printf("INSERT INTO raster_pyramids " "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) " "VALUES ( '%s', %.18f, %.18f, %d )", osTableName.c_str(), padfXResolutions[0], padfYResolutions[0], nBlocksMainRes); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); } osSQL.Printf("INSERT INTO raster_pyramids " "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) " "VALUES ( '%s', %.18f, %.18f, %d )", osTableName.c_str(), dfXResolution, dfYResolution, nTotalBlocks); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); } return eErr; }
int OGRShapeDataSource::OpenFile( const char *pszNewName, int bUpdate, int bTestOpen ) { SHPHandle hSHP; DBFHandle hDBF; const char *pszExtension = CPLGetExtension( pszNewName ); (void) bTestOpen; if( !EQUAL(pszExtension,"shp") && !EQUAL(pszExtension,"shx") && !EQUAL(pszExtension,"dbf") ) return FALSE; /* -------------------------------------------------------------------- */ /* SHPOpen() should include better (CPL based) error reporting, */ /* and we should be trying to distinquish at this point whether */ /* failure is a result of trying to open a non-shapefile, or */ /* whether it was a shapefile and we want to report the error */ /* up. */ /* */ /* Care is taken to suppress the error and only reissue it if */ /* we think it is appropriate. */ /* -------------------------------------------------------------------- */ CPLPushErrorHandler( CPLQuietErrorHandler ); if( bUpdate ) hSHP = DS_SHPOpen( pszNewName, "r+" ); else hSHP = DS_SHPOpen( pszNewName, "r" ); CPLPopErrorHandler(); if( hSHP == NULL && (!EQUAL(CPLGetExtension(pszNewName),"dbf") || strstr(CPLGetLastErrorMsg(),".shp") == NULL) ) { CPLString osMsg = CPLGetLastErrorMsg(); CPLError( CE_Failure, CPLE_OpenFailed, "%s", osMsg.c_str() ); return FALSE; } CPLErrorReset(); /* -------------------------------------------------------------------- */ /* Open the .dbf file, if it exists. To open a dbf file, the */ /* filename has to either refer to a successfully opened shp */ /* file or has to refer to the actual .dbf file. */ /* -------------------------------------------------------------------- */ if( hSHP != NULL || EQUAL(CPLGetExtension(pszNewName),"dbf") ) { if( bUpdate ) { hDBF = DS_DBFOpen( pszNewName, "r+" ); if( hSHP != NULL && hDBF == NULL ) { for(int i=0;i<2;i++) { VSIStatBufL sStat; const char* pszDBFName = CPLResetExtension(pszNewName, (i == 0 ) ? "dbf" : "DBF"); VSILFILE* fp = NULL; if( VSIStatExL( pszDBFName, &sStat, VSI_STAT_EXISTS_FLAG) == 0 ) { fp = VSIFOpenL(pszDBFName, "r+"); if (fp == NULL) { CPLError( CE_Failure, CPLE_OpenFailed, "%s exists, but cannot be opened in update mode", pszDBFName ); SHPClose(hSHP); return FALSE; } VSIFCloseL(fp); break; } } } } else hDBF = DS_DBFOpen( pszNewName, "r" ); } else hDBF = NULL; if( hDBF == NULL && hSHP == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRShapeLayer *poLayer; poLayer = new OGRShapeLayer( this, pszNewName, hSHP, hDBF, NULL, FALSE, bUpdate, wkbNone ); poLayer->SetModificationDate( CSLFetchNameValue( papszOpenOptions, "DBF_DATE_LAST_UPDATE" ) ); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ AddLayer(poLayer); return TRUE; }
CPLErr RasterliteDataset::ReloadOverviews() { if (nLevel != 0) return CE_Failure; /* -------------------------------------------------------------------- */ /* Fetch resolutions */ /* -------------------------------------------------------------------- */ CPLString osSQL; OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids"); if (hRasterPyramidsLyr) { osSQL.Printf("SELECT pixel_x_size, pixel_y_size " "FROM raster_pyramids WHERE table_prefix = '%s' " "ORDER BY pixel_x_size ASC", osTableName.c_str()); } else { osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size " "FROM \"%s_metadata\" WHERE pixel_x_size != 0 " "ORDER BY pixel_x_size ASC", osTableName.c_str()); } OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr == NULL) { if (hRasterPyramidsLyr == NULL) return CE_Failure; osSQL.Printf("SELECT DISTINCT(pixel_x_size), pixel_y_size " "FROM \"%s_metadata\" WHERE pixel_x_size != 0 " "ORDER BY pixel_x_size ASC", osTableName.c_str()); hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr == NULL) return CE_Failure; } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ int i; for(i=1;i<nResolutions;i++) delete papoOverviews[i-1]; CPLFree(papoOverviews); papoOverviews = NULL; CPLFree(padfXResolutions); padfXResolutions = NULL; CPLFree(padfYResolutions); padfYResolutions = NULL; /* -------------------------------------------------------------------- */ /* Rebuild arrays */ /* -------------------------------------------------------------------- */ nResolutions = OGR_L_GetFeatureCount(hSQLLyr, TRUE); padfXResolutions = (double*)CPLMalloc(sizeof(double) * nResolutions); padfYResolutions = (double*)CPLMalloc(sizeof(double) * nResolutions); i = 0; OGRFeatureH hFeat; while((hFeat = OGR_L_GetNextFeature(hSQLLyr)) != NULL) { padfXResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 0); padfYResolutions[i] = OGR_F_GetFieldAsDouble(hFeat, 1); OGR_F_Destroy(hFeat); i ++; } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); hSQLLyr = NULL; /* -------------------------------------------------------------------- */ /* Add overview levels as internal datasets */ /* -------------------------------------------------------------------- */ if (nResolutions > 1) { CPLString osRasterTableName = osTableName; osRasterTableName += "_rasters"; OGRLayerH hRasterLyr = OGR_DS_GetLayerByName(hDS, osRasterTableName.c_str()); papoOverviews = (RasterliteDataset**) CPLCalloc(nResolutions - 1, sizeof(RasterliteDataset*)); int nLev; for(nLev=1;nLev<nResolutions;nLev++) { int nOvrBands; GDALDataType eOvrDataType; int nBlockXSize, nBlockYSize; if (GetBlockParams(hRasterLyr, nLev, &nOvrBands, &eOvrDataType, &nBlockXSize, &nBlockYSize)) { if (eOvrDataType == GDT_Byte && nOvrBands == 1 && nBands == 3) nOvrBands = 3; papoOverviews[nLev-1] = new RasterliteDataset(this, nLev); int iBand; for(iBand=0;iBand<nBands;iBand++) { papoOverviews[nLev-1]->SetBand(iBand+1, new RasterliteBand(papoOverviews[nLev-1], iBand+1, eOvrDataType, nBlockXSize, nBlockYSize)); } } else { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find block characteristics for overview %d", nLev); papoOverviews[nLev-1] = NULL; } } } return CE_None; }
OGRErr OGRGFTTableLayer::ISetFeature( OGRFeature *poFeature ) { GetLayerDefn(); if (!poDS->IsReadWrite()) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode"); return OGRERR_FAILURE; } if (osTableId.size() == 0) { CPLError(CE_Failure, CPLE_NotSupported, "Cannot set feature to non-created table"); return OGRERR_FAILURE; } if (poDS->GetAccessToken().size() == 0) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in unauthenticated mode"); return OGRERR_FAILURE; } if (poFeature->GetFID() == OGRNullFID) { CPLError( CE_Failure, CPLE_AppDefined, "FID required on features given to SetFeature()." ); return OGRERR_FAILURE; } CPLString osCommand; osCommand += "UPDATE "; osCommand += osTableId; osCommand += " SET "; int iField; int nFieldCount = poFeatureDefn->GetFieldCount(); for(iField = 0; iField < nFieldCount + bHiddenGeometryField; iField++) { if (iField > 0) osCommand += ", "; if (iField == nFieldCount) { osCommand += EscapeAndQuote(GetGeometryColumn()); } else { const char* pszFieldName = poFeatureDefn->GetFieldDefn(iField)->GetNameRef(); osCommand += EscapeAndQuote(pszFieldName); } osCommand += " = "; OGRGeometry* poGeom = poFeature->GetGeometryRef(); if (iGeometryField != iLatitudeField && iField == iGeometryField && (iField == nFieldCount || poGeom != NULL || !poFeature->IsFieldSet( iField ))) { if (poGeom == NULL) osCommand += "''"; else { char* pszKML; if (poGeom->getSpatialReference() != NULL && !poGeom->getSpatialReference()->IsSame(poSRS)) { OGRGeometry* poGeom4326 = poGeom->clone(); poGeom4326->transformTo(poSRS); pszKML = poGeom4326->exportToKML(); delete poGeom4326; } else { pszKML = poGeom->exportToKML(); } osCommand += "'"; osCommand += pszKML; osCommand += "'"; CPLFree(pszKML); } continue; } if( !poFeature->IsFieldSet( iField ) ) { osCommand += "''"; } else { OGRFieldType eType = poFeatureDefn->GetFieldDefn(iField)->GetType(); if (eType != OFTInteger && eType != OFTReal) { CPLString osTmp; const char* pszVal = poFeature->GetFieldAsString(iField); if (!CPLIsUTF8(pszVal, -1)) { static int bFirstTime = TRUE; if (bFirstTime) { bFirstTime = FALSE; CPLError(CE_Warning, CPLE_AppDefined, "%s is not a valid UTF-8 string. Forcing it to ASCII.\n" "This warning won't be issued anymore", pszVal); } else { CPLDebug("OGR", "%s is not a valid UTF-8 string. Forcing it to ASCII", pszVal); } char* pszEscaped = CPLForceToASCII(pszVal, -1, '?'); osTmp = pszEscaped; CPLFree(pszEscaped); pszVal = osTmp.c_str(); } osCommand += EscapeAndQuote(pszVal); } else osCommand += poFeature->GetFieldAsString(iField); } } osCommand += " WHERE ROWID = '"; osCommand += CPLSPrintf(CPL_FRMT_GIB, poFeature->GetFID()); osCommand += "'"; CPLHTTPResult * psResult = poDS->RunSQL(osCommand); if (psResult == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Feature update failed (1)"); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* We expect a response like "affected_rows\n1". */ /* -------------------------------------------------------------------- */ char* pszLine = (char*) psResult->pabyData; if (pszLine == NULL || strncmp(pszLine, "affected_rows\n1\n", 16) != 0 || psResult->pszErrBuf != NULL) { CPLDebug( "GFT", "%s/%s", pszLine ? pszLine : "null", psResult->pszErrBuf ? psResult->pszErrBuf : "null"); CPLError(CE_Failure, CPLE_AppDefined, "Feature update failed (2)"); CPLHTTPDestroyResult(psResult); return OGRERR_FAILURE; } CPLHTTPDestroyResult(psResult); return OGRERR_NONE; }
OGRErr OGRIngresTableLayer::CreateFeature( OGRFeature *poFeature ) { CPLString osCommand; int i, bNeedComma = FALSE; /* -------------------------------------------------------------------- */ /* Form the INSERT command. */ /* -------------------------------------------------------------------- */ osCommand.Printf( "INSERT INTO %s (", poFeatureDefn->GetName() ); /* -------------------------------------------------------------------- */ /* Accumulate fields to be inserted. */ /* -------------------------------------------------------------------- */ if( poFeature->GetGeometryRef() != NULL && osGeomColumn.size() ) { osCommand = osCommand + osGeomColumn + " "; bNeedComma = TRUE; } if( poFeature->GetFID() != OGRNullFID && osFIDColumn.size() ) { if( bNeedComma ) osCommand += ", "; osCommand = osCommand + osFIDColumn + " "; bNeedComma = TRUE; } for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ ) { if( !poFeature->IsFieldSet( i ) ) continue; if( !bNeedComma ) bNeedComma = TRUE; else osCommand += ", "; osCommand = osCommand + poFeatureDefn->GetFieldDefn(i)->GetNameRef(); } osCommand += ") VALUES ("; /* -------------------------------------------------------------------- */ /* Insert the geometry (as a place holder) */ /* -------------------------------------------------------------------- */ CPLString osGeomText; // Set the geometry bNeedComma = FALSE; if( poFeature->GetGeometryRef() != NULL && osGeomColumn.size() ) { bNeedComma = TRUE; OGRErr localErr; if( poDS->IsNewIngres() ) { localErr = PrepareNewStyleGeometry( poFeature->GetGeometryRef(), osGeomText ); } else { localErr = PrepareOldStyleGeometry( poFeature->GetGeometryRef(), osGeomText ); } if( localErr == OGRERR_NONE ) { if( CSLTestBoolean( CPLGetConfigOption( "INGRES_INSERT_SUB", "NO") ) ) { osCommand += " ~V"; } else if( poDS->IsNewIngres() == FALSE ) { osCommand += "'"; osCommand += osGeomText; osCommand += "'"; osGeomText = ""; } else { osCommand += osGeomText; //osGeomText = ""; } } else { osGeomText = ""; osCommand += "NULL"; /* is this sort of empty geometry legal? */ } } /* -------------------------------------------------------------------- */ /* Set the FID */ /* -------------------------------------------------------------------- */ if( poFeature->GetFID() != OGRNullFID && osFIDColumn.size() ) { if( bNeedComma ) osCommand += ", "; osCommand += CPLString().Printf( "%ld ", poFeature->GetFID() ); bNeedComma = TRUE; } /* -------------------------------------------------------------------- */ /* Copy in the attribute values. */ /* -------------------------------------------------------------------- */ for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ ) { if( !poFeature->IsFieldSet( i ) ) continue; if( bNeedComma ) osCommand += ", "; else bNeedComma = TRUE; const char *pszStrValue = poFeature->GetFieldAsString(i); if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTReal && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTBinary ) { int iChar; //We need to quote and escape string fields. osCommand += "'"; for( iChar = 0; pszStrValue[iChar] != '\0'; iChar++ ) { if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTIntegerList && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTRealList && poFeatureDefn->GetFieldDefn(i)->GetWidth() > 0 && iChar == poFeatureDefn->GetFieldDefn(i)->GetWidth() ) { CPLDebug( "INGRES", "Truncated %s field value, it was too long.", poFeatureDefn->GetFieldDefn(i)->GetNameRef() ); break; } if( pszStrValue[iChar] == '\'' ) { osCommand += '\''; osCommand += pszStrValue[iChar]; } else osCommand += pszStrValue[iChar]; } osCommand += "'"; } else if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTBinary ) { int binaryCount = 0; GByte* binaryData = poFeature->GetFieldAsBinary(i, &binaryCount); char* pszHexValue = CPLBinaryToHex( binaryCount, binaryData ); osCommand += "x'"; osCommand += pszHexValue; osCommand += "'"; CPLFree( pszHexValue ); } else { osCommand += pszStrValue; } } osCommand += ")"; /* -------------------------------------------------------------------- */ /* Execute it. */ /* -------------------------------------------------------------------- */ poDS->EstablishActiveLayer( NULL ); OGRIngresStatement oStmt( poDS->GetConn() ); oStmt.bDebug = FALSE; if( osGeomText.size() > 0 && poDS->IsNewIngres() == FALSE ) oStmt.addInputParameter( IIAPI_LVCH_TYPE, osGeomText.size(), (GByte *) osGeomText.c_str() ); if( osGeomText.size() > 0 && poDS->IsNewIngres() == TRUE ) { GByte * pabyWKB; int nSize = poFeature->GetGeometryRef()->WkbSize(); pabyWKB = (GByte *) CPLMalloc(nSize); poFeature->GetGeometryRef()->exportToWkb(wkbNDR, pabyWKB); oStmt.addInputParameter( IIAPI_LBYTE_TYPE, nSize, pabyWKB ); CPLFree(pabyWKB); /* * Test code char * pszWKT; poFeature->GetGeometryRef()->exportToWkt(&pszWKT); oStmt.addInputParameter(IIAPI_LVCH_TYPE, strlen(pszWKT), (GByte *) pszWKT);*/ } if( !oStmt.ExecuteSQL( osCommand ) ) return OGRERR_FAILURE; return OGRERR_NONE; }
/*********************************************************************** * \brief Returns the metadata for this band * * If the metadata is actually stored in band's properties, simply * returns them. Otherwise, it raises a query to fetch metadata * FROM db **********************************************************************/ GBool PostGISRasterRasterBand::GetBandMetadata( GDALDataType * peDataType, GBool * pbHasNoData, double * pdfNoData) { // No need to raise a query if (eDataType != GDT_Unknown) { if (peDataType) *peDataType = eDataType; if (pbHasNoData) *pbHasNoData = bNoDataValueSet; if (pdfNoData) *pdfNoData = dfNoDataValue; return true; } /** * Queries are expensive. So, we only raise them if all parameters * are not null **/ if (!peDataType || !pbHasNoData || !pdfNoData) { return false; } /** * It is safe to assume all the tiles will have the same values for * metadata properties. That was checked during band's construction * (or we simply trusted the user, to avoid expensive checkings). * So, we can limit the results to just one. **/ int nTuples = 0; CPLString osCommand = NULL; PGresult * poResult = NULL; PostGISRasterDataset * poRDS = (PostGISRasterDataset *)poDS; osCommand.Printf("st_bandpixeltype(%s, %d), " "st_bandnodatavalue(%s, %d) is not null, " "st_bandnodatavalue(%s, %d) FROM %s.%s limit 1", pszColumn, nBand, pszColumn, nBand, pszColumn, nBand, pszSchema, pszTable); #ifdef DEBUG_QUERY CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::GetBandMetadata(): Query: %s", osCommand.c_str()); #endif poResult = PQexec(poRDS->poConn, osCommand.c_str()); nTuples = PQntuples(poResult); /* Error getting info FROM database */ if (poResult == NULL || PQresultStatus(poResult) != PGRES_TUPLES_OK || nTuples <= 0) { ReportError(CE_Failure, CPLE_AppDefined, "Error getting band metadata while creating raster " "bands"); CPLDebug("PostGIS_Raster", "PostGISRasterDataset::GetBandMetadata(): %s", PQerrorMessage(poRDS->poConn)); if (poResult) PQclear(poResult); return false; } // Fill band metadata values GBool bSignedByte = false; int nBitsDepth = 8; char* pszDataType = NULL; pszDataType = CPLStrdup(PQgetvalue(poResult, 0, 0)); TranslateDataType(pszDataType, &eDataType, &nBitsDepth, &bSignedByte); // Add pixeltype to image structure domain if (bSignedByte) { SetMetadataItem("PIXELTYPE", "SIGNEDBYTE", "IMAGE_STRUCTURE" ); } // Add NBITS to metadata only for sub-byte types if (nBitsDepth < 8) SetMetadataItem("NBITS", CPLString().Printf( "%d", nBitsDepth ), "IMAGE_STRUCTURE" ); CPLFree(pszDataType); bNoDataValueSet = EQUALN(PQgetvalue(poResult, 0, 1), "t", sizeof(char)); dfNoDataValue = CPLAtof(PQgetvalue(poResult, 0, 2)); // Fill output arguments *peDataType = eDataType; *pbHasNoData = bNoDataValueSet; *pdfNoData = dfNoDataValue; return true; }
/** * \brief Fetch a document from an url and return in a string. * * @param pszURL valid URL recognized by underlying download library (libcurl) * @param papszOptions option list as a NULL-terminated array of strings. May be NULL. * The following options are handled : * <ul> * <li>TIMEOUT=val, where val is in seconds</li> * <li>HEADERS=val, where val is an extra header to use when getting a web page. * For example "Accept: application/x-ogcwkt" * <li>HTTPAUTH=[BASIC/NTLM/GSSNEGOTIATE/ANY] to specify an authentication scheme to use. * <li>USERPWD=userid:password to specify a user and password for authentication * <li>POSTFIELDS=val, where val is a nul-terminated string to be passed to the server * with a POST request. * <li>PROXY=val, to make requests go through a proxy server, where val is of the * form proxy.server.com:port_number * <li>PROXYUSERPWD=val, where val is of the form username:password * <li>CUSTOMREQUEST=val, where val is GET, PUT, POST, DELETE, etc.. (GDAL >= 1.9.0) * </ul> * * Alternatively, if not defined in the papszOptions arguments, the PROXY and * PROXYUSERPWD values are searched in the configuration options named * GDAL_HTTP_PROXY and GDAL_HTTP_PROXYUSERPWD, as proxy configuration belongs * to networking setup and makes more sense at the configuration option level * than at the connection level. * * @return a CPLHTTPResult* structure that must be freed by * CPLHTTPDestroyResult(), or NULL if libcurl support is disabled */ CPLHTTPResult *CPLHTTPFetch( const char *pszURL, char **papszOptions ) { #ifndef HAVE_CURL (void) papszOptions; (void) pszURL; CPLError( CE_Failure, CPLE_NotSupported, "GDAL/OGR not compiled with libcurl support, remote requests not supported." ); return NULL; #else /* -------------------------------------------------------------------- */ /* Are we using a persistent named session? If so, search for */ /* or create it. */ /* */ /* Currently this code does not attempt to protect against */ /* multiple threads asking for the same named session. If that */ /* occurs it will be in use in multiple threads at once which */ /* might have bad consequences depending on what guarantees */ /* libcurl gives - which I have not investigated. */ /* -------------------------------------------------------------------- */ CURL *http_handle = NULL; const char *pszPersistent = CSLFetchNameValue( papszOptions, "PERSISTENT" ); const char *pszClosePersistent = CSLFetchNameValue( papszOptions, "CLOSE_PERSISTENT" ); if (pszPersistent) { CPLString osSessionName = pszPersistent; CPLMutexHolder oHolder( &hSessionMapMutex ); if( oSessionMap.count( osSessionName ) == 0 ) { oSessionMap[osSessionName] = curl_easy_init(); CPLDebug( "HTTP", "Establish persistent session named '%s'.", osSessionName.c_str() ); } http_handle = oSessionMap[osSessionName]; } /* -------------------------------------------------------------------- */ /* Are we requested to close a persistent named session? */ /* -------------------------------------------------------------------- */ else if (pszClosePersistent) { CPLString osSessionName = pszClosePersistent; CPLMutexHolder oHolder( &hSessionMapMutex ); std::map<CPLString,CURL*>::iterator oIter = oSessionMap.find( osSessionName ); if( oIter != oSessionMap.end() ) { curl_easy_cleanup(oIter->second); oSessionMap.erase(oIter); CPLDebug( "HTTP", "Ended persistent session named '%s'.", osSessionName.c_str() ); } else { CPLDebug( "HTTP", "Could not find persistent session named '%s'.", osSessionName.c_str() ); } return NULL; } else http_handle = curl_easy_init(); /* -------------------------------------------------------------------- */ /* Setup the request. */ /* -------------------------------------------------------------------- */ char szCurlErrBuf[CURL_ERROR_SIZE+1]; CPLHTTPResult *psResult; struct curl_slist *headers=NULL; const char* pszArobase = strchr(pszURL, '@'); const char* pszSlash = strchr(pszURL, '/'); const char* pszColon = (pszSlash) ? strchr(pszSlash, ':') : NULL; if (pszArobase != NULL && pszColon != NULL && pszArobase - pszColon > 0) { /* http://user:[email protected] */ char* pszSanitizedURL = CPLStrdup(pszURL); pszSanitizedURL[pszColon-pszURL] = 0; CPLDebug( "HTTP", "Fetch(%s:#password#%s)", pszSanitizedURL, pszArobase ); CPLFree(pszSanitizedURL); } else { CPLDebug( "HTTP", "Fetch(%s)", pszURL ); } psResult = (CPLHTTPResult *) CPLCalloc(1,sizeof(CPLHTTPResult)); curl_easy_setopt(http_handle, CURLOPT_URL, pszURL ); if (CSLTestBoolean(CPLGetConfigOption("CPL_CURL_VERBOSE", "NO"))) curl_easy_setopt(http_handle, CURLOPT_VERBOSE, 1); const char *pszHttpVersion = CSLFetchNameValue( papszOptions, "HTTP_VERSION"); if( pszHttpVersion && strcmp(pszHttpVersion, "1.0") == 0 ) curl_easy_setopt(http_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 ); /* Support control over HTTPAUTH */ const char *pszHttpAuth = CSLFetchNameValue( papszOptions, "HTTPAUTH" ); if( pszHttpAuth == NULL ) /* do nothing */; /* CURLOPT_HTTPAUTH is defined in curl 7.11.0 or newer */ #if LIBCURL_VERSION_NUM >= 0x70B00 else if( EQUAL(pszHttpAuth,"BASIC") ) curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ); else if( EQUAL(pszHttpAuth,"NTLM") ) curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_NTLM ); else if( EQUAL(pszHttpAuth,"ANY") ) curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY ); #ifdef CURLAUTH_GSSNEGOTIATE else if( EQUAL(pszHttpAuth,"NEGOTIATE") ) curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_GSSNEGOTIATE ); #endif else { CPLError( CE_Warning, CPLE_AppDefined, "Unsupported HTTPAUTH value '%s', ignored.", pszHttpAuth ); } #else else {
/***************************************************** * \brief Write a natural block of raster band data *****************************************************/ CPLErr PostGISRasterRasterBand::IWriteBlock(int nBlockXOff, int nBlockYOff, void * pImage) { int nPixelSize = GDALGetDataTypeSize(eDataType) / 8; int nNaturalBlockXSize = 0; int nNaturalBlockYSize = 0; int nDataSize = 0; int nBandMetaDataSize = 0; PostGISRasterDataset * poRDS = (PostGISRasterDataset *)poDS; CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock(): Table %s.%s (%s), Srid : %d", pszSchema, pszTable, pszColumn,poRDS->nSrid); // How much data are we going to copy? GetBlockSize(&nNaturalBlockXSize, &nNaturalBlockYSize); nDataSize = nNaturalBlockXSize * nNaturalBlockYSize * nPixelSize; // Allocating space for band metadata nBandMetaDataSize = (nPixelSize + 1); char * pszBandMetadata = (char*) VSIMalloc2(2 * nBandMetaDataSize, sizeof (char)); // Allocate memory for all bands data, if needed if (!poRDS->pBufferToInsert) { CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock(); " "Allocating memory for buffer to hold insert query data (%d characters)", 2 * (nDataSize + nBandMetaDataSize) * poRDS->nBandsToCopy); poRDS->pBufferToInsert = (char *)VSIMalloc3(poRDS->nBandsToCopy, 2 * (nDataSize + nBandMetaDataSize), sizeof(char)); poRDS->nPosToCopy = 0; poRDS->nBandsCopied = 0; } CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock(): Block (%d x %d), Metadata %d. We are " "copying %d bytes", nNaturalBlockXSize, nNaturalBlockYSize, nBandMetaDataSize, nDataSize+nBandMetaDataSize); /** * Copy the band data into the dataset buffer. We will raise the query * after we have the data of all bands in the buffer. * * NOTE: At this point, datatype translation between src and dst has been * performed by IRasterIO. So, we can use band datatype for both, origin * and destination buffers. **/ // GDALCopyWords(pImage, eDataType, 0, // poRDS->pBufferToInsert + poRDS->nPosToCopy, eDataType, 0, nDataSize); char cPostGISQueryWKT = TranslateDataTypeGDALtoPostGIS(&eDataType); if(cPostGISQueryWKT == '\0'){ CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock(): PostGIS Datatype id : %c", cPostGISQueryWKT); return CE_Failure; } CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock(): HasNoDataValue = %s, NoDataValue = %f", bNoDataValueSet? "True" : "False", dfNoDataValue); /* Testing bNoDataValueSet :: Hack */ // bNoDataValueSet = 1; // dfNoDataValue = 0; if(bNoDataValueSet) pszBandMetadata[0] = '4'; else pszBandMetadata[0] = '0'; pszBandMetadata[1] = cPostGISQueryWKT; strcpy(pszBandMetadata + 2, CPLBinaryToHex(nPixelSize,(GByte *)&dfNoDataValue)); memcpy(poRDS->pBufferToInsert + poRDS->nPosToCopy, pszBandMetadata, nBandMetaDataSize * 2); poRDS->nPosToCopy += nBandMetaDataSize * 2; memcpy(poRDS->pBufferToInsert + poRDS->nPosToCopy, CPLBinaryToHex(nDataSize,(GByte *)pImage), nDataSize * 2); poRDS->nPosToCopy += nDataSize * 2; poRDS->pBufferToInsert[poRDS->nPosToCopy] = '\0'; poRDS->nBandsCopied++; // Check if we're done, to raise the insert query if (poRDS->nBandsToCopy == poRDS->nBandsCopied) { PGresult * poResult = NULL; CPLString osCommand; /* // hack pszSchema = "public"; pszTable = "newtable"; pszColumn = "rast"; */ // Raise insert query // TODO: The table may contain more fields // FIXME: For some reason, pszSchema, pszTable and pszColumn are NULL. // I think it's related with the fact we overwrote GDALDataset::IRasterIO, // and we delegate in default implementation. Here, poDS is a simple // GDALDataset *, not a PostGISRasterDataset * // FIXME: anyway, even hardcoding schema/table/column names here, we // still have an error: // ERROR: rt_raster_from_wkb: WKB version 10091 unsupported // This is caused because we're not correctly creating the hex string // representing PostGIS Raster. Version should be 0, and number 10091 // is being read instead. We're not including headers in the hex string, // just raster data. Need to fix this. osCommand.Printf("insert into %s.%s (%s) values('010000",pszSchema, pszTable, pszColumn); osCommand += CPLSPrintf("%s",CPLBinaryToHex(2, (GByte*)&poRDS->nBandsToCopy)); osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_WE_RES])); osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_NS_RES])); osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_X])); osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_Y])); osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_ROTATION_PARAM1])); osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_ROTATION_PARAM2])); osCommand += CPLSPrintf("%s",CPLBinaryToHex(4, (GByte*)&poRDS->nSrid)); osCommand += CPLSPrintf("%s",CPLBinaryToHex(2, (GByte*)&nNaturalBlockXSize)); osCommand += CPLSPrintf("%s",CPLBinaryToHex(2, (GByte*)&nNaturalBlockYSize)); osCommand += poRDS->pBufferToInsert; osCommand += "'::raster)"; CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock: Insert " "query raised: %s", osCommand.c_str()); poResult = PQexec(poRDS->poConn, osCommand.c_str()); if (poResult == NULL || PQresultStatus(poResult) != PGRES_COMMAND_OK) { CPLError(CE_Failure, CPLE_AppDefined, "Error inserting raster data in %s.%s: %s", pszSchema, pszTable, PQerrorMessage(poRDS->poConn)); if (poResult != NULL) PQclear(poResult); // rollback poResult = PQexec(poRDS->poConn, "rollback"); if (poResult == NULL || PQresultStatus(poResult) != PGRES_COMMAND_OK) { CPLError(CE_Failure, CPLE_AppDefined, "Error rolling back transaction: %s", PQerrorMessage(poRDS->poConn)); } if (poResult != NULL) PQclear(poResult); } // Release memory VSIFree(poRDS->pBufferToInsert); poRDS->pBufferToInsert = NULL; } return CE_None; }
const char* E00GRIDDataset::GetProjectionRef() { ReadMetadata(); return osProjection.c_str(); }
int OGRGFTResultLayer::RunSQL() { CPLString osChangedSQL(osSQL); int bHasSetLimit = FALSE; OGRGFTTableLayer* poTableLayer = NULL; OGRFeatureDefn* poTableDefn = NULL; CPLString osTableId; if (EQUALN(osSQL.c_str(), "SELECT", 6)) { size_t nPosFROM = osSQL.ifind(" FROM "); if (nPosFROM == std::string::npos) { CPLError(CE_Failure, CPLE_AppDefined, "RunSQL() failed. Missing FROM in SELECT"); return FALSE; } CPLString osReminder; nPosFROM += 6; osTableId = OGRGFTExtractTableID(osSQL.c_str() + nPosFROM, osReminder); poTableLayer = (OGRGFTTableLayer*) poDS->GetLayerByName(osTableId); if (poTableLayer != NULL) poTableDefn = poTableLayer->GetLayerDefn(); if (poTableLayer != NULL && poTableLayer->GetTableId().size() && !EQUAL(osTableId, poTableLayer->GetTableId())) { osChangedSQL = osSQL; osChangedSQL.resize(nPosFROM); osChangedSQL += poTableLayer->GetTableId(); osChangedSQL += osReminder; osSQL = osChangedSQL; CPLDebug("GFT", "Patching table name (%s) to table id (%s)", osTableId.c_str(), poTableLayer->GetTableId().c_str()); } int nFeaturesToFetch = GetFeaturesToFetch(); if (osSQL.ifind(" OFFSET ") == std::string::npos && osSQL.ifind(" LIMIT ") == std::string::npos && nFeaturesToFetch > 0) { osChangedSQL += CPLSPrintf(" LIMIT %d", nFeaturesToFetch); bHasSetLimit = TRUE; } } else { bGotAllRows = bEOF = TRUE; poFeatureDefn->SetGeomType( wkbNone ); } CPLHTTPResult * psResult = poDS->RunSQL(osChangedSQL); if (psResult == NULL) return FALSE; char* pszLine = (char*) psResult->pabyData; if (pszLine == NULL || psResult->pszErrBuf != NULL) { CPLError(CE_Failure, CPLE_AppDefined, "RunSQL() failed"); CPLHTTPDestroyResult(psResult); return FALSE; } if (EQUALN(osSQL.c_str(), "SELECT", 6) || EQUAL(osSQL.c_str(), "SHOW TABLES") || EQUALN(osSQL.c_str(), "DESCRIBE", 8)) { ParseCSVResponse(pszLine, aosRows); if (aosRows.size() > 0) { char** papszTokens = OGRGFTCSVSplitLine(aosRows[0], ','); for(int i=0;papszTokens && papszTokens[i];i++) { CPLString osLaunderedColName(LaunderColName(papszTokens[i])); int iIndex = (poTableDefn) ? poTableDefn->GetFieldIndex(osLaunderedColName) : -1; if (iIndex >= 0) { poFeatureDefn->AddFieldDefn(poTableDefn->GetFieldDefn(iIndex)); if (iIndex == poTableLayer->GetGeometryFieldIndex()) iGeometryField = i; if (iIndex == poTableLayer->GetLatitudeFieldIndex()) iLatitudeField = i; if (iIndex == poTableLayer->GetLongitudeFieldIndex()) iLongitudeField = i; } else { OGRFieldType eType = OFTString; if (EQUAL(osLaunderedColName, "COUNT()")) eType = OFTInteger; OGRFieldDefn oFieldDefn(osLaunderedColName, eType); poFeatureDefn->AddFieldDefn(&oFieldDefn); } } CSLDestroy(papszTokens); aosRows.erase(aosRows.begin()); } if (iLatitudeField >= 0 && iLongitudeField >= 0) { iGeometryField = iLatitudeField; poFeatureDefn->SetGeomType( wkbPoint ); } if (bHasSetLimit) bGotAllRows = bEOF = (int)aosRows.size() < GetFeaturesToFetch(); else bGotAllRows = bEOF = TRUE; } SetGeomFieldName(); CPLHTTPDestroyResult(psResult); return TRUE; }
OGRCSVLayer::OGRCSVLayer( const char *pszLayerNameIn, VSILFILE * fp, const char *pszFilename, int bNew, int bInWriteMode, char chDelimiter, const char* pszNfdcGeomField, const char* pszGeonamesGeomFieldPrefix) { fpCSV = fp; iWktGeomReadField = -1; iNfdcLatitudeS = iNfdcLongitudeS = -1; iLatitudeField = iLongitudeField = -1; this->bInWriteMode = bInWriteMode; this->bNew = bNew; this->pszFilename = CPLStrdup(pszFilename); this->chDelimiter = chDelimiter; bFirstFeatureAppendedDuringSession = TRUE; bUseCRLF = FALSE; bNeedRewindBeforeRead = FALSE; eGeometryFormat = OGR_CSV_GEOM_NONE; nNextFID = 1; poFeatureDefn = new OGRFeatureDefn( pszLayerNameIn ); poFeatureDefn->Reference(); poFeatureDefn->SetGeomType( wkbNone ); bCreateCSVT = FALSE; bDontHonourStrings = FALSE; bWriteBOM = FALSE; bIsEurostatTSV = FALSE; nEurostatDims = 0; nTotalFeatures = -1; /* -------------------------------------------------------------------- */ /* If this is not a new file, read ahead to establish if it is */ /* already in CRLF (DOS) mode, or just a normal unix CR mode. */ /* -------------------------------------------------------------------- */ if( !bNew && bInWriteMode ) { int nBytesRead = 0; char chNewByte; while( nBytesRead < 10000 && VSIFReadL( &chNewByte, 1, 1, fpCSV ) == 1 ) { if( chNewByte == 13 ) { bUseCRLF = TRUE; break; } nBytesRead ++; } VSIRewindL( fpCSV ); } /* -------------------------------------------------------------------- */ /* Check if the first record seems to be field definitions or */ /* not. We assume it is field definitions if none of the */ /* values are strictly numeric. */ /* -------------------------------------------------------------------- */ char **papszTokens = NULL; int nFieldCount=0, iField; CPLValueType eType; if( !bNew ) { const char *pszLine = NULL; char szDelimiter[2]; szDelimiter[0] = chDelimiter; szDelimiter[1] = '\0'; pszLine = CPLReadLineL( fpCSV ); if ( pszLine != NULL ) { /* Detect and remove UTF-8 BOM marker if found (#4623) */ if (pszLine[0] == (char)0xEF && pszLine[1] == (char)0xBB && pszLine[2] == (char)0xBF) { pszLine += 3; } /* tokenize the strings and preserve quotes, so we can separate string from numeric */ /* this is only used in the test for bHasFeldNames (bug #4361) */ papszTokens = CSLTokenizeString2( pszLine, szDelimiter, (CSLT_HONOURSTRINGS | CSLT_ALLOWEMPTYTOKENS | CSLT_PRESERVEQUOTES) ); nFieldCount = CSLCount( papszTokens ); bHasFieldNames = TRUE; for( iField = 0; iField < nFieldCount && bHasFieldNames; iField++ ) { eType = CPLGetValueType(papszTokens[iField]); if ( (eType == CPL_VALUE_INTEGER || eType == CPL_VALUE_REAL) ) { /* we have a numeric field, therefore do not consider the first line as field names */ bHasFieldNames = FALSE; } } CPLString osExt = OGRCSVDataSource::GetRealExtension(pszFilename); /* Eurostat .tsv files */ if( EQUAL(osExt, "tsv") && nFieldCount > 1 && strchr(papszTokens[0], ',') != NULL && strchr(papszTokens[0], '\\') != NULL ) { bHasFieldNames = TRUE; bIsEurostatTSV = TRUE; } /* tokenize without quotes to get the actual values */ CSLDestroy( papszTokens ); // papszTokens = OGRCSVReadParseLineL( fpCSV, chDelimiter, FALSE ); papszTokens = CSLTokenizeString2( pszLine, szDelimiter, (CSLT_HONOURSTRINGS | CSLT_ALLOWEMPTYTOKENS)); nFieldCount = CSLCount( papszTokens ); } } else bHasFieldNames = FALSE; if( !bNew && !bHasFieldNames ) VSIRewindL( fpCSV ); /* -------------------------------------------------------------------- */ /* Check for geonames.org tables */ /* -------------------------------------------------------------------- */ if( !bHasFieldNames && nFieldCount == 19 ) { if (CPLGetValueType(papszTokens[0]) == CPL_VALUE_INTEGER && CPLGetValueType(papszTokens[4]) == CPL_VALUE_REAL && CPLGetValueType(papszTokens[5]) == CPL_VALUE_REAL && CPLAtof(papszTokens[4]) >= -90 && CPLAtof(papszTokens[4]) <= 90 && CPLAtof(papszTokens[5]) >= -180 && CPLAtof(papszTokens[4]) <= 180) { bHasFieldNames = TRUE; CSLDestroy(papszTokens); papszTokens = NULL; static const struct { const char* pszName; OGRFieldType eType; } asGeonamesFieldDesc[] = { { "GEONAMEID", OFTString }, { "NAME", OFTString }, { "ASCIINAME", OFTString }, { "ALTNAMES", OFTString }, { "LATITUDE", OFTReal }, { "LONGITUDE", OFTReal }, { "FEATCLASS", OFTString }, { "FEATCODE", OFTString }, { "COUNTRY", OFTString }, { "CC2", OFTString }, { "ADMIN1", OFTString }, { "ADMIN2", OFTString }, { "ADMIN3", OFTString }, { "ADMIN4", OFTString }, { "POPULATION", OFTReal }, { "ELEVATION", OFTInteger }, { "GTOPO30", OFTInteger }, { "TIMEZONE", OFTString }, { "MODDATE", OFTString } }; for(iField = 0; iField < nFieldCount; iField++) { OGRFieldDefn oFieldDefn(asGeonamesFieldDesc[iField].pszName, asGeonamesFieldDesc[iField].eType); poFeatureDefn->AddFieldDefn(&oFieldDefn); } iLatitudeField = 4; iLongitudeField = 5; nFieldCount = 0; } } /* -------------------------------------------------------------------- */ /* Search a csvt file for types */ /* -------------------------------------------------------------------- */ char** papszFieldTypes = NULL; if (!bNew) { char* dname = strdup(CPLGetDirname(pszFilename)); char* fname = strdup(CPLGetBasename(pszFilename)); VSILFILE* fpCSVT = VSIFOpenL(CPLFormFilename(dname, fname, ".csvt"), "r"); free(dname); free(fname); if (fpCSVT!=NULL) { VSIRewindL(fpCSVT); papszFieldTypes = OGRCSVReadParseLineL(fpCSVT, ',', FALSE); VSIFCloseL(fpCSVT); } } /* -------------------------------------------------------------------- */ /* Build field definitions. */ /* -------------------------------------------------------------------- */ for( iField = 0; !bIsEurostatTSV && iField < nFieldCount; iField++ ) { char *pszFieldName = NULL; char szFieldNameBuffer[100]; if( bHasFieldNames ) { pszFieldName = papszTokens[iField]; // trim white space. while( *pszFieldName == ' ' ) pszFieldName++; while( pszFieldName[0] != '\0' && pszFieldName[strlen(pszFieldName)-1] == ' ' ) pszFieldName[strlen(pszFieldName)-1] = '\0'; if (*pszFieldName == '\0') pszFieldName = NULL; } if (pszFieldName == NULL) { /* Re-read single column CSV files that have a trailing comma */ /* in the header line */ if( iField == 1 && nFieldCount == 2 && papszTokens[1][0] == '\0' ) { nFieldCount = 1; break; } pszFieldName = szFieldNameBuffer; sprintf( szFieldNameBuffer, "field_%d", iField+1 ); } OGRFieldDefn oField(pszFieldName, OFTString); if (papszFieldTypes!=NULL && iField<CSLCount(papszFieldTypes)) { char* pszLeftParenthesis = strchr(papszFieldTypes[iField], '('); if (pszLeftParenthesis && pszLeftParenthesis != papszFieldTypes[iField] && pszLeftParenthesis[1] >= '0' && pszLeftParenthesis[1] <= '9') { int nWidth = 0; int nPrecision = 0; char* pszDot = strchr(pszLeftParenthesis, '.'); if (pszDot) *pszDot = 0; *pszLeftParenthesis = 0; if (pszLeftParenthesis[-1] == ' ') pszLeftParenthesis[-1] = 0; nWidth = atoi(pszLeftParenthesis+1); if (pszDot) nPrecision = atoi(pszDot+1); oField.SetWidth(nWidth); oField.SetPrecision(nPrecision); } if (EQUAL(papszFieldTypes[iField], "Integer")) oField.SetType(OFTInteger); else if (EQUAL(papszFieldTypes[iField], "Real")) oField.SetType(OFTReal); else if (EQUAL(papszFieldTypes[iField], "String")) oField.SetType(OFTString); else if (EQUAL(papszFieldTypes[iField], "Date")) oField.SetType(OFTDate); else if (EQUAL(papszFieldTypes[iField], "Time")) oField.SetType(OFTTime); else if (EQUAL(papszFieldTypes[iField], "DateTime")) oField.SetType(OFTDateTime); else CPLError(CE_Warning, CPLE_NotSupported, "Unknown type : %s", papszFieldTypes[iField]); } if( EQUAL(oField.GetNameRef(),"WKT") && oField.GetType() == OFTString && iWktGeomReadField == -1 ) { iWktGeomReadField = iField; poFeatureDefn->SetGeomType( wkbUnknown ); } /*http://www.faa.gov/airports/airport_safety/airportdata_5010/menu/index.cfm specific */ if ( pszNfdcGeomField != NULL && EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) && EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LatitudeS") ) iNfdcLatitudeS = iField; else if ( pszNfdcGeomField != NULL && EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) && EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LongitudeS") ) iNfdcLongitudeS = iField; /* GNIS specific */ else if ( pszGeonamesGeomFieldPrefix != NULL && EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) && (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LAT_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE")) ) { oField.SetType(OFTReal); iLatitudeField = iField; } else if ( pszGeonamesGeomFieldPrefix != NULL && EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) && (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONG_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE")) ) { oField.SetType(OFTReal); iLongitudeField = iField; } poFeatureDefn->AddFieldDefn( &oField ); } if ( iNfdcLatitudeS != -1 && iNfdcLongitudeS != -1 ) { bDontHonourStrings = TRUE; poFeatureDefn->SetGeomType( wkbPoint ); } else if ( iLatitudeField != -1 && iLongitudeField != -1 ) { poFeatureDefn->SetGeomType( wkbPoint ); } /* -------------------------------------------------------------------- */ /* Build field definitions for Eurostat TSV files. */ /* -------------------------------------------------------------------- */ CPLString osSeqDim; for( iField = 0; bIsEurostatTSV && iField < nFieldCount; iField++ ) { if( iField == 0 ) { char** papszDims = CSLTokenizeString2( papszTokens[0], ",\\", 0 ); nEurostatDims = CSLCount(papszDims) - 1; for(int iSubField = 0; iSubField < nEurostatDims; iSubField++) { OGRFieldDefn oField(papszDims[iSubField], OFTString); poFeatureDefn->AddFieldDefn( &oField ); } osSeqDim = papszDims[nEurostatDims]; CSLDestroy(papszDims); } else { if( papszTokens[iField][0] != '\0' && papszTokens[iField][strlen(papszTokens[iField])-1] == ' ' ) papszTokens[iField][strlen(papszTokens[iField])-1] = '\0'; OGRFieldDefn oField(CPLSPrintf("%s_%s", osSeqDim.c_str(), papszTokens[iField]), OFTReal); poFeatureDefn->AddFieldDefn( &oField ); OGRFieldDefn oField2(CPLSPrintf("%s_%s_flag", osSeqDim.c_str(), papszTokens[iField]), OFTString); poFeatureDefn->AddFieldDefn( &oField2 ); } } /* -------------------------------------------------------------------- */ /* Cleanup. */ /* -------------------------------------------------------------------- */ CSLDestroy( papszTokens ); CSLDestroy( papszFieldTypes ); }
/** * \brief Fetch a document from an url and return in a string. * * @param pszURL valid URL recognized by underlying download library (libcurl) * @param papszOptions option list as a NULL-terminated array of strings. May be NULL. * The following options are handled : * <ul> * <li>TIMEOUT=val, where val is in seconds</li> * <li>HEADERS=val, where val is an extra header to use when getting a web page. * For example "Accept: application/x-ogcwkt" * <li>HTTPAUTH=[BASIC/NTLM/ANY] to specify an authentication scheme to use. * <li>USERPWD=userid:password to specify a user and password for authentication * <li>POSTFIELDS=val, where val is a nul-terminated string to be passed to the server * with a POST request. * <li>PROXY=val, to make requests go through a proxy server, where val is of the * form proxy.server.com:port_number * <li>PROXYUSERPWD=val, where val is of the form username:password * </ul> * * Alternatively, if not defined in the papszOptions arguments, the PROXY and PROXYUSERPWD * values are searched in the configuration options named GDAL_HTTP_PROXY and GDAL_HTTP_PROXYUSERPWD, * as proxy configuration belongs to networking setup and makes more sense at the configuration * option level than at the connection level. * * @return a CPLHTTPResult* structure that must be freed by CPLHTTPDestroyResult(), * or NULL if libcurl support is disabled */ CPLHTTPResult *CPLHTTPFetch( const char *pszURL, char **papszOptions ) { #ifndef HAVE_CURL (void) papszOptions; (void) pszURL; CPLError( CE_Failure, CPLE_NotSupported, "GDAL/OGR not compiled with libcurl support, remote requests not supported." ); return NULL; #else /* -------------------------------------------------------------------- */ /* Are we using a persistent named session? If so, search for */ /* or create it. */ /* */ /* Currently this code does not attempt to protect against */ /* multiple threads asking for the same named session. If that */ /* occurs it will be in use in multiple threads at once which */ /* might have bad consequences depending on what guarantees */ /* libcurl gives - which I have not investigated. */ /* -------------------------------------------------------------------- */ CURL *http_handle = NULL; const char *pszPersistent = CSLFetchNameValue( papszOptions, "PERSISTENT" ); if (pszPersistent) { CPLString osSessionName = pszPersistent; CPLMutexHolder oHolder( &hSessionMapMutex ); if( oSessionMap.count( osSessionName ) == 0 ) { oSessionMap[osSessionName] = curl_easy_init(); CPLDebug( "HTTP", "Establish persistent session named '%s'.", osSessionName.c_str() ); } http_handle = oSessionMap[osSessionName]; } else http_handle = curl_easy_init(); /* -------------------------------------------------------------------- */ /* Setup the request. */ /* -------------------------------------------------------------------- */ char szCurlErrBuf[CURL_ERROR_SIZE+1]; CPLHTTPResult *psResult; struct curl_slist *headers=NULL; CPLDebug( "HTTP", "Fetch(%s)", pszURL ); psResult = (CPLHTTPResult *) CPLCalloc(1,sizeof(CPLHTTPResult)); curl_easy_setopt(http_handle, CURLOPT_URL, pszURL ); const char *pszHttpVersion = CSLFetchNameValue( papszOptions, "HTTP_VERSION"); if( pszHttpVersion && strcmp(pszHttpVersion, "1.0") == 0 ) curl_easy_setopt(http_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 ); /* Support control over HTTPAUTH */ const char *pszHttpAuth = CSLFetchNameValue( papszOptions, "HTTPAUTH" ); if( pszHttpAuth == NULL ) /* do nothing */; /* CURLOPT_HTTPAUTH is defined in curl 7.11.0 or newer */ #if LIBCURL_VERSION_NUM >= 0x70B00 else if( EQUAL(pszHttpAuth,"BASIC") ) curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ); else if( EQUAL(pszHttpAuth,"NTLM") ) curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_NTLM ); else if( EQUAL(pszHttpAuth,"ANY") ) curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY ); else { CPLError( CE_Warning, CPLE_AppDefined, "Unsupported HTTPAUTH value '%s', ignored.", pszHttpAuth ); } #else else {
CPLErr HFAAuxBuildOverviews( const char *pszOvrFilename, GDALDataset *poParentDS, GDALDataset **ppoODS, int nBands, int *panBandList, int nNewOverviews, int *panNewOverviewList, const char *pszResampling, GDALProgressFunc pfnProgress, void *pProgressData ) { /* ==================================================================== */ /* If the .aux file doesn't exist yet then create it now. */ /* ==================================================================== */ if( *ppoODS == NULL ) { GDALDataType eDT = GDT_Unknown; /* -------------------------------------------------------------------- */ /* Determine the band datatype, and verify that all bands are */ /* the same. */ /* -------------------------------------------------------------------- */ int iBand; for( iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBand *poBand = poParentDS->GetRasterBand( panBandList[iBand] ); if( iBand == 0 ) eDT = poBand->GetRasterDataType(); else { if( eDT != poBand->GetRasterDataType() ) { CPLError( CE_Failure, CPLE_NotSupported, "HFAAuxBuildOverviews() doesn't support a mixture of band" " data types." ); return CE_Failure; } } } /* -------------------------------------------------------------------- */ /* Create the HFA (.aux) file. We create it with */ /* COMPRESSED=YES so that no space will be allocated for the */ /* base band. */ /* -------------------------------------------------------------------- */ GDALDriver *poHFADriver = (GDALDriver *) GDALGetDriverByName("HFA"); if (poHFADriver == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "HFA driver is unavailable." ); return CE_Failure; } const char *apszOptions[4] = { "COMPRESSED=YES", "AUX=YES", NULL, NULL }; CPLString osDepFileOpt = "DEPENDENT_FILE="; osDepFileOpt += CPLGetFilename(poParentDS->GetDescription()); apszOptions[2] = osDepFileOpt.c_str(); *ppoODS = poHFADriver->Create( pszOvrFilename, poParentDS->GetRasterXSize(), poParentDS->GetRasterYSize(), poParentDS->GetRasterCount(), eDT, (char **)apszOptions ); if( *ppoODS == NULL ) return CE_Failure; } /* ==================================================================== */ /* Create the layers. We depend on the normal buildoverviews */ /* support for HFA to do this. But we disable the internal */ /* computation of the imagery for these layers. */ /* */ /* We avoid regenerating the new layers here, because if we did */ /* it would use the base layer from the .aux file as the source */ /* data, and that is fake (all invalid tiles). */ /* ==================================================================== */ CPLString oAdjustedResampling = "NO_REGEN:"; oAdjustedResampling += pszResampling; CPLErr eErr = (*ppoODS)->BuildOverviews( oAdjustedResampling, nNewOverviews, panNewOverviewList, nBands, panBandList, pfnProgress, pProgressData ); return eErr; }
GDALDataset* HF2Dataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "HF2 driver does not support source dataset with zero band.\n"); return NULL; } if (nBands != 1) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "HF2 driver only uses the first band of the dataset.\n"); if (bStrict) return NULL; } if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) ) return NULL; /* -------------------------------------------------------------------- */ /* Get source dataset info */ /* -------------------------------------------------------------------- */ int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); double adfGeoTransform[6]; poSrcDS->GetGeoTransform(adfGeoTransform); int bHasGeoTransform = !(adfGeoTransform[0] == 0 && adfGeoTransform[1] == 1 && adfGeoTransform[2] == 0 && adfGeoTransform[3] == 0 && adfGeoTransform[4] == 0 && adfGeoTransform[5] == 1); if (adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0) { CPLError( CE_Failure, CPLE_NotSupported, "HF2 driver does not support CreateCopy() from skewed or rotated dataset.\n"); return NULL; } GDALDataType eSrcDT = poSrcDS->GetRasterBand(1)->GetRasterDataType(); GDALDataType eReqDT; float fVertPres = (float) 0.01; if (eSrcDT == GDT_Byte || eSrcDT == GDT_Int16) { fVertPres = 1; eReqDT = GDT_Int16; } else eReqDT = GDT_Float32; /* -------------------------------------------------------------------- */ /* Read creation options */ /* -------------------------------------------------------------------- */ const char* pszCompressed = CSLFetchNameValue(papszOptions, "COMPRESS"); int bCompress = FALSE; if (pszCompressed) bCompress = CSLTestBoolean(pszCompressed); const char* pszVerticalPrecision = CSLFetchNameValue(papszOptions, "VERTICAL_PRECISION"); if (pszVerticalPrecision) { fVertPres = (float) CPLAtofM(pszVerticalPrecision); if (fVertPres <= 0) { CPLError(CE_Warning, CPLE_AppDefined, "Unsupported value for VERTICAL_PRECISION. Defaulting to 0.01"); fVertPres = (float) 0.01; } if (eReqDT == GDT_Int16 && fVertPres > 1) eReqDT = GDT_Float32; } const char* pszBlockSize = CSLFetchNameValue(papszOptions, "BLOCKSIZE"); int nTileSize = 256; if (pszBlockSize) { nTileSize = atoi(pszBlockSize); if (nTileSize < 8 || nTileSize > 4096) { CPLError(CE_Warning, CPLE_AppDefined, "Unsupported value for BLOCKSIZE. Defaulting to 256"); nTileSize = 256; } } /* -------------------------------------------------------------------- */ /* Parse source dataset georeferencing info */ /* -------------------------------------------------------------------- */ int nExtendedHeaderLen = 0; if (bHasGeoTransform) nExtendedHeaderLen += 58; const char* pszProjectionRef = poSrcDS->GetProjectionRef(); int nDatumCode = -2; int nUTMZone = 0; int bNorth = FALSE; int nEPSGCode = 0; int nExtentUnits = 1; if (pszProjectionRef != NULL && pszProjectionRef[0] != '\0') { OGRSpatialReference oSRS; char* pszTemp = (char*) pszProjectionRef; if (oSRS.importFromWkt(&pszTemp) == OGRERR_NONE) { const char* pszValue = NULL; if( oSRS.GetAuthorityName( "GEOGCS|DATUM" ) != NULL && EQUAL(oSRS.GetAuthorityName( "GEOGCS|DATUM" ),"EPSG") ) nDatumCode = atoi(oSRS.GetAuthorityCode( "GEOGCS|DATUM" )); else if ((pszValue = oSRS.GetAttrValue("GEOGCS|DATUM")) != NULL) { if (strstr(pszValue, "WGS") && strstr(pszValue, "84")) nDatumCode = 6326; } nUTMZone = oSRS.GetUTMZone(&bNorth); } if( oSRS.GetAuthorityName( "PROJCS" ) != NULL && EQUAL(oSRS.GetAuthorityName( "PROJCS" ),"EPSG") ) nEPSGCode = atoi(oSRS.GetAuthorityCode( "PROJCS" )); if( oSRS.IsGeographic() ) { nExtentUnits = 0; } else { double dfLinear = oSRS.GetLinearUnits(); if( ABS(dfLinear - 0.3048) < 0.0000001 ) nExtentUnits = 2; else if( ABS(dfLinear - CPLAtof(SRS_UL_US_FOOT_CONV)) < 0.00000001 ) nExtentUnits = 3; else nExtentUnits = 1; } } if (nDatumCode != -2) nExtendedHeaderLen += 26; if (nUTMZone != 0) nExtendedHeaderLen += 26; if (nEPSGCode) nExtendedHeaderLen += 26; /* -------------------------------------------------------------------- */ /* Create target file */ /* -------------------------------------------------------------------- */ CPLString osFilename; if (bCompress) { osFilename = "/vsigzip/"; osFilename += pszFilename; } else osFilename = pszFilename; VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "wb"); if (fp == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot create %s", pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Write header */ /* -------------------------------------------------------------------- */ VSIFWriteL("HF2\0", 4, 1, fp); WriteShort(fp, 0); WriteInt(fp, nXSize); WriteInt(fp, nYSize); WriteShort(fp, (GInt16) nTileSize); WriteFloat(fp, fVertPres); float fHorizScale = (float) ((fabs(adfGeoTransform[1]) + fabs(adfGeoTransform[5])) / 2); WriteFloat(fp, fHorizScale); WriteInt(fp, nExtendedHeaderLen); /* -------------------------------------------------------------------- */ /* Write extended header */ /* -------------------------------------------------------------------- */ char szBlockName[16 + 1]; if (bHasGeoTransform) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-extents"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 34); WriteShort(fp, (GInt16) nExtentUnits); WriteDouble(fp, adfGeoTransform[0]); WriteDouble(fp, adfGeoTransform[0] + nXSize * adfGeoTransform[1]); WriteDouble(fp, adfGeoTransform[3] + nYSize * adfGeoTransform[5]); WriteDouble(fp, adfGeoTransform[3]); } if (nUTMZone != 0) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-utm"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) ((bNorth) ? nUTMZone : -nUTMZone)); } if (nDatumCode != -2) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-datum"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) nDatumCode); } if (nEPSGCode != 0) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-epsg-prj"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) nEPSGCode); } /* -------------------------------------------------------------------- */ /* Copy imagery */ /* -------------------------------------------------------------------- */ int nXBlocks = (nXSize + nTileSize - 1) / nTileSize; int nYBlocks = (nYSize + nTileSize - 1) / nTileSize; void* pTileBuffer = (void*) VSIMalloc(nTileSize * nTileSize * (GDALGetDataTypeSize(eReqDT) / 8)); if (pTileBuffer == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory"); VSIFCloseL(fp); return NULL; } int i, j, k, l; CPLErr eErr = CE_None; for(j=0;j<nYBlocks && eErr == CE_None;j++) { for(i=0;i<nXBlocks && eErr == CE_None;i++) { int nReqXSize = MIN(nTileSize, nXSize - i * nTileSize); int nReqYSize = MIN(nTileSize, nYSize - j * nTileSize); eErr = poSrcDS->GetRasterBand(1)->RasterIO(GF_Read, i * nTileSize, MAX(0, nYSize - (j + 1) * nTileSize), nReqXSize, nReqYSize, pTileBuffer, nReqXSize, nReqYSize, eReqDT, 0, 0, NULL); if (eErr != CE_None) break; if (eReqDT == GDT_Int16) { WriteFloat(fp, 1); /* scale */ WriteFloat(fp, 0); /* offset */ for(k=0;k<nReqYSize;k++) { int nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; GByte nWordSize = 1; for(l=1;l<nReqXSize;l++) { int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; int nDiff = nVal - nLastVal; if (nDiff < -32768 || nDiff > 32767) { nWordSize = 4; break; } if (nDiff < -128 || nDiff > 127) nWordSize = 2; nLastVal = nVal; } VSIFWriteL(&nWordSize, 1, 1, fp); nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; WriteInt(fp, nLastVal); for(l=1;l<nReqXSize;l++) { int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; int nDiff = nVal - nLastVal; if (nWordSize == 1) { CPLAssert(nDiff >= -128 && nDiff <= 127); signed char chDiff = (signed char)nDiff; VSIFWriteL(&chDiff, 1, 1, fp); } else if (nWordSize == 2) { CPLAssert(nDiff >= -32768 && nDiff <= 32767); WriteShort(fp, (short)nDiff); } else { WriteInt(fp, nDiff); } nLastVal = nVal; } } } else { float fMinVal = ((float*)pTileBuffer)[0]; float fMaxVal = fMinVal; for(k=1;k<nReqYSize*nReqXSize;k++) { float fVal = ((float*)pTileBuffer)[k]; if (fVal < fMinVal) fMinVal = fVal; if (fVal > fMaxVal) fMaxVal = fVal; } float fIntRange = (fMaxVal - fMinVal) / fVertPres; float fScale = (fMinVal == fMaxVal) ? 1 : (fMaxVal - fMinVal) / fIntRange; float fOffset = fMinVal; WriteFloat(fp, fScale); /* scale */ WriteFloat(fp, fOffset); /* offset */ for(k=0;k<nReqYSize;k++) { float fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; float fIntLastVal = (fLastVal - fOffset) / fScale; CPLAssert(fIntLastVal >= -2147483648.0f && fIntLastVal <= 2147483647.0f); int nLastVal = (int)fIntLastVal; GByte nWordSize = 1; for(l=1;l<nReqXSize;l++) { float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; float fIntVal = (fVal - fOffset) / fScale; CPLAssert(fIntVal >= -2147483648.0f && fIntVal <= 2147483647.0f); int nVal = (int)fIntVal; int nDiff = nVal - nLastVal; CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff); if (nDiff < -32768 || nDiff > 32767) { nWordSize = 4; break; } if (nDiff < -128 || nDiff > 127) nWordSize = 2; nLastVal = nVal; } VSIFWriteL(&nWordSize, 1, 1, fp); fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; fIntLastVal = (fLastVal - fOffset) / fScale; nLastVal = (int)fIntLastVal; WriteInt(fp, nLastVal); for(l=1;l<nReqXSize;l++) { float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; float fIntVal = (fVal - fOffset) / fScale; int nVal = (int)fIntVal; int nDiff = nVal - nLastVal; CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff); if (nWordSize == 1) { CPLAssert(nDiff >= -128 && nDiff <= 127); signed char chDiff = (signed char)nDiff; VSIFWriteL(&chDiff, 1, 1, fp); } else if (nWordSize == 2) { CPLAssert(nDiff >= -32768 && nDiff <= 32767); WriteShort(fp, (short)nDiff); } else { WriteInt(fp, nDiff); } nLastVal = nVal; } } } if( pfnProgress && !pfnProgress( (j * nXBlocks + i + 1) * 1.0 / (nXBlocks * nYBlocks), NULL, pProgressData ) ) { eErr = CE_Failure; break; } } } CPLFree(pTileBuffer); VSIFCloseL(fp); if (eErr != CE_None) return NULL; return (GDALDataset*) GDALOpen(osFilename.c_str(), GA_ReadOnly); }
int ILI1Reader::ReadTable(CPL_UNUSED const char *layername) { char **tokens = NULL; int ret = TRUE; int warned = FALSE; int geomIdx = -1; OGRFeatureDefn *featureDef = curLayer->GetLayerDefn(); OGRFeature *feature = NULL; bool bFeatureAdded = false; while (ret && (tokens = ReadParseLine()) != NULL) { const char *firsttok = CSLGetField(tokens, 0); if (EQUAL(firsttok, "OBJE")) { if (featureDef->GetFieldCount() == 0 && curLayer->GetFeatureCount() == 0) { CPLError( CE_Warning, CPLE_AppDefined, "No field definition found for table: %s", featureDef->GetName() ); // Model not read - use heuristics. for( int fIndex=1; fIndex<CSLCount(tokens); fIndex++ ) { char szFieldName[32]; snprintf(szFieldName, sizeof(szFieldName), "Field%02d", fIndex); OGRFieldDefn oFieldDefn(szFieldName, OFTString); featureDef->AddFieldDefn(&oFieldDefn); } } //start new feature if( !bFeatureAdded ) delete feature; feature = new OGRFeature(featureDef); for( int fIndex=1, fieldno = 0; fIndex<CSLCount(tokens) && fieldno < featureDef->GetFieldCount(); fIndex++, fieldno++ ) { if (!(tokens[fIndex][0] == codeUndefined && tokens[fIndex][1] == '\0')) { #ifdef DEBUG_VERBOSE CPLDebug( "READ TABLE OGR_ILI", "Setting Field %d (Type %d): %s", fieldno, featureDef->GetFieldDefn(fieldno)->GetType(), tokens[fIndex] ); #endif if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTString) { // Interlis 1 encoding is ISO 8859-1 (Latin1) -> Recode to UTF-8 char* pszRecoded = CPLRecode( tokens[fIndex], CPL_ENC_ISO8859_1, CPL_ENC_UTF8); // Replace space marks for( char* pszString = pszRecoded; *pszString != '\0'; pszString++ ) { if (*pszString == codeBlank) *pszString = ' '; } feature->SetField(fieldno, pszRecoded); CPLFree(pszRecoded); } else { feature->SetField(fieldno, tokens[fIndex]); } if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTReal && fieldno > 0 && featureDef->GetFieldDefn(fieldno-1)->GetType() == OFTReal) { // Check for Point geometry (Coord type). // If there is no ili model read, // we have no chance to detect the // geometry column. CPLString geomfldname = featureDef->GetFieldDefn(fieldno)->GetNameRef(); // Check if name ends with _1. if (geomfldname.size() >= 2 && geomfldname[geomfldname.size()-2] == '_') { geomfldname = geomfldname.substr(0, geomfldname.size()-2); geomIdx = featureDef->GetGeomFieldIndex(geomfldname.c_str()); if (geomIdx == -1) { CPLError( CE_Warning, CPLE_AppDefined, "No matching definition for field '%s' of " "table %s found", geomfldname.c_str(), featureDef->GetName() ); } } else { geomIdx = -1; } if (geomIdx >= 0) { if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint) { // Add Point geometry. OGRPoint *ogrPoint = new OGRPoint( CPLAtof(tokens[fIndex-1]), CPLAtof(tokens[fIndex])); feature->SetGeomFieldDirectly(geomIdx, ogrPoint); } else if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint25D && fieldno > 1 && featureDef->GetFieldDefn(fieldno-2)->GetType() == OFTReal) { // Add 3D Point geometry. OGRPoint *ogrPoint = new OGRPoint( CPLAtof(tokens[fIndex-2]), CPLAtof(tokens[fIndex-1]), CPLAtof(tokens[fIndex]) ); feature->SetGeomFieldDirectly(geomIdx, ogrPoint); } } } } } if (!warned && featureDef->GetFieldCount() != CSLCount(tokens)-1) { CPLError( CE_Warning, CPLE_AppDefined, "Field count of table %s doesn't match. %d declared, " "%d found (e.g. ignored LINEATTR)", featureDef->GetName(), featureDef->GetFieldCount(), CSLCount(tokens) - 1 ); warned = TRUE; } if (feature->GetFieldCount() > 0) { // USE _TID as FID. TODO: respect IDENT field from model. feature->SetFID(feature->GetFieldAsInteger64(0)); } curLayer->AddFeature(feature); bFeatureAdded = true; geomIdx = -1; //Reset } else if (EQUAL(firsttok, "STPT") && feature != NULL) { //Find next non-Point geometry if (geomIdx < 0) geomIdx = 0; while (geomIdx < featureDef->GetGeomFieldCount() && featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint) { geomIdx++; } OGRwkbGeometryType geomType = (geomIdx < featureDef->GetGeomFieldCount()) ? featureDef->GetGeomFieldDefn(geomIdx)->GetType() : wkbNone; if( CSLCount(tokens) >= 3 ) ReadGeom(tokens, geomIdx, geomType, feature); } else if (EQUAL(firsttok, "ELIN")) { // Empty geom. } else if (EQUAL(firsttok, "EDGE") && feature != NULL) { CSLDestroy(tokens); tokens = ReadParseLine(); //STPT //Find next non-Point geometry do { geomIdx++; } while (geomIdx < featureDef->GetGeomFieldCount() && featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint); if( CSLCount(tokens) >= 3 ) ReadGeom(tokens, geomIdx, wkbMultiLineString, feature); } else if (EQUAL(firsttok, "PERI")) { } else if (EQUAL(firsttok, "ETAB")) { CPLDebug( "OGR_ILI", "Total features: " CPL_FRMT_GIB, curLayer->GetFeatureCount() ); CSLDestroy(tokens); if( !bFeatureAdded ) delete feature; return TRUE; } else { CPLError( CE_Warning, CPLE_AppDefined, "Unexpected token: %s", firsttok ); } CSLDestroy(tokens); } if( !bFeatureAdded ) delete feature; return ret; }