Exemple #1
0
def reallocClassRaster(image_input,
                       image_output,
                       table_reallocation,
                       path_time_log,
                       overwrite=True):

    # Mise à jour du Log
    starting_event = "reallocClassRaster() : Realocation micro class on classification image starting : "
    timeLine(path_time_log, starting_event)

    CODAGE = "uint16"

    if debug >= 3:
        print(cyan + "reallocClassRaster() : " + endC + "image_input : " +
              str(image_input))
        print(cyan + "reallocClassRaster() : " + endC + "image_output : " +
              str(image_output))
        print(cyan + "reallocClassRaster() : " + endC +
              "table_reallocation : " + str(table_reallocation))
        print(cyan + "reallocClassRaster() : " + endC + "path_time_log : " +
              str(path_time_log))
        print(cyan + "reallocClassRaster() : " + endC + "overwrite : " +
              str(overwrite))

    print(cyan + "reallocClassRaster() : " + bold + green + "START ...\n" +
          endC)

    # Lecture du fichier table de proposition
    supp_class_list, reaff_class_list, macro_reaff_class_list, sub_sampling_class_list, sub_sampling_number_list = readReallocationTable(
        table_reallocation)

    if debug >= 3:
        print("supp_class_list : " + str(supp_class_list))
        print("reaff_class_list : " + str(reaff_class_list))
        print("macro_reaff_class_list : " + str(macro_reaff_class_list))

    # Gestion du cas de suppression
    if len(supp_class_list) > 0:
        print(
            cyan + "reallocClassRaster() : " + bold + yellow +
            "ATTENTION : Les classes %s vont être supprimees dans le  fichier classification format raster."
            % (str(supp_class_list)) + endC)
        for supp_class in supp_class_list:
            reaff_class_list.append(supp_class)
            macro_reaff_class_list.append(0)

    # Gestion du cas de réaffectation
    if len(reaff_class_list) > 0:
        reallocateClassRaster(image_input, image_output, reaff_class_list,
                              macro_reaff_class_list, CODAGE)
    else:
        shutil.copyfile(image_input, image_output)

    print(cyan + "reallocClassRaster() : " + bold + green + "END\n" + endC)

    # Mise à jour du Log
    ending_event = "reallocClassRaster() : Realocation micro class on classification image ending : "
    timeLine(path_time_log, ending_event)
    return
