Embeds the full 'GeoLibre' geographic information system in
'R Markdown', 'Quarto', 'Shiny', and the 'RStudio' Viewer. Create maps from
'GeoJSON' and 'sf' objects, markers, heatmaps, and tabular coordinates; add
'Cloud Optimized GeoTIFF', 'XYZ', 'WMS', 'WMTS', 'WFS', 'PMTiles', vector
tile, '3D Tiles', and video sources; classify choropleths, arrange layers,
and add legends, colorbars, and split-map comparisons. Control the camera,
export standalone 'HTML', and read and write '.geolibre.json' project files.
The underlying application is described in Wu (2026)
geolibre brings the full GeoLibre GIS application to
RStudio, Quarto, R Markdown, and Shiny. It is an htmlwidgets interface to
GeoLibre's project format and embed bridge.
Open the live interactive map example to try the R widget directly in your browser.
# Once released on CRAN:
install.packages("geolibre")
# Development version:
install.packages("pak")
pak::pak("opengeos/geolibre-r")
library(geolibre)
points <- list(
type = "FeatureCollection",
features = list(list(
type = "Feature",
properties = list(name = "Washington, DC"),
geometry = list(type = "Point", coordinates = c(-77.0369, 38.9072))
))
)
geolibre(layout = "maponly") |>
add_geojson(points, name = "Places", fillColor = "#dc2626", circleRadius = 8) |>
set_view(center = c(-77.0369, 38.9072), zoom = 10)
Style overrides can be passed as named arguments, as above, or as a style list.
Every add_*(), set_*(), and control function takes the map first and returns
it, so calls compose with the pipe.
sfadd_sf() transforms data to WGS 84 before sending GeoJSON to the browser.
library(sf)
nc <- st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
geolibre() |>
add_sf(nc, "North Carolina counties")
cities <- data.frame(
name = c("Washington", "New York", "Boston"),
longitude = c(-77.0369, -74.0060, -71.0589),
latitude = c(38.9072, 40.7128, 42.3601)
)
geolibre() |>
add_xy_data(cities, name = "Cities", circleRadius = 8) |>
fit_bounds(c(-78, 38, -70, 43))
add_markers(), add_circle_markers(), add_marker_cluster(), and
add_heatmap() accept the same points in any of several shapes: a list of
c(longitude, latitude) pairs, a two-column matrix, a data frame, point
GeoJSON, or an sf object. add_csv() reads a path, a URL, or CSV text.
add_choropleth() classifies a numeric column and colors it from a named ramp,
computing the same stops the application's Style panel does.
geolibre() |>
add_choropleth(nc, column = "BIR74", colormap = "blues", class_count = 6) |>
add_legend("Births", legend = c(Low = "#eff6ff", High = "#1e3a8a"))
See color_ramp_names() for the available ramps and basemaps() for the named
basemap styles.
Remote Cloud Optimized GeoTIFFs are read directly by GeoLibre in the browser. The server must support CORS and HTTP range requests.
geolibre() |>
add_raster("https://example.org/visual.tif", name = "Satellite", bands = c(1, 2, 3)) |>
add_tile_layer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", name = "OSM") |>
add_wms("https://example.org/geoserver/wms", layers = "topp:states") |>
add_pmtiles("https://example.org/buildings.pmtiles") |>
add_3d_tiles("https://example.org/tileset.json")
add_vector() hands a URL to the application's in-browser vector control, so
GeoParquet, FlatGeobuf, zipped Shapefiles, and GeoPackages stream without being
inlined in the project. A local path is read with sf instead.
geolibre() |> add_geoparquet("https://example.org/parcels.parquet")
map <- geolibre() |>
add_raster("https://example.org/before.tif", name = "Before") |>
add_raster("https://example.org/after.tif", name = "After")
get_layers(map) # one row per layer
map |>
set_layer_opacity("Before", 0.6) |>
move_layer("After", 1) |>
split_map("Before", "After") # a swipe comparison slider
Layers are addressed by name or by id. layer_properties() and
column_values() read attributes back out of an inlined vector layer.
to_html() writes a self-contained page that needs no running R session.
to_html(map, "map.html", title = "Before and after")
map <- geolibre() |> add_geojson(points)
save_project(map, "example.geolibre.json")
restored <- geolibre(load_project("example.geolibre.json"))
The saved file uses GeoLibre's portable .geolibre.json format and can be
opened in the web or desktop application, or in the Python API. save_project()
saves the state held by the R widget and strips credentials such as layer request
headers and signed URLs; pass keep_credentials = TRUE for a trusted local file.
describe_project() summarizes a project without printing its inlined data. In
Shiny, browser-side changes are also available as input$<outputId>_project.
library(shiny)
library(geolibre)
ui <- fluidPage(
geolibreOutput("map", height = "80vh"),
actionButton("reset", "Reset view")
)
server <- function(input, output, session) {
map <- reactiveVal(geolibre(layout = "maponly"))
output$map <- renderGeolibre(map())
# Replace the whole project.
observeEvent(input$reset, {
next_map <- set_view(map(), center = c(0, 20), zoom = 2)
map(next_map)
update_geolibre(geolibre_proxy("map"), next_map)
})
# Or drive the map that is already on screen, without re-rendering it.
observeEvent(input$fly, {
geolibre_fly_to(geolibre_proxy("map"), center = c(-77.0369, 38.9072), zoom = 12)
})
observeEvent(input$map_project, {
message("GeoLibre now has ", length(input$map_project$layers), " layers")
})
# Where a command's reply lands.
observeEvent(input$map_result, {
message(input$map_result$method, " -> ok = ", input$map_result$ok)
})
# Clicks, selection changes, and layer changes from the browser.
observeEvent(input$map_event, {
message("event: ", input$map_event$event)
})
}
shinyApp(ui, server)
The proxy functions cover the things a project cannot express: geolibre_fly_to(),
geolibre_fit_bounds(), geolibre_zoom_to_layer(), geolibre_get_view(),
geolibre_identify(), geolibre_layer_features(), geolibre_to_image(), and
geolibre_run_algorithm() for the application's browser-side processing tools.
geolibre_command() forwards anything else the bridge implements.
Use app_url per widget or set a session-wide option:
options(geolibre.app_url = "https://gis.example.org/")
The deployment must expose the GeoLibre web app and support its ?embed=1
project bridge.
sf, GeoParquet, FlatGeobuf, Shapefiles,
GeoPackage, KML, and CSV or data frame coordinatesThe package intentionally does not bundle GeoLibre's large web distribution. This keeps the R package small and lets maps use the latest compatible hosted application. Offline bundling can be added as an optional distribution later.