Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GeoRaster: Added GENSTATS options, security fixes, and prevent failing when password is near expiration #9290

Merged
merged 37 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
fd40934
GeoRaster: Added generate statistics option for GeoRaster driver
Alan5142 Jul 14, 2023
ebbfc7b
Merge pull request #1 from Alan5142/georaster-statistics
Alan5142 Jul 14, 2023
88b14b7
Georaster: Set Generate statistics res length to 5
Alan5142 Jul 17, 2023
7e54cb3
Georaster: Changed generate statistics to use BindName for certain pa…
Alan5142 Jul 17, 2023
46c5ac2
Georaster: Added docs for statistics options
Alan5142 Jul 18, 2023
2ee5282
GeoRaster: Prevent injection in INSERT and DESCRIPTION options
Alan5142 Jul 18, 2023
87ea7a3
Statistics and general use fix
coim32 Jul 18, 2023
a824e77
Merge pull request #2 from coim32/patch-1
Alan5142 Jul 18, 2023
6cb773e
GeoRaster: Fixed insert statement check for '--' comments
Alan5142 Jul 18, 2023
6a189bd
GeoRaster: fixed out of bounds when checking for invalid INSERT expre…
Alan5142 Jul 19, 2023
666a14a
GeoRaster: Added georaster missing options
Alan5142 Jul 19, 2023
0992659
GeoRaster: Fixed insert expression validation, now considers '' as es…
Alan5142 Jul 20, 2023
cb968c1
Merge branch 'OSGeo:master' into master
Alan5142 Jul 25, 2023
f61d933
fix: CreationOptionList XML now properly closed
Alan5142 Jul 31, 2023
dde317f
Merge branch 'georaster-statistics' into insert-injection-georaster-s…
Alan5142 Oct 20, 2023
b699da7
description of all tables on a schema
coim32 Oct 20, 2023
01f8b69
Merge branch 'insert-injection' into insert-injection-georaster-stati…
Alan5142 Oct 23, 2023
ac20c7f
changed genstatistics option name to genstats
Alan5142 Oct 24, 2023
1159a7e
Merge branch 'OSGeo:master' into master
Alan5142 Oct 24, 2023
ccd72f8
Merge branch 'insert-injection-georaster-statistics'
Alan5142 Oct 24, 2023
f547c8f
fixed GENSTATS_USEBIN field
Alan5142 Oct 24, 2023
df499cc
doc changes
Alan5142 Oct 25, 2023
7525bff
fixed GenStatsHistogram value
Alan5142 Oct 25, 2023
7835622
changed some CPLSPrintf parameters to use Bind instead
Alan5142 Oct 27, 2023
a129234
format and docs fixes
Alan5142 Oct 27, 2023
060755e
fixed georaster_dataset duplicated default value
Alan5142 Feb 7, 2024
7ddfaff
log warning when password is about to expire
Alan5142 Feb 12, 2024
f6f9bef
updated georaster GENSTATS docs
Alan5142 Feb 13, 2024
0551c5b
added password expired warning log workaround to display it only once
Alan5142 Feb 19, 2024
b9aa45f
added workaround for gdal warning message when using gdal_translate
Alan5142 Feb 21, 2024
4d5ea68
added a default error handler as a workaround
Alan5142 Feb 22, 2024
589c5a8
merge upstream
Alan5142 Feb 22, 2024
eed7b54
code format
Alan5142 Feb 23, 2024
28d6c8f
fixed XML metadata spacing
Alan5142 Feb 26, 2024
ab12d50
fixed connection string in autotest/gdrivers/georaster.py
Alan5142 Feb 28, 2024
f0fa59a
format python code
Alan5142 Feb 28, 2024
7a3e52d
fix xml tag in genstats
Alan5142 Feb 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 120 additions & 19 deletions doc/source/drivers/raster/georaster.rst
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,102 @@ Creation Options
generated. If :co:`GENPYRAMID` is not informed the resample method NN
(nearest neighbor) will apply.

- .. co:: GENSTATS
:choices: TRUE, FALSE
:default: FALSE

