From e74927f2e0af770fadfca2f44d139d65989ad5e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Grelot?= <frederic.grelot@irstea.fr> Date: Tue, 22 Nov 2022 10:33:44 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20l'option=20scope=20=C3=A0=20map=5F?= =?UTF-8?q?so=5Fii=20et=20adaptation=20des=20options=20bar=20et=20insert?= =?UTF-8?q?=20en=20cons=C3=A9quences?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dev/tag-message | 36 ++++++++------- so.ii/DESCRIPTION | 5 ++- so.ii/R/map_so_ii.r | 100 ++++++++++++++++++++++++++++++++--------- so.ii/man/map_so_ii.Rd | 25 ++++++++--- 4 files changed, 120 insertions(+), 46 deletions(-) diff --git a/dev/tag-message b/dev/tag-message index 0947018..9464e39 100644 --- a/dev/tag-message +++ b/dev/tag-message @@ -1,25 +1,27 @@ -so.ii Version: 1.0.21.0 +so.ii Version: 1.0.22.0 0 errors ✔ | 0 warnings ✔ | 0 notes ✔ **Note de version** - * ajout des options add, limit à map_so_ii + * ajout de l'option scope à map_so_ii + * adaptation de l'option inset + * adaptation de l'option bar **Détails** - * l'option limit (logical) de map_so_ii permet de gérer le fait que la - limite du paramètre est effectivement affichée : - * si l'option est à TRUE (défaut), le périmètre est affiché une fois que - le thème ou le dataset le sont (mais plus avant). Donc si aucun theme ni - dataset n'est donné, rien n'est affiché ! - * si l'option est à FALSE, le périmètre n'est jamais affiché. - * l'option add (logical) permet d'utiliser map_so_ii pour ajouter des - informations à un carte existante : - * si l'option est à TRUE, les informations sont ajoutées. L'option "bar" - est mise à FALSE. Si l'option "path" donne un chemin de fichier, une - sauvegarde de la carte en cours de création est crée en utilisant - dev.copy juste avant de sortir de la fonction. - * si l'option est à FALSE, le comportement ne change pas avec ce qui - était précédemment donné. + * l'option "scope" (character) de map_so_ii permet de définir le scope de la + carte : + * si l'option est à "so-ii" (défaut), le périmètre total est affiché. + C'est le même comportement que précédemment. + * si l'option est un vecteur différent de "so-ii", alors il est cherché + l'ensemble des communes de so-ii dont le code INSEE correspond aux + valeurs de scope. Seules les bonnes valeurs sont gardées. Si aucune + bonne valeur n'est trouvée, un avertissement est lancé et la valeur par + d'afut est prise + * l'option "inset" permet de choisir la valeur "so-ii" pour situer un scope + plus petit que le périmètre total à l'intérieur de so-ii. + * l'option "bar" n'est pas mofifiée dans son appel, mais dans son + implémentation pour permettre d'ajuster la taille de la barre au scope + choisi. -# git tag -a v1.0.21.0 -F dev/tag-message +# git tag -a v1.0.22.0 -F dev/tag-message # git push --tags diff --git a/so.ii/DESCRIPTION b/so.ii/DESCRIPTION index 27af69c..a46a835 100644 --- a/so.ii/DESCRIPTION +++ b/so.ii/DESCRIPTION @@ -1,6 +1,6 @@ Package: so.ii Title: Utilities very useful to share within so_ii team -Version: 1.0.21.0 +Version: 1.0.22.0 Authors@R: c( person(given = "Frédéric", @@ -27,7 +27,8 @@ Imports: rio, scales, sf, - terra + terra, + units Suggests: rmarkdown, testthat diff --git a/so.ii/R/map_so_ii.r b/so.ii/R/map_so_ii.r index 44f0f76..43bb685 100644 --- a/so.ii/R/map_so_ii.r +++ b/so.ii/R/map_so_ii.r @@ -1,5 +1,5 @@ #' @title Plot a thematic map of so-ii -#' +#' #' @details #' \subsection{theme specification}{ #' For the specification of detail, it depends on the theme chosen. @@ -68,18 +68,31 @@ #' as.character(inset). Non-case sensitive partial matching is used, with "é" #' interpreted as "e". #' \itemize{ -#' \item{\strong{department}: so-ii perimeter is located within Hérault -#' departement, if inset may be interpreted as "department", "département", -#' "hérault", "34".} -#' \item{\strong{region}: so-ii perimeter is located within Occitanie region, -#' if inset may be interpreted as "région", "Occitanie", "76" (INSEE code for -#' Occitanie region).} -#' \item{\strong{nation}: so-ii perimeter is located within the metropolitean -#' part of France, if inset may be interpreted as "France", "métropole", -#' "nation".} +#' \item{\strong{so-ii}: scope perimeter is located within so-ii. Only +#' useful when scope is less than so-ii.} +#' \item{\strong{department}: scope perimeter is located within Hérault +#' departement, if inset may be interpreted as "department", "département", +#' "hérault", "34".} +#' \item{\strong{region}: scope perimeter is located within Occitanie region, +#' if inset may be interpreted as "région", "Occitanie", "76" (INSEE code +#' for Occitanie region).} +#' \item{\strong{nation}: scope perimeter is located within the metropolitean +#' part of France, if inset may be interpreted as "France", "métropole", +#' "nation".} #' } #' If all other cases, nothing is added. #' } +#' \subsection{scope specification}{ +#' The scope should be either: +#' \itemize{ +#' \item{\strong{so.ii}: the whole perimiter of so.ii is chosen. This is +#' default value.} +#' \item{\strong{vector of INSEE codes of collectivities in so.ii}: a +#' perimeter is build with those collectivies. Only valid codes are taken +#' into account. If none is chosen, a warning is dropped, and default +#' value is used.} +#' } +#' } #' \subsection{path specification}{ #' Depending on the extension a device is chosen. #' \itemize{ @@ -98,6 +111,7 @@ #' @param theme_legend logical, should a legend be plotted for the theme. #' @param detail character, detail for theme, depends on theme. See details. #' @param year character, the year chosen for some themes. See details. +#' @param scope character, choice for the scope of the map. See details. #' @param bar logical, should a bar be plotted for the dataset. See details. #' @param limit logical, should the limit of so.ii be plotted for the dataset. #' Default to TRUE. @@ -129,6 +143,7 @@ map_so_ii = function( theme_legend = FALSE, detail, year, + scope = "so.ii", bar = TRUE, limit = TRUE, inset = NULL, @@ -210,10 +225,27 @@ map_so_ii = function( } } + ## Check scope + if (identical(scope, "so.ii")) { + scope = so.ii::so_ii_limit + } else { + scope = scope[scope %in% so.ii::so_ii_collectivity[["commune"]]] + if (length(scope) == 0) { + warnings("Nothing pertinent found in scope, default value is used.") + scope = so.ii::so_ii_limit + } else { + scope = sf::st_union( + so.ii::so_ii_collectivity[ + so.ii::so_ii_collectivity[["commune"]] %in% scope, + ] + ) + } + } + ## Init map if (add != TRUE) { graphics::par(mai = c(.65, .60, .50, .15)) - plot(so.ii::so_ii_limit, border = NA, axes = TRUE, main = list(...)[["main"]], cex.main = 2.5) + plot(scope, border = NA, axes = TRUE, main = list(...)[["main"]], cex.main = 2.5) } else { bar = FALSE } @@ -235,18 +267,31 @@ map_so_ii = function( ## Plot dataset if any if (!missing(dataset)) plot(dataset[["geometry"]], add = TRUE, ...) - ## Make so_ii_limit visible + ## Make scope visible if (limit == TRUE) { - plot(so.ii::so_ii_limit, lwd = 2, add = TRUE) + plot(scope, lwd = 2, add = TRUE) } ## Plot bar if (bar == TRUE) { + if (identical(scope, so.ii::so_ii_limit)) { + d = 10 + xy = c(3.55, 43.47) + below = "km" + label = c(0, 5, 10) + } else { + area = sf::st_area(sf::st_as_sfc(sf::st_bbox(scope))) + d = max(pretty(units::set_units(sqrt(area) / 5, "km"))) + xy = "bottomleft" + below = "km" + label = c(0, d/2, d) + } terra::sbar( - 10, c(3.55, 43.47), + d = d, + xy = xy, type = "bar", - below = "km", - label = c(0, 5, 10), + below = below, + label = label, cex = .8 ) } @@ -255,9 +300,10 @@ map_so_ii = function( if (!is.null(inset)) { inset = gsub("\u00e9", "e", tolower(as.character(inset)[1])) admissible = list( - department = c("34", "departement", "department", "herault"), - region = c("76", "occitanie", "region"), - nation = c("france", "metropole", "nation") + "so-ii" = c("so-ii"), + "department" = c("34", "departement", "department", "herault"), + "region" = c("76", "occitanie", "region"), + "nation" = c("france", "metropole", "nation") ) inset = names(which(sapply( admissible, @@ -265,10 +311,20 @@ map_so_ii = function( inset ))) if (length(inset) == 1 && inset %in% rownames(so.ii::so_ii_inset)) { + scope_sf = sf::st_as_sf(scope) + names(scope_sf) = "geometry" + sf::st_geometry(scope_sf) = "geometry" + inset = rbind( + so.ii::so_ii_inset[inset, "geometry"], + sf::st_as_sf(scope_sf) + + ) add_inset( - so.ii::so_ii_inset[c(inset, "so-ii"), ], - so.ii::so_ii_limit, - col = c("gray85", "red"), border = c("gray", "red"), lwd = 1:2 + inset, + scope, + col = c("gray85", "red"), + border = c("gray", "red"), + lwd = 1:2 ) } } diff --git a/so.ii/man/map_so_ii.Rd b/so.ii/man/map_so_ii.Rd index 1c6b609..16ccac9 100644 --- a/so.ii/man/map_so_ii.Rd +++ b/so.ii/man/map_so_ii.Rd @@ -13,6 +13,7 @@ map_so_ii( theme_legend = FALSE, detail, year, + scope = "so.ii", bar = TRUE, limit = TRUE, inset = NULL, @@ -34,6 +35,8 @@ map_so_ii( \item{year}{character, the year chosen for some themes. See details.} +\item{scope}{character, choice for the scope of the map. See details.} + \item{bar}{logical, should a bar be plotted for the dataset. See details.} \item{limit}{logical, should the limit of so.ii be plotted for the dataset. @@ -123,18 +126,30 @@ If inset is not NULL, an inset will be plotted, depending on the value of as.character(inset). Non-case sensitive partial matching is used, with "é" interpreted as "e". \itemize{ -\item{\strong{department}: so-ii perimeter is located within Hérault +\item{\strong{so-ii}: scope perimeter is located within so-ii.} +\item{\strong{department}: scope perimeter is located within Hérault departement, if inset may be interpreted as "department", "département", "hérault", "34".} -\item{\strong{region}: so-ii perimeter is located within Occitanie region, -if inset may be interpreted as "région", "Occitanie", "76" (INSEE code for -Occitanie region).} -\item{\strong{nation}: so-ii perimeter is located within the metropolitean +\item{\strong{region}: scope perimeter is located within Occitanie region, +if inset may be interpreted as "région", "Occitanie", "76" (INSEE code +for Occitanie region).} +\item{\strong{nation}: scope perimeter is located within the metropolitean part of France, if inset may be interpreted as "France", "métropole", "nation".} } If all other cases, nothing is added. } +\subsection{scope specification}{ +The scope should be either: +\itemize{ +\item{\strong{so.ii}: the whole perimiter of so.ii is chosen. This is +default value.} +\item{\strong{vector of INSEE codes of collectivities in so.ii}: a +perimeter is build with those collectivies. Only valid codes are taken +into account. If none is chosen, a warning is dropped, and default +value is used.} +} +} \subsection{path specification}{ Depending on the extension a device is chosen. \itemize{ -- GitLab