OGRErr OGRSQLiteSelectLayerCommonBehaviour::SetAttributeFilter( const char *pszQuery )

{
    char*& m_pszAttrQuertyString = poLayer->GetAttrQueryString();
    if( m_pszAttrQuertyString == NULL && pszQuery == NULL )
        return OGRERR_NONE;

    CPLFree(m_pszAttrQuertyString);
    m_pszAttrQuertyString = (pszQuery) ? CPLStrdup(pszQuery) : NULL;

    bAllowResetReadingEvenIfIndexAtZero = TRUE;

    OGRFeatureQuery oQuery;

    CPLPushErrorHandler(CPLQuietErrorHandler);
    int bHasSpecialFields = (pszQuery != NULL && pszQuery[0] != '\0' &&
        oQuery.Compile( poLayer->GetLayerDefn(), pszQuery ) == OGRERR_NONE &&
        HasSpecialFields((swq_expr_node*)oQuery.GetSWQExpr(), poLayer->GetLayerDefn()->GetFieldCount()) );
    CPLPopErrorHandler();

    if( bHasSpecialFields || !BuildSQL() )
    {
        return poLayer->BaseSetAttributeFilter(pszQuery);
    }

    ResetReading();

    return OGRERR_NONE;
}
Beispiel #2
0
Debug::Debug(bool isDebug, pdal::LogPtr log)
    : m_isDebug(isDebug)
    , m_log(log)
{
    if (m_isDebug)
    {
        const char* gdal_debug = ::pdal::Utils::getenv("CPL_DEBUG");
        if (gdal_debug == 0)
        {
            pdal::Utils::putenv("CPL_DEBUG=ON");
        }
        m_gdal_callback = boost::bind(&Debug::log, this, _1, _2, _3);
    }
    else
    {
        m_gdal_callback = boost::bind(&Debug::error, this, _1, _2, _3);
    }


#if ((GDAL_VERSION_MAJOR == 1 && GDAL_VERSION_MINOR >= 9) || (GDAL_VERSION_MAJOR > 1)) 
    CPLPushErrorHandlerEx(&Debug::trampoline, this);
#else
    CPLPushErrorHandler(&Debug::trampoline);
#endif
}
Beispiel #3
0
int IMapInfoFile::TestUtf8Capability() const
{
    const char* pszEncoding( GetEncoding() );
    if( strlen( pszEncoding ) == 0 )
    {
        return FALSE;
    }

    CPLClearRecodeWarningFlags();
    CPLErrorReset();

    CPLPushErrorHandler(CPLQuietErrorHandler);
    char* pszTest( CPLRecode( "test", GetEncoding(), CPL_ENC_UTF8 ) );
    CPLPopErrorHandler();

    if( pszTest == nullptr )
    {
        return FALSE;
    }

    CPLFree( pszTest );

    if( CPLGetLastErrorType() != 0 )
    {
        return FALSE;
    }

    return TRUE;
}
Beispiel #4
0
OGRFieldType GeoJSONStringPropertyToFieldType( json_object* poObject )
{
    if (poObject == NULL) {
        return OFTString;
    }
    const char* pszStr = json_object_get_string( poObject );

    OGRField sWrkField;
    CPLPushErrorHandler(CPLQuietErrorHandler);
    int bSuccess = OGRParseDate( pszStr, &sWrkField, 0 );
    CPLPopErrorHandler();
    CPLErrorReset();
    if( bSuccess )
    {
        int bHasDate = strchr( pszStr, '/' ) != NULL ||
                       strchr( pszStr, '-' ) != NULL;
        int bHasTime = strchr( pszStr, ':' ) != NULL;
        if( bHasDate && bHasTime )
            return OFTDateTime;
        else if( bHasDate )
            return OFTDate;
        else
            return OFTTime;
    }
    return OFTString;
}
Beispiel #5
0
OGRFeature * OGRGFTTableLayer::GetFeature( GIntBig nFID )
{
    GetLayerDefn();

    CPLString osSQL("SELECT ROWID");
    for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
    {
        osSQL += ",";

        const char* pszFieldName =
            poFeatureDefn->GetFieldDefn(i)->GetNameRef();
        osSQL += EscapeAndQuote(pszFieldName);
    }
    if (bHiddenGeometryField)
    {
        osSQL += ",";
        osSQL += EscapeAndQuote(GetGeometryColumn());
    }
    osSQL += " FROM ";
    osSQL += osTableId;
    osSQL += CPLSPrintf(" WHERE ROWID='" CPL_FRMT_GIB "'", nFID);

    CPLPushErrorHandler(CPLQuietErrorHandler);
    CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
    CPLPopErrorHandler();

    if (psResult == NULL)
        return NULL;

    char* pszLine = (char*) psResult->pabyData;
    if (pszLine == NULL || psResult->pszErrBuf != NULL)
    {
        CPLHTTPDestroyResult(psResult);
        return NULL;
    }

    /* skip header line */
    pszLine = OGRGFTGotoNextLine(pszLine);
    if (pszLine == NULL || pszLine[0] == 0)
    {
        CPLHTTPDestroyResult(psResult);
        return NULL;
    }

    int nLen = (int)strlen(pszLine);
    if (nLen > 0 && pszLine[nLen-1] == '\n')
        pszLine[nLen-1] = '\0';

    OGRFeature* poFeature = BuildFeatureFromSQL(pszLine);

    CPLHTTPDestroyResult(psResult);

    return poFeature;
}
Beispiel #6
0
 void object::test<2>()
 {
     if( GDALHasTriangulation() )
     {
         double adfX[] = { 0, 1, 2, 3 };
         double adfY[] = { 0, 1, 2, 3 };
         CPLPushErrorHandler(CPLQuietErrorHandler);
         psDT = GDALTriangulationCreateDelaunay(4, adfX, adfY);
         CPLPopErrorHandler();
         ensure(psDT == nullptr);
     }
 }
Beispiel #7
0
 void object::test<1>()
 {
     if( GDALHasTriangulation() )
     {
         double adfX[] = { 0, -5, -5, 5, 5 };
         double adfY[] = { 0, -5, 5, -5, 5 };
         CPLPushErrorHandler(CPLQuietErrorHandler);
         psDT = GDALTriangulationCreateDelaunay(2, adfX, adfY);
         CPLPopErrorHandler();
         ensure(psDT == NULL);
     }
 }
Beispiel #8
0
int main( int argc, char **argv )
{
  QCoreApplication app( argc, argv );

  const QStringList args = QCoreApplication::arguments();

  bool verbose = false;

  for ( const QString &arg : args )
  {
    if ( arg == QLatin1String( "--verbose" ) )
      verbose = true;
  }

  QgsApplication::init();

  if ( !QgsApplication::isRunningFromBuildDir() )
  {
    char *prefixPath = getenv( "QGIS_PREFIX_PATH" );
    QgsApplication::setPrefixPath( prefixPath ? prefixPath : CMAKE_INSTALL_PREFIX, TRUE );
  }

  if ( verbose )
    std::cout << "Synchronizing CRS database with GDAL/PROJ definitions." << std::endl;

  CPLPushErrorHandler( showError );

  int res = QgsCoordinateReferenceSystem::syncDatabase();

  CPLPopErrorHandler();

  if ( res == 0 && verbose )
  {
    std::cout << "No CRS updates were necessary." << std::endl;
  }
  else if ( res > 0 && verbose )
  {
    std::cout << res << " CRSs updated." << std::endl;
  }
  else if ( res == std::numeric_limits<int>::min() )
  {
    std::cout << "CRSs synchronization not possible." << std::endl;
  }
  else if ( res < 0 )
  {
    std::cout << -res << " CRSs could not be updated." << std::endl;
  }

  QgsApplication::exitQgis();

  return 0;
}
Beispiel #9
0
GDALDatasetH gv_manager_get_dataset( GvManager *manager, const char * filename)