To generate statistics from the given rasters, set this value to TRUE.
Default value is FALSE.
This option must be present in order to generate the stats, otherwise,
other GENSTATS options are ignored.


- .. co:: GENSTATS_SAMPLINGFACTOR
:choices: <integer>
:default: 1

Defines the number of cells skipped in both row and column dimensions when
the statistics are computed.
For example, when setting this value to 4, one-sixteenth of the cells are sampled.
The higher the value, the less accurate the statistics are likely to be,
but the more quickly they will be computed.
Defaults to 1, which means that all cells are sampled.

- .. co:: GENSTATS_SAMPLINGWINDOW
:choices: <integer\,integer\,integer\,integer>

This parameter identifies the upper-left (row, column) and lower-right
(row, column) coordinates of a rectangular window, and raster space is assumed.
The intersection of the MBR (minimum bounding rectangle) of the
GeoRaster object in raster space is used for computing statistics.
When this value is not specified, statistics are computed for the entire raster.

- .. co:: GENSTATS_HISTOGRAM
:choices: TRUE, FALSE
:default: FALSE

When this value is set to TRUE, a histogram will be computed and stored.
Defaults to FALSE, so a histogram won't be generated.

- .. co:: GENSTATS_LAYERNUMBERS
:choices: <integer\,integer\,...>, <integer>-<integer>

Defines the numbers of the layers for which to compute the statistics.
This can include numbers, ranges (indicated by hyphens), and commas
to separate any combination of those.
For example, '1,3-5,7', '1,3,6', '1-6'.
If this value is not specified, statistics will be computed for all
layers.

- .. co:: GENSTATS_USEBIN
:choices: TRUE, FALSE
:default: TRUE

Defaults to TRUE.
Specifies whether or not to use a provided bin function
(specified in :co:`GENSTATS_BINFUNCTION`).
When this value is set to TRUE, the bin function to be
used follows the following sequence: (1) the bin function
specified in :co:`GENSTATS_BINFUNCTION`. (2) the bin
function specified by the <binFunction> element in the
GeoRaster XML metadata. (3) a dynamically generated bin
function generated as follows:
Min and max are the actual min and max values of the raster
Numbins is defined as:
* celldepth = 1, numbins = 2.
* cellDepth = 2, numbins = 4.
* cellDepth = 4, numbins = 8.
* cellDepth >= 8, numbins = 256.

When this value is set to FALSE, then the bin function
to use is the one generated dynamically as previously
described.

- .. co:: GENSTATS_BINFUNCTION
:choices: <integer\,integer\,integer\,integer\,integer>

An array whose element specify the bin type, total
number of bins, first bin number, minimum cell value,
and maximum cell value. Bin type must be linear (0).
When this value is not specified, and :co:`GENSTATS_USEBIN`
is TRUE, then the bin function to use is as follows:

1. A valid function defined in the GeoRaster metadata.
2. The same bin function generated when :co:`GENSTATS_USEBIN` is FALSE.

- .. co:: GENSTATS_NODATA
:choices: TRUE, FALSE
:default: FALSE

Specifies whether or not to compare each cell values
with NODATA values defined in the metadata when computing
statistics. When set to TRUE, all pixels with a NODATA
value won't be considered. When set to FALSE, NODATA
pixels will be considered as regular pixels.

A NODATA value is used for cells whose values are either not known
or meaningless

- .. co:: QUALITY
:choices: 0-100
:default: 75
Expand Down Expand Up @@ -366,23 +462,28 @@ Loading:
General use of GeoRaster
------------------------

| GeoRaster can be used in any GDAL command line tool with all the
available options. Like a image subset extraction or re-project:
| % gdal_translate -of gtiff geor:scott/tiger@dbdemo,landsat,scene,id=54
output.tif \\
GeoRaster can be used in any GDAL command line tool with all the available options.
Like a image subset extraction or re-project:

.. code-block:: bash

% gdal_translate -of gtiff geor:scott/tiger@dbdemo,landsat,scene,id=54 output.tif \
  -srcwin 0 0 800 600
