使用jsonlite读取GeoJSON后Leaflet无法渲染MultiPolygons的问题
Let's break down why your first approach doesn't work, and how to fix it so you can add your custom fields for a choropleth map.
The Root Cause
When you use jsonlite::fromJSON() on a GeoJSON URL, it parses the JSON into a flattened R list/data frame structure by default. The problem is that leaflet's addGeoJSON() expects either raw GeoJSON text or a properly structured GeoJSON object—not the simplified, de-nested output from jsonlite. This flattening breaks the hierarchical structure that leaflet needs to recognize MultiPolygon features.
In contrast, readr::read_lines() just pulls the raw text of the GeoJSON file, preserving its original structure, so addGeoJSON() can interpret it correctly.
Fix 1: Preserve GeoJSON Structure with jsonlite
If you want to stick with jsonlite, you need to avoid simplifying the GeoJSON structure during parsing, then convert it back to valid GeoJSON text before passing it to leaflet:
library(leaflet) library(jsonlite) library(geojsonlint) url <- paste0("https://geodata.nationaalgeoregister.nl/cbsgebiedsindelingen/wfs?", "request=GetFeature&service=WFS&version=1.1.0&", "typeName=cbsgebiedsindelingen:cbs_arrondissementsgebied_2019_gegeneraliseerd&", "outputFormat=application/json&srsName=EPSG:4326&propertyName=geom,statcode") # Parse without simplifying the nested structure boundaries <- jsonlite::fromJSON(url, simplifyVector = FALSE) # Convert back to valid GeoJSON text boundaries_geojson <- jsonlite::toJSON(boundaries, auto_unbox = TRUE) # Now it will render correctly leaflet() %>% addTiles() %>% addGeoJSON(boundaries_geojson) %>% setView(5.387740, 52.155499, 7)
The simplifyVector = FALSE argument tells jsonlite to keep the original nested list structure of the GeoJSON, so converting it back with toJSON() produces a valid format that leaflet understands.
Fix 2: Use sf (Recommended for Choropleths)
For adding custom fields and building choropleths, the sf package is far more flexible—it's the standard tool for spatial data in R. It reads GeoJSON directly into a spatial data frame, which you can manipulate just like a regular data frame (e.g., joining with other datasets):
library(leaflet) library(sf) library(dplyr) url <- paste0("https://geodata.nationaalgeoregister.nl/cbsgebiedsindelingen/wfs?", "request=GetFeature&service=WFS&version=1.1.0&", "typeName=cbsgebiedsindelingen:cbs_arrondissementsgebied_2019_gegeneraliseerd&", "outputFormat=application/json&srsName=EPSG:4326&propertyName=geom,statcode") # Read GeoJSON directly into an sf spatial data frame boundaries_sf <- st_read(url, quiet = TRUE) # Example: Join with your custom dataset (replace with your actual data) # custom_data <- data.frame(statcode = c("GM0014", "GM0034"), your_field = c(10, 25)) # boundaries_merged <- boundaries_sf %>% left_join(custom_data, by = "statcode") # Build your choropleth map leaflet(boundaries_merged) %>% addTiles() %>% addPolygons( fillColor = ~colorNumeric("viridis", your_field)(your_field), fillOpacity = 0.7, color = "#BDBDC3", weight = 1, popup = ~paste("Statcode:", statcode, "<br>Value:", your_field) ) %>% setView(5.387740, 52.155499, 7)
This approach makes it trivial to merge your additional fields and customize the choropleth styling directly in leaflet.
内容的提问来源于stack exchange,提问作者Willy

