map_so_ii.r 24.5 KB
Newer Older
1
2
#' @title Plot a thematic map of so-ii
#' 
Grelot Frederic's avatar
Grelot Frederic committed
3
#' @details
Grelot Frederic's avatar
Grelot Frederic committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#' \subsection{theme specification}{
#' For the specification of detail, it depends on the theme chosen.
#' \itemize{
#'   \item{\strong{none}: perimeter of so_ii is plotted.}
#'   \item{\strong{catchment}: The area of catchments are plotted with a scope
#'      depending on detail. At least, a division between Lez and
#'      Bassin de l'Or is plotted.}
#'   \item{\strong{catnat}: Informations on the number of "Arrêtés Cat
#'      Nat are provided at the scale of collectivities."}
#'   \item{\strong{collectivty}: Boundaries of collectivities are plotted, more
#'      some administrative informations depending on detail.}
#'   \item{\strong{hydro}: The hydrophic network is plotted. Depending on
#'      detail, only a part (rivers, canals, water bodies) or a degre of detail
#'      is plotted.}
#'   \item{\strong{onrn}: Informations on the claims coming from Cat Nat system
#'      are plotted at the scale of the collectivities. With detail a selection
#'      of the data is made, with year a selection of the period.}
#'   \item{\strong{osm}: A tile from OSM is plotted.}
#'   \item{\strong{population}: Informations on the population coming from
#'      INSEE are plotted at the scale of the collectivities. With year a
#'      selection of the period is made, with detail a selection of how
#'      evolution between 2 years.}
#' }
#' }
Grelot Frederic's avatar
Grelot Frederic committed
28
29
30
#' \subsection{detail specification}{
#' For the specification of detail, it depends on the theme chosen.
#' \itemize{
Grelot Frederic's avatar
Grelot Frederic committed
31
32
#'   \item{\strong{catchment}: detail must be chosen in "none", "1", "2", "3"
#'      for levels of detail. If missing, "1" will be chosen.}
Grelot Frederic's avatar
Grelot Frederic committed
33
34
35
36
37
38
39
40
41
42
#'   \item{\strong{catnat}: detail must be chosen in "inondation",
#'      "submersion", or "nappe". If missing all type will be chosen and
#'      aggregated before plotting.}
#'   \item{\strong{collectivity}: detail must be chosen in "none", "syble",
#'      "symbo", "epci" or "syndicate". If missing, "none" will be chosen,
#'      and only the boundaries of collectivities are plotted.}
#'   \item{\strong{hydro}: detail must be chosen in "none", "1", "2", "3" for
#'      levels of detail or "canal", "river", "waterbody" for types of
#'      hydrographic elements. If missing, "none" will be chosen, and
#'      everything is plotted.}
Grelot Frederic's avatar
Grelot Frederic committed
43
44
#'   \item{\strong{onrn}: detail must be chosen in "n_catnat", "freq_sin",
#'      "cost", "cost_hab", "cost_mean", "ratio", "balance", "ppri_year".}
Grelot Frederic's avatar
Grelot Frederic committed
45
46
47
#'   \item{\strong{population}: detail must be chosen in "absolute",
#'      "relative". It used only when more than one year is provided to plot
#'      aither absolute or relative evolution.}
Grelot Frederic's avatar
Grelot Frederic committed
48
49
50
51
52
#' }
#' }
#' \subsection{year specification}{
#' For the specification of year, it depends on the theme chosen.
#' \itemize{
Grelot Frederic's avatar
Grelot Frederic committed
53
54
55
56
#'   \item{\strong{catnat}: year corresponds to the year of data. If 2 or more
#'      years are given, the sum of the period corresponding to the range of
#'      given years is plotted. If missing, the whole available period is
#'      plotted.}
Grelot Frederic's avatar
Grelot Frederic committed
57
#'   \item{\strong{population}: year corresponds to the year of data. If
Grelot Frederic's avatar
Grelot Frederic committed
58
59
60
#'      missing, last available year is plotted. If 2 or more years are
#'      provided an analysis of the evolution between the range of given
#'      years is plotted.}
Grelot Frederic's avatar
Grelot Frederic committed
61
62
#' }
#' }
Grelot Frederic's avatar
Grelot Frederic committed
63
64
65
66
67
68
69
70
71
72
73
#' \subsection{path specification}{
#' Depending on the extension a device is chosen.
#' \itemize{
#'   \item{\strong{pdf}: grDevices::cairo_pdf}
#'   \item{\strong{png}: grDevices::png}
#'   \item{\strong{svg}: grDevices::svg}
#' }
#' If path is NULL, standard plotting is used. If an extension is not managed,
#' an error is raised.
#' }
#'
74
75
#' @param dataset sf objectf, data to be plotted
#' @param dataset_legend list of parameters to be passed to legend
Grelot Frederic's avatar
Grelot Frederic committed
76
#' @param theme character, choice for the theme (if any). See details.
Grelot Frederic's avatar
Grelot Frederic committed
77
78
#' @param theme_legend logical, should a legend be plotted for the theme
#' @param detail character, detail for theme, depends on theme. See details.
Grelot Frederic's avatar
Grelot Frederic committed
79
#' @param year character, the year chosen for some themes. See details.
Grelot Frederic's avatar
Grelot Frederic committed
80
#' @param bar logical, should a bar be plotted for the dataset
Grelot Frederic's avatar
Grelot Frederic committed
81
82
#' @param path character, the name of the file to save the plot. Graphical
#'  device is chosen depending on extension. See details.
83
84
85
86
#' @param ...  some parameters that will be used by plot (from sf)
#'
#' @return Nothing useful.
#' 
Grelot Frederic's avatar
Grelot Frederic committed
87
#' @export map_so_ii
88
89
90
#'
#' @encoding UTF-8
#' @author Frédéric Grelot
Grelot Frederic's avatar
Grelot Frederic committed
91
#' @author David Nortes Martinez
92
93
94
95
96
97
98
#' 
#' @examples
#' 
#' \dontrun{
#' # To be added (soon)
#' }