Exemple #2
0
def comparareClassificationToReferenceGrid(image_input,
                                           vector_cut_input,
                                           vector_sample_input,
                                           vector_grid_input,
                                           vector_grid_output,
                                           size_grid,
                                           field_value_verif,
                                           no_data_value,
                                           path_time_log,
                                           epsg=2154,
                                           format_raster='GTiff',
                                           format_vector="ESRI Shapefile",
                                           extension_raster=".tif",
                                           extension_vector=".shp",
                                           save_results_intermediate=False,
                                           overwrite=True):

    # Mise à jour du Log
    starting_event = "comparareClassificationToReferenceGrid() : starting : "
    timeLine(path_time_log, starting_event)

    print(endC)
    print(bold + green +
          "## START : COMPARE QUALITY FROM CLASSIF IMAGE BY GRID" + endC)
    print(endC)

    if debug >= 2:
        print(
            bold + green +
            "comparareClassificationToReferenceGrid() : Variables dans la fonction"
            + endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "image_input : " + str(image_input) + endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "vector_cut_input : " + str(vector_cut_input) + endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "vector_sample_input : " + str(vector_sample_input) + endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "vector_grid_input : " + str(vector_grid_input) + endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "vector_grid_output : " + str(vector_grid_output) + endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "size_grid : " + str(size_grid) + endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "field_value_verif : " + str(field_value_verif))
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "no_data_value : " + str(no_data_value))
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "path_time_log : " + str(path_time_log) + endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "epsg  : " + str(epsg) + endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "format_raster : " + str(format_raster) + endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "format_vector : " + str(format_vector) + endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "extension_raster : " + str(extension_raster) + endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "extension_vector : " + str(extension_vector) + endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "save_results_intermediate : " + str(save_results_intermediate) +
              endC)
        print(cyan + "comparareClassificationToReferenceGrid() : " + endC +
              "overwrite : " + str(overwrite) + endC)

    # ETAPE 0 : PREPARATION DES FICHIERS INTERMEDIAIRES'

    CODAGE = "uint16"
    SUFFIX_STUDY = '_study'
    SUFFIX_TEMP = '_temp'
    SUFFIX_FUSION = '_other_fusion'

    NONE_VALUE_QUANTITY = -1.0
    FIELD_VALUE_OTHER = 65535

    FIELD_NAME_ID = "id"
    FIELD_NAME_RATE_BUILD = "rate_build"
    FIELD_NAME_RATE_OTHER = "rate_other"
    FIELD_NAME_SREF_BUILD = "sref_build"
    FIELD_NAME_SCLA_BUILD = "scla_build"
    FIELD_NAME_SREF_OTHER = "sref_other"
    FIELD_NAME_SCLA_OTHER = "scla_other"
    FIELD_NAME_KAPPA = "kappa"
    FIELD_NAME_ACCURACY = "accuracy"

    pixel_size_x, pixel_size_y = getPixelWidthXYImage(image_input)

    repertory_output = os.path.dirname(vector_grid_output)
    base_name = os.path.splitext(os.path.basename(vector_grid_output))[0]

    vector_study = repertory_output + os.sep + base_name + SUFFIX_STUDY + extension_vector
    vector_grid_temp = repertory_output + os.sep + base_name + SUFFIX_TEMP + extension_vector
    image_raster_other_fusion = repertory_output + os.sep + base_name + SUFFIX_FUSION + extension_raster

    # ETAPE 0 : VERIFICATION

    # Verification de la valeur de la nomemclature à verifier
    if field_value_verif >= FIELD_VALUE_OTHER:
        print(
            cyan + "comparareClassificationToReferenceGrid() : " + bold + red +
            "Attention de valeur de nomenclature à vérifier  : " +
            str(field_value_verif) +
            " doit être inferieur à la valeur de fusion des valeur autre arbitraire de : "
            + str(FIELD_VALUE_OTHER) + endC,
            file=sys.stderr)
        sys.exit(1)  #exit with an error code

    # ETAPE 1 : DEFINIR UN SHAPE ZONE D'ETUDE

    if (not vector_cut_input is None) and (vector_cut_input != "") and (
            os.path.isfile(vector_cut_input)):
        cutting_action = True
        vector_study = vector_cut_input
    else:
        cutting_action = False
        createVectorMask(image_input, vector_study)

    # ETAPE 2 : UNIFORMISATION DE LA ZONE OTHER

    # Réalocation des valeurs de classification pour les valeurs autre que le bati
    change_reaff_value_list = []
    reaff_value_list = identifyPixelValues(image_input)
    if field_value_verif in reaff_value_list:
        reaff_value_list.remove(field_value_verif)
    if no_data_value in reaff_value_list:
        reaff_value_list.remove(no_data_value)
    for elem in reaff_value_list:
        change_reaff_value_list.append(FIELD_VALUE_OTHER)
    reallocateClassRaster(image_input, image_raster_other_fusion,
                          reaff_value_list, change_reaff_value_list)

    # ETAPE 3 : CREATION DE LA GRILLE SUR LA ZONE D'ETUDE

    # Définir les attibuts du fichier
    attribute_dico = {
        FIELD_NAME_ID: ogr.OFTInteger,
        FIELD_NAME_RATE_BUILD: ogr.OFTReal,
        FIELD_NAME_RATE_OTHER: ogr.OFTReal,
        FIELD_NAME_SREF_BUILD: ogr.OFTReal,
        FIELD_NAME_SCLA_BUILD: ogr.OFTReal,
        FIELD_NAME_SREF_OTHER: ogr.OFTReal,
        FIELD_NAME_SCLA_OTHER: ogr.OFTReal,
        FIELD_NAME_KAPPA: ogr.OFTReal,
        FIELD_NAME_ACCURACY: ogr.OFTReal
    }
    nb_polygon = 0

    if (not vector_grid_input is None) and (vector_grid_input != "") and (
            os.path.isfile(vector_grid_input)):
        # Utilisation du fichier grille d'entrée

        # Recopie du fichier grille d'entrée vers le fichier grille de sortie
        copyVectorFile(vector_grid_input, vector_grid_output)

        # Ajout des champs au fichier grille de sortie
        for field_name in attribute_dico:
            addNewFieldVector(vector_grid_output, field_name,
                              attribute_dico[field_name], None, None, None,
                              format_vector)

        # Mettre le champs "id" identifiant du carré de l'élément de la grille
        nb_polygon = updateIndexVector(vector_grid_output, FIELD_NAME_ID,
                                       format_vector)

    else:
        # Si il n'existe pas de fichier grille on en créer un avec la valeur de size_grid

        # Creer le fichier grille
        nb_polygon = createGridVector(vector_study, vector_grid_temp,
                                      size_grid, size_grid, attribute_dico,
                                      overwrite, epsg, format_vector)

        # Découper la grille avec le shape zone d'étude
        cutVectorAll(vector_study, vector_grid_temp, vector_grid_output,
                     format_vector)

    # ETAPE 4 : CALCUL DE L'INDICATEUR DE QUALITE POUR CHAQUE CASE DE LA GRILLE

    if debug >= 2:
        print(bold + "nb_polygon = " + endC + str(nb_polygon) + "\n")

    # Pour chaque polygone existant
    sum_rate_quantity_build = 0
    nb_rate_sum = 0
    size_area_pixel = abs(pixel_size_x * pixel_size_y)

    for id_polygon in range(nb_polygon):
        geom_list = getGeomPolygons(vector_grid_output, FIELD_NAME_ID,
                                    id_polygon, format_vector)
        if geom_list is not None and geom_list != []:  # and (id_polygon == 24 or id_polygon == 30):

            if debug >= 1:
                print(cyan + "comparareClassificationToReferenceGrid() : " +
                      bold + green +
                      "Calcul de la matrice pour le polygon n°: " +
                      str(id_polygon) + endC)

            geom = geom_list[0]
            class_ref_list, class_pro_list, rate_quantity_list, kappa, accuracy, matrix = computeQualityIndiceRateQuantity(
                image_raster_other_fusion, vector_sample_input,
                repertory_output, base_name + str(id_polygon), geom, size_grid,
                pixel_size_x, pixel_size_y, field_value_verif,
                FIELD_VALUE_OTHER, no_data_value, epsg, format_raster,
                format_vector, extension_raster, extension_vector, overwrite,
                save_results_intermediate)

            # Si les calculs indicateurs de qualité sont ok
            if debug >= 2:
                print(matrix)
            if matrix != None and matrix != [] and matrix[0] != []:

                # Récuperer la quantité de bati et calcul de la surface de référence et de la surface de classification (carreau entier ou pas!)
                if len(class_ref_list) == 2 and len(
                        class_pro_list
                ) == 2:  # Cas ou l'on a des pixels de build et other (en ref et en prod)
                    rate_quantity_build = rate_quantity_list[0]
                    rate_quantity_other = rate_quantity_list[1]
                    size_area_ref_build = (matrix[0][0] +
                                           matrix[0][1]) * size_area_pixel
                    size_area_classif_build = (matrix[0][0] +
                                               matrix[1][0]) * size_area_pixel
                    size_area_ref_other = (matrix[1][0] +
                                           matrix[1][1]) * size_area_pixel
                    size_area_classif_other = (matrix[0][1] +
                                               matrix[1][1]) * size_area_pixel
                    sum_rate_quantity_build += rate_quantity_build
                    nb_rate_sum += 1

                else:  # Cas ou l'on a uniquement des pixels de build OU uniquement des pixels de other

                    if class_ref_list[
                            0] == field_value_verif:  # Cas ou l'on a uniquement des pixels references build
                        rate_quantity_build = rate_quantity_list[0]
                        rate_quantity_other = NONE_VALUE_QUANTITY
                        size_area_ref_other = 0

                        if len(
                                class_pro_list
                        ) == 2:  # Cas ou l'on a des pixels de prod build et other
                            size_area_ref_build = (
                                matrix[0][0] + matrix[0][1]) * size_area_pixel
                            size_area_classif_build = matrix[0][
                                0] * size_area_pixel
                            size_area_classif_other = matrix[0][
                                1] * size_area_pixel

                        else:
                            size_area_ref_build = matrix[0][0] * size_area_pixel
                            if class_pro_list[
                                    0] == field_value_verif:  # Cas ou l'on a uniquement des pixels prod build
                                size_area_classif_build = matrix[0][
                                    0] * size_area_pixel
                                size_area_classif_other = 0

                            else:  # Cas ou l'on a uniquement des pixels prod other
                                size_area_classif_build = 0
                                size_area_classif_other = matrix[0][
                                    0] * size_area_pixel

                    else:  # Cas ou l'on a uniquement des pixels references other
                        rate_quantity_build = NONE_VALUE_QUANTITY
                        rate_quantity_other = rate_quantity_list[0]
                        size_area_ref_build = 0

                        if len(
                                class_pro_list
                        ) == 2:  # Cas ou l'on a des pixels de prod build et other
                            size_area_ref_other = (
                                matrix[0][0] + matrix[0][1]) * size_area_pixel
                            size_area_classif_build = matrix[0][
                                0] * size_area_pixel
                            size_area_classif_other = matrix[0][
                                1] * size_area_pixel

                        else:
                            size_area_ref_other = matrix[0][0] * size_area_pixel
                            if class_pro_list[
                                    0] == field_value_verif:  # Cas ou l'on a uniquement des pixels prod build
                                size_area_classif_build = matrix[0][
                                    0] * size_area_pixel
                                size_area_classif_other = 0

                            else:  # Cas ou l'on a uniquement des pixels prod other
                                size_area_classif_build = 0
                                size_area_classif_other = matrix[0][
                                    0] * size_area_pixel

                # Mettre à jour ses éléments du carré de la grille
                setAttributeValues(
                    vector_grid_output, FIELD_NAME_ID, id_polygon, {
                        FIELD_NAME_RATE_BUILD: rate_quantity_build,
                        FIELD_NAME_RATE_OTHER: rate_quantity_other,
                        FIELD_NAME_SREF_BUILD: size_area_ref_build,
                        FIELD_NAME_SCLA_BUILD: size_area_classif_build,
                        FIELD_NAME_SREF_OTHER: size_area_ref_other,
                        FIELD_NAME_SCLA_OTHER: size_area_classif_other,
                        FIELD_NAME_KAPPA: kappa,
                        FIELD_NAME_ACCURACY: accuracy
                    }, format_vector)

    # Calcul de la moyenne
    if nb_rate_sum != 0:
        average_quantity_build = sum_rate_quantity_build / nb_rate_sum
    else:
        average_quantity_build = 0
    if debug >= 2:
        print(bold + "nb_polygon_used = " + endC + str(nb_rate_sum))
        print(bold + "average_quantity_build = " + endC +
              str(average_quantity_build) + "\n")

    # ETAPE 5 : SUPPRESIONS FICHIERS INTERMEDIAIRES INUTILES

    # Suppression des données intermédiairess
    if not save_results_intermediate:

        if not cutting_action:
            if os.path.isfile(vector_study):
                removeVectorFile(vector_study)

        if os.path.isfile(image_raster_other_fusion):
            removeFile(image_raster_other_fusion)

        if os.path.isfile(vector_grid_temp):
            removeVectorFile(vector_grid_temp)

    print(endC)
    print(bold + green +
          "## END : COMPARE QUALITY FROM CLASSIF IMAGE BY GRID" + endC)
    print(endC)

    # Mise à jour du Log
    ending_event = "comparareClassificationToReferenceGrid() :  ending : "
    timeLine(path_time_log, ending_event)

    return average_quantity_build
