lczexplore_fr

Matthieu Gousseff

2026-10-19

Présentation du paquet lczexplore

Origine et finalité

Le paquet lczexplore a été développé dans le cadre du projet Pændora 2 (Pour la gestion du confort estival : Données, Outils et Recherche-Action, 2022 -2025), de l’ADEME.

Il a pour objectif de faciliter la comparaison de classifications en zones climatiques locales produites par différents algorithmes sur une même zone. En amont de ce paquet, l’utilisateur aura affecté à chacune des unités de référence spatiales (RSU) de la zone d’étude une valeur de Zone Climatique Locale (LCZ). Plusieurs méthodes peuvent aboutir à plusieurs classifications. Ce paquet permet de représenter et de comparer ces classifications.

Installation

L’approche recommandée est l’installation depuis le dépôt github :devtools::install_github("orbisgis/lczexplore", build_vignettes = TRUE)).

Le charger avec library(lczexplore).

Cas général : charger un fichier contenant des géométries et les LCZ associées

Importer les fichiers contenant les LCZ avec la fonction importLCZvect

La fonction importLCZvect est la fonction générique d’import d’un fichier “vecteur” contenant les LCZ (pour les fichiers raster, voir la vignette “lcz_explore_raster_vector”). L’import des fichiers .fgb (format recommandé), .geojson et .shp a été testé, mais tous les formats acceptés par la fonction st_read de sf sont normalement importés sans problème.

L’argument dirPath permet d’indiquer le chemin du répertoire où se trouvent le fichier et l’argument file le nom du fichier. L’argument column, renseigne le nom de la colonne contenant les types de zones climatiques locales ou LCZ. Les arguments optionnels geomID et confid permettent de spécifier les colonnes contenant les identifiants des géométries et une mesure de la confiance qu’on a en la valeur de LCZ attribuée à une géométrie.