99
100
101
map_so_ii = function(
    dataset,
    dataset_legend = NULL,
Grelot Frederic's avatar
Grelot Frederic committed
102
    theme = c("none", "collectivity", "catchment", "catnat", "clc", "hydro", "onrn", "osm", "population"),
Grelot Frederic's avatar
Grelot Frederic committed
103
104
105
    theme_legend = FALSE,
    detail,
    year,
106
107
108
109
    bar = TRUE,
    path = NULL,
    ...
) {
Grelot Frederic's avatar
Grelot Frederic committed
110
    theme = match.arg(theme)
111
112

    if (!is.null(path)) {
Grelot Frederic's avatar
Grelot Frederic committed
113
114
        width = 18
        height = 18
115
116
        switch(
            EXPR = tolower(tools::file_ext(path)),
Grelot Frederic's avatar
Grelot Frederic committed
117
118
119
120
            "pdf" = grDevices::cairo_pdf(path, width = width / 2.54, height = height / 2.54),
            "png" = grDevices::png(path, width = width, height = height, units = "cm"),
            "jpg" = grDevices::jpeg(path, width = width, height = height, units = "cm"),
            "svg" = grDevices::svg(path, width = width / 2.54, height = height / 2.54),
121
122
            stop(sprintf("%s not recognized", tolower(tools::file_ext(path))))
        )
123
        on.exit(grDevices::dev.off())
124
125
126
127
    }

    ## Init map
    graphics::par(mai = c(.65, .60, .50, .15))
Grelot Frederic's avatar
Grelot Frederic committed
128
    plot(so.ii::so_ii_limit, axes = TRUE, main = list(...)[["main"]], cex.main = 2.5)
129

Grelot Frederic's avatar
Grelot Frederic committed
130
    ## Plot theme if any, return theme_legend
Grelot Frederic's avatar
Grelot Frederic committed
131
132
    theme_legend = switch(
        EXPR = theme,
Grelot Frederic's avatar
Grelot Frederic committed
133
134
135
136
137
138
        "catchment" = map_theme_catchment(detail, theme_legend),
        "catnat" = map_theme_catnat(detail, year, theme_legend),
        "clc" = map_theme_clc(theme_legend),
        "collectivity" = map_theme_collectivity(detail, theme_legend),
        "hydro" = map_theme_hydro(detail, theme_legend),
        "onrn" = map_theme_onrn(detail, theme_legend),
Grelot Frederic's avatar
Grelot Frederic committed
139
        "osm" = map_theme_osm(),
Grelot Frederic's avatar
Grelot Frederic committed
140
        "population" = map_theme_population(detail, year, theme_legend),
Grelot Frederic's avatar
Grelot Frederic committed
141
        NULL
Grelot Frederic's avatar
Grelot Frederic committed
142
143
    )

Grelot Frederic's avatar
Grelot Frederic committed
144
    ## Plot dataset if any
Grelot Frederic's avatar
Grelot Frederic committed
145
146
    if (!missing(dataset)) plot(dataset[["geometry"]], add = TRUE, ...)

Grelot Frederic's avatar
Grelot Frederic committed
147
    ## Make so_ii_limit visible
Grelot Frederic's avatar
Grelot Frederic committed
148
    plot(so.ii::so_ii_limit, lwd = 2, add = TRUE)
Grelot Frederic's avatar
Grelot Frederic committed
149

Grelot Frederic's avatar
Grelot Frederic committed
150
    ## Plot bar
Grelot Frederic's avatar
Grelot Frederic committed
151
152
153
154
155
156
157
    if (bar == TRUE) {
        terra::sbar(
            10, c(3.55, 43.47),
            type = "bar",
            below = "km",
            label = c(0, 5, 10),
            cex = .8
Grelot Frederic's avatar
Grelot Frederic committed
158
        )
Grelot Frederic's avatar
Grelot Frederic committed
159
160
    }

Grelot Frederic's avatar
Grelot Frederic committed
161
    ## Plotdataset_legend if any
Grelot Frederic's avatar
Grelot Frederic committed
162
163
164
    if (!is.null(dataset_legend)) {
        dataset_legend = c(
            x = "bottomright",
Grelot Frederic's avatar
Grelot Frederic committed
165
166
167
            cex = .8,
            bg = "white",
            inset = 0.01,
Grelot Frederic's avatar
Grelot Frederic committed
168
169
            dataset_legend)
        do.call(graphics::legend, dataset_legend)
Grelot Frederic's avatar
Grelot Frederic committed
170
171
    }

Grelot Frederic's avatar
Grelot Frederic committed
172
173
    ## Plot theme_legend if any
    if (!is.null(theme_legend)) {
Grelot Frederic's avatar
Grelot Frederic committed
174
175
176
        if (!is.null(theme_legend[["text.width"]])) {
            text_legend = theme_legend[["legend"]]
            theme_legend[["legend"]] = rep("", length(text_legend))
Grelot Frederic's avatar
Grelot Frederic committed
177
        }
Grelot Frederic's avatar
Grelot Frederic committed
178
179
180
181
182
183
184
        temp = do.call(graphics::legend, theme_legend)
        if (!is.null(theme_legend[["text.width"]])) {
            graphics::text(
                x = temp[["rect"]][["left"]] + temp[["rect"]][["w"]],
                y = temp[["text"]][["y"]],
                labels = text_legend,
                pos = 2
Grelot Frederic's avatar
Grelot Frederic committed
185
186
            )
        }
Grelot Frederic's avatar
Grelot Frederic committed
187
    }
Grelot Frederic's avatar
Grelot Frederic committed
188

Grelot Frederic's avatar
Grelot Frederic committed
189
190
191
192
193
194
    return(invisible(NULL))
}

