@@ -9015,6 +9015,37 @@ CPLErr CPL_STDCALL GDALSetDefaultRAT(GDALRasterBandH hBand,
90159015 return poBand->SetDefaultRAT (GDALRasterAttributeTable::FromHandle (hRAT));
90169016}
90179017
9018+ /* ***********************************************************************/
9019+ /* HasNoData() */
9020+ /* ***********************************************************************/
9021+
9022+ bool GDALRasterBand::HasNoData () const
9023+ {
9024+ int bHaveNoDataRaw = FALSE ;
9025+ bool bHaveNoData = false ;
9026+ GDALRasterBand *poThis = const_cast <GDALRasterBand *>(this );
9027+ if (eDataType == GDT_Int64)
9028+ {
9029+ CPL_IGNORE_RET_VAL (poThis->GetNoDataValueAsInt64 (&bHaveNoDataRaw));
9030+ bHaveNoData = CPL_TO_BOOL (bHaveNoDataRaw);
9031+ }
9032+ else if (eDataType == GDT_UInt64)
9033+ {
9034+ CPL_IGNORE_RET_VAL (poThis->GetNoDataValueAsUInt64 (&bHaveNoDataRaw));
9035+ bHaveNoData = CPL_TO_BOOL (bHaveNoDataRaw);
9036+ }
9037+ else
9038+ {
9039+ const double dfNoDataValue = poThis->GetNoDataValue (&bHaveNoDataRaw);
9040+ if (bHaveNoDataRaw &&
9041+ GDALNoDataMaskBand::IsNoDataInRange (dfNoDataValue, eDataType))
9042+ {
9043+ bHaveNoData = true ;
9044+ }
9045+ }
9046+ return bHaveNoData;
9047+ }
9048+
90189049/* ***********************************************************************/
90199050/* GetMaskBand() */
90209051/* ***********************************************************************/
@@ -9072,32 +9103,6 @@ CPLErr CPL_STDCALL GDALSetDefaultRAT(GDALRasterBandH hBand,
90729103GDALRasterBand *GDALRasterBand::GetMaskBand ()
90739104
90749105{
9075- const auto HasNoData = [this ]()
9076- {
9077- int bHaveNoDataRaw = FALSE ;
9078- bool bHaveNoData = false ;
9079- if (eDataType == GDT_Int64)
9080- {
9081- CPL_IGNORE_RET_VAL (GetNoDataValueAsInt64 (&bHaveNoDataRaw));
9082- bHaveNoData = CPL_TO_BOOL (bHaveNoDataRaw);
9083- }
9084- else if (eDataType == GDT_UInt64)
9085- {
9086- CPL_IGNORE_RET_VAL (GetNoDataValueAsUInt64 (&bHaveNoDataRaw));
9087- bHaveNoData = CPL_TO_BOOL (bHaveNoDataRaw);
9088- }
9089- else
9090- {
9091- const double dfNoDataValue = GetNoDataValue (&bHaveNoDataRaw);
9092- if (bHaveNoDataRaw &&
9093- GDALNoDataMaskBand::IsNoDataInRange (dfNoDataValue, eDataType))
9094- {
9095- bHaveNoData = true ;
9096- }
9097- }
9098- return bHaveNoData;
9099- };
9100-
91019106 if (poMask != nullptr )
91029107 {
91039108 if (poMask.IsOwned ())
@@ -9599,6 +9604,78 @@ GDALMaskValueRange GDALRasterBand::GetMaskValueRange() const
95999604 return GMVR_UNKNOWN;
96009605}
96019606
9607+ /* ***********************************************************************/
9608+ /* HasConflictingMaskSources() */
9609+ /* ***********************************************************************/
9610+
9611+ /* *
9612+ * \brief Returns whether a raster band has conflicting mask sources.
9613+ *
9614+ * That is, if more than one of the following conditions is met:
9615+ * - it has a binary mask band (that is not an alpha band)
9616+ * - it has an external mask flags (.msk file)
9617+ * - it has a nodata value
9618+ * - it belongs to a dataset with the NODATA_VALUES metadata item set
9619+ * - it belongs to a dataset that has a band with a GCI_AlphaBand color interpretation
9620+ *
9621+ * @param[out] posDetailMessage Pointer to a string that will contain the
9622+ * details of the conflict.
9623+ * @param bMentionPrioritarySource Whether the mask source used should be
9624+ * mentioned in *posDetailMessage.
9625+ * @since GDAL 3.13.0
9626+ */
9627+
9628+ bool GDALRasterBand::HasConflictingMaskSources (
9629+ std::string *posDetailMessage, bool bMentionPrioritarySource) const
9630+ {
9631+ const bool bHasExternalMask = poDS && poDS->oOvManager .HaveMaskFile ();
9632+ const bool bHasBinaryMaskBand =
9633+ ((const_cast <GDALRasterBand *>(this )->GetMaskFlags () &
9634+ (GMF_ALL_VALID | GMF_NODATA | GMF_ALPHA)) == 0 ) &&
9635+ (!bHasExternalMask || poDS->oOvManager .GetMaskBand (nBand) != this );
9636+ const bool bHasNoData = HasNoData ();
9637+ const bool bHasNODATA_VALUES =
9638+ poDS && poDS->GetMetadataItem (" NODATA_VALUES" );
9639+ const bool bHasAlphaBand =
9640+ poDS &&
9641+ poDS->GetRasterBand (poDS->GetRasterCount ())->GetColorInterpretation () ==
9642+ GCI_AlphaBand;
9643+ const bool abMaskSources[] = {bHasBinaryMaskBand, bHasExternalMask,
9644+ bHasNoData, bHasNODATA_VALUES, bHasAlphaBand};
9645+ const size_t nCount =
9646+ std::count (std::begin (abMaskSources), std::end (abMaskSources), true );
9647+ if (nCount >= 2 )
9648+ {
9649+ if (posDetailMessage)
9650+ {
9651+ *posDetailMessage = " Raster band " ;
9652+ *posDetailMessage += std::to_string (nBand);
9653+ if (poDS && poDS->GetDescription ()[0 ])
9654+ {
9655+ *posDetailMessage += " of dataset " ;
9656+ *posDetailMessage += poDS->GetDescription ();
9657+ }
9658+ *posDetailMessage += " has several conflicting mask sources:\n " ;
9659+ if (bHasExternalMask)
9660+ *posDetailMessage += " - internal binary mask band\n " ;
9661+ if (bHasExternalMask)
9662+ *posDetailMessage += " - external mask band (.msk)\n " ;
9663+ if (bHasNoData)
9664+ *posDetailMessage += " - nodata value\n " ;
9665+ if (bHasNODATA_VALUES)
9666+ *posDetailMessage += " - NODATA_VALUES dataset metadata item\n " ;
9667+ if (bHasAlphaBand)
9668+ *posDetailMessage +=
9669+ " - related to a raster band that is an alpha band\n " ;
9670+ if (bMentionPrioritarySource)
9671+ *posDetailMessage +=
9672+ " Only the first listed one will be taken into account." ;
9673+ }
9674+ return true ;
9675+ }
9676+ return false ;
9677+ }
9678+
96029679/* ***********************************************************************/
96039680/* GetIndexColorTranslationTo() */
96049681/* ***********************************************************************/
0 commit comments