{
    int       i;
    GvDataset *ds;
    GDALDatasetH dataset;

    /*
     * Check for dataset in existing list of open files.  Note that our
     * filename check does not account for different possible names for
     * one dataset.
     */
    for( i = 0; i < manager->datasets->len; i++ )
    {
        ds = (GvDataset *) g_ptr_array_index(manager->datasets, i);

        if( EQUAL(GDALGetDescription(ds->dataset),filename) )
        {
            return ds->dataset;
        }
    }

    /*
     * Try to open the dataset, preferably with update access.  We don't
     * want to report update access errors so we supress error reporting
     * temporarily. 
     */
    
    CPLErrorReset();
    CPLPushErrorHandler( CPLQuietErrorHandler );
    dataset = GDALOpen( filename, GA_Update );
    CPLPopErrorHandler();

    if( dataset == NULL )
    {
        dataset = GDALOpen( filename, GA_ReadOnly );
    }

    if( dataset == NULL )
        return NULL;

    /* 
     * Add the dataset to the list of managed datasets. 
     */
    ds = g_new(GvDataset,1);
    ds->dataset = dataset;
    ds->rasters = g_new0(GvRaster *, GDALGetRasterCount(dataset));
    
    g_ptr_array_add( manager->datasets, ds );

    return dataset;
}
Beispiel #10
0
static OGRLayer* GetLayerAndOverwriteIfNecessary(GDALDataset *poDstDS,
                                                 const char* pszNewLayerName,
                                                 int bOverwrite,
                                                 int* pbErrorOccured)
{
    if( pbErrorOccured )
        *pbErrorOccured = FALSE;

    /* GetLayerByName() can instanciate layers that would have been */
    /* 'hidden' otherwise, for example, non-spatial tables in a */
    /* Postgis-enabled database, so this apparently useless command is */
    /* not useless... (#4012) */
    CPLPushErrorHandler(CPLQuietErrorHandler);
    OGRLayer* poDstLayer = poDstDS->GetLayerByName(pszNewLayerName);
    CPLPopErrorHandler();
    CPLErrorReset();

    int iLayer = -1;
    if (poDstLayer != NULL)
    {
        int nLayerCount = poDstDS->GetLayerCount();
        for( iLayer = 0; iLayer < nLayerCount; iLayer++ )
        {
            OGRLayer        *poLayer = poDstDS->GetLayer(iLayer);
            if (poLayer == poDstLayer)
                break;
        }

        if (iLayer == nLayerCount)
            /* shouldn't happen with an ideal driver */
            poDstLayer = NULL;
    }

/* -------------------------------------------------------------------- */
/*      If the user requested overwrite, and we have the layer in       */
/*      question we need to delete it now so it will get recreated      */
/*      (overwritten).                                                  */
/* -------------------------------------------------------------------- */
    if( poDstLayer != NULL && bOverwrite )
    {
        if( poDstDS->DeleteLayer( iLayer ) != OGRERR_NONE )
        {
            fprintf( stderr,
                     "DeleteLayer() failed when overwrite requested.\n" );
            if( pbErrorOccured )
                *pbErrorOccured = TRUE;
        }
        poDstLayer = NULL;
    }

    return poDstLayer;
}
Beispiel #11
0
void msGDALInitialize( void )