% gdalwarp -of png geor:scott/tiger@dbdemo,st_rdt_1,130 output.png
-t_srs EPSG:9000913
Two different GeoRaster can be used as input and output on the same
operation:
| % gdal_translate -of georaster
geor:scott/tiger@dbdemo,landsat,scene,id=54
geor:scott/tiger@proj1,projview,image -co INSERT="VALUES
(102, SDO_GEOR.INIT())"
Applications that use GDAL can theoretically read and write from
GeoRaster just like any other format but most of then are more
inclined to try to access files on the file system so one alternative
is to create VRT to represent the GeoRaster description, e.g.:
| % gdal_translate -of VRT geor:scott/tiger@dbdemo,landsat,scene,id=54
view_54.vrt
% openenv view_54.vrt
% gdalwarp -of png geor:scott/tiger@dbdemo,st_rdt_1,130 output.png
-t_srs EPSG:9000913

Two different GeoRaster can be used as input and output on the same operation:

.. code-block:: bash

% gdal_translate -of georaster geor:scott/tiger@dbdemo,landsat,scene,id=54 \
geor:scott/tiger@proj1,projview,image -co INSERT="VALUES (102, SDO_GEOR.INIT())"

Applications that use GDAL can theoretically read and write from GeoRaster just like
any other format but most of then are more inclined to try to access files on the file
system so one alternative is to create VRT to represent the GeoRaster description, e.g.:

.. code-block:: bash

% gdal_translate -of VRT geor:scott/tiger@dbdemo,landsat,scene,id=54 view_54.vrt
% openenv view_54.vrt
114 changes: 113 additions & 1 deletion frmts/georaster/georaster_dataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,21 @@ char **GeoRasterDataset::GetFileList()
return papszFileList;
}

static bool ParseCommaSeparatedString(const char *str, double pfValues[],
int nMaxValues)
{
int nValues = 0;
char **papszTokens = CSLTokenizeString2(str, ",", 0);

for (int i = 0; papszTokens && papszTokens[i] && nValues < nMaxValues; i++)
{
pfValues[nValues++] = CPLAtof(papszTokens[i]);
}

CSLDestroy(papszTokens);
return nValues == nMaxValues;
}

// ---------------------------------------------------------------------------
// Create()
// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -1252,6 +1267,103 @@ GDALDataset *GeoRasterDataset::Create(const char *pszFilename, int nXSize,
poGRD->poGeoRaster->nPyramidLevels = atoi(pszFetched);
}

pszFetched = CSLFetchNameValue(papszOptions, "GENSTATS");

if (pszFetched != nullptr)
{
poGRD->poGeoRaster->bGenStats = EQUAL(pszFetched, "TRUE");
}
Comment on lines +1270 to +1275
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be simplified as:

Suggested change
pszFetched = CSLFetchNameValue(papszOptions, "GENSTATS");
if (pszFetched != nullptr)
{
poGRD->poGeoRaster->bGenStats = EQUAL(pszFetched, "TRUE");
}
poGRD->poGeoRaster->bGenStats = CPLFetchBool(papszOptions, "GENSTATS", FALSE);

similar occurrences below


bool bGenStatsOptionsUsed = false;

pszFetched = CSLFetchNameValue(papszOptions, "GENSTATS_SAMPLINGFACTOR");

if (pszFetched != nullptr)
{
bGenStatsOptionsUsed = true;
poGRD->poGeoRaster->nGenStatsSamplingFactor = atoi(pszFetched);
}

pszFetched = CSLFetchNameValue(papszOptions, "GENSTATS_SAMPLINGWINDOW");

if (pszFetched != nullptr)
{
bGenStatsOptionsUsed = true;

// Sampling window contains 4 double values
const int nSize = 4;
if (!ParseCommaSeparatedString(
pszFetched, poGRD->poGeoRaster->dfGenStatsSamplingWindow,
nSize))
{
CPLError(CE_Failure, CPLE_IllegalArg,
"Wrong comma separated string for sampling window (%s)",
pszFetched);
delete poGRD;
return nullptr;
}

poGRD->poGeoRaster->bGenStatsUseSamplingWindow = true;
}

