在R Shiny Leaflet中批量创建15000+多边形网格地图
Absolutely feasible! Handling 15k+ polygons in Leaflet within a Shiny app is totally manageable, and you don’t need to struggle with the older SpatialPolygonsDataFrame format. The modern sf (Simple Features) package simplifies spatial data handling, making batch polygon creation much more intuitive. Here’s a step-by-step guide:
Step 1: Prepare Your Data
First, make sure your data is structured as a data.frame (or tibble) with the boundary coordinates (LAT1, LONG1 = bottom-left corner; LAT2, LONG2 = top-right corner) and your metadata (num, categorie). Using your sample data:
library(dplyr) library(sf) library(leaflet) library(shiny) # Sample data (expand to 15k rows as needed) df <- tibble( ID_Area = c(102584, 102053), num = c(929, 549), LAT1 = c(53.34, 53.33), LONG1 = c(-6.27, -6.26), LAT2 = c(53.35, 53.34), LONG2 = c(-6.26, -6.25), categorie = c("More than 50", "More than 50") )
Step 2: Batch Generate Square Polygons
We’ll use sf to convert each row into a square polygon. The key is to define the four corners of each square in a closed loop (start and end at the same point) and wrap them into an sf geometry object.
Use dplyr::rowwise() to process each row individually, then create the polygon with sf::st_polygon():
# Convert data to sf object with square polygons sf_df <- df %>% rowwise() %>% mutate( # Define the 4 corners of the square (closed loop) polygon = list( matrix( c( LONG1, LAT1, # Bottom-left LONG2, LAT1, # Bottom-right LONG2, LAT2, # Top-right LONG1, LAT2, # Top-left LONG1, LAT1 # Close the loop ), ncol = 2, byrow = TRUE ) %>% st_polygon() ) ) %>% ungroup() %>% # Convert to sf object (set CRS to WGS84, standard for Leaflet) st_sf(sf_column_name = "polygon", crs = 4326)
Step 3: Build the Shiny App with Leaflet
Now integrate the sf object into a Shiny app. Leaflet works seamlessly with sf—you can directly pass the sf object to addPolygons(), and bind your metadata for popups or styling.
Here’s a complete app example:
ui <- fluidPage( leafletOutput("map", height = "90vh") ) server <- function(input, output) { output$map <- renderLeaflet({ # Create color palette for categories pal <- colorFactor( palette = "viridis", domain = sf_df$categorie ) leaflet(sf_df) %>% addTiles() %>% # Add base map addPolygons( fillColor = ~pal(categorie), fillOpacity = 0.7, color = "#000000", weight = 0.5, # Show num and categorie in popup popup = ~paste0( "<strong>ID:</strong> ", ID_Area, "<br>", "<strong>Count:</strong> ", num, "<br>", "<strong>Category:</strong> ", categorie ) ) %>% addLegend( pal = pal, values = ~categorie, position = "bottomright", title = "Category" ) }) } shinyApp(ui, server)
Performance Tips for 15k Polygons
- CRS Consistency: Always ensure your
sfobject uses WGS84 (EPSG:4326), which is the default for Leaflet—this avoids coordinate conversion overhead. - Simplify Polygons: Since your polygons are simple squares, simplification isn’t necessary, but if you ever have complex shapes, use
sf::st_simplify()to reduce vertex count. - Leaflet Options: Use
weight = 0.5(thin borders) to reduce rendering load. You can also enablegroupand useaddLayersControl()to let users toggle polygons on/off if needed.
This approach is efficient and scalable for 15k+ rows—sf handles the spatial data cleanly, and Leaflet can render this volume of polygons smoothly in most modern browsers.
内容的提问来源于stack exchange,提问作者Julien Bender