map_theme_catchment = function(detail, add_legend) {
    if (missing(detail)) {
        detail = "1"
Grelot Frederic's avatar
Grelot Frederic committed
195
    }
Grelot Frederic's avatar
Grelot Frederic committed
196
197
    detail = match.arg(
        as.character(detail), 
Grelot Frederic's avatar
Grelot Frederic committed
198
        choices = levels(so.ii::so_ii_catchment[["degre"]])
Grelot Frederic's avatar
Grelot Frederic committed
199
    )
Grelot Frederic's avatar
Grelot Frederic committed
200

Grelot Frederic's avatar
Grelot Frederic committed
201
202
203
    selection  = so.ii::so_ii_catchment[["degre"]] == detail
    geometry = so.ii::so_ii_catchment[["geometry"]][selection]
    catchment = as.factor(so.ii::so_ii_catchment[["catchment_name"]][selection])
Grelot Frederic's avatar
Grelot Frederic committed
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
    color_legend = grDevices::hcl.colors(nlevels(catchment), "Pastel 1", alpha = .3)
    color = color_legend[catchment]
    border = "grey80"
    lwd = 2
    theme_legend = list(
        title = sprintf("Bassin versant"),
        legend = levels(catchment),
        x = "topright",
        cex = .8,
        bg = "white",
        inset = 0.01,
        fill = color_legend,
        border = border
    )
    plot(geometry, border = border, col = color, lwd = lwd, add = TRUE)
Grelot Frederic's avatar
Grelot Frederic committed
219

Grelot Frederic's avatar
Grelot Frederic committed
220
221
222
223
    if (add_legend == TRUE && detail != "3") {
        return(theme_legend)
    } else {
        return(NULL)
Grelot Frederic's avatar
Grelot Frederic committed
224
    }
Grelot Frederic's avatar
Grelot Frederic committed
225
}
Grelot Frederic's avatar
Grelot Frederic committed
226