{
  if( !bGDALInitialized ) {
    msAcquireLock( TLOCK_GDAL );

    GDALAllRegister();
    CPLPushErrorHandler( CPLQuietErrorHandler );
    msReleaseLock( TLOCK_GDAL );

    bGDALInitialized = 1;
  }
}
Beispiel #12
0
SEXP
RGDAL_OpenDataset(SEXP filename, SEXP read_only, SEXP silent) {

  const char *fn = asString(filename);

  GDALAccess RWFlag;

  if (asLogical(read_only))
    RWFlag = GA_ReadOnly;
  else
    RWFlag = GA_Update;

/* Modification suggested by Even Rouault, 2009-08-08: */

  CPLErrorReset();
  if (asLogical(silent))
    CPLPushErrorHandler(CPLQuietErrorHandler);
  else
     installErrorHandler();

  GDALDataset *pDataset = (GDALDataset *) GDALOpen(fn, RWFlag);

  if (pDataset == NULL)
    error("%s\n", CPLGetLastErrorMsg());

  if (asLogical(silent))
    CPLPopErrorHandler();
  else
    uninstallErrorHandlerAndTriggerError();

/* Similarly to SWIG bindings, the following lines will cause
RGDAL_OpenDataset() to fail on - uncleared - errors even if pDataset is not
NULL. They could also be just removed. While pDataset != NULL, there's some
hope ;-) */

/*  CPLErr eclass = CPLGetLastErrorType();

  if (pDataset != NULL && eclass == CE_Failure) {
    GDALClose(pDataset);
    pDataset = NULL;
    __errorHandler(eclass, CPLGetLastErrorNo(), CPLGetLastErrorMsg());
  }*/


  SEXP sxpHandle = R_MakeExternalPtr((void *) pDataset,
				     mkChar("GDAL Dataset"),
				     R_NilValue);

  return(sxpHandle);

}
Beispiel #13
0
int OGRGFTResultLayer::FetchNextRows()
{
    if (!EQUALN(osSQL.c_str(), "SELECT", 6))
        return FALSE;

    aosRows.resize(0);

    CPLString osChangedSQL(osSQL);
    if (osSQL.ifind(" OFFSET ") == std::string::npos &&
        osSQL.ifind(" LIMIT ") == std::string::npos)
    {
        osChangedSQL += CPLSPrintf(" OFFSET %d LIMIT %d",
                                   nOffset, GetFeaturesToFetch());
    }

    CPLPushErrorHandler(CPLQuietErrorHandler);
    CPLHTTPResult * psResult = poDS->RunSQL(osChangedSQL);
    CPLPopErrorHandler();

    if (psResult == NULL)
    {
        bEOF = TRUE;
        return FALSE;
    }

    char* pszLine = (char*) psResult->pabyData;
    if (pszLine == NULL ||
        psResult->pszErrBuf != NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "RunSQL() failed");
        CPLHTTPDestroyResult(psResult);
        bEOF = TRUE;
        return FALSE;
    }

    pszLine = OGRGFTGotoNextLine(pszLine);
    if (pszLine == NULL)
    {
        CPLHTTPDestroyResult(psResult);
        bEOF = TRUE;
        return FALSE;
    }

    ParseCSVResponse(pszLine, aosRows);

    CPLHTTPDestroyResult(psResult);

    bEOF = (int)aosRows.size() < GetFeaturesToFetch();

    return TRUE;
}
OGRLayer* OGRPLScenesDataset::ExecuteSQL( const char *pszSQLCommand,
                                          OGRGeometry *poSpatialFilter,
                                          const char *pszDialect )
{
    if( EQUALN(pszSQLCommand, "SELECT ", strlen("SELECT ")) )
    {
        swq_select oSelect;
        CPLString osSQLCommand(pszSQLCommand);
        size_t nLimitPos = osSQLCommand.ifind(" limit ");
        if( nLimitPos != std::string::npos )
            osSQLCommand.resize(nLimitPos);

        CPLPushErrorHandler(CPLQuietErrorHandler);
        OGRErr eErr = oSelect.preparse(osSQLCommand);
        CPLPopErrorHandler();
        if( eErr != OGRERR_NONE )
            return GDALDataset::ExecuteSQL(pszSQLCommand, poSpatialFilter, pszDialect);

/* -------------------------------------------------------------------- */
/*      ORDER BY optimization on acquired field                         */
/* -------------------------------------------------------------------- */
        if( oSelect.join_count == 0 && oSelect.poOtherSelect == NULL &&
            oSelect.table_count == 1 && oSelect.order_specs == 1 &&
            strcmp(oSelect.order_defs[0].field_name, "acquired") == 0 )
        {
            int idx;
            OGRPLScenesLayer* poLayer = NULL;
            for(idx = 0; idx < nLayers; idx ++ )
            {
                if( strcmp( papoLayers[idx]->GetName(),
                            oSelect.table_defs[0].table_name) == 0 )
                {
                    poLayer = papoLayers[idx];
                    break;
                }
            }
            if( poLayer != NULL )
            {
                poLayer->SetAcquiredOrderingFlag(
                                        oSelect.order_defs[0].ascending_flag);
                OGRLayer* poRet = GDALDataset::ExecuteSQL(pszSQLCommand, poSpatialFilter, pszDialect);
                if( poRet )
                    oMapResultSetToSourceLayer[poRet] = poLayer;
                return poRet;
            }
        }
    }
    return GDALDataset::ExecuteSQL(pszSQLCommand, poSpatialFilter, pszDialect);
}
static
void OGR2SQLITE_ST_Area(sqlite3_context* pContext,
                        int argc, sqlite3_value** argv)
{
    OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL);
    if( poGeom != NULL )
    {
        CPLPushErrorHandler(CPLQuietErrorHandler);
        sqlite3_result_double( pContext, OGR_G_Area((OGRGeometryH)poGeom) );
        CPLPopErrorHandler();
    }
    else
        sqlite3_result_null(pContext);
    delete poGeom;
}
static
void OGR2SQLITE_ST_SRID(sqlite3_context* pContext,
                        int argc, sqlite3_value** argv)
{
    int nSRSId = -1;
    OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, &nSRSId);
    if( poGeom != NULL )
    {
        CPLPushErrorHandler(CPLQuietErrorHandler);
        sqlite3_result_int( pContext, nSRSId );
        CPLPopErrorHandler();
    }
    else
        sqlite3_result_null(pContext);
    delete poGeom;
}
Beispiel #17
0
Rcpp::CharacterVector p4s_from_spatial_reference(OGRSpatialReference *ref) {
	Rcpp::CharacterVector proj4string(1);
	char *cp;
	CPLPushErrorHandler(CPLQuietErrorHandler); // don't break on EPSG's without proj4string
	ref->morphFromESRI();
	(void) ref->exportToProj4(&cp);

	// eliminate trailing white space, the C-way:
	if (strlen(cp) > 0)
		for (char *cpws = cp + strlen(cp) - 1; cpws != cp && *cpws == ' '; cpws--)
			*cpws = '\0';

	proj4string[0] = cp;
	CPLFree(cp);
	CPLPopErrorHandler();
	return proj4string;
}
Beispiel #18
0
GlobalDebug::GlobalDebug()
{

    const char* gdal_debug = ::pdal::Utils::getenv("CPL_DEBUG");
    if (gdal_debug == 0)
    {
        pdal::Utils::putenv("CPL_DEBUG=ON");
    }
    m_gdal_callback = boost::bind(&GlobalDebug::log, this, _1, _2, _3);


#if ((GDAL_VERSION_MAJOR == 1 && GDAL_VERSION_MINOR >= 9) || (GDAL_VERSION_MAJOR > 1)) 
    CPLPushErrorHandlerEx(&GlobalDebug::trampoline, this);
#else
    CPLPushErrorHandler(&GlobalDebug::trampoline);
#endif
}
char* OGRCouchDBDataSource::GetETag(const char* pszURI)
{

    // make a head request and only return the etag response header
    char* pszEtag = NULL;
    char **papszTokens;
    char** papszOptions = NULL;

    bMustCleanPersistant = TRUE;

    papszOptions = CSLAddString(papszOptions, CPLSPrintf("PERSISTENT=CouchDB:%p", this));
    papszOptions = CSLAddString(papszOptions, "HEADERS=Content-Type: application/json");
    papszOptions = CSLAddString(papszOptions, "NO_BODY=1");
    
    if (osUserPwd.size())
    {
        CPLString osUserPwdOption("USERPWD=");
        osUserPwdOption += osUserPwd;
        papszOptions = CSLAddString(papszOptions, osUserPwdOption);
    }

    CPLDebug("CouchDB", "HEAD %s", pszURI);

    CPLString osFullURL(osURL);
    osFullURL += pszURI;
    CPLPushErrorHandler(CPLQuietErrorHandler);

    CPLHTTPResult * psResult = CPLHTTPFetch( osFullURL, papszOptions);
    CPLPopErrorHandler();
    CSLDestroy(papszOptions);
    if (psResult == NULL)
        return NULL;

    if (CSLFetchNameValue(psResult->papszHeaders, "Etag") != NULL)
    {
        papszTokens = 
            CSLTokenizeString2( CSLFetchNameValue(psResult->papszHeaders, "Etag"), "\"\r\n", 0 );
        
        pszEtag = CPLStrdup(papszTokens[0]);

        CSLDestroy( papszTokens );
    }

    CPLHTTPDestroyResult(psResult);
    return pszEtag;
}
Beispiel #20
0
void gdal::fast_delete_and_close( gdal::dataset_unique_ptr &dataset, GDALDriverH driver, const QString &path )
{
  // see https://github.com/qgis/QGIS/commit/d024910490a39e65e671f2055c5b6543e06c7042#commitcomment-25194282
  // faster if we close the handle AFTER delete, but doesn't work for windows
#ifdef Q_OS_WIN
  // close dataset handle
  dataset.reset();
#endif

  CPLPushErrorHandler( CPLQuietErrorHandler );
  GDALDeleteDataset( driver, path.toUtf8().constData() );
  CPLPopErrorHandler();

#ifndef Q_OS_WIN
  // close dataset handle
  dataset.reset();
#endif
}
Beispiel #21
0
 // Test that GDALWarp() detects error in flush cache
 template<> template<> void object::test<9>()
 {
     GDALDriver* poDriver = new GDALDriver();
     poDriver->SetDescription("DatasetWithErrorInFlushCache");
     poDriver->pfnCreate = DatasetWithErrorInFlushCache::Create;
     GetGDALDriverManager()->RegisterDriver( poDriver );
     const char* args[] = { "-of", "DatasetWithErrorInFlushCache", NULL };
     GDALWarpAppOptions* psOptions = GDALWarpAppOptionsNew((char**)args, NULL);
     GDALDatasetH hSrcDS = GDALOpen("../gcore/data/byte.tif", GA_ReadOnly);
     CPLErrorReset();
     CPLPushErrorHandler(CPLQuietErrorHandler);
     GDALDatasetH hOutDS = GDALWarp("/", NULL, 1, &hSrcDS, psOptions, NULL);
     CPLPopErrorHandler();
     GDALClose(hSrcDS);
     GDALWarpAppOptionsFree(psOptions);
     ensure(hOutDS == NULL);
     ensure(CPLGetLastErrorType() != CE_None);
     GetGDALDriverManager()->DeregisterDriver( poDriver );
     delete poDriver;
 }