Par défaut, importLCZvect ressort un fichier de classe simple feature, telle que définie par l’OpenGIS et gérée par le paquet sf, paquet de référence pour la gestion des données vecteurs dans R [https://doi.org/10.32614/RJ-2018-009]. On peut également choisir output="bBox" pour que la fonction ressorte la bounding box des géométries contenues dans le fichier concerné (utile pour définir une zone et importer un raster, par exemple).

dirPath <- system.file("extdata/multipleWfs/Redon", package = "lczexplore")
redonOSM <- importLCZvect(dirPath = dirPath, file = "osm_lcz.fgb", column = "LCZ_PRIMARY", verbose = FALSE)
redonBDT <- importLCZvect(dirPath = dirPath, file = "bdt_lcz.fgb", column = "LCZ_PRIMARY", verbose = FALSE)

Représenter les LCZ avec la fonction showLCZ

Une fois que le fichier a été chargé dans un objet R de classe sf, la fonction showLCZ permet de le représenter. On lui spécifie le jeu de données qu’on a chargé par l’argument sf, et on lui précise la colonne contenant les valeurs de LCZ par l’argument column. L’argument wf permet de spécifier le workflow qui a servi à générer les données (il sera repris dans le titre du graphique produit).

Représentation standard

L’argument repr=standard (valeur par défaut), permet de gérer les niveaux de LCZ les plus usuels pour des cartes mises en forme avec des couleurs standardisées.

On remarque que par défaut, tous les niveaux attendus d’une classification LCZ sont présents, ce qui peut faciliter l’exploration de cartes où les niveaux présents ne sont pas les mêmes. Si on souhaite ne représenter que les niveaux présents dans les données, il suffit de préciser drop=TRUE et les niveaux absents ne seront pas représentés.

Représentation alternative

En utilisant la représentation non standard, soit repr="alter", on peut traiter les cas où : - on a procédé à un regroupement de modalités, - les LCZ ont un encodage particulier, - on veut utiliser d’autres couleurs, - on veut utiliser la fonction pour représenter d’autres variables (voir la fonction importQualVar).

On passera le vecteur contenant les valeurs possibles dans un vecteur, par exemple LCZlevels et les couleurs leur correspondant dans un vecteur qu’il faut nommer colors.

Si repr=alter et que LCZlvels et colors ne sont pas renseignés les couleurs sont choisies au sein de la palette “Polychrome 36” du package grDevice, et les niveaux déduits des valeurs présentes.

# Choix d'un vecteur de couleurs alternatif aléatoire
testCol <- palette.colors(n = 17, palette = "Polychrome 36")
map3 <- showLCZ(sf = redonOSM, wf = "OSM", column = "LCZ_PRIMARY", repr = "alter", colors = testCol, useStandCol = FALSE)
#> typeLevels before trying to group are #5A5156typeLevels before trying to group are #E4E1E3typeLevels before trying to group are #F6222EtypeLevels before trying to group are #FE00FAtypeLevels before trying to group are #16FF32typeLevels before trying to group are #3283FEtypeLevels before trying to group are #FEAF16typeLevels before trying to group are #B00068typeLevels before trying to group are #1CFFCEtypeLevels before trying to group are #90AD1CtypeLevels before trying to group are #2ED9FFtypeLevels before trying to group are #DEA0FDtypeLevels before trying to group are #AA0DFEtypeLevels before trying to group are #F8A19FtypeLevels before trying to group are #325A9BtypeLevels before trying to group are #C4451CtypeLevels before trying to group are #1C8356typeLevels before trying to group are #fc2aac
#> 3: No levels but a color vector which size does not cover the number of levels in the data, missing colors will be picked from a standard palette.

L’argument LCZlevels permet de spécifier les niveaux qui se trouvent dans les données (il ne peut être utilisé dans le mode standard). Dans l’exemple ci-dessous, on force la prise en compte d’un niveau “10” qui n’est pas présent dans les données, et on laisse la fonction choisir des couleurs aléatoires.


LCZlevels <- c(2, 3, 5, 6, 8, 9, 10, 101, 102, 104, 105, 107)
map4 <- showLCZ(sf = redonOSM, wf = "OSM", column = "LCZ_PRIMARY", repr = "alter", LCZlevels = LCZlevels, drop = FALSE)
#> typeLevels before trying to group are #3659f7typeLevels before trying to group are #0daa7btypeLevels before trying to group are #a02318typeLevels before trying to group are #baebf4typeLevels before trying to group are #599901typeLevels before trying to group are #e585d2typeLevels before trying to group are #fce4b0typeLevels before trying to group are #ef3ba1typeLevels before trying to group are #655fe2typeLevels before trying to group are #f466c0typeLevels before trying to group are #8ef2a6typeLevels before trying to group are #196284typeLevels before trying to group are #0d59ddtypeLevels before trying to group are #cca9e8typeLevels before trying to group are #db5569typeLevels before trying to group are #82e26ftypeLevels before trying to group are #aad8eftypeLevels before trying to group are #ffd9cc
#> 8: No color vector but a level vector whose names don't cover the levels in the data.
#>          Missing levels will be deduced from the data and colors will be chosen from a standard palette.

On peut également renseigner le vecteur des couleurs qu’on souhaite utiliser en renseignant l’argumentcolors. On peut renseigner les noms de couleurs connues de R ou un code RGB.

# Choix de couleurs prises au hasard

# Après une première représentation on constate qu'il n'y a que les typeLevels 2, 3, 5, 6, 8, 9, 101, 102, 104, 105, 107.
# Je spécifie un vecteur de couleur de taille 11 colors
LCZlevels <- c(2, 3, 5, 6, 8, 9, 101, 102, 104, 105, 107)
couleurs <- c("red", "brown1", "orange", "coral", "grey", "darkgreen", "chartreuse4", "springgreen3",
              "darkolivegreen", "black", "#6d67fd")
map5 <- showLCZ(sf = redonOSM, wf = "OSM", column = "LCZ_PRIMARY", repr = "alter", drop = TRUE, LCZlevels = LCZlevels, colors = couleurs)
#> typeLevels before trying to group are redtypeLevels before trying to group are orangetypeLevels before trying to group are coraltypeLevels before trying to group are greytypeLevels before trying to group are darkgreentypeLevels before trying to group are chartreuse4typeLevels before trying to group are springgreen3typeLevels before trying to group are darkolivegreentypeLevels before trying to group are blacktypeLevels before trying to group are #6d67fd
#> One vector of levels, one vector of colors, either the same length (case 9: and 10:), or colors longer (case 12:, unused colors were dropped),
#>          reduced to  4: & 5: A single vector was provided, whose names cover the levels in the data (values are expected to be colors). Drop=TRUE, some of the specified levels were not found in the data and were dropped

Regrouper des types de LCZ avec la fonction groupLCZ

Il peut être intéressant de regrouper des niveaux en catégories plus vastes pour une analyse plus générale. On peut, par exemple, choisir de regrouper les LCZ urbaines et les LCZ de végétation et ainsi dessiner une enveloppe urbaine. La fonction groupLCZ prend en argument le jeu de données à regrouper, sf, et la colonne où se trouvent les LCZ à regrouper, column.

On renseigne ensuite des vecteurs dont le nom correspond à la catégorie regroupée et qui contient les niveaux à regrouper dans cette catégorie.

Les catégories créées sont ajoutées au jeu de données dans une colonne, dont on précise le nom dans l’argument outCol (par défaut outCol="grouped").

On peut alors passer le nouveau jeu de données dans la fonction LCZshow.

redonOSMgrouped <- groupLCZ(redonOSM, column = "LCZ_PRIMARY",
                            urban = c("1", "2", "3", "4", "5", "6", "7", "8", "9"),
                            industry = "10",
                            vegetation = c("101", "102", "103", "104"),
                            impervious = "105", pervious = "106", water = "107", colors = c("red", "black", "green", "grey", "burlywood", "blue"))
#> Grouping
#> One of the specified levels to group doesn't exist in the data, if it is a mispelled level of the data,
#>               this level will be kept as ungroupedsimpleWarning: Unknown levels in `f`: 1, 3, 4, 7, 10, 103, 106
#> Warning: Unknown levels in `f`: 1, 3, 4, 7, 10, 103, 106
map6 <- showLCZ(redonOSMgrouped, column = "grouped", repr = "alter", wf = "OSM",
                LCZlevels = c("urban", "industry", "vegetation", "impervious", "pervious", "water"),
                colors = c("red", "black", "green", "grey", "burlywood", "blue"))
#> typeLevels before trying to group are redtypeLevels before trying to group are blacktypeLevels before trying to group are greentypeLevels before trying to group are greytypeLevels before trying to group are burlywoodtypeLevels before trying to group are bluetypeLevels before trying to group are #e8a0df
#> One vector of levels, one vector of colors, either the same length (case 9: and 10:), or colors longer (case 12:, unused colors were dropped),
#>          reduced to  6: A single vector was provided, whose names don't cover the levels in the data, 
#>       missing levels were assigned random colors.

Comparer deux classifications LCZ avec la fonction compareLCZ

L’objectif de ce paquet R est de proposer une comparaison facile de deux classifications en LCZ. Dans notre exemple, on compare naturellement les LCZ créés par la chaîne GeoClimate à partir des données de la BD TOPO® v2.2 produite par l’IGN et celles produites à partir d’OpenStreetMap sur la même zone.

Représentations graphiques

La fonction compareLCZ produit une carte pour chaque classification en LCZ.

Elle intersecte les géométries des deux fichiers afin d’obtenir des géométries sur lesquelles les deux classifications sont soit tout à fait d’accord, soit tout à fait en désaccord.

Cet accord entre géométries intersectées est ensuite représenté dans un troisième graphique.

Une matrice de confusion (appelée parfois matrice d’agrément) est aussi calculée : pour chaque géométrie, on retient sa surface et les valeurs des deux classifications en LCZ. On calcule alors comment chaque modalité de la première classification LCZ est ventilée parmi les modalités de la seconde classification LCZ. Le dernier graphique représente cette information.

Le graphique produit contient quatre graphiques, il est plus lisible zoomé.

#>  The column  LCZ_PRIMARY  of the dataset sf1 is the reference against which the  LCZ_PRIMARY  column of the dataset  sf2 will be compared.
#> For Technical reason in this package, worfklow names can't contain spaces or underscores, they were replaced by dots
#> Workflow names are used in produced graphics and as column names, long names are not suitable,
#>     the first 3 and last 3 letters were kept instead
#> For Technical reason in this package, worfklow names can't contain spaces or underscores, they were replaced by dots
#> Workflow names are used in produced graphics and as column names, long names are not suitable,
#>     the first 3 and last 3 letters were kept instead
#> Both sf datasets need to live in the same crs projection (srid / epsg),
#> they will be coerced to the specified reference (sf1)
#> Warning: attribute variables are assumed to be spatially constant throughout
#> all geometries

Lecture du fichier correctement zoomé et enregistré en png.

path <- system.file('extdata/redonCompare.png',package="lczexplore")
knitr::include_graphics(path, error=FALSE)

file.remove(path)
#> [1] TRUE

Données produites et analyses ultérieures

La fonction renvoie dans R un objet appelé matConfOut qui contient plusieurs éléments :

Enfin, si l’argument exwrite=TRUE la fonction compareLCZ exporte les données qui ont servi à produire la matrice de confusion dans un fichier csv. Ce fichier peut ensuite être chargé dans R pour d’autres analyses.

comparaison$percAgg
#>    percAgg
#>      <num>
#> 1:   56.05
comparaison$pseudoK
#> [1] 0.4507959

Etude de la sensibilité de l’accord à la confiance accordée aux valeurs de LCZ

Certains algorithmes de classement en LCZ peuvent fournir une valeur de “confiance” au type de LCZ qu’ils affectent à une unité spatiale de référence.

Par exemple, GeoClimate, pour une géométrie donnée, peut lui avoir attribué une modalité de LCZ principale, mais également indiquer qu’une autre modalité secondaire était possible, même si moins justifiée. GeoClimate propose alors une valeur d’unicité, ou uniqueness. Cette unicité évolue entre 1 et 0, plus elle s’éloigne de 1, plus la seconde modalité était une candidate crédible. Cette uniqueness peut donc être vue comme une mesure de confiance.

Prise en compte des géométries et des valeurs de confiance lors de l’import des fichiers.

La fonction importLCZvect permet d’indiquer quelles colonnes du geojson contiennent l’identifiant de la géométrie (geomID) et l’indicateur de confiance associé (confid) nécessaires à l’analyse de sensibilité.

dirPath <- paste0(system.file("extdata", package = "lczexplore"), "/multipleWfs/Redon")

redonOSM <- importLCZvect(dirPath = dirPath, file = "osm_lcz.fgb", column = "LCZ_PRIMARY", geomID = "ID_RSU", confid = "LCZ_UNIQUENESS_VALUE")

redonBDT <- importLCZvect(dirPath = dirPath, file = "bdt_lcz.fgb", column = "LCZ_PRIMARY", geomID = "ID_RSU", confid = "LCZ_UNIQUENESS_VALUE")

redonCompare <- compareLCZ(sf1 = redonBDT, wf1 = "bdt", geomID1 = "ID_RSU", column1 = "LCZ_PRIMARY",
                           confid1 = "LCZ_UNIQUENESS_VALUE",
                           sf2 = redonOSM, wf2 = "osm", geomID2 = "ID_RSU", column2 = "LCZ_PRIMARY", confid2 = "LCZ_UNIQUENESS_VALUE", exwrite = FALSE, plot = FALSE)
#>  The column  LCZ_PRIMARY  of the dataset sf1 is the reference against which the  LCZ_PRIMARY  column of the dataset  sf2 will be compared.
#> Both sf datasets need to live in the same crs projection (srid / epsg),
#> they will be coerced to the specified reference (sf1)
#> Warning: attribute variables are assumed to be spatially constant throughout
#> all geometries
#> Plot set to FALSE, no plots created

À chaque unité de référence spatiale (RSU, une géométrie) est maintenant associé un type de LCZ et un niveau de confiance.

path <- system.file('extdata/redonCompare',package="lczexplore")
redonCompare <- compareLCZ(sf1 = redonBDT, wf1 = "bdt", geomID1 = "ID_RSU", column1 = "LCZ_PRIMARY",
                           confid1 = "LCZ_UNIQUENESS_VALUE",
                           sf2 = redonOSM, wf2 = "osm", geomID2 = "ID_RSU", column2 = "LCZ_PRIMARY",
                           confid2 = "LCZ_UNIQUENESS_VALUE", exwrite = FALSE, saveG = path)
#>  The column  LCZ_PRIMARY  of the dataset sf1 is the reference against which the  LCZ_PRIMARY  column of the dataset  sf2 will be compared.
#> Both sf datasets need to live in the same crs projection (srid / epsg),
#> they will be coerced to the specified reference (sf1)
#> Warning: attribute variables are assumed to be spatially constant throughout
#> all geometries
# redonInputSensib<-read.csv()
path <- system.file('extdata/GeneralUniquenessSensib.png',package="lczexplore")
knitr::include_graphics(path, error=FALSE)

Il est important de noter que les colonnes contenant les LCZ en entrée sont renommées à partir des noms de workflow en sortie, pour éviter des renommages du type lcz_primary et lcz_primary.1.

La question à laquelle cette fonction permet de répondre est : est-ce que l’accord entre les deux classifications LCZ augmente si on ne conserve que les géométries pour lesquelles l’indicateur de confiance associé aux LCZ est supérieur à un certain seuil ?

L’étendue des valeurs de confiance est découpée en autant de points que spécifié par le paramètre nPoints. Pour chacun de ces seuils de confiance, la fonction conserve uniquement les géométries pour lesquelles la valeur de confiance est supérieure à ce seuil dans les deux fichiers.

Elle calcule ensuite l’accord entre les deux classifications en se basant uniquement sur ces RSU “de confiance”, et le représente en bleu sur le graphique final.

On représente aussi, en magenta, l’accord entre les géométries dont la valeur de confiance était inférieure au seuil.

names(redonCompare$data)
#> [1] "ID_RSU"                 "bdt"                    "LCZ_UNIQUENESS_VALUE"  
#> [4] "ID_RSU.1"               "osm"                    "LCZ_UNIQUENESS_VALUE.1"
#> [7] "area"                   "location"               "agree"
confidRedon <- confidSensib(inputDf = redonCompare$data, filePath = "", nPoints = 10,
                            wf1 = "bdtopo_2_2", wf2 = "osm",
                            geomID1 = "ID_RSU", column1 = "bdt", confid1 = "LCZ_UNIQUENESS_VALUE",
                            geomID2 = "ID_RSU.1", column2 = "osm", confid2 = "LCZ_UNIQUENESS_VALUE.1",
                            sep = ";", repr = "standard",
                            plot = TRUE, saveG = system.file("extdata/", package = "lczexplore"))
#> Warning in geom_text(aes(x = 0.5, y = NAPercAgr, label = etiquette, vjust = 1.5, : All aesthetics have length 1, but the data has 20 rows.
#> ℹ Please consider using `annotate()` or provide this layer with data containing
#>   a single row.
#> Warning: Removed 1 row containing missing values or values outside the scale range
#> (`geom_point()`).
#> Warning: Removed 1 row containing missing values or values outside the scale range
#> (`geom_text()`).
#> Warning in geom_text(aes(x = 0.5, y = NAPercAgr, label = etiquette, vjust = 1.5, : All aesthetics have length 1, but the data has 20 rows.
#> ℹ Please consider using `annotate()` or provide this layer with data containing
#>   a single row.
#> Warning: Removed 1 row containing missing values or values outside the scale range
#> (`geom_point()`).
#> Warning: Removed 1 row containing missing values or values outside the scale range
#> (`geom_text()`).
#> Ignoring unknown labels:
#> • size : "1.3"
#> Warning: Removed 4 rows containing missing values or values outside the scale range
#> (`geom_point()`).
#> Warning: Removed 4 rows containing missing values or values outside the scale range
#> (`geom_text()`).
#> Ignoring unknown labels:
#> • size : "1.3"
#> Warning: Removed 4 rows containing missing values or values outside the scale range
#> (`geom_point()`).
#> Removed 4 rows containing missing values or values outside the scale range
#> (`geom_text()`).
path <- paste0(system.file("extdata/GeneralUniquenessSensib",package="lczexplore"), ".png")
knitr::include_graphics(path, error=FALSE)

La fonction confidSensib propose également cette analyse par type de LCZ.

path <- paste0(system.file("extdata/byLCZUniquenessSensib", package = "lczexplore"), ".png")
knitr::include_graphics(path, error = FALSE)

Les principales fonctions ont été évoquées ici, pour plus d’information consulter les fichiers d’aide de chacune des fonctions.

path <- system.file("extdata/byLCZUniquenessSensib.png", package = "lczexplore")
if (file.exists(path)){file.remove(path)}
#> [1] TRUE

path <- system.file("extdata/GeneralUniquenessSensib.png", package = "lczexplore")
if (file.exists(path)){file.remove(path)}
#> [1] TRUE
path <- system.file("extdata/redonCompare.png", package = "lczexplore")
if (file.exists(path)){file.remove(path)}