hubflow.core.Classification reclassify fails to write GTiff category names

Issue #225 resolved
Benjamin Jakimow created an issue

hubflow.core.Classification.reclassify(...) allows to write a GTiff but fails to set the category names.

    def test_hubflow_reclassify(self):
        import hubflow.core
        from enmapbox.testing import TestObjects
        dsSrc = TestObjects.inMemoryImage(10,20,nc=5)
        self.assertIsInstance(dsSrc, gdal.Dataset)
        classNamesOld = ['Unclassified', 'Class 1', 'Class 2', 'Class 3', 'Class 4']
        self.assertEqual(dsSrc.GetRasterBand(1).GetCategoryNames(), classNamesOld)
        pathSrc = dsSrc.GetFileList()[0]
        self.assertTrue(pathSrc.startswith('/vsimem/'))
        pathDst = '/vsimem/testclasstiff.tif'

        classification = hubflow.core.Classification(pathSrc)
        oldDef = classification.classDefinition()
        self.assertEqual(oldDef.names(), classNamesOld[1:])

        newNames = ['No Class', 'Class B', 'Class D']
        newColors = [QColor('black'), QColor('yellow'), QColor('brown')]

        # this works
        c = hubflow.core.Color(QColor('black'))

        # but this does'nt
        #newDef = hubflow.core.ClassDefinition(names=newNames[1:], colors=newColors[1:])


        newDef = hubflow.core.ClassDefinition(names=newNames[1:], colors=[c.name() for c in newColors[1:]])
        newDef.setNoDataNameAndColor(newNames[0], QColor('yellow'))

        driver = hubflow.core.GTiffDriver()
        r = classification.reclassify(filename=pathDst,
                                  classDefinition=newDef,
                                  mapping={0:0,1:1,2:1},
                                    outclassificationDriver=driver)

        ds = gdal.Open(pathDst)

        self.assertIsInstance(ds, gdal.Dataset)
        self.assertTrue(ds.GetDriver().ShortName == 'GTiff')
        band = ds.GetRasterBand(1)
        self.assertIsInstance(band.GetCategoryNames(), list)
        self.assertEqual(newNames, band.GetCategoryNames())

Comments (3)

  1. Andreas Janz

    I heavily tested this. Here are my conclusion. Setting the category names and colors (internally done with gdal.Band.SetCategoryNames and gdal.Band.SetColorTable) requires to close the dataset to really flush the changes to disk. Another thing is: if a color table already exists for a Band, it can not be changed. After reopening the Dataset, all changes are gone. I created an issue for that in the GDAL issue tracker.

  2. Andreas Janz

    so in the code above:

    r = classification.reclassify(filename=pathDst,
                                      classDefinition=newDef,
                                      mapping={0:0,1:1,2:1},
                                        outclassificationDriver=driver)
    
            ds = gdal.Open(pathDst)
    

    "r" needs to be closed before reopening the result. Use r.dataset().close().

  3. Log in to comment