Skip to contents

Introduction

This vignette demonstrates the use of the family of functions that facilitates the production of interactive HTML maps of the so-ii territory: set_provider(), map_leaflet_commune(), add_visual_param() and map_leaflet_multilayer(). This document will cover the available options and demonstrate how to customize the resulting plots.

The function set_provider()

This function helps to set the background map provider for interactive mapping applications. It allows you to select different base maps from a predefined list of options, primarily from the French Institut national de l’information géographique et forestière (IGN).

The set_provider() function retrieves the URL for the map provider and its attribution information based on an alias, that it takes as a parameter. The function returns either a list containing both the provider URL address and the attribution information or just the provider URL address depending on the value of the parameter attribution. The output of the function can be used directly in functions map_leaflet_commune() and map_leaflet_multilayer().

Currently, the function supports the following provider aliases:

  • ign_ortho: orthophotos
  • ign_plan: plan IGN v2 (Cartographie multi-échelles sur le territoire national français)
  • ign_parcellaire: cadastral plots(Cartographie parcellaire cadastral multi-échelles sur le territoire national français)
  • ign_3d: 3D representation using shading derived from MNH LiDAR HD (estompage issu du MNH LiDAR HD)
  • ign_building: BD TOPO® V3 - Buildings layer (BD TOPO® V3 - Bâtiments)
  • ign_rpg: French land parcel identification system (RPG Dernière édition)
  • ign_aoc_viti: IGN’s AOC wine region boundaries (délimitations parcellaires AOC viticoles (INAO))

The usage of this function is very straightforward:

First of all let us load the library so.ii in our R session.

Default provider

If you call the function without specifying an alias, it will issue a warning and default to “ign_ortho”. This is useful for quickly getting a base map without needing to specify it each time.

set_provider()
#> Warning in set_provider(): Provider alias missing. Please see documentation.
#> Choosing 'ign_ortho' by default
#> $provider
#> [1] "https://data.geopf.fr/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE=normal&TILEMATRIXSET=PM&FORMAT=image/jpeg&LAYER=ORTHOIMAGERY.ORTHOPHOTOS&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}"
#> 
#> $attribution
#> [1] "IGN-F/Geoportail"

Provider with attribution

To set a specific provider and retrieve both the provider URL and its attribution information, simply pass the desired alias as the first argument.


set_provider("ign_ortho")
#> $provider
#> [1] "https://data.geopf.fr/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE=normal&TILEMATRIXSET=PM&FORMAT=image/jpeg&LAYER=ORTHOIMAGERY.ORTHOPHOTOS&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}"
#> 
#> $attribution
#> [1] "IGN-F/Geoportail"

Specifying a provider without attribution

If you only need the provider URL and don’t require the attribution information, set the attribution argument to FALSE.


set_provider("ign_plan", attribution = FALSE)  
#> [1] "https://data.geopf.fr/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE=normal&TILEMATRIXSET=PM&FORMAT=image/png&LAYER=GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}"

The function map_leaflet_commune()

This function creates an interactive Leaflet map displaying commune-level data with customizable styling and popups. This is particularly useful for visualizing geographic data related to the commune administrative level.

The map_leaflet_commune() function generates a Leaflet map as follows: over a base map layer set using set_provider(), it overlays the polygons in the dataset sf object, and uses the content in the popup column of the dataset to display information about each polygon.

Let us create a simple example using the so_ii_collectivity dataset to display a map with commune-level information. First, load the necessary data and create a popup variable containing the information you want to display in the popups. In this example, we will display the commune name and population.

dataset = so_ii_collectivity
dataset[["popup"]] = paste(
 dataset[["commune_name"]],
 sprintf("(%s hab)", formatC(so_ii_population[,"2019"], big.mark = " ", format = "d"))
)

Now, call the map_leaflet_commune() function with the prepared dataset to generate the interactive Leaflet map. Clicking on a commune will reveal its corresponding popup with the name and population.

map = map_leaflet_commune(dataset = dataset)

# Display map
map

You can customize the base map by providing a different map_bg list, which is generated using the set_provider() function. For example, to use the “ign_plan” provider:

