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 sliderLayers 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.