pszFetched = CSLFetchNameValue(papszOptions, "GENSTATS_HISTOGRAM");

if (pszFetched != nullptr)
{
bGenStatsOptionsUsed = true;
poGRD->poGeoRaster->bGenStatsHistogram = EQUAL(pszFetched, "TRUE");
}

pszFetched = CSLFetchNameValue(papszOptions, "GENSTATS_LAYERNUMBERS");

if (pszFetched != nullptr)
{
bGenStatsOptionsUsed = true;
poGRD->poGeoRaster->sGenStatsLayerNumbers = pszFetched;
}

pszFetched = CSLFetchNameValue(papszOptions, "GENSTATS_USEBIN");

if (pszFetched != nullptr)
{
bGenStatsOptionsUsed = true;
poGRD->poGeoRaster->bGenStatsUseBin = EQUAL(pszFetched, "TRUE");
}

pszFetched = CSLFetchNameValue(papszOptions, "GENSTATS_BINFUNCTION");

if (pszFetched != nullptr)
{
bGenStatsOptionsUsed = true;
const int nSize = 5;
if (!ParseCommaSeparatedString(
pszFetched, poGRD->poGeoRaster->dfGenStatsBinFunction, nSize))
{
CPLError(CE_Failure, CPLE_IllegalArg,
"Wrong comma separated string for bin function (%s)",
pszFetched);
delete poGRD;
return nullptr;
}
}

pszFetched = CSLFetchNameValue(papszOptions, "GENSTATS_NODATA");

if (pszFetched != nullptr)
{
bGenStatsOptionsUsed = true;
poGRD->poGeoRaster->bGenStatsNodata = EQUAL(pszFetched, "TRUE");
}

if (bGenStatsOptionsUsed && !poGRD->poGeoRaster->bGenStats)
{
CPLError(
CE_Warning, CPLE_AppDefined,
"Some GENSTATS* options were used but GENSTATS is not set. "
"Statistics won't be computed, please set GENSTATS option to true "
"if you want to generate statistics");
}

// -------------------------------------------------------------------
// Return a new Dataset
// -------------------------------------------------------------------
Expand Down Expand Up @@ -2421,7 +2533,7 @@ void GeoRasterDataset::SetSubdatasets(GeoRasterWrapper *poGRW)

papszSubdatasets = CSLSetNameValue(
papszSubdatasets, CPLSPrintf("SUBDATASET_%d_DESC", nCount),
CPLSPrintf("%s.Table=%s", szOwner, szTable));
CPLSPrintf("Table=%s.%s", szOwner, szTable));

nCount++;
} while (poStmt->Fetch());
Expand Down
13 changes: 13 additions & 0 deletions frmts/georaster/georaster_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,9 @@ class GeoRasterWrapper
char *GetVAT(int nBand);
bool GeneratePyramid(int nLevels, const char *pszResampling,
bool bInternal = false);
bool GenerateStatistics(int nSamplingFactor, double *pdfSamplingWindow,
bool bHistogram, const char *pszLayerNumbers,
bool bUseBin, double *pdfBinFunction, bool bNodata);
void DeletePyramid();
void PrepareToOverwrite();
bool InitializeMask(int nLevel, int nBlockColumns, int nBlockRows,
Expand Down Expand Up @@ -465,6 +468,16 @@ class GeoRasterWrapper
bool bHasBitmapMask;
bool bUniqueFound;

bool bGenStats;
int nGenStatsSamplingFactor;
bool bGenStatsUseSamplingWindow;
double dfGenStatsSamplingWindow[4];
bool bGenStatsHistogram;
CPLString sGenStatsLayerNumbers;
bool bGenStatsUseBin;
double dfGenStatsBinFunction[5];
bool bGenStatsNodata;

int eModelCoordLocation;
unsigned int anULTCoordinate[3];

Expand Down
Loading
Loading