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

[pull] master from OSGeo:master #157

Merged
merged 14 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
48 changes: 44 additions & 4 deletions alg/contour.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,11 @@ struct PolygonContourWriter
currentGeometry_->addGeometryDirectly(currentPart_);
}

OGRPolygonContourWriter(previousLevel_, currentLevel_,
*currentGeometry_, poInfo_);
if (currentGeometry_->getNumGeometries() > 0)
{
OGRPolygonContourWriter(previousLevel_, currentLevel_,
*currentGeometry_, poInfo_);
}

currentGeometry_.reset(nullptr);
currentPart_ = nullptr;
Expand Down Expand Up @@ -514,7 +517,9 @@ an averaged value from the two nearby points (in this case (12+3+5)/3).
* FIXED_LEVELS=f[,f]*
*
* The list of fixed contour levels at which contours should be generated.
* This option has precedence on LEVEL_INTERVAL
* This option has precedence on LEVEL_INTERVAL. MIN and MAX can be used
* as special values to represent the minimum and maximum values of the
* raster.
*
* NODATA=f
*
Expand Down Expand Up @@ -607,7 +612,19 @@ CPLErr GDALContourGenerateEx(GDALRasterBandH hBand, void *hLayer,
fixedLevels.resize(aosLevels.size());
for (size_t i = 0; i < fixedLevels.size(); i++)
{
fixedLevels[i] = CPLAtof(aosLevels[i]);
// Handle min/max values
if (EQUAL(aosLevels[i], "MIN"))
{
fixedLevels[i] = std::numeric_limits<double>::lowest();
}
else if (EQUAL(aosLevels[i], "MAX"))
{
fixedLevels[i] = std::numeric_limits<double>::max();
}
else
{
fixedLevels[i] = CPLAtof(aosLevels[i]);
}
if (i > 0 && !(fixedLevels[i] >= fixedLevels[i - 1]))
{
CPLError(CE_Failure, CPLE_AppDefined,
Expand Down Expand Up @@ -712,13 +729,27 @@ CPLErr GDALContourGenerateEx(GDALRasterBandH hBand, void *hLayer,

bool ok = true;

// Replace fixed levels min/max values with raster min/max values
if (!fixedLevels.empty())
{
if (fixedLevels[0] == std::numeric_limits<double>::lowest())
{
fixedLevels[0] = dfMinimum;
}
if (fixedLevels.back() == std::numeric_limits<double>::max())
{
fixedLevels.back() = dfMaximum;
}
}

try
{
if (polygonize)
{

if (!fixedLevels.empty())
{

// If the minimum raster value is larger than the first requested
// level, select the requested level that is just below the
// minimum raster value
Expand Down Expand Up @@ -781,6 +812,8 @@ CPLErr GDALContourGenerateEx(GDALRasterBandH hBand, void *hLayer,
}
// Append minimum value to fixed levels
fixedLevels.push_back(dfMinimum);
// Append maximum value to fixed levels
fixedLevels.push_back(dfMaximum);
}
else if (contourInterval != 0)
{
Expand All @@ -798,6 +831,8 @@ CPLErr GDALContourGenerateEx(GDALRasterBandH hBand, void *hLayer,
}
// Append minimum value to fixed levels
fixedLevels.push_back(dfMinimum);
// Append maximum value to fixed levels
fixedLevels.push_back(dfMaximum);
}

if (!fixedLevels.empty())
Expand All @@ -814,6 +849,11 @@ CPLErr GDALContourGenerateEx(GDALRasterBandH hBand, void *hLayer,
-std::numeric_limits<double>::infinity(), dfMaximum);
SegmentMerger<RingAppender, FixedLevelRangeIterator> writer(
appender, levels, /* polygonize */ true);
std::vector<int> aoiSkipLevels;
// Skip first and last levels (min/max) in polygonal case
aoiSkipLevels.push_back(0);
aoiSkipLevels.push_back(static_cast<int>(levels.levelsCount()));
writer.setSkipLevels(aoiSkipLevels);
ContourGeneratorFromRaster<decltype(writer),
FixedLevelRangeIterator>
cg(hBand, useNoData, noDataValue, writer, levels);
Expand Down
5 changes: 5 additions & 0 deletions alg/gdalwarper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1284,6 +1284,10 @@ CPLErr GDALWarpDstAlphaMasker(void *pMaskFuncArg, int nBandCount,
* EXCLUDED_VALUES_PCT_THRESHOLD.
* Only taken into account by Average currently.</li>
*
* <li>MODE_TIES=FIRST/MIN/MAX: (GDAL >= 3.11) Strategy to use when breaking
* ties with MODE resampling. By default, the first value encountered will be used.
* Alternatively, the minimum or maximum value can be selected.</li>
*
* </ul>
*/

Expand All @@ -1305,6 +1309,7 @@ GDALWarpOptions *CPL_STDCALL GDALCreateWarpOptions()
psOptions->eResampleAlg = GRA_NearestNeighbour;
psOptions->pfnProgress = GDALDummyProgress;
psOptions->eWorkingDataType = GDT_Unknown;
psOptions->eTieStrategy = GWKTS_First;

return psOptions;
}
Expand Down
12 changes: 12 additions & 0 deletions alg/gdalwarper.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ CPLErr CPL_DLL GDALWarpCutlineMaskerEx(void *pMaskFuncArg, int nBandCount,

/*! @endcond */

/*! GWKMode tie-breaking strategy */
typedef enum
{
/* Choose the first value encountered */ GWKTS_First = 1,
/* Choose the minimal value */ GWKTS_Min = 2,
/* Choose the maximum value */ GWKTS_Max = 3,
} GWKTieStrategy;

/************************************************************************/
/* GDALWarpOptions */
/************************************************************************/
Expand Down Expand Up @@ -243,6 +251,8 @@ typedef struct
* zero. */
double dfCutlineBlendDist;

/** Tie-breaking method */
GWKTieStrategy eTieStrategy;
} GDALWarpOptions;

GDALWarpOptions CPL_DLL *CPL_STDCALL GDALCreateWarpOptions(void);
Expand Down Expand Up @@ -451,6 +461,8 @@ class CPL_DLL GDALWarpKernel
// Average currently
std::vector<std::vector<double>> m_aadfExcludedValues{};

GWKTieStrategy eTieStrategy;

/*! @endcond */

GDALWarpKernel();
Expand Down
Loading
Loading