def occupationIndicator(input_grid,
                        output_grid,
                        class_label_dico_out,
                        input_vector_classif,
                        field_classif_name,
                        input_soil_occupation,
                        input_height_model,
                        class_build_list,
                        class_road_list,
                        class_baresoil_list,
                        class_water_list,
                        class_vegetation_list,
                        class_high_vegetation_list,
                        class_low_vegetation_list,
                        epsg=2154,
                        no_data_value=0,
                        format_raster='GTiff',
                        format_vector='ESRI Shapefile',
                        extension_raster='.tif',
                        extension_vector='.shp',
                        path_time_log='',
                        save_results_intermediate=False,
                        overwrite=True):

    if debug >= 3:
        print(
            '\n' + bold + green +
            "Calcul d'indicateurs du taux de classes OCS - Variables dans la fonction :"
            + endC)
        print(cyan + "    occupationIndicator() : " + endC + "input_grid : " +
              str(input_grid) + endC)
        print(cyan + "    occupationIndicator() : " + endC + "output_grid : " +
              str(output_grid) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "class_label_dico_out : " + str(class_label_dico_out) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "input_vector_classif : " + str(input_vector_classif) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "field_classif_name : " + str(field_classif_name) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "input_soil_occupation : " + str(input_soil_occupation) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "input_height_model : " + str(input_height_model) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "class_build_list : " + str(class_build_list) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "class_road_list : " + str(class_road_list) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "class_baresoil_list : " + str(class_baresoil_list) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "class_water_list : " + str(class_water_list) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "class_vegetation_list : " + str(class_vegetation_list) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "class_high_vegetation_list : " +
              str(class_high_vegetation_list) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "class_low_vegetation_list : " + str(class_low_vegetation_list) +
              endC)
        print(cyan + "    occupationIndicator() : " + endC + "epsg : " +
              str(epsg) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "no_data_value : " + str(no_data_value) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "format_raster : " + str(format_raster) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "format_vector : " + str(format_vector) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "extension_raster : " + str(extension_raster) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "extension_vector : " + str(extension_vector) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "path_time_log : " + str(path_time_log) + endC)
        print(cyan + "    occupationIndicator() : " + endC +
              "save_results_intermediate : " + str(save_results_intermediate) +
              endC)
        print(cyan + "    occupationIndicator() : " + endC + "overwrite : " +
              str(overwrite) + endC + '\n')

    # Définition des constantes
    CODAGE_8BITS = 'uint8'
    CODAGE_FLOAT = 'float'
    NODATA_FIELD = 'nodata'

    PREFIX_S = 'S_'
    SUFFIX_TEMP = '_temp'
    SUFFIX_RASTER = '_raster'
    SUFFIX_HEIGHT = '_height'
    SUFFIX_VEGETATION = '_vegetation'

    VEG_MEAN_FIELD = 'veg_h_mean'
    VEG_MAX_FIELD = 'veg_h_max'
    VEG_RATE_FIELD = 'veg_h_rate'
    MAJ_OCS_FIELD = 'class_OCS'

    BUILT_FIELD, BUILT_LABEL = 'built', 1
    MINERAL_FIELD, MINERAL_LABEL = 'mineral', 2
    BARESOIL_FIELD, BARESOIL_LABEL = 'baresoil', 3
    WATER_FIELD, WATER_LABEL = 'water', 4
    VEGETATION_FIELD, VEGETATION_LABEL = 'veget', 5
    HIGH_VEGETATION_FIELD, HIGH_VEGETATION_LABEL = 'high_veg', 6
    LOW_VEGETATION_FIELD, LOW_VEGETATION_LABEL = 'low_veg', 7

    # Mise à jour du log
    starting_event = "occupationIndicator() : Début du traitement : "
    timeLine(path_time_log, starting_event)

    print(cyan + "occupationIndicator() : " + bold + green +
          "DEBUT DES TRAITEMENTS" + endC + '\n')

    # Définition des variables 'basename'
    output_grid_basename = os.path.basename(os.path.splitext(output_grid)[0])
    output_grid_dirname = os.path.dirname(output_grid)
    soil_occupation_basename = os.path.basename(
        os.path.splitext(input_soil_occupation)[0])

    # Définition des variables temp
    temp_directory = output_grid_dirname + os.sep + output_grid_basename
    temp_grid = temp_directory + os.sep + output_grid_basename + SUFFIX_TEMP + extension_vector
    temp_soil_occupation = temp_directory + os.sep + soil_occupation_basename + SUFFIX_TEMP + SUFFIX_RASTER + extension_raster
    temp_height_vegetation = temp_directory + os.sep + output_grid_basename + SUFFIX_HEIGHT + SUFFIX_VEGETATION + extension_raster

    # Nettoyage des traitements précédents
    if overwrite:
        if debug >= 3:
            print(cyan + "occupationIndicator() : " + endC +
                  "Nettoyage des traitements précédents." + endC + '\n')
        removeFile(output_grid)
        cleanTempData(temp_directory)
    else:
        if os.path.exists(output_grid):
            raise NameError(
                cyan + "occupationIndicator() : " + bold + yellow +
                "Le fichier de sortie existe déjà et ne sera pas regénéré." +
                endC + '\n')
        pass

    #############
    # Etape 0/3 # Préparation des traitements
    #############

    print(cyan + "occupationIndicator() : " + bold + green +
          "ETAPE 0/3 - Début de la préparation des traitements." + endC + '\n')

    # Rasterisation de l'information de classification (OCS) si au format vecteur en entrée
    if input_vector_classif != "":
        if debug >= 3:
            print(cyan + "occupationIndicator() : " + endC + bold +
                  "Rasterisation de l'OCS vecteur." + endC + '\n')
        reference_image = input_soil_occupation
        soil_occupation_vector_basename = os.path.basename(
            os.path.splitext(input_vector_classif)[0])
        input_soil_occupation = temp_directory + os.sep + soil_occupation_vector_basename + SUFFIX_RASTER + extension_raster
        command = "otbcli_Rasterization -in %s -out %s %s -im %s -background 0 -mode attribute -mode.attribute.field %s" % (
            input_vector_classif, input_soil_occupation, CODAGE_8BITS,
            reference_image, field_classif_name)
        if debug >= 3:
            print(command)
        exit_code = os.system(command)
        if exit_code != 0:
            raise NameError(
                cyan + "occupationIndicator() : " + bold + red +
                "Erreur lors de la rasterisation de l'OCS vecteur." + endC)

    # Analyse de la couche OCS raster
    class_other_list = identifyPixelValues(input_soil_occupation)
    no_data_ocs = getNodataValueImage(input_soil_occupation, 1)
    if no_data_ocs != None:
        no_data_value = no_data_ocs

    # Affectation de nouveaux codes de classification
    divide_vegetation_classes = False
    if class_high_vegetation_list != [] and class_low_vegetation_list != []:
        divide_vegetation_classes = True

    col_to_delete_list = [
        "minority", PREFIX_S + NODATA_FIELD, PREFIX_S + BUILT_FIELD,
        PREFIX_S + MINERAL_FIELD, PREFIX_S + BARESOIL_FIELD,
        PREFIX_S + WATER_FIELD
    ]
    class_label_dico = {
        int(no_data_value): NODATA_FIELD,
        int(BUILT_LABEL): BUILT_FIELD,
        int(MINERAL_LABEL): MINERAL_FIELD,
        int(BARESOIL_LABEL): BARESOIL_FIELD,
        int(WATER_LABEL): WATER_FIELD
    }
    if not divide_vegetation_classes:
        class_label_dico[int(VEGETATION_LABEL)] = VEGETATION_FIELD
        col_to_delete_list.append(PREFIX_S + VEGETATION_FIELD)
    else:
        class_label_dico[int(HIGH_VEGETATION_LABEL)] = HIGH_VEGETATION_FIELD
        class_label_dico[int(LOW_VEGETATION_LABEL)] = LOW_VEGETATION_FIELD
        col_to_delete_list.append(PREFIX_S + HIGH_VEGETATION_FIELD)
        col_to_delete_list.append(PREFIX_S + LOW_VEGETATION_FIELD)

    # Gestion de la réaffectation des classes
    if debug >= 3:
        print(cyan + "occupationIndicator() : " + endC + bold +
              "Reaffectation du raster OCS." + endC + '\n')

    reaff_class_list = []
    macro_reaff_class_list = []

    for label in class_build_list:
        if label in class_other_list:
            class_other_list.remove(label)
        reaff_class_list.append(label)
        macro_reaff_class_list.append(BUILT_LABEL)

    for label in class_road_list:
        if label in class_other_list:
            class_other_list.remove(label)
        reaff_class_list.append(label)
        macro_reaff_class_list.append(MINERAL_LABEL)

    for label in class_baresoil_list:
        if label in class_other_list:
            class_other_list.remove(label)
        reaff_class_list.append(label)
        macro_reaff_class_list.append(BARESOIL_LABEL)

    for label in class_water_list:
        if label in class_other_list:
            class_other_list.remove(label)
        reaff_class_list.append(label)
        macro_reaff_class_list.append(WATER_LABEL)

    if not divide_vegetation_classes:
        for label in class_vegetation_list:
            if label in class_other_list:
                class_other_list.remove(label)
            reaff_class_list.append(label)
            macro_reaff_class_list.append(VEGETATION_LABEL)
    else:
        for label in class_high_vegetation_list:
            if label in class_other_list:
                class_other_list.remove(label)
            reaff_class_list.append(label)
            macro_reaff_class_list.append(HIGH_VEGETATION_LABEL)
        for label in class_low_vegetation_list:
            if label in class_other_list:
                class_other_list.remove(label)
            reaff_class_list.append(label)
            macro_reaff_class_list.append(LOW_VEGETATION_LABEL)

    # Reste des valeurs de pixel nom utilisé
    for label in class_other_list:
        reaff_class_list.append(label)
        macro_reaff_class_list.append(no_data_value)

    reallocateClassRaster(input_soil_occupation, temp_soil_occupation,
                          reaff_class_list, macro_reaff_class_list,
                          CODAGE_8BITS)

    print(cyan + "occupationIndicator() : " + bold + green +
          "ETAPE 0/3 - Fin de la préparation des traitements." + endC + '\n')

    #############
    # Etape 1/3 # Calcul des indicateurs de taux de classes OCS
    #############

    print(
        cyan + "occupationIndicator() : " + bold + green +
        "ETAPE 1/3 - Début du calcul des indicateurs de taux de classes OCS." +
        endC + '\n')

    if debug >= 3:
        print(cyan + "occupationIndicator() : " + endC + bold +
              "Calcul des indicateurs de taux de classes OCS." + endC + '\n')

    statisticsVectorRaster(temp_soil_occupation, input_grid, temp_grid, 1,
                           True, True, False, col_to_delete_list, [],
                           class_label_dico, path_time_log, True,
                           format_vector, save_results_intermediate, overwrite)

    # Fusion des classes végétation dans le cas où haute et basse sont séparées (pour utilisation du taux de végétation dans le logigramme)
    if divide_vegetation_classes:
        temp_grid_v2 = os.path.splitext(
            temp_grid)[0] + "_v2" + extension_vector
        sql_statement = "SELECT *, (%s + %s) AS %s FROM %s" % (
            HIGH_VEGETATION_FIELD, LOW_VEGETATION_FIELD, VEGETATION_FIELD,
            os.path.splitext(os.path.basename(temp_grid))[0])
        os.system("ogr2ogr -sql '%s' -dialect SQLITE %s %s" %
                  (sql_statement, temp_grid_v2, temp_grid))
        removeVectorFile(temp_grid, format_vector=format_vector)
        copyVectorFile(temp_grid_v2, temp_grid, format_vector=format_vector)

    print(cyan + "occupationIndicator() : " + bold + green +
          "ETAPE 1/3 - Fin du calcul des indicateurs de taux de classes OCS." +
          endC + '\n')

    #############
    # Etape 2/3 # Calcul de l'indicateur de "hauteur de végétation"
    #############

    print(
        cyan + "occupationIndicator() : " + bold + green +
        "ETAPE 2/3 - Début du calcul de l'indicateur de \"hauteur de végétation\"."
        + endC + '\n')

    computeVegetationHeight(
        temp_grid, output_grid, temp_soil_occupation, input_height_model,
        temp_height_vegetation, divide_vegetation_classes, VEGETATION_LABEL,
        HIGH_VEGETATION_LABEL, LOW_VEGETATION_LABEL, HIGH_VEGETATION_FIELD,
        LOW_VEGETATION_FIELD, VEG_MEAN_FIELD, VEG_MAX_FIELD, VEG_RATE_FIELD,
        CODAGE_FLOAT, SUFFIX_TEMP, no_data_value, format_vector, path_time_log,
        save_results_intermediate, overwrite)

    print(
        cyan + "occupationIndicator() : " + bold + green +
        "ETAPE 2/3 - Fin du calcul de l'indicateur de \"hauteur de végétation\"."
        + endC + '\n')

    #############
    # Etape 3/3 # Calcul de l'indicateur de classe majoritaire
    #############

    print(
        cyan + "occupationIndicator() : " + bold + green +
        "ETAPE 3/3 - Début du calcul de l'indicateur de classe majoritaire." +
        endC + '\n')

    if input_height_model != "":
        computeMajorityClass(output_grid, temp_directory, NODATA_FIELD,
                             BUILT_FIELD, MINERAL_FIELD, BARESOIL_FIELD,
                             WATER_FIELD, VEGETATION_FIELD,
                             HIGH_VEGETATION_FIELD, LOW_VEGETATION_FIELD,
                             MAJ_OCS_FIELD, VEG_MEAN_FIELD,
                             class_label_dico_out, format_vector,
                             extension_vector, overwrite)
    else:
        print(
            cyan + "occupationIndicator() : " + bold + yellow +
            "Pas de calcul de l'indicateur de classe majoritaire demandé (pas de MNH en entrée)."
            + endC + '\n')

    print(cyan + "occupationIndicator() : " + bold + green +
          "ETAPE 3/3 - Fin du calcul de l'indicateur de classe majoritaire." +
          endC + '\n')

    ####################################################################

    # Suppression des fichiers temporaires
    if not save_results_intermediate:
        if debug >= 3:
            print(cyan + "occupationIndicator() : " + endC +
                  "Suppression des fichiers temporaires." + endC + '\n')
        deleteDir(temp_directory)

    print(cyan + "occupationIndicator() : " + bold + green +
          "FIN DES TRAITEMENTS" + endC + '\n')

    # Mise à jour du log
    ending_event = "occupationIndicator() : Fin du traitement : "
    timeLine(path_time_log, ending_event)

    return 0