Grelot Frederic's avatar
Grelot Frederic committed
227
228
map_theme_catnat = function(detail, year, add_legend) {
    if (missing(detail)) {
Grelot Frederic's avatar
Grelot Frederic committed
229
        detail = dimnames(so.ii::so_ii_catnat)[["hazard"]]
Grelot Frederic's avatar
Grelot Frederic committed
230
231
232
    }
    detail = match.arg(
        detail, 
Grelot Frederic's avatar
Grelot Frederic committed
233
        dimnames(so.ii::so_ii_catnat)[["hazard"]],
Grelot Frederic's avatar
Grelot Frederic committed
234
235
        several.ok = TRUE
    )
Grelot Frederic's avatar
Grelot Frederic committed
236

Grelot Frederic's avatar
Grelot Frederic committed
237
    if (missing(year)) {
Grelot Frederic's avatar
Grelot Frederic committed
238
        year = range(dimnames(so.ii::so_ii_catnat)[["period"]])
Grelot Frederic's avatar
Grelot Frederic committed
239
    }
Grelot Frederic's avatar
Grelot Frederic committed
240
241
    year = match.arg(
        as.character(year),
Grelot Frederic's avatar
Grelot Frederic committed
242
        dimnames(so.ii::so_ii_catnat)[["period"]],
Grelot Frederic's avatar
Grelot Frederic committed
243
244
245
246
        several.ok = TRUE
    )
    year = as.character(seq(min(year), max(year)))
    catnat = apply(
Grelot Frederic's avatar
Grelot Frederic committed
247
        so.ii::so_ii_catnat[, year, detail, drop = FALSE],
Grelot Frederic's avatar
Grelot Frederic committed
248
249
250
        1,
        sum
    )
Grelot Frederic's avatar
Grelot Frederic committed
251

Grelot Frederic's avatar
Grelot Frederic committed
252
253
254
255
256
257
    border = "grey80"
    catnat_palette = scales::colour_ramp(c("white", "grey50"), alpha = .5)
    color = scales::cscale(
        c(0, catnat),
        catnat_palette
    )[-1]
Grelot Frederic's avatar
Grelot Frederic committed
258
    plot(
Grelot Frederic's avatar
Grelot Frederic committed
259
        so.ii::so_ii_collectivity[["geometry"]],
Grelot Frederic's avatar
Grelot Frederic committed
260
261
262
263
        border = border,
        col = color,
        add = TRUE
    )
Grelot Frederic's avatar
Grelot Frederic committed
264

Grelot Frederic's avatar
Grelot Frederic committed
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
    legend_title = sprintf(
        "Cat Nat %s",
        if (length(detail) == 3) "" else paste(sort(detail), collapse = " & ")
    )
    legend_title = sprintf(
        "%s [%s]",
        legend_title,
        if (length(year) == 1) year else paste(range(year), collapse = "-")
    )

    value_legend = unique(sort(c(min(catnat), round(seq(0, max(catnat), length.out = 5)))))
    color_legend = scales::cscale(
        value_legend,
        catnat_palette
    )

    theme_legend = list(
        title = legend_title,
        legend = value_legend,
        x = "topright",
        cex = .8,
        bg = "white",
        inset = 0.01,
        fill = color_legend,
        border = border,
        text.width = max(graphics::strwidth(value_legend))
    )

Grelot Frederic's avatar
Grelot Frederic committed
293
294
295
296
    if (add_legend == TRUE) {
        return(theme_legend)
    } else {
        return(NULL)
Grelot Frederic's avatar
Grelot Frederic committed
297
    }
Grelot Frederic's avatar
Grelot Frederic committed
298
}
Grelot Frederic's avatar
Grelot Frederic committed
299

Grelot Frederic's avatar
Grelot Frederic committed
300
301
map_theme_clc = function(add_legend) {
    plot(
Grelot Frederic's avatar
Grelot Frederic committed
302
        so.ii::so_ii_clc[["geometry"]],
Grelot Frederic's avatar
Grelot Frederic committed
303
        border = NA,
Grelot Frederic's avatar
Grelot Frederic committed
304
        col = so.ii::so_ii_clc[["color"]],
Grelot Frederic's avatar
Grelot Frederic committed
305
306
        add = TRUE
    )
Grelot Frederic's avatar
Grelot Frederic committed
307

Grelot Frederic's avatar
Grelot Frederic committed
308
309
    theme_legend = list(
        title = "CLC (2018)",
Grelot Frederic's avatar
Grelot Frederic committed
310
        legend = so.ii::clc_color[["label_fr"]],
Grelot Frederic's avatar
Grelot Frederic committed
311
312
313
314
        x = "topright",
        cex = .8,
        bg = "white",
        inset = 0.01,
Grelot Frederic's avatar
Grelot Frederic committed
315
        fill = so.ii::clc_color[["color"]]
Grelot Frederic's avatar
Grelot Frederic committed
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
    )

    if (add_legend == TRUE) {
        return(theme_legend)
    } else {
        return(NULL)
    }
}

map_theme_collectivity = function(detail, add_legend)  {
    if (missing(detail)) {
        detail = "none"
    }
    detail = match.arg(
        detail, 
        c("none", "syble", "symbo", "epci", "syndicate")
    )

    border = "grey80"
    color = NA

    theme_legend = list(
        title = "Caract\u00e9ristiques des communes",
        legend = "Commune",
        x = "topright",
        cex = .8,
        bg = "white",
        inset = 0.01,
        fill = color,
        border = border
    )
Grelot Frederic's avatar
Grelot Frederic committed
347
    geometry = so.ii::so_ii_collectivity[["geometry"]]
Grelot Frederic's avatar
Grelot Frederic committed
348
349
350
351
352
    plot(geometry, border = border, col = color, add = TRUE)
    
    if (detail %in% c("syble", "syndicate")) {
        color_legend = scales::alpha("orange", .3)
        color = ifelse(
Grelot Frederic's avatar
Grelot Frederic committed
353
            so.ii::so_ii_collectivity[["syble"]],
Grelot Frederic's avatar
Grelot Frederic committed
354
355
            color_legend,
            NA
Grelot Frederic's avatar
Grelot Frederic committed
356
        )
Grelot Frederic's avatar
Grelot Frederic committed
357
358
359
360
361
362
363
        plot(geometry, border = border, col = color, add = TRUE)
        theme_legend[["legend"]] = c(theme_legend[["legend"]], "SYBLE")
        theme_legend[["fill"]] = c(theme_legend[["fill"]], color_legend)  
    }
    if (detail %in% c("symbo", "syndicate")) {
        color_legend = scales::alpha("green", .3)
        color = ifelse(
Grelot Frederic's avatar
Grelot Frederic committed
364
            so.ii::so_ii_collectivity[["symbo"]],
Grelot Frederic's avatar
Grelot Frederic committed
365
366
            color_legend,
            NA
Grelot Frederic's avatar
Grelot Frederic committed
367
        )
Grelot Frederic's avatar
Grelot Frederic committed
368
369
370
371
372
        plot(geometry, border = border, col = color, add = TRUE)
        theme_legend[["legend"]] = c(theme_legend[["legend"]], "SYMBO")
        theme_legend[["fill"]] = c(theme_legend[["fill"]], color_legend) 
    }
    if (detail == "epci") {
Grelot Frederic's avatar
Grelot Frederic committed
373
        epci = as.factor(so.ii::so_ii_collectivity[["epci_name"]])
Grelot Frederic's avatar
Grelot Frederic committed
374
375
376
377
378
379
        color_legend = grDevices::hcl.colors(nlevels(epci), "Lisbon", alpha = .3)
        color = color_legend[epci]
        plot(geometry, border = border, col = color, add = TRUE)
        theme_legend[["legend"]] = levels(epci)
        theme_legend[["fill"]] = color_legend
    }
Grelot Frederic's avatar
Grelot Frederic committed
380

Grelot Frederic's avatar
Grelot Frederic committed
381
382
383
384
385
386
    if (add_legend == TRUE) {
        return(theme_legend)
    } else {
        return(NULL)
    }
}
Grelot Frederic's avatar
Grelot Frederic committed
387