Beispiel #22
0
CPLErr GS7BGDataset::GetGeoTransform( double *padfGeoTransform )
{
    if( padfGeoTransform == NULL )
        return CE_Failure;

    GS7BGRasterBand *poGRB = (GS7BGRasterBand *)GetRasterBand( 1 );

    if( poGRB == NULL )
    {
        padfGeoTransform[0] = 0;
        padfGeoTransform[1] = 1;
        padfGeoTransform[2] = 0;
        padfGeoTransform[3] = 0;
        padfGeoTransform[4] = 0;
        padfGeoTransform[5] = 1;
        return CE_Failure;
    }

    /* check if we have a PAM GeoTransform stored */
    CPLPushErrorHandler( CPLQuietErrorHandler );
    CPLErr eErr = GDALPamDataset::GetGeoTransform( padfGeoTransform );
    CPLPopErrorHandler();

    if( eErr == CE_None )
        return CE_None;

    /* calculate pixel size first */
    padfGeoTransform[1] = (poGRB->dfMaxX - poGRB->dfMinX)/(nRasterXSize - 1);
    padfGeoTransform[5] = (poGRB->dfMinY - poGRB->dfMaxY)/(nRasterYSize - 1);

    /* then calculate image origin */
    padfGeoTransform[0] = poGRB->dfMinX - padfGeoTransform[1] / 2;
    padfGeoTransform[3] = poGRB->dfMaxY - padfGeoTransform[5] / 2;

    /* tilt/rotation does not supported by the GS grids */
    padfGeoTransform[4] = 0.0;
    padfGeoTransform[2] = 0.0;

    return CE_None;
}
Beispiel #23
0
int main( int argc, char ** argv )
{
  QCoreApplication app( argc, argv );

  QgsApplication::init();

  if ( !QgsApplication::isRunningFromBuildDir() )
  {
    char* prefixPath = getenv( "QGIS_PREFIX_PATH" );
    QgsApplication::setPrefixPath( prefixPath ? prefixPath : CMAKE_INSTALL_PREFIX, TRUE );
  }

  std::cout << "Synchronizing CRS database with GDAL/PROJ definitions." << std::endl;

  CPLPushErrorHandler( showError );

  int res = QgsCoordinateReferenceSystem::syncDb();

  CPLPopErrorHandler();

  if ( res == 0 )
  {
    std::cout << "No CRS updates were necessary." << std::endl;
  }
  else if ( res > 0 )
  {
    std::cout << res << " CRSs updated." << std::endl;
  }
  else if ( res == std::numeric_limits<int>::min() )
  {
    std::cout << "CRSs synchronization not possible." << std::endl;
  }
  else if ( res < 0 )
  {
    std::cout << -res << " CRSs could not be updated." << std::endl;
  }

  exit( 0 );
}
Beispiel #24
0
// [[Rcpp::export]]
Rcpp::List CPL_transform(Rcpp::List sfc, Rcpp::CharacterVector proj4) {

	// import proj4string:
	OGRSpatialReference *dest = new OGRSpatialReference;
	handle_error(dest->importFromProj4((const char *) (proj4[0])));

	// transform geometries:
	std::vector<OGRGeometry *> g = ogr_from_sfc(sfc, NULL);
	if (g.size() == 0) {
		dest->Release(); // #nocov
		Rcpp::stop("CPL_transform: zero length geometry list"); // #nocov
	}
	OGRCoordinateTransformation *ct = 
		OGRCreateCoordinateTransformation(g[0]->getSpatialReference(), dest);
	if (ct == NULL) {
		dest->Release(); // #nocov
		Rcpp::stop("OGRCreateCoordinateTransformation() returned NULL: PROJ.4 available?"); // #nocov
	}
	for (size_t i = 0; i < g.size(); i++) {
		CPLPushErrorHandler(CPLQuietErrorHandler);
		OGRErr err = 0;
		if (! g[i]->IsEmpty())
			err = g[i]->transform(ct);
		CPLPopErrorHandler();
		if (err == 1 || err == 6) {
			OGRwkbGeometryType geomType = g[i]->getGeometryType();
			OGRGeometryFactory f;
			f.destroyGeometry(g[i]);
			g[i] = f.createGeometry(geomType);
		} else
			handle_error(err);
	}

	Rcpp::List ret = sfc_from_ogr(g, true); // destroys g;
	ct->DestroyCT(ct);
	dest->Release();
	return ret; 
}
Beispiel #25
0
CPLErr SAGADataset::GetGeoTransform( double *padfGeoTransform )
{
    if( padfGeoTransform == NULL )
		return CE_Failure;

    SAGARasterBand *poGRB = dynamic_cast<SAGARasterBand *>(GetRasterBand( 1 ));

    if( poGRB == NULL )
    {
		padfGeoTransform[0] = 0;
		padfGeoTransform[1] = 1;
		padfGeoTransform[2] = 0;
		padfGeoTransform[3] = 0;
		padfGeoTransform[4] = 0;
		padfGeoTransform[5] = 1;
		return CE_Failure;
    }

    /* check if we have a PAM GeoTransform stored */
    CPLPushErrorHandler( CPLQuietErrorHandler );
    CPLErr eErr = GDALPamDataset::GetGeoTransform( padfGeoTransform );
    CPLPopErrorHandler();

    if( eErr == CE_None )
		return CE_None;

	padfGeoTransform[1] = poGRB->m_Cellsize;
	padfGeoTransform[5] = poGRB->m_Cellsize * -1.0;
	padfGeoTransform[0] = poGRB->m_Xmin - poGRB->m_Cellsize / 2;
	padfGeoTransform[3] = poGRB->m_Ymin + (nRasterYSize - 1) * poGRB->m_Cellsize + poGRB->m_Cellsize / 2;

	/* tilt/rotation is not supported by SAGA grids */
    padfGeoTransform[4] = 0.0;
    padfGeoTransform[2] = 0.0;

    return CE_None;
}
Beispiel #26
0
GDALDataset * AAIGDataset::CreateCopy(
    const char *pszFilename, GDALDataset *poSrcDS,
    int /* bStrict */,
    char **papszOptions,
    GDALProgressFunc pfnProgress, void *pProgressData )
{
    const int nBands = poSrcDS->GetRasterCount();
    const int nXSize = poSrcDS->GetRasterXSize();
    const int nYSize = poSrcDS->GetRasterYSize();

    // Some rudimentary checks.
    if( nBands != 1 )
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "AAIG driver doesn't support %d bands.  Must be 1 band.",
                 nBands);

        return nullptr;
    }

    if( !pfnProgress(0.0, nullptr, pProgressData) )
        return nullptr;

    // Create the dataset.
    VSILFILE *fpImage = VSIFOpenL(pszFilename, "wt");
    if( fpImage == nullptr )
    {
        CPLError(CE_Failure, CPLE_OpenFailed,
                 "Unable to create file %s.",
                 pszFilename);
        return nullptr;
    }

    // Write ASCII Grid file header.
    double adfGeoTransform[6] = {};
    char szHeader[2000] = {};
    const char *pszForceCellsize =
        CSLFetchNameValue(papszOptions, "FORCE_CELLSIZE");

    poSrcDS->GetGeoTransform(adfGeoTransform);

    if( std::abs(adfGeoTransform[1] + adfGeoTransform[5]) < 0.0000001 ||
        std::abs(adfGeoTransform[1]-adfGeoTransform[5]) < 0.0000001 ||
        (pszForceCellsize && CPLTestBool(pszForceCellsize)) )
    {
        CPLsnprintf(
            szHeader, sizeof(szHeader),
            "ncols        %d\n"
            "nrows        %d\n"
            "xllcorner    %.12f\n"
            "yllcorner    %.12f\n"
            "cellsize     %.12f\n",
            nXSize, nYSize,
            adfGeoTransform[0],
            adfGeoTransform[3] - nYSize * adfGeoTransform[1],
            adfGeoTransform[1]);
    }
    else
    {
        if( pszForceCellsize == nullptr )
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Producing a Golden Surfer style file with DX and DY "
                     "instead of CELLSIZE since the input pixels are "
                     "non-square.  Use the FORCE_CELLSIZE=TRUE creation "
                     "option to force use of DX for even though this will "
                     "be distorted.  Most ASCII Grid readers (ArcGIS "
                     "included) do not support the DX and DY parameters.");
        CPLsnprintf(
            szHeader, sizeof(szHeader),
            "ncols        %d\n"
            "nrows        %d\n"
            "xllcorner    %.12f\n"
            "yllcorner    %.12f\n"
            "dx           %.12f\n"
            "dy           %.12f\n",
            nXSize, nYSize,
            adfGeoTransform[0],
            adfGeoTransform[3] + nYSize * adfGeoTransform[5],
            adfGeoTransform[1],
            fabs(adfGeoTransform[5]));
    }

    // Builds the format string used for printing float values.
    char szFormatFloat[32] = { '\0' };
    strcpy(szFormatFloat, " %.20g");
    const char *pszDecimalPrecision =
        CSLFetchNameValue(papszOptions, "DECIMAL_PRECISION");
    const char *pszSignificantDigits =
        CSLFetchNameValue(papszOptions, "SIGNIFICANT_DIGITS");
    bool bIgnoreSigDigits = false;
    if( pszDecimalPrecision && pszSignificantDigits )
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                 "Conflicting precision arguments, using DECIMAL_PRECISION");
        bIgnoreSigDigits = true;
    }
    int nPrecision;
    if ( pszSignificantDigits && !bIgnoreSigDigits )
    {
        nPrecision = atoi(pszSignificantDigits);
        if (nPrecision >= 0)
            snprintf(szFormatFloat, sizeof(szFormatFloat), " %%.%dg",
                     nPrecision);
        CPLDebug("AAIGrid", "Setting precision format: %s", szFormatFloat);
    }
    else if( pszDecimalPrecision )
    {
        nPrecision = atoi(pszDecimalPrecision);
        if ( nPrecision >= 0 )
            snprintf(szFormatFloat, sizeof(szFormatFloat), " %%.%df",
                     nPrecision);
        CPLDebug("AAIGrid", "Setting precision format: %s", szFormatFloat);
    }

    // Handle nodata (optionally).
    GDALRasterBand *poBand = poSrcDS->GetRasterBand(1);
    const bool bReadAsInt =
        poBand->GetRasterDataType() == GDT_Byte ||
        poBand->GetRasterDataType() == GDT_Int16 ||
        poBand->GetRasterDataType() == GDT_UInt16 ||
        poBand->GetRasterDataType() == GDT_Int32;

    // Write `nodata' value to header if it is exists in source dataset
    int bSuccess = FALSE;
    const double dfNoData = poBand->GetNoDataValue(&bSuccess);
    if ( bSuccess )
    {
        snprintf(szHeader + strlen(szHeader),
                 sizeof(szHeader) - strlen(szHeader), "%s", "NODATA_value ");
        if( bReadAsInt )
            snprintf(szHeader + strlen(szHeader),
                     sizeof(szHeader) - strlen(szHeader), "%d",
                     static_cast<int>(dfNoData));
        else
            CPLsnprintf(szHeader + strlen(szHeader),
                        sizeof(szHeader) - strlen(szHeader),
                        szFormatFloat, dfNoData);
        snprintf(szHeader + strlen(szHeader),
                 sizeof(szHeader) - strlen(szHeader), "%s", "\n");
    }

    if( VSIFWriteL(szHeader, strlen(szHeader), 1, fpImage) != 1)
    {
        CPL_IGNORE_RET_VAL(VSIFCloseL(fpImage));
        return nullptr;
    }

    // Loop over image, copying image data.

    // Write scanlines to output file
    int *panScanline = bReadAsInt
                           ? static_cast<int *>(CPLMalloc(
                                 nXSize * GDALGetDataTypeSizeBytes(GDT_Int32)))
                           : nullptr;

    double *padfScanline =
        bReadAsInt ? nullptr
                   : static_cast<double *>(CPLMalloc(
                         nXSize * GDALGetDataTypeSizeBytes(GDT_Float64)));

    CPLErr eErr = CE_None;

    bool bHasOutputDecimalDot = false;
    for( int iLine = 0; eErr == CE_None && iLine < nYSize; iLine++ )
    {
        CPLString osBuf;
        eErr = poBand->RasterIO(
            GF_Read, 0, iLine, nXSize, 1,
            bReadAsInt ? reinterpret_cast<void *>(panScanline) :
            reinterpret_cast<void *>(padfScanline),
            nXSize, 1, bReadAsInt ? GDT_Int32 : GDT_Float64,
            0, 0, nullptr);

        if( bReadAsInt )
        {
            for ( int iPixel = 0; iPixel < nXSize; iPixel++ )
            {
                snprintf(szHeader, sizeof(szHeader),
                         " %d", panScanline[iPixel]);
                osBuf += szHeader;
                if( (iPixel & 1023) == 0 || iPixel == nXSize - 1 )
                {
                    if ( VSIFWriteL(osBuf, static_cast<int>(osBuf.size()), 1,
                                    fpImage) != 1 )
                    {
                        eErr = CE_Failure;
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "Write failed, disk full?");
                        break;
                    }
                    osBuf = "";
                }
            }
        }
        else
        {
            for ( int iPixel = 0; iPixel < nXSize; iPixel++ )
            {
                CPLsnprintf(szHeader, sizeof(szHeader),
                            szFormatFloat, padfScanline[iPixel]);

                // Make sure that as least one value has a decimal point (#6060)
                if( !bHasOutputDecimalDot )
                {
                    if( strchr(szHeader, '.') || strchr(szHeader, 'e') ||
                        strchr(szHeader, 'E') )
                    {
                        bHasOutputDecimalDot = true;
                    }
                    else if( !CPLIsInf(padfScanline[iPixel]) &&
                             !CPLIsNan(padfScanline[iPixel]) )
                    {
                        strcat(szHeader, ".0");
                        bHasOutputDecimalDot = true;
                    }
                }

                osBuf += szHeader;
                if( (iPixel & 1023) == 0 || iPixel == nXSize - 1 )
                {
                  if ( VSIFWriteL(osBuf, static_cast<int>(osBuf.size()), 1,
                                  fpImage) != 1 )
                    {
                        eErr = CE_Failure;
                        CPLError(CE_Failure, CPLE_AppDefined,
                                 "Write failed, disk full?");
                        break;
                    }
                    osBuf = "";
                }
            }
        }
        if( VSIFWriteL("\n", 1, 1, fpImage) != 1 )
            eErr = CE_Failure;

        if( eErr == CE_None &&
            !pfnProgress((iLine + 1) / static_cast<double>(nYSize), nullptr,
                         pProgressData) )
        {
            eErr = CE_Failure;
            CPLError(CE_Failure, CPLE_UserInterrupt,
                     "User terminated CreateCopy()");
        }
    }

    CPLFree(panScanline);
    CPLFree(padfScanline);
    if( VSIFCloseL(fpImage) != 0 )
        eErr = CE_Failure;

    if( eErr != CE_None )
        return nullptr;

    // Try to write projection file.
    const char *pszOriginalProjection = poSrcDS->GetProjectionRef();
    if( !EQUAL(pszOriginalProjection, "") )
    {
        char *pszDirname = CPLStrdup(CPLGetPath(pszFilename));
        char *pszBasename = CPLStrdup(CPLGetBasename(pszFilename));
        char *pszPrjFilename =
            CPLStrdup(CPLFormFilename(pszDirname, pszBasename, "prj"));
        VSILFILE *fp = VSIFOpenL(pszPrjFilename, "wt");
        if (fp != nullptr)
        {
            OGRSpatialReference oSRS;
            oSRS.importFromWkt(pszOriginalProjection);
            oSRS.morphToESRI();
            char *pszESRIProjection = nullptr;
            oSRS.exportToWkt(&pszESRIProjection);
            CPL_IGNORE_RET_VAL(VSIFWriteL(pszESRIProjection, 1,
                                          strlen(pszESRIProjection), fp));

            CPL_IGNORE_RET_VAL(VSIFCloseL(fp));
            CPLFree(pszESRIProjection);
        }
        else
        {
            CPLError(CE_Failure, CPLE_FileIO, "Unable to create file %s.",
                     pszPrjFilename);
        }
        CPLFree(pszDirname);
        CPLFree(pszBasename);
        CPLFree(pszPrjFilename);
    }

    // Re-open dataset, and copy any auxiliary pam information.

    // If writing to stdout, we can't reopen it, so return
    // a fake dataset to make the caller happy.
    CPLPushErrorHandler(CPLQuietErrorHandler);
    GDALPamDataset *poDS =
        reinterpret_cast<GDALPamDataset *>(GDALOpen(pszFilename, GA_ReadOnly));
    CPLPopErrorHandler();
    if (poDS)
    {
        poDS->CloneInfo(poSrcDS, GCIF_PAM_DEFAULT);
        return poDS;
    }

    CPLErrorReset();

    AAIGDataset *poAAIG_DS = new AAIGDataset();
    poAAIG_DS->nRasterXSize = nXSize;
    poAAIG_DS->nRasterYSize = nYSize;
    poAAIG_DS->nBands = 1;
    poAAIG_DS->SetBand(1, new AAIGRasterBand(poAAIG_DS, 1));
    return poAAIG_DS;
}
Beispiel #27
0
GvSymbolObj *
gv_symbol_manager_get_symbol(GvSymbolManager *manager, const char *symbol_name)
{
    gchar   *pszOpenEVHome = NULL;
    gchar   *pszSymbolsDir = NULL;
    gchar   *pszAbsolutePath = NULL;
    gchar   *pszPathSeparator = NULL;
    GDALDatasetH hDataset;
    GvSymbolObj *poSymbol;
    CPLXMLNode  *xml_shape = NULL;
    GByte *rgba_buffer;

/* -------------------------------------------------------------------- */
/*      Lookup the symbol in the hash table, and return it if found.    */
/* -------------------------------------------------------------------- */
    poSymbol = g_hash_table_lookup( manager->symbol_cache, symbol_name );
    if( poSymbol != NULL )
        return poSymbol;

/* -------------------------------------------------------------------- */
/*      We didn't already have it, so try to find a file to load it     */
/*      from.                                                           */
/* -------------------------------------------------------------------- */
#ifndef WIN32
    pszPathSeparator = "/";
#else
    pszPathSeparator = "\\";
#endif /* WIN32 */

    /* validate inputs */
    g_return_val_if_fail( manager != NULL, 0 );
    g_return_val_if_fail( symbol_name != NULL, 0 );

    /* get an absolute path */
    if ( !g_path_is_absolute( symbol_name ) )
    {
        /* check configuration option first */
        pszSymbolsDir = g_strdup( gv_manager_get_preference( gv_get_manager(),
                                                             "symbols_dir" ) );

        /* if not configured check $OPENEV_HOME */
        if ( !pszSymbolsDir )
        {
            pszOpenEVHome = g_getenv( "OPENEV_HOME" );
            if( pszOpenEVHome == NULL )
                pszOpenEVHome = g_getenv( "OPENEVHOME" );
            if ( pszOpenEVHome )
                pszSymbolsDir = g_strjoin( pszPathSeparator, pszOpenEVHome,
                                           "symbols", NULL );
        }
        
        /* get current directory as last resort */
        if ( !pszSymbolsDir )
            pszSymbolsDir = g_get_current_dir();

        pszAbsolutePath = g_strjoin( pszPathSeparator, pszSymbolsDir, 
                                     symbol_name, NULL );
        g_free( pszSymbolsDir );
    }
    else
        pszAbsolutePath = g_strdup( symbol_name );

/* -------------------------------------------------------------------- */
/*      pszAbsolutePath contains a newly allocated string that is       */
/*      suitable for using as a key in the hash table.  If a texture    */
/*      is found in the hash table then this string needs to be         */
/*      freed.  If one isn't found then the string is used in the       */
/*      hash table and should be freed when the associated hash         */
/*      table entry is released                                         */
/* -------------------------------------------------------------------- */
    CPLDebug( "OpenEV", 
              "gv_symbol_manager_get_symbol(%s) ... need to load.", 
                  pszAbsolutePath );
    
    /* 
     * validate path by opening with GDAL and looking for an error 
     * Disable CPL error handler to supress error reporting
     */
    
    CPLErrorReset();
    CPLPushErrorHandler( CPLQuietErrorHandler );
    hDataset = GDALOpen( pszAbsolutePath, GA_ReadOnly );
    CPLPopErrorHandler();
    
    if ( hDataset )
    {
        rgba_buffer = gdal_to_rgba( hDataset );
        
        if ( rgba_buffer )
        {
            gv_symbol_manager_inject_raster_symbol( 
                manager, symbol_name,
                GDALGetRasterXSize( hDataset ),
                GDALGetRasterYSize( hDataset ),
                rgba_buffer );
            CPLFree( rgba_buffer );
        }
        
        GDALClose( hDataset );
    }
    /* probably we have vector symbol? */
    else if ( ( xml_shape = CPLParseXMLFile( pszAbsolutePath ) ) )
    {
        GvShape     *shape;
        shape = gv_shape_from_xml_tree( xml_shape );
        
        CPLDestroyXMLNode( xml_shape );
        
        if( shape != NULL )
            gv_symbol_manager_inject_vector_symbol( manager, symbol_name,
                                                    shape );
        else
        {
            CPLDebug( "OpenEV", 
                      "Failed to instantiate GvSahpe from file %s, using simple point.", 
                      pszAbsolutePath );
        
            shape = gv_shape_new( GVSHAPE_POINT );
            gv_symbol_manager_inject_vector_symbol( manager, symbol_name,
                                                    shape );
        }
    }
    else
    {
        GvShape *shape;

        CPLDebug( "OpenEV", "Failed to open file %s, using simple point.", 
                  pszAbsolutePath );
        
        shape = gv_shape_new( GVSHAPE_POINT );
        gv_symbol_manager_inject_vector_symbol( manager, symbol_name,
                                                shape );
    }
    
    /* look up in the hash table again */
    poSymbol = g_hash_table_lookup(manager->symbol_cache, symbol_name );

    g_free( pszAbsolutePath );

    return poSymbol;
}
Beispiel #28
0
json_object* OGRCouchDBDataSource::REQUEST(const char* pszVerb,
                                           const char* pszURI,
                                           const char* pszData)
{
    bMustCleanPersistent = true;

    char** papszOptions = NULL;
    papszOptions = CSLAddString(papszOptions, CPLSPrintf("PERSISTENT=CouchDB:%p", this));

    CPLString osCustomRequest("CUSTOMREQUEST=");
    osCustomRequest += pszVerb;
    papszOptions = CSLAddString(papszOptions, osCustomRequest);

    CPLString osPOSTFIELDS("POSTFIELDS=");
    if (pszData)
        osPOSTFIELDS += pszData;
    papszOptions = CSLAddString(papszOptions, osPOSTFIELDS);

    papszOptions = CSLAddString(papszOptions, "HEADERS=Content-Type: application/json");

    if (!osUserPwd.empty() )
    {
        CPLString osUserPwdOption("USERPWD=");
        osUserPwdOption += osUserPwd;
        papszOptions = CSLAddString(papszOptions, osUserPwdOption);
    }

    CPLDebug("CouchDB", "%s %s", pszVerb, pszURI);
    CPLString osFullURL(osURL);
    osFullURL += pszURI;
    CPLPushErrorHandler(CPLQuietErrorHandler);

    CPLHTTPResult * psResult = CPLHTTPFetch( osFullURL, papszOptions);
    CPLPopErrorHandler();
    CSLDestroy(papszOptions);
    if (psResult == NULL)
        return NULL;

    const char* pszServer = CSLFetchNameValue(psResult->papszHeaders, "Server");
    if (pszServer == NULL || !STARTS_WITH_CI(pszServer, "CouchDB"))
    {
        CPLHTTPDestroyResult(psResult);
        return NULL;
    }

    if (psResult->nDataLen == 0)
    {
        CPLHTTPDestroyResult(psResult);
        return NULL;
    }

    json_object* jsobj = NULL;
    const char* pszText = reinterpret_cast<const char*>(psResult->pabyData);
    if( !OGRJSonParse(pszText, &jsobj, true) )
    {
        CPLHTTPDestroyResult(psResult);
        return NULL;
    }

    CPLHTTPDestroyResult(psResult);
    return jsobj;
}
Beispiel #29
0
GDALDataset *
WEBPDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS,
                        int bStrict, char ** papszOptions,
                        GDALProgressFunc pfnProgress, void * pProgressData )