def addCorrectionClass(image_input, image_output, class_add_data_dico, path_time_log, save_results_intermediate=False, overwrite=True) :

    # Mise à jour du Log
    starting_event = "addCorrectionClass() : Add data file treat to classification starting : "
    timeLine(path_time_log,starting_event)

    # print
    if debug >= 3:
        print(bold + green + "Variables dans la fonction" + endC)
        print(cyan + "addCorrectionClass() : " + endC + "image_input : " + str(image_input) + endC)
        print(cyan + "addCorrectionClass() : " + endC + "image_output : " + str(image_output) + endC)
        print(cyan + "addCorrectionClass() : " + endC + "class_add_data_dico : " + str(class_add_data_dico) + endC)
        print(cyan + "addCorrectionClass() : " + endC + "path_time_log : " + str(path_time_log) + endC)
        print(cyan + "addCorrectionClass() : " + endC + "save_results_intermediate : " + str(save_results_intermediate) + endC)
        print(cyan + "addCorrectionClass() : " + endC + "overwrite : " + str(overwrite) + endC)

    # Constantes
    FOLDER_MASK_TEMP = 'Mask_'
    SUFFIX_MASK = '_mask_'
    SUFFIX_MASK_FUSION = '_mask_fusion_'
    SUFFIX_CLASS_FUSION = '_macro_class_'
    CODAGE = "uint16"
    CODAGE_8B = "uint8"

    # Définition du répertoire temporaire
    name = os.path.splitext(os.path.basename(image_output))[0]
    repertory_samples_output = os.path.dirname(image_output)
    repertory_temp = repertory_samples_output + os.sep + FOLDER_MASK_TEMP + name

    # Création du répertoire temporaire si il n'existe pas
    if not os.path.isdir(repertory_temp):
        os.makedirs(repertory_temp)

    # Nettoyage du répertoire temporaire si il n'est pas vide
    cleanTempData(repertory_temp)

    # Test si le fichier résultat existent déjà et si ils doivent être écrasés
    check = os.path.isfile(image_output)
    if check and not overwrite: # Si les fichiers echantillons existent deja et que overwrite n'est pas activé
        print(bold + yellow + "File output : " + image_output + " already exists and will not be created again." + endC)
    else :
        if check:
            try:
                removeFile(image_output)
            except Exception:
                pass # si le fichier n'existe pas, il ne peut pas être supprimé : cette étape est ignorée

        image_combined_list = []
        # Parcours du dictionnaire associant les macroclasses aux noms de fichiers et aux traitement associés
        for macroclass_label in class_add_data_dico :
            if debug >= 3:
                print("\nmacroclass_label : " + str(macroclass_label))

            mask_fusion_list = []
            # Parcours des fichiers à ajouter à la macro class
            for treatement_info_list in class_add_data_dico[macroclass_label] :
                input_image_to_treat = treatement_info_list[0]
                threshold_min = float(treatement_info_list[1])
                threshold_max = float(treatement_info_list[2])
                if debug >= 3:
                    print("input_image_to_treat : " + str(input_image_to_treat))
                    print("threshold_min : " + str(threshold_min))
                    print("threshold_max : " + str(threshold_max))

                # Traitement préparation
                file_mask_output_temp = repertory_temp + os.sep + os.path.splitext(os.path.basename(input_image_to_treat))[0] + SUFFIX_MASK + macroclass_label + os.path.splitext(input_image_to_treat)[1]
                if os.path.isfile(file_mask_output_temp) :
                    removeFile(file_mask_output_temp)
                mask_fusion_list.append(file_mask_output_temp)

                # Creation masque binaire
                createBinaryMaskThreshold(input_image_to_treat, file_mask_output_temp, threshold_min, threshold_max)

            # Fusion des masques
            file_mask_output_fusion = repertory_temp + os.sep + os.path.splitext(os.path.basename(image_output))[0] + SUFFIX_MASK_FUSION + macroclass_label + os.path.splitext(image_output)[1]
            file_macroclass_output_fusion = repertory_temp + os.sep + os.path.splitext(os.path.basename(image_output))[0] + SUFFIX_CLASS_FUSION + macroclass_label + os.path.splitext(image_output)[1]
            image_combined_list.append(file_macroclass_output_fusion)

            if len(mask_fusion_list) == 1:
                # Pas de traitement à faire simple copie
                shutil.copyfile(mask_fusion_list[0], file_mask_output_fusion)
            else :
                # Fusionne les images mask en un seul masque
                image_mask_input = mask_fusion_list[0]
                for idx_image in range(1,len(mask_fusion_list)):
                    print(idx_image)
                    if idx_image == len(mask_fusion_list)-1:
                        image_mask_output = file_mask_output_fusion
                    else :
                        image_mask_output = repertory_temp + os.sep + os.path.splitext(os.path.basename(image_output))[0] + SUFFIX_MASK_FUSION + macroclass_label + "_" + str(idx_image) + os.path.splitext(image_output)[1]

                    applyMaskAnd(image_mask_input, mask_fusion_list[idx_image], image_mask_output, CODAGE_8B)
                    image_mask_input = image_mask_output

            # Affectation du label de la macro class associé
            reaff_value_list =[]
            reaff_value_list.append(1)
            change_reaff_value_list = []
            change_reaff_value_list.append(int(macroclass_label))
            reallocateClassRaster(file_mask_output_fusion, file_macroclass_output_fusion, reaff_value_list, change_reaff_value_list, CODAGE)


        # Ajout de l'image de classification a la liste des image bd conbinées
        image_combined_list.append(image_input)
        # Fusionne les images raster et la classification
        mergeListRaster(image_combined_list, image_output, CODAGE)

    # Suppression des données intermédiaires
    if not save_results_intermediate:

        # Supression des .geom dans le dossier
        for to_delete in glob.glob(repertory_samples_output + os.sep + "*.geom"):
            removeFile(to_delete)

        # Suppression du repertoire temporaire
        deleteDir(repertory_temp)

    # Mise à jour du Log
    ending_event = "addCorrectionClass() : Add data file treat to classification ending : "
    timeLine(path_time_log,ending_event)

    return