map_leaflet_commune(dataset = dataset, map_bg = set_provider("ign_plan"))

If your dataset does not contain a popup column, the function will issue a warning and create an empty popup column, preventing errors.

# Example with a dataset missing the 'popup' column
dataset_no_popup = so_ii_collectivity
map = map_leaflet_commune(dataset = dataset_no_popup)
#> Warning in map_leaflet_commune(dataset = dataset_no_popup): 'popup' column is
#> missing. Using commune names as pooup content

# Display map
map

The function add_visual_param()

This function is a wrapper of the base::merge() intended to enhance a spatial layer with visual parameters provided as a data.frame. The function handles sf and sfc objects as inputs and always outputs an sf object.

Its usage is straightforward. Let us see 3 key examples:

Example 1: sf object with and a single junction

Let’s demonstrate how to add visual parameters to the so_ii_hydro dataset. To do so we will use a data.frame containing color, fill, and opacity values, joining based on the common column "type".

enhanced_sf = add_visual_param(
  layer = so_ii_hydro,
  visual_param = data.frame(
    type = unique(so.ii::so_ii_hydro[["type"]]),
    color = c("blue", "red", "dodgerblue"),
    fill = c("blue", "red", "dodgerblue"),
    opacity = 0.8
  ),
  junction = "type"
)

Example 2: sf object and two junctions

If your visual parameters and spatial data have different column names for the join key, you should specify both. In the prior example that would be as follows:

enhanced_sf = add_visual_param(
  layer = so_ii_hydro,
  visual_param = data.frame(
    id = unique(so.ii::so_ii_hydro[["type"]]),
    color = scales::alpha(c("blue", "red", "dodgerblue"), 0.5), 
    fill = scales::alpha(c("blue", "red", "dodgerblue"), 0.5),
    opacity = 0.5
  ),
  junction = c("type", "id")
)

Example 3: sfc object

For sfc objects, the function directly adds the visual parameters as attributes.

enhanced_sfc = add_visual_param(
  layer = so_ii_limit,
  visual_param = data.frame(
    id = "perimeter",
    label = "perimeter",
    color = "white",
    fill = "transparent",
    opacity = 1
  )
)

The function add_leaflet_layer()

This function adds a spatial layer to an existing Leaflet map, allowing customization of its appearance ( based on attributes in the layer object ) and interactivity. This function dynamically handles different geometry types (polygons, polylines, and points) within the spatial layer and generates a legend for non-point geometries.

Let us see an example for each geometry type the function is able to handle. First of all, we need to create a leaflet map, so we can add layers to it. We will use the set_provider() function to set the background map :

library(leaflet)

# Create a base map
map_bg = set_provider("ign_3d")
map = leaflet::leaflet() |>
  leaflet::addTiles(
    urlTemplate = map_bg[["provider"]],
    attribution = map_bg[["attribution"]],
    options = leaflet::tileOptions(opacity = 0.2)
  )

Example 1: adding a polygon layer

Let us now add the perimeter of the so-ii observatory to this map. The sf objet provided as layer is expected to include the following attributes in its attribute table (see the add_leaflet_layer() function documentation for more details):

  • color
  • opacity
  • fill
  • label
  • popup

These attributes can be added easily to the layer using the add_visual_param() function:


# Prepare the layer
perimeter_layer = add_visual_param(
  layer = so_ii_limit,
  visual_param = data.frame(
    id = "perimeter",
    label = "perimeter",
    popup = "so-ii perimeter",
    color = "white",
    fill = "transparent",
    opacity = 1
  )
)

Now that the layer is ready we just call the function to add iy to out existing map:

# Add the layer to the map
map = add_leaflet_layer(
  map = map,
  layer = perimeter_layer,
  group = "perimeter"
)

# Display map
map

Example 2: adding a multiple geometry layer

Sometimes we can find layer that present multiple geometries together. For example, the so_ii_hydro database mixes LINESTRING and MULTIPOLYGON geometries. The workflow to handle this type of layer is similar to the previous one: first, provide/create the visual and interactivity attributes needed in the add_leaflet_layer() function using the add_visual_param() function:

library(scales)

