mapgl R Package

repository·main·Indexed 41 days ago

https://github.com/walkerke/mapgl

An R package providing an interface to Mapbox GL JS and MapLibre GL JS for creating high-performance, interactive web maps. It supports sf objects and terra rasters, offering functions for adding fill, line, circle, symbol, heatmap, and fill-extrusion layers, as well as tools for animated transitions with fly_to(), synced swipe maps via compare(), and continuous color styling using interpolate_palette().

Tokens
86.9K
Snippets
252
Records
388
Agent score
49%

What's inside mapgl

  1. Overview of mapgl for interactive mapping in R

    main

    The mapgl package provides a unified interface for creating interactive maps in R using either Mapbox GL JS or MapLibre GL JS.

    Key capabilities include:

    • Creating interactive globe visualizations.
    • Layering sf (simple features) objects to generate filled maps, circle maps, heatmaps, and 3D graphics.
    • Customizing map styles and camera views.
    • Integrating Mapbox and MapLibre maps into Shiny web applications via provided utilities.
  2. Update map layers using set_filter() in story maps

    main

    When building interactive story maps, instead of clearing and re-adding layers to change data visibility, use set_filter() for better performance. This function invokes the underlying MapLibre setFilter() JavaScript method to operate directly on the map layer.

    • To clear a filter and show all data: Pass NULL to the filter argument.
    • To apply a filter: Pass a list defining the filter criteria (e.g., list("==", "column_name", value)).

    This is typically used within on_section() handlers to trigger map updates as the user scrolls into specific story sections.

    # Example: Clearing a filter in a section
    on_section("map", "intro", {
      maplibre_proxy("map") |> 
        set_filter("fl_tracts", NULL) |> 
        fit_bounds(fl_age, animate = TRUE)
    })
    
    # Example: Applying a filter based on a Shiny input in a section
    on_section("map", "county", {
      maplibre_proxy("map") |> 
        set_filter("fl_tracts", filter = list("==", "county", input$county)) |> 
        fit_bounds(sel_county(), animate = TRUE)
    })
  3. Configure FlowmapGL tooltips and popups

    main

    Both tooltip and popup allow you to define content that appears on hover or click. They accept several formats:

    • TRUE: Default content.
    • FALSE or NULL: Disabled.
    • A column name from the data.
    • A {brace} template.
    • A concat() or number_format() expression.
    • A named list(location = ..., flow = ...) to provide different content for locations vs flows.

    Available Fields:

    • Locations: name, id, lat, lon, incoming, outgoing, internal, plus any additional columns in the locations data.
    • Flows: count, origin_id, origin_name, dest_id, dest_name, plus any additional columns in the flows data.

    Use tooltip_style or popup_style to customize appearance using presets ("light", "dark", or "auto") or a tooltip_style() object.

  4. How comparison modes work in `compare()`

    main

    The compare() function supports two distinct modes:

    1. mode="swipe" (default): Creates a swipeable interface with a slider to reveal portions of exactly two maps. Use orientation ("horizontal" or "vertical") to set the layout and swiper_color to customize the slider handle.
    2. mode="sync": Places maps next to each other in a synchronized grid. This mode supports two or more maps. You can control the grid layout using ncol. When laser = TRUE, a laser pointer follows the cursor on the other maps in the grid.
  5. Understand the FlowmapGL temporal scale-domain patch

    main

    Because FlowmapGL 9.3.0 only supports viewport-adaptive scaling, mapgl applies a local patch (patches/flowmap-temporal-scale-domain.patch) to enable temporal scale-domain control.

    This allows for two distinct scaling behaviors:

    • adaptiveScalesEnabled: Remains spatial; limits scale domains to flows with endpoints in the current viewport.
    • temporalScaleDomain: Controls temporal scaling:
      • "selected": Uses flows at the selected time for width/color domains.
      • "all": Uses all-time flows to ensure comparable widths/colors across different time steps.
  6. Configure map bounds and constraints

    main

    The maplibre() function allows you to constrain the map view using the bounds argument or MapLibre GL JS options passed via ...:

    Setting Bounds

    The bounds argument accepts:

    • An sf object.
    • The output of st_bbox().
    • An unnamed numeric vector: c(xmin, ymin, xmax, ymax).

    Restricting Panning

    To restrict panning to a specific bounding box, pass maxBounds through the ... argument. It must be specified as a list of two coordinate pairs: list(c(sw_lng, sw_lat), c(ne_lng, ne_lat)).

  7. Add an attribute editor to drawn features

    main

    You can enable an attribute editor for classification workflows by providing an attributes argument to add_draw_control(). This argument takes a named list of fields defined using draw_attribute().

    When a user selects exactly one drawn feature, a small editor opens. Clicking Save writes the values to the feature properties. These properties can then be retrieved as sf columns using get_drawn_features().

    Note: The editor works for newly drawn features and features loaded via the source argument or add_features_to_draw(). It is not currently supported in compare widgets.

    mapboxgl() |> 
        add_draw_control(
            attributes = list(
                class = draw_attribute(
                    "select",
                    choices = c("forest", "water", "urban"),
                    required = TRUE
                ),
                notes = draw_attribute("textarea"),
                confidence = draw_attribute(
                    "numeric",
                    min = 0,
                    max = 1,
                    step = 0.1,
                    default = 1
                )
            )
        )
  8. Perform client-side geospatial analysis with turf.js

    main

    Version 0.4.0 added support for turf.js v7.2.0, enabling spatial operations directly in the browser. This avoids server round-trips and works with existing map layers, sources, or sf objects. Supported operations include:

    • Geometric operations: turf_buffer(), turf_union(), turf_intersect(), turf_difference().
    • Spatial filtering: turf_filter() using predicates like intersects, within, contains, crosses, or disjoint.
    • Point analysis: turf_convex_hull(), turf_concave_hull(), turf_voronoi(), turf_centroid(), turf_center_of_mass().
    • Measurements: turf_distance() and turf_area() (Shiny-only).
  9. Configure FlowmapGL color schemes

    main

    The flow_color_scheme argument determines the color ramp for flows. You can provide:

    1. A FlowMapGL preset name (case-sensitive, e.g., "Teal"). Use flowmap_color_schemes() to list available presets.
    2. A character vector of at least two CSS colors (e.g., c("red", "white", "blue")).
    3. A mapgl_continuous_scale object created by interpolate_palette().
    # Example using a preset
    add_flowmap(map, "my_id", locations, flows, flow_color_scheme = "Teal")
    
    # Example using a custom color vector
    add_flowmap(map, "my_id", locations, flows, flow_color_scheme = c("red", "white", "blue"))
  10. How to update a clustered circle layer in Shiny

    main

    When using add_circle_layer() with cluster_options(), the function creates three layers: "id", "id-clusters", and "id-cluster-count".

    To update the data reactively in a Shiny application without tearing down the layers, do not re-run add_circle_layer(). Instead, use set_source() to replace the underlying data, which triggers Mapbox/MapLibre to re-cluster automatically:

    mapboxgl_proxy("map") |> set_source(layer_id = "circles", source = filtered())

    If you need to remove a clustered layer entirely (for example, before switching map backends), you must pass the full trio of layer IDs to clear_layer():

    clear_layer(proxy, c("circles", "circles-clusters", "circles-cluster-count"))
  11. Configure slider visual presentation and histogram

    main

    The slider's appearance can be customized via presentation, histogram, and styling arguments.

    Presentation Modes

    • "compact" (default): A standard small slider.
    • "timeline": A prominent, brushable histogram. This mode requires histogram = TRUE and either counts or histogram_data to be provided.

    Histogram Settings

    • histogram: Set to TRUE to draw a density strip behind the slider.
    • histogram_data: A numeric vector of raw property values; the package bins these to create the bars.
    • counts: A numeric vector of pre-computed bar heights (one per value in values).

    Styling

    • slider_style: Use a preset ("light", "dark", or "auto") or a slider_style() object for full control.
    • Legacy styling: Use width, background_color, text_color, and accent_color for basic overrides.