Grelot Frederic's avatar
Grelot Frederic committed
388
389
390
391
392
393
394
395
map_theme_hydro = function(detail, add_legend) {
    if (missing(detail)) {
        detail = "none"
    }
    detail = match.arg(
        as.character(detail),
        choices = c(
            "none",
Grelot Frederic's avatar
Grelot Frederic committed
396
397
            levels(so.ii::so_ii_hydro[["degre"]]),
            levels(so.ii::so_ii_hydro[["type"]])
Grelot Frederic's avatar
Grelot Frederic committed
398
        )
Grelot Frederic's avatar
Grelot Frederic committed
399
400
401
402
    )
    color = scales::alpha("blue", .3)
    bg = scales::alpha("blue", .3)
    border = NA
Grelot Frederic's avatar
Grelot Frederic committed
403
    selection = seq(nrow(so.ii::so_ii_hydro))
Grelot Frederic's avatar
Grelot Frederic committed
404
405
406
407
408
409
410
411
412
413
    theme_legend = list(
        title = sprintf("R\u00e9seau hydrographique"),
        legend = "\u00e9l\u00e9ment du r\u00e9seau",
        x = "topright",
        cex = .8,
        bg = "white",
        inset = 0.01,
        col = color,
        lwd = 1
    )
Grelot Frederic's avatar
Grelot Frederic committed
414
415
    if (detail %in% levels(so.ii::so_ii_hydro[["type"]])) {
        selection  = as.character(so.ii::so_ii_hydro[["type"]]) == detail
Grelot Frederic's avatar
Grelot Frederic committed
416
417
        theme_legend[["legend"]] = detail
    }
Grelot Frederic's avatar
Grelot Frederic committed
418
419
    if (detail %in% levels(so.ii::so_ii_hydro[["degre"]])) {
        selection  = as.character(so.ii::so_ii_hydro[["degre"]]) <= detail
Grelot Frederic's avatar
Grelot Frederic committed
420
    }
Grelot Frederic's avatar
Grelot Frederic committed
421
422
    geometry = so.ii::so_ii_hydro[["geometry"]][selection]
    lwd = 4 - as.numeric(so.ii::so_ii_hydro[["degre"]][selection])
Grelot Frederic's avatar
Grelot Frederic committed
423

Grelot Frederic's avatar
Grelot Frederic committed
424
425
426
427
428
429
430
431
432
433
434
435
    plot(geometry, col = color, lwd = lwd, border = border, add = TRUE)

    if (add_legend == TRUE) {
        return(theme_legend)
    } else {
        return(NULL)
    }
}