{
    int  nBands = poSrcDS->GetRasterCount();
    int  nXSize = poSrcDS->GetRasterXSize();
    int  nYSize = poSrcDS->GetRasterYSize();

/* -------------------------------------------------------------------- */
/*      WEBP library initialization                                     */
/* -------------------------------------------------------------------- */

    WebPPicture sPicture;
    if (!WebPPictureInit(&sPicture))
    {
        CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureInit() failed");
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Some some rudimentary checks                                    */
/* -------------------------------------------------------------------- */

    if( nXSize > 16383 || nYSize > 16383 )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "WEBP maximum image dimensions are 16383 x 16383.");

        return NULL;
    }

    if( nBands != 3
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
        && nBands != 4
#endif
        )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "WEBP driver doesn't support %d bands. Must be 3 (RGB) "
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
                  "or 4 (RGBA) "
#endif
                  "bands.",
                  nBands );

        return NULL;
    }

    GDALDataType eDT = poSrcDS->GetRasterBand(1)->GetRasterDataType();

    if( eDT != GDT_Byte )
    {
        CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported,
                  "WEBP driver doesn't support data type %s. "
                  "Only eight bit byte bands supported.",
                  GDALGetDataTypeName(
                      poSrcDS->GetRasterBand(1)->GetRasterDataType()) );

        if (bStrict)
            return NULL;
    }