hydro_layer = add_visual_param(
    layer = so_ii_hydro,
    visual_param = data.frame(
        id = unique(so.ii::so_ii_hydro[["type"]]),
        label = unique(so.ii::so_ii_hydro[["type"]]),
        color = scales::alpha(c("blue", "red", "dodgerblue"), 0.5), 
        fill = scales::alpha(c("blue", "red", "dodgerblue"), 0.5),
        opacity = 0.5
    ),
    junction = c("type", "id")
)

Then call the add_leaflet_layer() function:

map = add_leaflet_layer(
  map = map,
  layer = hydro_layer,
  group = "hydrography"
)

# Display map
map

Example 3: adding a points layer

You can also add points to the map. To do so, let us first create our sf object with a few random points within the so-ii perimeter:

random_points = data.frame(
  label = c("point1", "point2", "point3"),
  long = c(3.821011, 3.870760, 3.896732),
  lat = c(43.55250, 43.65147, 43.61877)
)

random_points = sf::st_as_sf(
  x = random_points,
  coords = c("long","lat"),
  crs = sf::st_crs(so_ii_hydro)
)

Next, we will use add_visual_param() function to provide the visual and interactivity attributes needed:

random_points_layer = add_visual_param(
  layer = random_points,
  visual_param = data.frame(
    id = unique(random_points[["label"]]),
    label = unique(random_points[["label"]]),
    color = NA, 
    fill = NA,
    opacity = 0.5,
    popup = sprintf("This is random %s", random_points[["label"]])
  ),
  junction = "label"
)

Finally, let us add it to our map:

map = add_leaflet_layer(
  map = map,
  layer = random_points_layer,
  group = "random_points"
)

# Display map
map

You can use the function add_leaflet_layer() in combination with the map_leaflet_commune() function. This will allow you to add a layer of points, lines or polygons on top of the map of communes of the so-ii territory. For instance, you could the following:

map = map_leaflet_commune() #uses default values and issues warning about popup
#> Warning in map_leaflet_commune(): 'popup' column is missing. Using commune
#> names as pooup content

# adds random points 
map = add_leaflet_layer(
  map = map,
  layer = random_points_layer,
  group = "random_points"
)

# Display map
map

The function map_leaflet_multilayer()

This function is a wrapper of add_leaflet_layer() to generate an interactive Leaflet map displaying multiple layers of spatial data whose visualization can be activated/deactivated. The map_leaflet_multilayer() function expects well-structured sf objects with defined aesthetic attributes for optimal rendering.

It makes internal use of add_visual_param() and add_leaflet_layer() functions to handle the layering and customization processes, so it inherits their requirements in order to properly handle objects.

Layers are divided between base layers nad overlay layers. Base layers cannot be deactivated, whereas overlay layers can be activated/deactivated.

Let us make a multilayer interactive map showcasing the so-ii perimeter as base layer and the hydrographic network and the randon points as overlay layers:

map = map_leaflet_multilayer(
    base_layer = list(
        perimeter = so.ii::so_ii_limit
    ),
    base_color = list(
        perimeter = data.frame(
            id = "perimeter",
            label = "perimeter",
            color = "white",
            fill = "transparent",
            opacity = 1
        )
    ),
    overlay_layer = list(
        hydrography = so.ii::so_ii_hydro,
        point = random_points
        ),
    overlay_color = list(
        hydrography = data.frame(
            id = unique(so.ii::so_ii_hydro[["type"]]),
            label = unique(so.ii::so_ii_hydro[["type"]]),
            color = scales::alpha(c("blue", "red", "dodgerblue"), 0.5), 
            fill = scales::alpha(c("blue", "red", "dodgerblue"), 0.5),
            opacity = 0.5
        ),
        point = data.frame(
            id = unique(random_points[["label"]]),
            label = unique(random_points[["label"]]),
            color = NA, 
            fill = NA,
            opacity = 0.5,
            popup = sprintf("This is random %s", random_points[["label"]])
        )
    ),
    overlay_junction = list(
        hydrography = c("type", "id"),
        point = "label"
    ),
    map_bg = so.ii::set_provider("ign_3d"),
    bg_opacity = 0.6
)

# Display map
map