map_theme_onrn = function(detail, add_legend) {
    if (missing(detail)) {
        detail = "cost"
436
    }
Grelot Frederic's avatar
Grelot Frederic committed
437
438
    detail = match.arg(
        as.character(detail),
Grelot Frederic's avatar
Grelot Frederic committed
439
        sort(colnames(so.ii::so_ii_onrn)[1:8])
Grelot Frederic's avatar
Grelot Frederic committed
440
    )
441

Grelot Frederic's avatar
Grelot Frederic committed
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
    onrn_palette = switch(
        EXPR = detail,
        "n_catnat"  = scales::colour_ramp(c("white", "red"), alpha = .5),
        "freq_sin"  = scales::colour_ramp(c("white", "red"), alpha = .5),
        "cost"      = scales::colour_ramp(c("white", "red"), alpha = .5),
        "cost_hab"  = scales::colour_ramp(c("white", "red"), alpha = .5),
        "cost_mean" = scales::colour_ramp(c("white", "red"), alpha = .5),
        "ratio"     = scales::colour_ramp(c("green", "white", "red"), alpha = .5),
        "balance"   = scales::colour_ramp(c("red", "white", "green"), alpha = .5),
        "ppri_year" = scales::colour_ramp(c("grey80", "grey50"), alpha = .5),
        NULL
    )
    onrn_trans = switch(
        EXPR = detail,
        "n_catnat"  = scales::identity_trans(),
        "freq_sin"  = scales::identity_trans(),
        "cost"      = scales::sqrt_trans(),
        "cost_hab"  = scales::sqrt_trans(),
        "cost_mean" = scales::sqrt_trans(),
        "ratio"     = scales::sqrt_trans(),
        "balance"   = scales::modulus_trans(.5),
        "ppri_year" = scales::identity_trans(),
        NULL
    )
    onrn_range = switch(
        EXPR = detail,
        "ratio"     = c(0, 4),
Grelot Frederic's avatar
Grelot Frederic committed
469
        "balance"   = max(abs(range(so.ii::so_ii_onrn[["balance"]]))) * c(-1, 1),
Grelot Frederic's avatar
Grelot Frederic committed
470
471
472
473
        NULL
    )

    color = scales::cscale(
Grelot Frederic's avatar
Grelot Frederic committed
474
        c(onrn_range, so.ii::so_ii_onrn[[detail]]),
Grelot Frederic's avatar
Grelot Frederic committed
475
476
477
478
479
480
481
        onrn_palette,
        trans = onrn_trans)
    if (length(onrn_range) > 0) {
        color = color[-seq(onrn_range)]
    }
    border = "grey80"
    plot(
Grelot Frederic's avatar
Grelot Frederic committed
482
        so.ii::so_ii_collectivity[["geometry"]],
Grelot Frederic's avatar
Grelot Frederic committed
483
484
485
486
487
        border = border,
        col = color,
        add = TRUE
    )

Grelot Frederic's avatar
Grelot Frederic committed
488
    if (sprintf("%s_min", detail) %in% names(so.ii::so_ii_onrn)) {
Grelot Frederic's avatar
Grelot Frederic committed
489
        selection = c(detail, sprintf("%s_min", detail), sprintf("%s_max", detail))
Grelot Frederic's avatar
Grelot Frederic committed
490
        temp = unique(so.ii::so_ii_onrn[selection])
Grelot Frederic's avatar
Grelot Frederic committed
491
492
493
494
495
496
497
        temp = temp[order(temp[[detail]]), ]
        text_legend = gsub("0 - 0", "0",
            sprintf(
                "%s - %s",
                temp[[sprintf("%s_min", detail)]],
                temp[[sprintf("%s_max", detail)]]
            )
Grelot Frederic's avatar
Grelot Frederic committed
498
        )
Grelot Frederic's avatar
Grelot Frederic committed
499
500
501
502
503
        value_legend = temp[[detail]]
    }
    if (detail %in% c("n_catnat", "ppri_year")) {
        value_legend = round(
            seq(
Grelot Frederic's avatar
Grelot Frederic committed
504
505
                min(so.ii::so_ii_onrn[[detail]], na.rm = TRUE),
                max(so.ii::so_ii_onrn[[detail]], na.rm = TRUE),
Grelot Frederic's avatar
Grelot Frederic committed
506
507
                length.out = 5
            )
Grelot Frederic's avatar
Grelot Frederic committed
508
        )
Grelot Frederic's avatar
Grelot Frederic committed
509
510
511
512
513
        text_legend = value_legend
    }
    if (detail %in% c("balance")) {
        value_legend = unique(
            c(
Grelot Frederic's avatar
Grelot Frederic committed
514
515
                seq(min(so.ii::so_ii_onrn[[detail]]), 0, length.out = 4),
                seq(0, max(so.ii::so_ii_onrn[[detail]]), length.out = 4)
Grelot Frederic's avatar
Grelot Frederic committed
516
            )
Grelot Frederic's avatar
Grelot Frederic committed
517
518
        )
        text_legend = formatC(
Grelot Frederic's avatar
Grelot Frederic committed
519
            as.integer(signif(round(value_legend), 2)),
Grelot Frederic's avatar
Grelot Frederic committed
520
521
            big.mark = " "
        )
Grelot Frederic's avatar
Grelot Frederic committed
522
        text.width = max(graphics::strwidth(text_legend))
Grelot Frederic's avatar
Grelot Frederic committed
523
524
525
526
527
    }
    color_legend = scales::cscale(
            c(onrn_range, value_legend),
            onrn_palette,
            trans = onrn_trans
Grelot Frederic's avatar
Grelot Frederic committed
528
        )
Grelot Frederic's avatar
Grelot Frederic committed
529
530
    if (length(onrn_range) > 0) {
        color_legend = color_legend[-seq(onrn_range)]
Grelot Frederic's avatar
Grelot Frederic committed
531
    }
Grelot Frederic's avatar
Grelot Frederic committed
532
533
    title_onrn = switch(
        EXPR = detail,
Grelot Frederic's avatar
Grelot Frederic committed
534
        "n_catnat"  = "Arr\u00eat\u00e9s Cat-Nat [1982-2021]",
Grelot Frederic's avatar
Grelot Frederic committed
535
536
537
538
539
540
541
542
543
        "freq_sin"  = "Sinistre / Risque [1995-2018]",
        "cost"      = "Co\u00fbt cumul\u00e9 (\u20AC) [1995-2018]",
        "cost_hab"  = "Co\u00fbt / hab (\u20ac) [1995-2018]",
        "cost_mean" = "Co\u00fbt / sinistre (\u20ac) [1995-2018]",
        "ratio"     = "Co\u00fbt / Prime [1995-2018]",
        "balance"   = "Co\u00fbt - Prime (\u20ac) [1995-2018]",
        "ppri_year" = "Ann\u00e9e des PPRI",
        NULL
    )
Grelot Frederic's avatar
Grelot Frederic committed
544

Grelot Frederic's avatar
Grelot Frederic committed
545
546
547
548
549
550
551
552
553
554
    theme_legend = list(
        title = title_onrn,
        legend = text_legend,
        x = "topright",
        cex = .8,
        bg = "white",
        inset = 0.01,
        fill = color_legend,
        border = border
    )
Grelot Frederic's avatar
Grelot Frederic committed
555
556
557
558
    if (detail %in% c("balance", "cost")) {
        theme_legend[["text.width"]] = max(graphics::strwidth(text_legend))
    }
    
Grelot Frederic's avatar
Grelot Frederic committed
559
560
561
562
    if (add_legend == TRUE) {
        return(theme_legend)
    } else {
        return(NULL)
563
    }
Grelot Frederic's avatar
Grelot Frederic committed
564
}
565