/* -------------------------------------------------------------------- */
/*      What options has the user selected?                             */
/* -------------------------------------------------------------------- */
    float fQuality = 75.0f;
    const char* pszQUALITY = CSLFetchNameValue(papszOptions, "QUALITY"); 
    if( pszQUALITY != NULL )
    {
        fQuality = (float) CPLAtof(pszQUALITY);
        if( fQuality < 0.0f || fQuality > 100.0f )
        {
            CPLError( CE_Failure, CPLE_IllegalArg,
                      "%s=%s is not a legal value.", "QUALITY", pszQUALITY);
            return NULL;
        }
    }

    WebPPreset nPreset = WEBP_PRESET_DEFAULT;
    const char* pszPRESET = CSLFetchNameValueDef(papszOptions, "PRESET", "DEFAULT");
    if (EQUAL(pszPRESET, "DEFAULT"))
        nPreset = WEBP_PRESET_DEFAULT;
    else if (EQUAL(pszPRESET, "PICTURE"))
        nPreset = WEBP_PRESET_PICTURE;
    else if (EQUAL(pszPRESET, "PHOTO"))
        nPreset = WEBP_PRESET_PHOTO;
    else if (EQUAL(pszPRESET, "PICTURE"))
        nPreset = WEBP_PRESET_PICTURE;
    else if (EQUAL(pszPRESET, "DRAWING"))
        nPreset = WEBP_PRESET_DRAWING;
    else if (EQUAL(pszPRESET, "ICON"))
        nPreset = WEBP_PRESET_ICON;
    else if (EQUAL(pszPRESET, "TEXT"))
        nPreset = WEBP_PRESET_TEXT;
    else
    {
        CPLError( CE_Failure, CPLE_IllegalArg,
                  "%s=%s is not a legal value.", "PRESET", pszPRESET );
        return NULL;
    }

    WebPConfig sConfig;
    if (!WebPConfigInitInternal(&sConfig, nPreset, fQuality, WEBP_ENCODER_ABI_VERSION))
    {
        CPLError(CE_Failure, CPLE_AppDefined, "WebPConfigInit() failed");
        return NULL;
    }


