bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature ) { feature.setFeatureId( OGR_F_GetFID( fet ) ); feature.initAttributes( mSource->mFields.count() ); feature.setFields( &mSource->mFields ); // allow name-based attribute lookups bool useIntersect = mRequest.flags() & QgsFeatureRequest::ExactIntersect; bool geometryTypeFilter = mSource->mOgrGeometryTypeFilter != wkbUnknown; if ( mFetchGeometry || useIntersect || geometryTypeFilter ) { OGRGeometryH geom = OGR_F_GetGeometryRef( fet ); if ( geom ) { if ( mGeometrySimplifier ) mGeometrySimplifier->simplifyGeometry( geom ); // get the wkb representation int memorySize = OGR_G_WkbSize( geom ); unsigned char *wkb = new unsigned char[memorySize]; OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb ); QgsGeometry* geometry = feature.geometry(); if ( !geometry ) feature.setGeometryAndOwnership( wkb, memorySize ); else geometry->fromWkb( wkb, memorySize ); } if (( useIntersect && ( !feature.geometry() || !feature.geometry()->intersects( mRequest.filterRect() ) ) ) || ( geometryTypeFilter && ( !feature.geometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.geometry()->wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) ) { OGR_F_Destroy( fet ); return false; } } if ( !mFetchGeometry ) { feature.setGeometry( 0 ); } // fetch attributes if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { const QgsAttributeList& attrs = mRequest.subsetOfAttributes(); for ( QgsAttributeList::const_iterator it = attrs.begin(); it != attrs.end(); ++it ) { getFeatureAttribute( fet, feature, *it ); } } else { // all attributes for ( int idx = 0; idx < mSource->mFields.count(); ++idx ) { getFeatureAttribute( fet, feature, idx ); } } return true; }
bool QgsOgrFeatureIterator::fetchFeatureWithId( QgsFeatureId id, QgsFeature &feature ) const { feature.setValid( false ); gdal::ogr_feature_unique_ptr fet; #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0) if ( !QgsOgrProviderUtils::canDriverShareSameDatasetAmongLayers( mSource->mDriverName ) ) { OGRLayerH nextFeatureBelongingLayer; bool found = false; // First pass: try to read from the last feature, in the hope the dataset // returns them in increasing feature id number (and as we use a std::set // for mFilterFids, we get them in increasing number by the iterator) // Second pass: reset before reading for ( int passNumber = 0; passNumber < 2; passNumber++ ) { while ( fet.reset( GDALDatasetGetNextFeature( mConn->ds, &nextFeatureBelongingLayer, nullptr, nullptr, nullptr ) ), fet ) { if ( nextFeatureBelongingLayer == mOgrLayer ) { if ( OGR_F_GetFID( fet.get() ) == FID_TO_NUMBER( id ) ) { found = true; break; } } } if ( found || passNumber == 1 ) { break; } GDALDatasetResetReading( mConn->ds ); } if ( !found ) { return false; } } else #endif { fet.reset( OGR_L_GetFeature( mOgrLayer, FID_TO_NUMBER( id ) ) ); } if ( !fet ) { return false; } if ( !readFeature( std::move( fet ), feature ) ) return false; feature.setValid( true ); geometryToDestinationCrs( feature, mTransform ); return true; }
bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature ) const { feature.setFeatureId( OGR_F_GetFID( fet ) ); feature.initAttributes( mSource->mFields.count() ); feature.setFields( mSource->mFields ); // allow name-based attribute lookups bool useIntersect = mRequest.flags() & QgsFeatureRequest::ExactIntersect; bool geometryTypeFilter = mSource->mOgrGeometryTypeFilter != wkbUnknown; if ( mFetchGeometry || useIntersect || geometryTypeFilter ) { OGRGeometryH geom = OGR_F_GetGeometryRef( fet ); if ( geom ) { feature.setGeometry( QgsOgrUtils::ogrGeometryToQgsGeometry( geom ) ); } else feature.clearGeometry(); if ( mSource->mOgrGeometryTypeFilter == wkbGeometryCollection && geom && wkbFlatten( OGR_G_GetGeometryType( geom ) ) == wkbGeometryCollection ) { // OK } else if (( useIntersect && ( !feature.hasGeometry() || !feature.geometry().intersects( mRequest.filterRect() ) ) ) || ( geometryTypeFilter && ( !feature.hasGeometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.geometry().wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) ) { OGR_F_Destroy( fet ); return false; } } if ( !mFetchGeometry ) { feature.clearGeometry(); } // fetch attributes if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { QgsAttributeList attrs = mRequest.subsetOfAttributes(); for ( QgsAttributeList::const_iterator it = attrs.begin(); it != attrs.end(); ++it ) { getFeatureAttribute( fet, feature, *it ); } } else { // all attributes for ( int idx = 0; idx < mSource->mFields.count(); ++idx ) { getFeatureAttribute( fet, feature, idx ); } } return true; }
bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature ) { feature.setFeatureId( OGR_F_GetFID( fet ) ); feature.initAttributes( P->fields().count() ); feature.setFields( &P->mAttributeFields ); // allow name-based attribute lookups bool fetchGeom = !( mRequest.flags() & QgsFeatureRequest::NoGeometry ); bool useIntersect = mRequest.flags() & QgsFeatureRequest::ExactIntersect; bool geometryTypeFilter = P->mOgrGeometryTypeFilter != wkbUnknown; if ( fetchGeom || useIntersect || geometryTypeFilter ) { OGRGeometryH geom = OGR_F_GetGeometryRef( fet ); if ( geom ) { // get the wkb representation unsigned char *wkb = new unsigned char[OGR_G_WkbSize( geom )]; OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb ); feature.setGeometryAndOwnership( wkb, OGR_G_WkbSize( geom ) ); } if (( useIntersect && ( !feature.geometry() || !feature.geometry()->intersects( mRequest.filterRect() ) ) ) || ( geometryTypeFilter && ( !feature.geometry() || wkbFlatten(( OGRwkbGeometryType )feature.geometry()->wkbType() ) != wkbFlatten( P->mOgrGeometryTypeFilter ) ) ) ) { OGR_F_Destroy( fet ); return false; } } if ( !fetchGeom ) { feature.setGeometry( 0 ); } // fetch attributes if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { const QgsAttributeList& attrs = mRequest.subsetOfAttributes(); for ( QgsAttributeList::const_iterator it = attrs.begin(); it != attrs.end(); ++it ) { getFeatureAttribute( fet, feature, *it ); } } else { // all attributes for ( int idx = 0; idx < P->mAttributeFields.count(); ++idx ) { getFeatureAttribute( fet, feature, idx ); } } return true; }
void QgsOgrFeatureIterator::getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature & f, int attindex ) const { if ( mSource->mFirstFieldIsFid && attindex == 0 ) { f.setAttribute( 0, static_cast<qint64>( OGR_F_GetFID( ogrFet ) ) ); return; } int attindexWithoutFid = ( mSource->mFirstFieldIsFid ) ? attindex - 1 : attindex; bool ok = false; QVariant value = QgsOgrUtils::getOgrFeatureAttribute( ogrFet, mSource->mFieldsWithoutFid, attindexWithoutFid, mSource->mEncoding, &ok ); if ( !ok ) return; f.setAttribute( attindex, value ); }
void QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature ) { feature.setFeatureId( OGR_F_GetFID( fet ) ); feature.initAttributes( P->fields().count() ); feature.setFields( &P->mAttributeFields ); // allow name-based attribute lookups // fetch geometry if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) ) { OGRGeometryH geom = OGR_F_GetGeometryRef( fet ); if ( geom ) { // get the wkb representation unsigned char *wkb = new unsigned char[OGR_G_WkbSize( geom )]; OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb ); feature.setGeometryAndOwnership( wkb, OGR_G_WkbSize( geom ) ); } else { feature.setGeometry( 0 ); } } // fetch attributes if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { const QgsAttributeList& attrs = mRequest.subsetOfAttributes(); for ( QgsAttributeList::const_iterator it = attrs.begin(); it != attrs.end(); ++it ) { getFeatureAttribute( fet, feature, *it ); } } else { // all attributes for ( int idx = 0; idx < P->mAttributeFields.count(); ++idx ) { getFeatureAttribute( fet, feature, idx ); } } }
QgsFeature QgsOgrUtils::readOgrFeature( OGRFeatureH ogrFet, const QgsFields& fields, QTextCodec* encoding ) { QgsFeature feature; if ( !ogrFet ) { feature.setValid( false ); return feature; } feature.setFeatureId( OGR_F_GetFID( ogrFet ) ); feature.setValid( true ); if ( !readOgrFeatureGeometry( ogrFet, feature ) ) { feature.setValid( false ); } if ( !readOgrFeatureAttributes( ogrFet, fields, feature, encoding ) ) { feature.setValid( false ); } return feature; }
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; }
GDALDataset * RasterliteCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError(CE_Failure, CPLE_NotSupported, "nBands == 0"); return NULL; } const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff"); GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName); if ( hTileDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName); return NULL; } GDALDriverH hMemDriver = GDALGetDriverByName("MEM"); if (hMemDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver"); return NULL; } int nXSize = GDALGetRasterXSize(poSrcDS); int nYSize = GDALGetRasterYSize(poSrcDS); double adfGeoTransform[6]; if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None) { adfGeoTransform[0] = 0; adfGeoTransform[1] = 1; adfGeoTransform[2] = 0; adfGeoTransform[3] = 0; adfGeoTransform[4] = 0; adfGeoTransform[5] = -1; } else if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot use geotransform with rotational terms"); return NULL; } int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES")); int nBlockXSize, nBlockYSize; if (bTiled) { nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256")); nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256")); if (nBlockXSize < 64) nBlockXSize = 64; else if (nBlockXSize > 4096) nBlockXSize = 4096; if (nBlockYSize < 64) nBlockYSize = 64; else if (nBlockYSize > 4096) nBlockYSize = 4096; } else { nBlockXSize = nXSize; nBlockYSize = nYSize; } /* -------------------------------------------------------------------- */ /* Analyze arguments */ /* -------------------------------------------------------------------- */ CPLString osDBName; CPLString osTableName; VSIStatBuf sBuf; int bExists; /* Skip optionnal RASTERLITE: prefix */ const char* pszFilenameWithoutPrefix = pszFilename; if (EQUALN(pszFilename, "RASTERLITE:", 11)) pszFilenameWithoutPrefix += 11; char** papszTokens = CSLTokenizeStringComplex( pszFilenameWithoutPrefix, ", ", FALSE, FALSE ); int nTokens = CSLCount(papszTokens); if (nTokens == 0) { osDBName = pszFilenameWithoutPrefix; osTableName = CPLGetBasename(pszFilenameWithoutPrefix); } else { osDBName = papszTokens[0]; int i; for(i=1;i<nTokens;i++) { if (EQUALN(papszTokens[i], "table=", 6)) osTableName = papszTokens[i] + 6; else { CPLError(CE_Warning, CPLE_AppDefined, "Invalid option : %s", papszTokens[i]); } } } CSLDestroy(papszTokens); papszTokens = NULL; bExists = (VSIStat(osDBName.c_str(), &sBuf) == 0); if (osTableName.size() == 0) { if (bExists) { CPLError(CE_Failure, CPLE_AppDefined, "Database already exists. Explicit table name must be specified"); return NULL; } osTableName = CPLGetBasename(osDBName.c_str()); } CPLString osRasterLayer; osRasterLayer.Printf("%s_rasters", osTableName.c_str()); CPLString osMetatadataLayer; osMetatadataLayer.Printf("%s_metadata", osTableName.c_str()); /* -------------------------------------------------------------------- */ /* Create or open the SQLite DB */ /* -------------------------------------------------------------------- */ if (OGRGetDriverCount() == 0) OGRRegisterAll(); OGRSFDriverH hSQLiteDriver = OGRGetDriverByName("SQLite"); if (hSQLiteDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load OGR SQLite driver"); return NULL; } OGRDataSourceH hDS; CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE"); CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE"); if (!bExists) { char** papszOGROptions = CSLAddString(NULL, "SPATIALITE=YES"); hDS = OGR_Dr_CreateDataSource(hSQLiteDriver, osDBName.c_str(), papszOGROptions); CSLDestroy(papszOGROptions); } else { hDS = OGROpen(osDBName.c_str(), TRUE, NULL); } CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str()); if (hDS == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load or create SQLite database"); return NULL; } CPLString osSQL; /* -------------------------------------------------------------------- */ /* Get the SRID for the SRS */ /* -------------------------------------------------------------------- */ int nSRSId = RasterliteInsertSRID(hDS, poSrcDS->GetProjectionRef()); /* -------------------------------------------------------------------- */ /* Create or wipe existing tables */ /* -------------------------------------------------------------------- */ int bWipeExistingData = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WIPE", "NO")); hDS = RasterliteCreateTables(hDS, osTableName.c_str(), nSRSId, bWipeExistingData); if (hDS == NULL) return NULL; OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str()); OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str()); if (hRasterLayer == NULL || hMetadataLayer == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find metadata and/or raster tables"); OGRReleaseDataSource(hDS); return NULL; } /* -------------------------------------------------------------------- */ /* Check if there is overlapping data and warn the user */ /* -------------------------------------------------------------------- */ double minx = adfGeoTransform[0]; double maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1]; double maxy = adfGeoTransform[3]; double miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5]; osSQL.Printf("SELECT COUNT(geometry) FROM \"%s\" " "WHERE rowid IN " "(SELECT pkid FROM \"idx_%s_metadata_geometry\" " "WHERE xmin < %.15f AND xmax > %.15f " "AND ymin < %.15f AND ymax > %.15f) " "AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f", osMetatadataLayer.c_str(), osTableName.c_str(), maxx, minx, maxy, miny, adfGeoTransform[1] - 1e-15, adfGeoTransform[1] + 1e-15, - adfGeoTransform[5] - 1e-15, - adfGeoTransform[5] + 1e-15); int nOverlappingGeoms = 0; OGRLayerH hCountLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hCountLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hCountLyr); if (hFeat) { nOverlappingGeoms = OGR_F_GetFieldAsInteger(hFeat, 0); OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hCountLyr); } if (nOverlappingGeoms != 0) { CPLError(CE_Warning, CPLE_AppDefined, "Raster tiles already exist in the %s table within " "the extent of the data to be inserted in", osTableName.c_str()); } /* -------------------------------------------------------------------- */ /* Iterate over blocks to add data into raster and metadata tables */ /* -------------------------------------------------------------------- */ int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize; GDALDataType eDataType = poSrcDS->GetRasterBand(1)->GetRasterDataType(); int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8; GByte* pabyMEMDSBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize); if (pabyMEMDSBuffer == NULL) { OGRReleaseDataSource(hDS); return NULL; } CPLString osTempFileName; osTempFileName.Printf("/vsimem/%p", hDS); int nTileId = 0; int nBlocks = 0; int nTotalBlocks = nXBlocks * nYBlocks; char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions); 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 > nXSize) nReqXSize = nXSize - nBlockXOff * nBlockXSize; if ((nBlockYOff+1) * nBlockYSize > nYSize) nReqYSize = nYSize - nBlockYOff * nBlockYSize; eErr = poSrcDS->RasterIO(GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nReqXSize, nReqYSize, 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** papszMEMDSOptions = NULL; char szTmp[64]; memset(szTmp, 0, sizeof(szTmp)); CPLPrintPointer(szTmp, pabyMEMDSBuffer + iBand * nDataTypeSize * nReqXSize * nReqYSize, sizeof(szTmp)); papszMEMDSOptions = CSLSetNameValue(papszMEMDSOptions, "DATAPOINTER", szTmp); GDALAddBand(hMemDS, eDataType, papszMEMDSOptions); CSLDestroy(papszMEMDSOptions); } 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, GDALGetDescription(poSrcDS)); OGR_F_SetFieldInteger(hFeat, 1, nTileId ++); OGR_F_SetFieldInteger(hFeat, 2, nReqXSize); OGR_F_SetFieldInteger(hFeat, 3, nReqYSize); OGR_F_SetFieldDouble(hFeat, 4, adfGeoTransform[1]); OGR_F_SetFieldDouble(hFeat, 5, -adfGeoTransform[5]); minx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff) * adfGeoTransform[1]; maxx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff + nReqXSize) * adfGeoTransform[1]; maxy = adfGeoTransform[3] + (nBlockYSize * nBlockYOff) * adfGeoTransform[5]; miny = adfGeoTransform[3] + (nBlockYSize * nBlockYOff + nReqYSize) * adfGeoTransform[5]; 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; } } if (eErr == CE_None) OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL); else OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL); CSLDestroy(papszTileDriverOptions); VSIFree(pabyMEMDSBuffer); OGRReleaseDataSource(hDS); return (GDALDataset*) GDALOpen(pszFilename, GA_Update); }
CPLErr RasterliteDataset::CreateOverviewLevel(const char * pszResampling, int nOvrFactor, char** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData) { double dfXResolution = padfXResolutions[0] * nOvrFactor; double dfYResolution = padfXResolutions[0] * nOvrFactor; CPLString osSQL; int nOvrXSize = nRasterXSize / nOvrFactor; int nOvrYSize = nRasterYSize / nOvrFactor; if (nOvrXSize == 0 || nOvrYSize == 0) return CE_Failure; int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES")); int nBlockXSize, nBlockYSize; if (bTiled) { nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256")); nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256")); if (nBlockXSize < 64) nBlockXSize = 64; else if (nBlockXSize > 4096) nBlockXSize = 4096; if (nBlockYSize < 64) nBlockYSize = 64; else if (nBlockYSize > 4096) nBlockYSize = 4096; } else { nBlockXSize = nOvrXSize; nBlockYSize = nOvrYSize; } int nXBlocks = (nOvrXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nOvrYSize + nBlockYSize - 1) / nBlockYSize; const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff"); if (EQUAL(pszDriverName, "MEM") || EQUAL(pszDriverName, "VRT")) { CPLError(CE_Failure, CPLE_AppDefined, "GDAL %s driver cannot be used as underlying driver", pszDriverName); return CE_Failure; } 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; } 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 " "%s LIMIT 1", osMetatadataLayer.c_str(), RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str()); 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++; } /* -------------------------------------------------------------------- */ /* Allocate buffer for tile of previous overview level */ /* -------------------------------------------------------------------- */ GDALDataset* poPrevOvrLevel = (papoOverviews != NULL && iLev >= 2 && iLev <= nResolutions && papoOverviews[iLev-2]) ? papoOverviews[iLev-2] : this; double dfRatioPrevOvr = poPrevOvrLevel->GetRasterBand(1)->GetXSize() / nOvrXSize; int nPrevOvrBlockXSize = (int)(nBlockXSize * dfRatioPrevOvr + 0.5); int nPrevOvrBlockYSize = (int)(nBlockYSize * dfRatioPrevOvr + 0.5); GByte* pabyPrevOvrMEMDSBuffer = NULL; if( !EQUALN(pszResampling, "NEAR", 4)) { pabyPrevOvrMEMDSBuffer = (GByte*)VSIMalloc3(nPrevOvrBlockXSize, nPrevOvrBlockYSize, nBands * nDataTypeSize); if (pabyPrevOvrMEMDSBuffer == NULL) { VSIFree(pabyMEMDSBuffer); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Iterate over blocks to add data into raster and metadata tables */ /* -------------------------------------------------------------------- */ char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions); 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++) { GDALDatasetH hPrevOvrMemDS = NULL; /* -------------------------------------------------------------------- */ /* 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; if( pabyPrevOvrMEMDSBuffer != NULL ) { int nPrevOvrReqXSize = (int)(nReqXSize * dfRatioPrevOvr + 0.5); int nPrevOvrReqYSize = (int)(nReqYSize * dfRatioPrevOvr + 0.5); eErr = RasterIO(GF_Read, nBlockXOff * nBlockXSize * nOvrFactor, nBlockYOff * nBlockYSize * nOvrFactor, nReqXSize * nOvrFactor, nReqYSize * nOvrFactor, pabyPrevOvrMEMDSBuffer, nPrevOvrReqXSize, nPrevOvrReqYSize, eDataType, nBands, NULL, 0, 0, 0, NULL); if (eErr != CE_None) { break; } hPrevOvrMemDS = GDALCreate(hMemDriver, "MEM:::", nPrevOvrReqXSize, nPrevOvrReqYSize, 0, eDataType, NULL); if (hPrevOvrMemDS == 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, pabyPrevOvrMEMDSBuffer + iBand * nDataTypeSize * nPrevOvrReqXSize * nPrevOvrReqYSize, sizeof(szTmp)); papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp); GDALAddBand(hPrevOvrMemDS, eDataType, papszOptions); CSLDestroy(papszOptions); } } else { eErr = RasterIO(GF_Read, nBlockXOff * nBlockXSize * nOvrFactor, nBlockYOff * nBlockYSize * nOvrFactor, nReqXSize * nOvrFactor, nReqYSize * nOvrFactor, pabyMEMDSBuffer, nReqXSize, nReqYSize, eDataType, nBands, NULL, 0, 0, 0, NULL); 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); } if( hPrevOvrMemDS != NULL ) { for(iBand = 0; iBand < nBands; iBand ++) { GDALRasterBandH hDstOvrBand = GDALGetRasterBand(hMemDS, iBand+1); eErr = GDALRegenerateOverviews( GDALGetRasterBand(hPrevOvrMemDS, iBand+1), 1, &hDstOvrBand, pszResampling, NULL, NULL ); if( eErr != CE_None ) break; } GDALClose(hPrevOvrMemDS); } 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); VSIFree(pabyPrevOvrMEMDSBuffer); CSLDestroy(papszTileDriverOptions); papszTileDriverOptions = NULL; /* -------------------------------------------------------------------- */ /* 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); hDS = RasterliteOpenSQLiteDB(osFileName.c_str(), GA_Update); hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids"); if (hRasterPyramidsLyr == NULL) return CE_Failure; } OGRFeatureDefnH hFDefn = OGR_L_GetLayerDefn(hRasterPyramidsLyr); /* Insert base resolution into raster_pyramids if not already done */ int bHasBaseResolution = FALSE; osSQL.Printf("SELECT * FROM raster_pyramids WHERE " "table_prefix = '%s' AND %s", osTableName.c_str(), RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str()); 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 %s", osMetatadataLayer.c_str(), RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str()); 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); } OGRFeatureH hFeat = OGR_F_Create( hFDefn ); OGR_F_SetFieldString(hFeat, OGR_FD_GetFieldIndex(hFDefn, "table_prefix"), osTableName.c_str()); OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_x_size"), padfXResolutions[0]); OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_y_size"), padfYResolutions[0]); OGR_F_SetFieldInteger(hFeat, OGR_FD_GetFieldIndex(hFDefn, "tile_count"), nBlocksMainRes); OGR_L_CreateFeature(hRasterPyramidsLyr, hFeat); OGR_F_Destroy(hFeat); } OGRFeatureH hFeat = OGR_F_Create( hFDefn ); OGR_F_SetFieldString(hFeat, OGR_FD_GetFieldIndex(hFDefn, "table_prefix"), osTableName.c_str()); OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_x_size"), dfXResolution); OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_y_size"), dfYResolution); OGR_F_SetFieldInteger(hFeat, OGR_FD_GetFieldIndex(hFDefn, "tile_count"), nTotalBlocks); OGR_L_CreateFeature(hRasterPyramidsLyr, hFeat); OGR_F_Destroy(hFeat); } return eErr; }
/*! \brief Read next feature from OGR layer. Skip empty features (level 1) This function implements sequential access. The action of this routine can be modified by: - Vect_read_constraint_region() - Vect_read_constraint_type() - Vect_remove_constraints() \param Map pointer to Map_info structure \param[out] line_p container used to store line points within \param[out] line_c container used to store line categories within \return feature type \return -2 no more features (EOF) \return -1 out of memory */ int V1_read_next_line_ogr(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c) { int itype; struct bound_box lbox, mbox; OGRFeatureH hFeature; OGRGeometryH hGeom; G_debug(3, "V1_read_next_line_ogr()"); if (line_p != NULL) Vect_reset_line(line_p); if (line_c != NULL) Vect_reset_cats(line_c); if (Map->Constraint_region_flag) Vect_get_constraint_box(Map, &mbox); while (TRUE) { /* Read feature to cache if necessary */ while (Map->fInfo.ogr.lines_next == Map->fInfo.ogr.lines_num) { hFeature = OGR_L_GetNextFeature(Map->fInfo.ogr.layer); if (hFeature == NULL) { return -2; } /* no more features */ hGeom = OGR_F_GetGeometryRef(hFeature); if (hGeom == NULL) { /* feature without geometry */ OGR_F_Destroy(hFeature); continue; } Map->fInfo.ogr.feature_cache_id = (int)OGR_F_GetFID(hFeature); if (Map->fInfo.ogr.feature_cache_id == OGRNullFID) { G_warning(_("OGR feature without ID")); } /* Cache the feature */ Map->fInfo.ogr.lines_num = 0; cache_feature(Map, hGeom, -1); G_debug(4, "%d lines read to cache", Map->fInfo.ogr.lines_num); OGR_F_Destroy(hFeature); Map->fInfo.ogr.lines_next = 0; /* next to be read from cache */ } /* Read next part of the feature */ G_debug(4, "read next cached line %d", Map->fInfo.ogr.lines_next); itype = Map->fInfo.ogr.lines_types[Map->fInfo.ogr.lines_next]; /* Constraint on Type of line * Default is all of Point, Line, Area and whatever else comes along */ if (Map->Constraint_type_flag) { if (!(itype & Map->Constraint_type)) { Map->fInfo.ogr.lines_next++; continue; } } /* Constraint on specified region */ if (Map->Constraint_region_flag) { Vect_line_box(Map->fInfo.ogr.lines[Map->fInfo.ogr.lines_next], &lbox); if (!Vect_box_overlap(&lbox, &mbox)) { Map->fInfo.ogr.lines_next++; continue; } } if (line_p != NULL) Vect_append_points(line_p, Map->fInfo.ogr.lines[Map->fInfo.ogr. lines_next], GV_FORWARD); if (line_c != NULL && Map->fInfo.ogr.feature_cache_id != OGRNullFID) Vect_cat_set(line_c, 1, Map->fInfo.ogr.feature_cache_id); Map->fInfo.ogr.lines_next++; G_debug(4, "next line read, type = %d", itype); return itype; } return -2; /* not reached */ }
/*! \brief Writes feature on level 1 (OGR interface) \param Map pointer to Map_info structure \param type feature type \param points pointer to line_pnts structure (feature geometry) \param cats pointer to line_cats structure (feature categories) \return feature offset into file \return -1 on error */ off_t V1_write_line_ogr(struct Map_info *Map, int type, const struct line_pnts *points, const struct line_cats *cats) { int i, cat, ret; struct field_info *Fi; struct Format_info_ogr *fInfo; OGRGeometryH Ogr_geometry; OGRFeatureH Ogr_feature; OGRFeatureDefnH Ogr_featuredefn; OGRwkbGeometryType Ogr_geom_type; if (!Map->fInfo.ogr.layer) { if (V2_open_new_ogr(Map, type) < 0) return -1; } cat = -1; /* no attributes to be written */ if (cats->n_cats > 0) { /* check for attributes */ Fi = Vect_get_dblink(Map, 0); if (Fi) { if (!Vect_cat_get(cats, Fi->number, &cat)) G_warning(_("No category defined for layer %d"), Fi->number); if (cats->n_cats > 1) { G_warning(_("Feature has more categories, using " "category %d (from layer %d)"), cat, cats->field[0]); } } } fInfo = &(Map->fInfo.ogr); Ogr_featuredefn = OGR_L_GetLayerDefn(fInfo->layer); Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn); /* determine matching OGR feature geometry type */ /* NOTE: centroids are not supported in OGR, * pseudotopo holds virtual centroids */ /* NOTE: boundaries are not supported in OGR, * pseudotopo treats polygons as boundaries */ if (type & (GV_POINT | GV_KERNEL)) { if (Ogr_geom_type != wkbPoint && Ogr_geom_type != wkbPoint25D) { G_warning(_("Feature is not a point. Skipping.")); return -1; } Ogr_geometry = OGR_G_CreateGeometry(wkbPoint); } else if (type & GV_LINE) { if (Ogr_geom_type != wkbLineString && Ogr_geom_type != wkbLineString25D) { G_warning(_("Feature is not a line. Skipping.")); return -1; } Ogr_geometry = OGR_G_CreateGeometry(wkbLineString); } else if (type & GV_BOUNDARY) { if (Ogr_geom_type != wkbPolygon) { G_warning(_("Feature is not a polygon. Skipping.")); return -1; } Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon); } else if (type & GV_FACE) { if (Ogr_geom_type != wkbPolygon25D) { G_warning(_("Feature is not a face. Skipping.")); return -1; } Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon25D); } else { G_warning(_("Unsupported feature type (%d)"), type); return -1; } G_debug(3, "V1_write_line_ogr(): type = %d", type); if (Ogr_geom_type == wkbPolygon || Ogr_geom_type == wkbPolygon25D) { /* create exterior ring */ OGRGeometryH Ogr_ring; int npoints; npoints = points->n_points - 1; Ogr_ring = OGR_G_CreateGeometry(wkbLinearRing); if (points->x[0] != points->x[npoints] || points->y[0] != points->y[npoints] || points->z[0] != points->z[npoints]) { G_warning(_("Boundary is not closed. Skipping.")); return -1; } /* add points */ for (i = 0; i < points->n_points; i++) { OGR_G_AddPoint(Ogr_ring, points->x[i], points->y[i], points->z[i]); } OGR_G_AddGeometry(Ogr_geometry, Ogr_ring); } else { for (i = 0; i < points->n_points; i++) { OGR_G_AddPoint(Ogr_geometry, points->x[i], points->y[i], points->z[i]); } } G_debug(4, " n_points = %d", points->n_points); /* create feature & set geometry */ Ogr_feature = OGR_F_Create(Ogr_featuredefn); OGR_F_SetGeometry(Ogr_feature, Ogr_geometry); /* write attributes */ if (cat > -1 && fInfo->dbdriver) { write_attributes(fInfo->dbdriver, cat, Fi, fInfo->layer, Ogr_feature); G_free(Fi); } /* write feature into layer */ ret = OGR_L_CreateFeature(fInfo->layer, Ogr_feature); /* update offset array */ if (fInfo->offset_num >= fInfo->offset_alloc) { fInfo->offset_alloc += 1000; fInfo->offset = (int *) G_realloc(fInfo->offset, fInfo->offset_alloc * sizeof(int)); } /* how to deal with OGRNullFID ? */ fInfo->offset[fInfo->offset_num] = (int)OGR_F_GetFID(Ogr_feature); /* destroy */ OGR_G_DestroyGeometry(Ogr_geometry); OGR_F_Destroy(Ogr_feature); if (ret != OGRERR_NONE) return -1; return fInfo->offset_num++; }
/*! \brief Write OGR feature \param Map pointer to Map_info structure \param type feature type (GV_POINT, GV_LINE, ...) \param bpoints feature geometry \param cats feature categories \param ipoints isle geometry for polygons on NULL \param nisles number of isles \return feature offset into file \return -1 on error */ off_t write_feature(struct Map_info *Map, int type, const struct line_pnts **p_points, int nparts, const struct line_cats *cats) { int i, cat, ret; struct field_info *Fi; const struct line_pnts *points; struct Format_info_ogr *ogr_info; struct Format_info_offset *offset_info; off_t offset; OGRGeometryH Ogr_geometry; OGRFeatureH Ogr_feature; OGRFeatureDefnH Ogr_featuredefn; OGRwkbGeometryType Ogr_geom_type; ogr_info = &(Map->fInfo.ogr); offset_info = &(ogr_info->offset); if (nparts < 1) return -1; points = p_points[0]; /* feature geometry */ if (!ogr_info->layer) { /* create OGR layer if doesn't exist */ if (create_ogr_layer(Map, type) < 0) return -1; } if (!points) return 0; cat = -1; /* no attributes to be written */ if (cats->n_cats > 0 && Vect_get_num_dblinks(Map) > 0) { /* check for attributes */ Fi = Vect_get_dblink(Map, 0); if (Fi) { if (!Vect_cat_get(cats, Fi->number, &cat)) G_warning(_("No category defined for layer %d"), Fi->number); if (cats->n_cats > 1) { G_warning(_("Feature has more categories, using " "category %d (from layer %d)"), cat, cats->field[0]); } } } Ogr_featuredefn = OGR_L_GetLayerDefn(ogr_info->layer); Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn); /* determine matching OGR feature geometry type */ if (type & (GV_POINT | GV_KERNEL)) { if (Ogr_geom_type != wkbPoint && Ogr_geom_type != wkbPoint25D) { G_warning(_("Feature is not a point. Skipping.")); return -1; } Ogr_geometry = OGR_G_CreateGeometry(wkbPoint); } else if (type & GV_LINE) { if (Ogr_geom_type != wkbLineString && Ogr_geom_type != wkbLineString25D) { G_warning(_("Feature is not a line. Skipping.")); return -1; } Ogr_geometry = OGR_G_CreateGeometry(wkbLineString); } else if (type & GV_BOUNDARY) { if (Ogr_geom_type != wkbPolygon) { G_warning(_("Feature is not a polygon. Skipping.")); return -1; } Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon); } else if (type & GV_FACE) { if (Ogr_geom_type != wkbPolygon25D) { G_warning(_("Feature is not a face. Skipping.")); return -1; } Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon25D); } else { G_warning(_("Unsupported feature type (%d)"), type); return -1; } G_debug(3, "V1_write_line_ogr(): type = %d", type); if (Ogr_geom_type == wkbPolygon || Ogr_geom_type == wkbPolygon25D) { int iring, npoints; /* add rings (first is exterior ring) */ for (iring = 0; iring < nparts; iring++) { OGRGeometryH Ogr_ring; points = p_points[iring]; npoints = points->n_points - 1; Ogr_ring = OGR_G_CreateGeometry(wkbLinearRing); if (points->x[0] != points->x[npoints] || points->y[0] != points->y[npoints] || points->z[0] != points->z[npoints]) { G_warning(_("Boundary is not closed. Feature skipped.")); return -1; } /* add points */ for (i = 0; i < npoints; i++) { OGR_G_AddPoint(Ogr_ring, points->x[i], points->y[i], points->z[i]); } G_debug(4, " ring(%d): n_points = %d", iring, npoints); OGR_G_AddGeometry(Ogr_geometry, Ogr_ring); } } else { for (i = 0; i < points->n_points; i++) { OGR_G_AddPoint(Ogr_geometry, points->x[i], points->y[i], points->z[i]); } G_debug(4, " n_points = %d", points->n_points); } /* create feature & set geometry */ Ogr_feature = OGR_F_Create(Ogr_featuredefn); OGR_F_SetGeometry(Ogr_feature, Ogr_geometry); /* write attributes */ if (cat > -1 && ogr_info->dbdriver) { if (0 > write_attributes(ogr_info->dbdriver, cat, Fi, ogr_info->layer, Ogr_feature)) G_warning(_("Unable to writes feature attributes")); G_free(Fi); } /* write feature into layer */ ret = OGR_L_CreateFeature(ogr_info->layer, Ogr_feature); /* update offset array */ if (offset_info->array_num >= offset_info->array_alloc) { offset_info->array_alloc += 1000; offset_info->array = (int *) G_realloc(offset_info->array, offset_info->array_alloc * sizeof(int)); } offset = offset_info->array_num; offset_info->array[offset_info->array_num++] = (int) OGR_F_GetFID(Ogr_feature); if (Ogr_geom_type == wkbPolygon || Ogr_geom_type == wkbPolygon25D) { /* register exterior ring in offset array */ offset_info->array[offset_info->array_num++] = 0; } /* destroy */ OGR_G_DestroyGeometry(Ogr_geometry); OGR_F_Destroy(Ogr_feature); if (ret != OGRERR_NONE) return -1; G_debug(3, "write_feature(): -> offset = %lu offset_num = %d cat = %d", (unsigned long) offset, offset_info->array_num, cat); return offset; }
/*! \brief Fetch record \param cn pointer to dbCursor \param position position indicator (DB_NEXT, DB_FIRST, DB_LAST, etc) \param[out] more 0 for no record fetched otherwise 1 \return DB_OK on success \return DB_FAILED on error */ int db__driver_fetch(dbCursor * cn, int position, int *more) { int i, col; int ogrType, sqlType; dbToken token; dbTable *table; dbColumn *column; dbValue *value; cursor *c; G_debug(3, "db_driver_fetch()"); /* get cursor token */ token = db_get_cursor_token(cn); /* get the cursor by its token */ if (!(c = (cursor *) db_find_token(token))) { append_error(_("Cursor not found")); report_error(); return DB_FAILED; } /* fetch on position */ switch (position) { case DB_NEXT: G_debug(4, "DB_NEXT:"); if (c->hFeature) OGR_F_Destroy(c->hFeature); c->hFeature = OGR_L_GetNextFeature(c->hLayer); break; case DB_CURRENT: break; case DB_PREVIOUS: append_error(_("DB_PREVIOUS not supported")); report_error(); return DB_FAILED; break; case DB_FIRST: OGR_L_ResetReading(c->hLayer); if (c->hFeature) OGR_F_Destroy(c->hFeature); c->hFeature = OGR_L_GetNextFeature(c->hLayer); break; case DB_LAST: append_error(_("DB_LAST not supported")); report_error(); return DB_FAILED; break; }; if (c->hFeature == NULL) { *more = 0; return DB_OK; } *more = 1; /* get the data out of the descriptor into the table */ table = db_get_cursor_table(cn); /* check fid column */ if (strlen(OGR_L_GetFIDColumn(c->hLayer)) > 0) { column = db_get_table_column(table, 0); ogrType = db_get_column_host_type(column); sqlType = db_get_column_sqltype(column); value = db_get_column_value(column); value->i = OGR_F_GetFID(c->hFeature); G_debug(3, "fidcol '%s': ogrType %d, sqlType %d: val = %d", db_get_column_name(column), ogrType, sqlType, value->i); col = 0; } else { col = -1; } /* loop attributes */ for (i = 0; i < c->ncols; i++) { if (!(c->cols[i])) { continue; } /* unknown type */ col++; column = db_get_table_column(table, col); ogrType = db_get_column_host_type(column); sqlType = db_get_column_sqltype(column); value = db_get_column_value(column); db_zero_string(&value->s); /* Is null? */ if (OGR_F_IsFieldSet(c->hFeature, i)) { value->isNull = 0; } else { value->isNull = 1; continue; } G_debug(3, "col %d, ogrType %d, sqlType %d: val = '%s'", col, ogrType, sqlType, OGR_F_GetFieldAsString(c->hFeature, i)); switch (ogrType) { case OFTInteger: value->i = OGR_F_GetFieldAsInteger(c->hFeature, i); break; case OFTReal: value->d = OGR_F_GetFieldAsDouble(c->hFeature, i); break; case OFTString: case OFTDate: case OFTTime: case OFTDateTime: db_set_string(&(value->s), (char *)OGR_F_GetFieldAsString(c->hFeature, i)); break; default: G_warning(_("Unknown type")); break; } } G_debug(4, "Row fetched"); return DB_OK; }
bool QgsOgrFeatureIterator::readFeature( gdal::ogr_feature_unique_ptr fet, QgsFeature &feature ) const { feature.setId( OGR_F_GetFID( fet.get() ) ); feature.initAttributes( mSource->mFields.count() ); feature.setFields( mSource->mFields ); // allow name-based attribute lookups bool useIntersect = !mRequest.filterRect().isNull(); bool geometryTypeFilter = mSource->mOgrGeometryTypeFilter != wkbUnknown; if ( mFetchGeometry || useIntersect || geometryTypeFilter ) { OGRGeometryH geom = OGR_F_GetGeometryRef( fet.get() ); if ( geom ) { QgsGeometry g = QgsOgrUtils::ogrGeometryToQgsGeometry( geom ); // Insure that multipart datasets return multipart geometry if ( QgsWkbTypes::isMultiType( mSource->mWkbType ) && !g.isMultipart() ) { g.convertToMultiType(); } feature.setGeometry( g ); } else feature.clearGeometry(); if ( mSource->mOgrGeometryTypeFilter == wkbGeometryCollection && geom && wkbFlatten( OGR_G_GetGeometryType( geom ) ) == wkbGeometryCollection ) { // OK } else if ( ( useIntersect && ( !feature.hasGeometry() || ( mRequest.flags() & QgsFeatureRequest::ExactIntersect && !feature.geometry().intersects( mFilterRect ) ) || ( !( mRequest.flags() & QgsFeatureRequest::ExactIntersect ) && !feature.geometry().boundingBoxIntersects( mFilterRect ) ) ) ) || ( geometryTypeFilter && ( !feature.hasGeometry() || QgsOgrProvider::ogrWkbSingleFlatten( ( OGRwkbGeometryType )feature.geometry().wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) ) { return false; } } if ( !mFetchGeometry ) { feature.clearGeometry(); } // fetch attributes if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { QgsAttributeList attrs = mRequest.subsetOfAttributes(); for ( QgsAttributeList::const_iterator it = attrs.constBegin(); it != attrs.constEnd(); ++it ) { getFeatureAttribute( fet.get(), feature, *it ); } } else { // all attributes const auto fieldCount = mSource->mFields.count(); for ( int idx = 0; idx < fieldCount; ++idx ) { getFeatureAttribute( fet.get(), feature, idx ); } } return true; }
int db__driver_execute_immediate(dbString * sql) { char *where, *table; int res, ncols, i; column_info *cols; OGRLayerH hLayer; OGRFeatureH hFeature; OGRFeatureDefnH hFeatureDefn; OGRFieldDefnH hFieldDefn; G_debug(1, "db__driver_execute_immediate():"); G_debug(3, "\tSQL: '%s'", db_get_string(sql)); /* try RDBMS SQL */ OGR_DS_ExecuteSQL(hDs, db_get_string(sql), NULL, NULL); if (CPLGetLastErrorType() == CE_None) return DB_OK; /* parse UPDATE statement */ res = parse_sql_update(db_get_string(sql), &table, &cols, &ncols, &where); G_debug(3, "\tUPDATE: table=%s, where=%s, ncols=%d", table, where ? where : "", ncols); if (res != 0) return DB_FAILED; /* get OGR layer */ hLayer = OGR_DS_GetLayerByName(hDs, table); if (!hLayer) { db_d_append_error(_("OGR layer <%s> not found"), table); db_d_report_error(); return DB_FAILED; } if (where) OGR_L_SetAttributeFilter(hLayer, where); /* get columns info */ hFeatureDefn = OGR_L_GetLayerDefn(hLayer); for (i = 0; i < ncols; i++) { cols[i].index = OGR_FD_GetFieldIndex(hFeatureDefn, cols[i].name); if (cols[i].index < 0) { db_d_append_error(_("Column <%s> not found in table <%s>"), cols[i].name, table); db_d_report_error(); return DB_FAILED; } cols[i].qindex = OGR_FD_GetFieldIndex(hFeatureDefn, cols[i].value); hFieldDefn = OGR_FD_GetFieldDefn(hFeatureDefn, cols[i].index); cols[i].type = OGR_Fld_GetType(hFieldDefn); G_debug(3, "\t\tcol=%s, val=%s, idx=%d, type=%d, qidx=%d", cols[i].name, cols[i].value, cols[i].index, cols[i].type, cols[i].qindex); } /* update features */ OGR_L_ResetReading(hLayer); while(TRUE) { char *value; hFeature = OGR_L_GetNextFeature(hLayer); if (!hFeature) break; G_debug(5, "\tfid=%ld", OGR_F_GetFID(hFeature)); for (i = 0; i < ncols; i++) { if (cols[i].qindex > -1) { value = (char *)OGR_F_GetFieldAsString(hFeature, cols[i].qindex); } else { if ((cols[i].type != OFTInteger || cols[i].type != OFTReal) && *(cols[i].value) == '\'') { value = G_strchg(cols[i].value, '\'', ' '); G_strip(value); } else { value = cols[i].value; } } OGR_F_SetFieldString(hFeature, cols[i].index, value); } OGR_L_SetFeature(hLayer, hFeature); OGR_F_Destroy(hFeature); } G_free(table); G_free(where); for (i = 0; i < ncols; i++) { G_free(cols[i].name); G_free(cols[i].value); } return DB_OK; }