Grelot Frederic's avatar
Grelot Frederic committed
566
567
568
569
map_theme_osm = function() {
    so_ii_osm = terra::rast(
        system.file("extdata", "so_ii_osm.tif", package = "geau", mustWork = TRUE)
    )
Grelot Frederic's avatar
Grelot Frederic committed
570
    try(terra::plot(so_ii_osm, add = TRUE), silent = TRUE)
Grelot Frederic's avatar
Grelot Frederic committed
571
572
573
574
    graphics::mtext(
        text = "Fond de carte : \u00a9 Contributeurs OpenStreetMap", 
        side = 1, line = -1, adj = 1, cex = .6, font = 3
    )
Grelot Frederic's avatar
Grelot Frederic committed
575
    return(NULL)
Grelot Frederic's avatar
Grelot Frederic committed
576
577
}

Grelot Frederic's avatar
Grelot Frederic committed
578
map_theme_population = function(detail, year, add_legend) {
Grelot Frederic's avatar
Grelot Frederic committed
579
    if (missing(year)) {
Grelot Frederic's avatar
Grelot Frederic committed
580
        year = utils::tail(sort(colnames(so.ii::so_ii_population)), 1)
581
    }
Grelot Frederic's avatar
Grelot Frederic committed
582
583
    year = match.arg(
        as.character(year),
Grelot Frederic's avatar
Grelot Frederic committed
584
        sort(colnames(so.ii::so_ii_population)),
Grelot Frederic's avatar
Grelot Frederic committed
585
        several.ok = TRUE
Grelot Frederic's avatar
Grelot Frederic committed
586
    )
Grelot Frederic's avatar
Grelot Frederic committed
587

Grelot Frederic's avatar
Grelot Frederic committed
588
    border = "grey80"
Grelot Frederic's avatar
Grelot Frederic committed
589
590
591
592
593

    if (length(year) == 1) {
        pop_palette = scales::colour_ramp(c("white", "red"), alpha = .5)
        color = matrix(
            scales::cscale(
Grelot Frederic's avatar
Grelot Frederic committed
594
                so.ii::so_ii_population,
Grelot Frederic's avatar
Grelot Frederic committed
595
596
                pop_palette,
                trans = scales::log_trans()),
Grelot Frederic's avatar
Grelot Frederic committed
597
598
            nrow = nrow(so.ii::so_ii_population),
            dimnames = dimnames(so.ii::so_ii_population)
Grelot Frederic's avatar
Grelot Frederic committed
599
600
601
        )

        plot(
Grelot Frederic's avatar
Grelot Frederic committed
602
            so.ii::so_ii_collectivity[["geometry"]],
Grelot Frederic's avatar
Grelot Frederic committed
603
604
605
606
            border = border,
            col = color[ , year],
            add = TRUE
        )
Grelot Frederic's avatar
Grelot Frederic committed
607
608
        max_pop = max(so.ii::so_ii_population[ , year])
        min_pop = min(so.ii::so_ii_population[ , year])
Grelot Frederic's avatar
Grelot Frederic committed
609
610
611
612
613
614
615
616
        base = 10

        value_legend = unique(c(
            min_pop,
            base^(ceiling(log(min_pop)/log(base)):floor(log(max_pop)/log(base))),
            max_pop
        ))
        color_legend = scales::cscale(
Grelot Frederic's avatar
Grelot Frederic committed
617
                c(range(so.ii::so_ii_population), value_legend),
Grelot Frederic's avatar
Grelot Frederic committed
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
                pop_palette,
                trans = scales::log_trans()
            )[-(1:2)]
        text_legend = formatC(
            as.integer(value_legend),
            big.mark = " "
        )

        theme_legend = list(
            title = sprintf("Population %s", year),
            legend = text_legend,
            x = "topright",
            cex = .8,
            bg = "white",
            inset = 0.01,
            fill = color_legend,
            border = border,
            text.width = max(graphics::strwidth(text_legend))
        )
    }
    
    if (length(year) > 1) {
        if (missing(detail)) {
            detail = "absolute"
        }
        detail = match.arg(as.character(detail), c("absolute", "relative"))
        year = range(year)

        pop_palette = scales::colour_ramp(
            c("red", "white", "green"),
            alpha = .5
        )
        pop_data = switch(
            EXPR = detail,
Grelot Frederic's avatar
Grelot Frederic committed
652
653
654
655
656
            "absolute" = so.ii::so_ii_population[ , year[2]] -
                so.ii::so_ii_population[ , year[1]],
            "relative"  = (so.ii::so_ii_population[ , year[2]] -
                so.ii::so_ii_population[ , year[1]]) /
                so.ii::so_ii_population[ , year[1]]
Grelot Frederic's avatar
Grelot Frederic committed
657
658
659
660
661
662
663
664
665
666
667
668
        )
        range_data = max(abs(range(pop_data))) * c(-1, 1)
        pop_trans = switch(
            EXPR = detail,
            "absolute"  = scales::modulus_trans(0.2),
            "relative"  = scales::modulus_trans(0.1),
            NULL
        )
        color = scales::cscale(
            c(range_data, pop_data),
            pop_palette,
            trans = pop_trans
Grelot Frederic's avatar
Grelot Frederic committed
669
        )[-(1:2)]
Grelot Frederic's avatar
Grelot Frederic committed
670
        plot(
Grelot Frederic's avatar
Grelot Frederic committed
671
            so.ii::so_ii_collectivity[["geometry"]],
Grelot Frederic's avatar
Grelot Frederic committed
672
673
674
675
            border = border,
            col = color,
            add = TRUE
        )
676

Grelot Frederic's avatar
Grelot Frederic committed
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
        max_pop = max(pop_data)
        min_pop = min(pop_data)

        if (detail == "absolute") {
            range_pop = max(abs(c(max_pop, min_pop)))
            base = max(10, 10^floor(ceiling(log(range_pop)/log(10)) / 2))

            if (sign(min_pop) == -1) {
                value_legend = c(
                    -base^(floor(log(abs(min_pop))/log(base)):1),
                    base^(1:floor(log(max_pop)/log(base)))
                )
                value_legend = value_legend[
                    value_legend < max_pop &
                    value_legend > min_pop &
                    abs(value_legend) >= base
                ]
                value_legend = sort(c(0, range(pop_data), value_legend))
            } else {
                value_legend = unique(c(
                    min_pop,
                    base^(ceiling(log(min_pop)/log(base)):floor(log(max_pop)/log(base))),
                    max_pop
                ))
            }
            color_legend = scales::cscale(
                c(range_data, value_legend),
                pop_palette,
                trans = pop_trans
            )[-(1:2)]
            text_legend = formatC(
                as.integer(value_legend),
                big.mark = " "
            )
            title_legend = sprintf("Population \u00e9volution [%s-%s]", year[1], year[2])
        }

        if (detail == "relative") {
            max_pop = max(pop_data) * 100
            min_pop = min(pop_data) * 100
            range_pop = max(abs(c(max_pop, min_pop)))
            base = max(10, 10^floor(ceiling(log(range_pop)/log(10)) / 2))

            if (sign(min_pop) == -1) {
                value_legend = unique(c(
                    min_pop,
                    -base^(floor(log(abs(min_pop))/log(base)):0),
                    0,
                    base^(0:floor(log(max_pop)/log(base))),
                    max_pop
                ))
            } else {
                value_legend = unique(c(
                    min_pop,
                    base^(ceiling(log(min_pop)/log(base)):floor(log(max_pop)/log(base))),
                    max_pop
                ))
            }
            color_legend = scales::cscale(
                    c(range_data, value_legend / 100),
                    pop_palette,
                    trans = pop_trans
                )[-(1:2)]
            text_legend = sprintf(
                "%s %%",
                formatC(
                    signif(value_legend, 3),
                    digits = 2, format = "f", flag = "+",
                    big.mark = " "
                )
            )
            title_legend = sprintf("Population \u00e9volution [%s-%s]", year[1], year[2])
        }

        theme_legend = list(
            title = title_legend,
            legend = text_legend,
            x = "topright",
            cex = .8,
            bg = "white",
            inset = 0.01,
            fill = color_legend,
            border = border,
            text.width = max(graphics::strwidth(text_legend))
        )
    }
Grelot Frederic's avatar
Grelot Frederic committed
763

Grelot Frederic's avatar
Grelot Frederic committed
764
765
766
767
768
    if (add_legend == TRUE) {
        return(theme_legend)
    } else {
        return(NULL)
    }
769
}