#define FETCH_AND_SET_OPTION_INT(name, fieldname, minval, maxval) \
{ \
    const char* pszVal = CSLFetchNameValue(papszOptions, name); \
    if (pszVal != NULL) \
    { \
        sConfig.fieldname = atoi(pszVal); \
        if (sConfig.fieldname < minval || sConfig.fieldname > maxval) \
        { \
            CPLError( CE_Failure, CPLE_IllegalArg, \
                      "%s=%s is not a legal value.", name, pszVal ); \
            return NULL; \
        } \
    } \
}

    FETCH_AND_SET_OPTION_INT("TARGETSIZE", target_size, 0, INT_MAX);

    const char* pszPSNR = CSLFetchNameValue(papszOptions, "PSNR");
    if (pszPSNR)
    {
        sConfig.target_PSNR = CPLAtof(pszPSNR);
        if (sConfig.target_PSNR < 0)
        {
            CPLError( CE_Failure, CPLE_IllegalArg,
                      "PSNR=%s is not a legal value.", pszPSNR );
            return NULL;
        }
    }

    FETCH_AND_SET_OPTION_INT("METHOD", method, 0, 6);
    FETCH_AND_SET_OPTION_INT("SEGMENTS", segments, 1, 4);
    FETCH_AND_SET_OPTION_INT("SNS_STRENGTH", sns_strength, 0, 100);
    FETCH_AND_SET_OPTION_INT("FILTER_STRENGTH", filter_strength, 0, 100);
    FETCH_AND_SET_OPTION_INT("FILTER_SHARPNESS", filter_sharpness, 0, 7);
    FETCH_AND_SET_OPTION_INT("FILTER_TYPE", filter_type, 0, 1);
    FETCH_AND_SET_OPTION_INT("AUTOFILTER", autofilter, 0, 1);
    FETCH_AND_SET_OPTION_INT("PASS", pass, 1, 10);
    FETCH_AND_SET_OPTION_INT("PREPROCESSING", preprocessing, 0, 1);
    FETCH_AND_SET_OPTION_INT("PARTITIONS", partitions, 0, 3);
#if WEBP_ENCODER_ABI_VERSION >= 0x0002
    FETCH_AND_SET_OPTION_INT("PARTITION_LIMIT", partition_limit, 0, 100);
#endif
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
    sConfig.lossless = CSLFetchBoolean(papszOptions, "LOSSLESS", FALSE);
    if (sConfig.lossless)
        sPicture.use_argb = 1;
#endif

    if (!WebPValidateConfig(&sConfig))
    {
        CPLError(CE_Failure, CPLE_AppDefined, "WebPValidateConfig() failed");
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Allocate memory                                                 */
/* -------------------------------------------------------------------- */
    GByte   *pabyBuffer;

    pabyBuffer = (GByte *) VSIMalloc( nBands * nXSize * nYSize );
    if (pabyBuffer == NULL)
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create the dataset.                                             */
/* -------------------------------------------------------------------- */
    VSILFILE    *fpImage;

    fpImage = VSIFOpenL( pszFilename, "wb" );
    if( fpImage == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Unable to create WEBP file %s.\n",
                  pszFilename );
        VSIFree(pabyBuffer);
        return NULL;
    }

    WebPUserData sUserData;
    sUserData.fp = fpImage;
    sUserData.pfnProgress = pfnProgress ? pfnProgress : GDALDummyProgress;
    sUserData.pProgressData = pProgressData;

/* -------------------------------------------------------------------- */
/*      WEBP library settings                                           */
/* -------------------------------------------------------------------- */

    sPicture.width = nXSize;
    sPicture.height = nYSize;
    sPicture.writer = WEBPDatasetWriter;
    sPicture.custom_ptr = &sUserData;
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
    sPicture.progress_hook = WEBPDatasetProgressHook;
#endif
    if (!WebPPictureAlloc(&sPicture))
    {
        CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureAlloc() failed");
        VSIFree(pabyBuffer);
        VSIFCloseL( fpImage );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Acquire source imagery.                                         */
/* -------------------------------------------------------------------- */
    CPLErr      eErr = CE_None;

    eErr = poSrcDS->RasterIO( GF_Read, 0, 0, nXSize, nYSize,
                              pabyBuffer, nXSize, nYSize, GDT_Byte,
                              nBands, NULL,
                              nBands, nBands * nXSize, 1, NULL );

/* -------------------------------------------------------------------- */
/*      Import and write to file                                        */
/* -------------------------------------------------------------------- */
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
    if (eErr == CE_None && nBands == 4)
    {
        if (!WebPPictureImportRGBA(&sPicture, pabyBuffer, nBands * nXSize))
        {
            CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureImportRGBA() failed");
            eErr = CE_Failure;
        }
    }
    else
#endif
    if (eErr == CE_None &&
        !WebPPictureImportRGB(&sPicture, pabyBuffer, nBands * nXSize))
    {
        CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureImportRGB() failed");
        eErr = CE_Failure;
    }

    if (eErr == CE_None && !WebPEncode(&sConfig, &sPicture))
    {
        const char* pszErrorMsg = NULL;
#if WEBP_ENCODER_ABI_VERSION >= 0x0100
        switch(sPicture.error_code)
        {
            case VP8_ENC_ERROR_OUT_OF_MEMORY: pszErrorMsg = "Out of memory"; break;
            case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: pszErrorMsg = "Out of memory while flushing bits"; break;
            case VP8_ENC_ERROR_NULL_PARAMETER: pszErrorMsg = "A pointer parameter is NULL"; break;
            case VP8_ENC_ERROR_INVALID_CONFIGURATION: pszErrorMsg = "Configuration is invalid"; break;
            case VP8_ENC_ERROR_BAD_DIMENSION: pszErrorMsg = "Picture has invalid width/height"; break;
            case VP8_ENC_ERROR_PARTITION0_OVERFLOW: pszErrorMsg = "Partition is bigger than 512k. Try using less SEGMENTS, or increase PARTITION_LIMIT value"; break;
            case VP8_ENC_ERROR_PARTITION_OVERFLOW: pszErrorMsg = "Partition is bigger than 16M"; break;
            case VP8_ENC_ERROR_BAD_WRITE: pszErrorMsg = "Error while flusing bytes"; break;
            case VP8_ENC_ERROR_FILE_TOO_BIG: pszErrorMsg = "File is bigger than 4G"; break;
            case VP8_ENC_ERROR_USER_ABORT: pszErrorMsg = "User interrupted"; break;
            default: break;
        }
#endif
        if (pszErrorMsg)
            CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode() failed : %s", pszErrorMsg);
        else
            CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode() failed");
        eErr = CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Cleanup and close.                                              */
/* -------------------------------------------------------------------- */
    CPLFree( pabyBuffer );

    WebPPictureFree(&sPicture);

    VSIFCloseL( fpImage );

    if( eErr != CE_None )
    {
        VSIUnlink( pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Re-open dataset, and copy any auxiliary pam information.         */
/* -------------------------------------------------------------------- */
    GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly);

    /* If outputing to stdout, we can't reopen it, so we'll return */
    /* a fake dataset to make the caller happy */
    CPLPushErrorHandler(CPLQuietErrorHandler);
    WEBPDataset *poDS = (WEBPDataset*) WEBPDataset::Open( &oOpenInfo );
    CPLPopErrorHandler();
    if( poDS )
    {
        poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT );
        return poDS;
    }

    return NULL;
}
Beispiel #30
0
int main(int argc, char* argv[])
{
    int i;
    int nThreads = CPLGetNumCPUs();
    std::vector<CPLJoinableThread*> apsThreads;
    Strategy eStrategy = STRATEGY_RANDOM;
    int bNewDatasetOption = FALSE;
    int nXSize = 5000;
    int nYSize = 5000;
    int nBands = 4;
    char** papszOptions = NULL;
    int bOnDisk = FALSE;
    std::vector<ThreadDescription> asThreadDescription;
    int bMemDriver = FALSE;
    GDALDataset* poMEMDS = NULL;
    int bMigrate = FALSE;
    int nMaxRequests = -1;

    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );

    GDALAllRegister();

    for(i = 1; i < argc; i++)
    {
        if( EQUAL(argv[i], "-threads") && i + 1 < argc)
        {
            i ++;
            nThreads = atoi(argv[i]);
        }
        else if( EQUAL(argv[i], "-loops") && i + 1 < argc)
        {
            i ++;
            nLoops = atoi(argv[i]);
            if( nLoops <= 0 )
                nLoops = INT_MAX;
        }
        else if( EQUAL(argv[i], "-max_requests") && i + 1 < argc)
        {
            i ++;
            nMaxRequests = atoi(argv[i]);
        }
        else if( EQUAL(argv[i], "-strategy") && i + 1 < argc)
        {
            i ++;
            if( EQUAL(argv[i], "random") )
                eStrategy = STRATEGY_RANDOM;
            else if( EQUAL(argv[i], "line") )
                eStrategy = STRATEGY_LINE;
            else if( EQUAL(argv[i], "block") )
                eStrategy = STRATEGY_BLOCK;
            else
                Usage();
        }
        else if( EQUAL(argv[i], "-xsize") && i + 1 < argc)
        {
            i ++;
            nXSize = atoi(argv[i]);
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-ysize") && i + 1 < argc)
        {
            i ++;
            nYSize = atoi(argv[i]);
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-bands") && i + 1 < argc)
        {
            i ++;
            nBands = atoi(argv[i]);
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-co") && i + 1 < argc)
        {
            i ++;
            papszOptions = CSLAddString(papszOptions, argv[i]);
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-ondisk"))
        {
            bOnDisk = TRUE;
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-check"))
        {
            bCheck = TRUE;
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-memdriver"))
        {
            bMemDriver = TRUE;
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-migrate"))
            bMigrate = TRUE;
        else if( argv[i][0] == '-' )
            Usage();
        else if( pszDataset == NULL )
            pszDataset = argv[i];
        else
        {
            Usage();
        }
    }

    if( pszDataset != NULL && bNewDatasetOption )
        Usage();

    CPLDebug("TEST", "Using %d threads", nThreads);

    int bCreatedDataset = FALSE;
    if( pszDataset == NULL )
    {
        bCreatedDataset = TRUE;
        if( bOnDisk )
            pszDataset = "/tmp/tmp.tif";
        else
            pszDataset = "/vsimem/tmp.tif";
        GDALDataset* poDS = ((GDALDriver*)GDALGetDriverByName((bMemDriver) ? "MEM" : "GTiff"))->Create(pszDataset,
                                nXSize, nYSize, nBands, GDT_Byte, papszOptions);
        if( bCheck )
        {
            GByte* pabyLine = (GByte*) VSIMalloc(nBands * nXSize);
            for(int iY=0;iY<nYSize;iY++)
            {
                for(int iX=0;iX<nXSize;iX++)
                {
                    for(int iBand=0;iBand<nBands;iBand++)
                    {
                        unsigned long seed = iBand * nXSize * nYSize + iY * nXSize + iX;
                        pabyLine[iBand * nXSize + iX] = (GByte)(myrand_r(&seed) & 0xff);
                    }
                }
                CPL_IGNORE_RET_VAL(poDS->RasterIO(GF_Write, 0, iY, nXSize, 1,
                               pabyLine, nXSize, 1,
                               GDT_Byte,
                               nBands, NULL,
                               0, 0, 0
#ifdef GDAL_COMPILATION
                               , NULL
#endif
                               ));
            }
            VSIFree(pabyLine);
        }
        if( bMemDriver ) 
            poMEMDS = poDS;
        else
            GDALClose(poDS);
    }
    else
    {
        bCheck = FALSE;
    }
    CSLDestroy(papszOptions);
    papszOptions = NULL;
    
    Request* psGlobalRequestLast = NULL;

    for(i = 0; i < nThreads; i++ )
    {
        GDALDataset* poDS;
        // Since GDAL 2.0, the MEM driver is thread-safe, i.e. does not use the block
        // cache, but only for operations not involving resampling, which is
        // the case here
        if( poMEMDS ) 
            poDS = poMEMDS;
        else
        {
            poDS = (GDALDataset*)GDALOpen(pszDataset, GA_ReadOnly);
            if( poDS == NULL )
                exit(1);
        }
        if( bMigrate )
        {
            Resource* psResource = (Resource*)CPLMalloc(sizeof(Resource));
            psResource->poDS = poDS;
            int nBufferSize;
            if( eStrategy == STRATEGY_RANDOM )
                nBufferSize = CreateRandomStrategyRequests(
                        poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast);
            else if( eStrategy == STRATEGY_LINE )
                nBufferSize = CreateLineStrategyRequests(
                        poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast);
            else
                nBufferSize = CreateBlockStrategyRequests(
                        poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast);
            psResource->pBuffer = CPLMalloc(nBufferSize);
            PutResourceAtEnd(psResource);
        }
        else
        {
            ThreadDescription sThreadDescription;
            sThreadDescription.poDS = poDS;
            sThreadDescription.psRequestList = NULL;
            Request* psRequestLast = NULL;
            if( eStrategy == STRATEGY_RANDOM )
                sThreadDescription.nBufferSize = CreateRandomStrategyRequests(
                        poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast);
            else if( eStrategy == STRATEGY_LINE )
                sThreadDescription.nBufferSize = CreateLineStrategyRequests(
                        poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast);
            else
                sThreadDescription.nBufferSize = CreateBlockStrategyRequests(
                        poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast);
            asThreadDescription.push_back(sThreadDescription);
        }
    }

    if( bCreatedDataset && poMEMDS == NULL && bOnDisk )
    {
        CPLPushErrorHandler(CPLQuietErrorHandler);
        VSIUnlink(pszDataset);
        CPLPopErrorHandler();
    }
    
    if( bMigrate )
    {
        psLock = CPLCreateLock(LOCK_SPIN);
    }

    for(i = 0; i < nThreads; i++ )
    {
        CPLJoinableThread* pThread;
        if( bMigrate )
            pThread = CPLCreateJoinableThread(ThreadFuncWithMigration, NULL);
        else
            pThread = CPLCreateJoinableThread(ThreadFuncDedicatedDataset,
                                              &(asThreadDescription[i]));
        apsThreads.push_back(pThread);
    }
    for(i = 0; i < nThreads; i++ )
    {
        CPLJoinThread(apsThreads[i]);
        if( !bMigrate && poMEMDS == NULL )
            GDALClose(asThreadDescription[i].poDS);
    }
    while( psGlobalResourceList != NULL )
    {
        CPLFree( psGlobalResourceList->pBuffer);
        if( poMEMDS == NULL )
            GDALClose(psGlobalResourceList->poDS);
        Resource* psNext = psGlobalResourceList->psNext;
        CPLFree( psGlobalResourceList );
        psGlobalResourceList = psNext;
    }

    if( psLock )
    {
        CPLDestroyLock( psLock );
    }

    if( bCreatedDataset && poMEMDS == NULL  )
    {
        CPLPushErrorHandler(CPLQuietErrorHandler);
        VSIUnlink(pszDataset);
        CPLPopErrorHandler();
    }
    if( poMEMDS )
        GDALClose(poMEMDS);

    assert( GDALGetCacheUsed64() == 0 );

    GDALDestroyDriverManager();
    CSLDestroy( argv );

    return 0;
}