Skip to content

R Geospatial Analysis Best Practices

Objective: Master senior-level R geospatial analysis patterns for production systems. When you need to analyze spatial data, when you want to build location-aware applications, when you need enterprise-grade geospatial patternsโ€”these best practices become your weapon of choice.

Core Principles

  • Spatial Data Types: Handle points, lines, polygons, and complex geometries
  • Coordinate Systems: Manage different coordinate reference systems (CRS)
  • Spatial Operations: Perform geometric calculations and spatial analysis
  • Visualization: Create effective spatial visualizations
  • Performance: Optimize spatial operations for large datasets

Spatial Data Handling

Spatial Data Import and Export

# R/01-spatial-data-handling.R

#' Comprehensive spatial data import
#'
#' @param file_path Path to spatial data file
#' @param file_type Type of spatial data file
#' @param crs Coordinate reference system
#' @return Spatial data object
import_spatial_data <- function(file_path, file_type = NULL, crs = NULL) {
  if (is.null(file_type)) {
    file_type <- detect_file_type(file_path)
  }

  switch(file_type,
    "shapefile" = import_shapefile(file_path, crs),
    "geojson" = import_geojson(file_path, crs),
    "kml" = import_kml(file_path, crs),
    "gpx" = import_gpx(file_path, crs),
    "csv" = import_spatial_csv(file_path, crs),
    stop("Unsupported file type: ", file_type)
  )
}

#' Detect file type from extension
#'
#' @param file_path File path
#' @return File type
detect_file_type <- function(file_path) {
  extension <- tolower(tools::file_ext(file_path))

  switch(extension,
    "shp" = "shapefile",
    "geojson" = "geojson",
    "kml" = "kml",
    "gpx" = "gpx",
    "csv" = "csv",
    "unknown"
  )
}

#' Import shapefile
#'
#' @param file_path Path to shapefile
#' @param crs Coordinate reference system
#' @return Spatial data object
import_shapefile <- function(file_path, crs = NULL) {
  library(sf)

  # Read shapefile
  spatial_data <- st_read(file_path, quiet = TRUE)

  # Set CRS if provided
  if (!is.null(crs)) {
    spatial_data <- st_set_crs(spatial_data, crs)
  }

  return(spatial_data)
}

#' Import GeoJSON
#'
#' @param file_path Path to GeoJSON file
#' @param crs Coordinate reference system
#' @return Spatial data object
import_geojson <- function(file_path, crs = NULL) {
  library(sf)

  # Read GeoJSON
  spatial_data <- st_read(file_path, quiet = TRUE)

  # Set CRS if provided
  if (!is.null(crs)) {
    spatial_data <- st_set_crs(spatial_data, crs)
  }

  return(spatial_data)
}

#' Import KML
#'
#' @param file_path Path to KML file
#' @param crs Coordinate reference system
#' @return Spatial data object
import_kml <- function(file_path, crs = NULL) {
  library(sf)

  # Read KML
  spatial_data <- st_read(file_path, quiet = TRUE)

  # Set CRS if provided
  if (!is.null(crs)) {
    spatial_data <- st_set_crs(spatial_data, crs)
  }

  return(spatial_data)
}

#' Import GPX
#'
#' @param file_path Path to GPX file
#' @param crs Coordinate reference system
#' @return Spatial data object
import_gpx <- function(file_path, crs = NULL) {
  library(sf)

  # Read GPX
  spatial_data <- st_read(file_path, quiet = TRUE)

  # Set CRS if provided
  if (!is.null(crs)) {
    spatial_data <- st_set_crs(spatial_data, crs)
  }

  return(spatial_data)
}

#' Import spatial CSV
#'
#' @param file_path Path to CSV file
#' @param crs Coordinate reference system
#' @param x_col X coordinate column name
#' @param y_col Y coordinate column name
#' @return Spatial data object
import_spatial_csv <- function(file_path, crs = NULL, x_col = "x", y_col = "y") {
  library(sf)

  # Read CSV
  data <- read.csv(file_path)

  # Create spatial object
  spatial_data <- st_as_sf(data, coords = c(x_col, y_col), crs = crs)

  return(spatial_data)
}

#' Export spatial data
#'
#' @param spatial_data Spatial data object
#' @param file_path Output file path
#' @param file_type Output file type
#' @return Export status
export_spatial_data <- function(spatial_data, file_path, file_type = NULL) {
  if (is.null(file_type)) {
    file_type <- detect_file_type(file_path)
  }

  switch(file_type,
    "shapefile" = export_shapefile(spatial_data, file_path),
    "geojson" = export_geojson(spatial_data, file_path),
    "kml" = export_kml(spatial_data, file_path),
    "csv" = export_spatial_csv(spatial_data, file_path),
    stop("Unsupported file type: ", file_type)
  )
}

#' Export shapefile
#'
#' @param spatial_data Spatial data object
#' @param file_path Output file path
#' @return Export status
export_shapefile <- function(spatial_data, file_path) {
  library(sf)

  # Write shapefile
  st_write(spatial_data, file_path, delete_dsn = TRUE, quiet = TRUE)

  return(TRUE)
}

#' Export GeoJSON
#'
#' @param spatial_data Spatial data object
#' @param file_path Output file path
#' @return Export status
export_geojson <- function(spatial_data, file_path) {
  library(sf)

  # Write GeoJSON
  st_write(spatial_data, file_path, delete_dsn = TRUE, quiet = TRUE)

  return(TRUE)
}

#' Export KML
#'
#' @param spatial_data Spatial data object
#' @param file_path Output file path
#' @return Export status
export_kml <- function(spatial_data, file_path) {
  library(sf)

  # Write KML
  st_write(spatial_data, file_path, delete_dsn = TRUE, quiet = TRUE)

  return(TRUE)
}

#' Export spatial CSV
#'
#' @param spatial_data Spatial data object
#' @param file_path Output file path
#' @return Export status
export_spatial_csv <- function(spatial_data, file_path) {
  library(sf)

  # Extract coordinates
  coords <- st_coordinates(spatial_data)

  # Create data frame
  data <- st_drop_geometry(spatial_data)
  data$x <- coords[, 1]
  data$y <- coords[, 2]

  # Write CSV
  write.csv(data, file_path, row.names = FALSE)

  return(TRUE)
}

Coordinate Reference Systems

# R/01-spatial-data-handling.R (continued)

#' Transform coordinate reference system
#'
#' @param spatial_data Spatial data object
#' @param target_crs Target coordinate reference system
#' @return Transformed spatial data
transform_crs <- function(spatial_data, target_crs) {
  library(sf)

  # Transform CRS
  transformed_data <- st_transform(spatial_data, target_crs)

  return(transformed_data)
}

#' Get coordinate reference system information
#'
#' @param spatial_data Spatial data object
#' @return CRS information
get_crs_info <- function(spatial_data) {
  library(sf)

  crs <- st_crs(spatial_data)

  return(list(
    epsg_code = crs$epsg,
    proj4_string = crs$proj4string,
    wkt = crs$wkt,
    is_geographic = crs$is_geographic,
    is_projected = crs$is_projected
  ))
}

#' Set coordinate reference system
#'
#' @param spatial_data Spatial data object
#' @param crs Coordinate reference system
#' @return Spatial data with set CRS
set_crs <- function(spatial_data, crs) {
  library(sf)

  # Set CRS
  spatial_data <- st_set_crs(spatial_data, crs)

  return(spatial_data)
}

#' Common coordinate reference systems
get_common_crs <- function() {
  list(
    wgs84 = 4326,
    web_mercator = 3857,
    utm_zone_10n = 32610,
    utm_zone_11n = 32611,
    utm_zone_12n = 32612,
    albers_conus = 5070,
    lambert_conformal_conic = 102004
  )
}

Spatial Operations

Geometric Operations

# R/02-spatial-operations.R

#' Comprehensive spatial operations
#'
#' @param spatial_data1 First spatial data object
#' @param spatial_data2 Second spatial data object
#' @param operation Spatial operation to perform
#' @return Result of spatial operation
perform_spatial_operation <- function(spatial_data1, spatial_data2, operation) {
  switch(operation,
    "intersection" = st_intersection(spatial_data1, spatial_data2),
    "union" = st_union(spatial_data1, spatial_data2),
    "difference" = st_difference(spatial_data1, spatial_data2),
    "symmetric_difference" = st_sym_difference(spatial_data1, spatial_data2),
    "contains" = st_contains(spatial_data1, spatial_data2),
    "within" = st_within(spatial_data1, spatial_data2),
    "touches" = st_touches(spatial_data1, spatial_data2),
    "overlaps" = st_overlaps(spatial_data1, spatial_data2),
    "crosses" = st_crosses(spatial_data1, spatial_data2),
    "disjoint" = st_disjoint(spatial_data1, spatial_data2),
    stop("Unsupported operation: ", operation)
  )
}

#' Calculate spatial distances
#'
#' @param spatial_data1 First spatial data object
#' @param spatial_data2 Second spatial data object
#' @param method Distance calculation method
#' @return Distance matrix
calculate_spatial_distances <- function(spatial_data1, spatial_data2, method = "euclidean") {
  library(sf)

  if (method == "euclidean") {
    distances <- st_distance(spatial_data1, spatial_data2)
  } else if (method == "haversine") {
    distances <- st_distance(spatial_data1, spatial_data2, which = "Haversine")
  } else if (method == "great_circle") {
    distances <- st_distance(spatial_data1, spatial_data2, which = "Great Circle")
  }

  return(distances)
}

#' Find nearest neighbors
#'
#' @param spatial_data1 First spatial data object
#' @param spatial_data2 Second spatial data object
#' @param k Number of nearest neighbors
#' @return Nearest neighbor indices
find_nearest_neighbors <- function(spatial_data1, spatial_data2, k = 1) {
  library(sf)

  # Calculate distances
  distances <- st_distance(spatial_data1, spatial_data2)

  # Find nearest neighbors
  nearest_indices <- apply(distances, 1, function(x) order(x)[1:k])

  return(nearest_indices)
}

#' Calculate spatial statistics
#'
#' @param spatial_data Spatial data object
#' @param statistics Statistics to calculate
#' @return Spatial statistics
calculate_spatial_statistics <- function(spatial_data, statistics = c("area", "length", "centroid")) {
  library(sf)

  results <- list()

  if ("area" %in% statistics) {
    results$area <- st_area(spatial_data)
  }

  if ("length" %in% statistics) {
    results$length <- st_length(spatial_data)
  }

  if ("centroid" %in% statistics) {
    results$centroid <- st_centroid(spatial_data)
  }

  if ("boundary" %in% statistics) {
    results$boundary <- st_boundary(spatial_data)
  }

  if ("convex_hull" %in% statistics) {
    results$convex_hull <- st_convex_hull(spatial_data)
  }

  return(results)
}

#' Perform spatial joins
#'
#' @param spatial_data1 First spatial data object
#' @param spatial_data2 Second spatial data object
#' @param join_type Type of spatial join
#' @return Joined spatial data
perform_spatial_join <- function(spatial_data1, spatial_data2, join_type = "intersects") {
  library(sf)

  switch(join_type,
    "intersects" = st_join(spatial_data1, spatial_data2, join = st_intersects),
    "contains" = st_join(spatial_data1, spatial_data2, join = st_contains),
    "within" = st_join(spatial_data1, spatial_data2, join = st_within),
    "touches" = st_join(spatial_data1, spatial_data2, join = st_touches),
    "overlaps" = st_join(spatial_data1, spatial_data2, join = st_overlaps),
    stop("Unsupported join type: ", join_type)
  )
}

Spatial Analysis

# R/02-spatial-operations.R (continued)

#' Perform spatial analysis
#'
#' @param spatial_data Spatial data object
#' @param analysis_type Type of spatial analysis
#' @param parameters Analysis parameters
#' @return Analysis results
perform_spatial_analysis <- function(spatial_data, analysis_type, parameters = list()) {
  switch(analysis_type,
    "point_pattern" = analyze_point_pattern(spatial_data, parameters),
    "spatial_autocorrelation" = analyze_spatial_autocorrelation(spatial_data, parameters),
    "hotspot_analysis" = analyze_hotspots(spatial_data, parameters),
    "clustering" = analyze_clustering(spatial_data, parameters),
    "interpolation" = perform_interpolation(spatial_data, parameters),
    stop("Unsupported analysis type: ", analysis_type)
  )
}

#' Analyze point pattern
#'
#' @param spatial_data Spatial data object
#' @param parameters Analysis parameters
#' @return Point pattern analysis results
analyze_point_pattern <- function(spatial_data, parameters) {
  library(spatstat)

  # Convert to ppp object
  coords <- st_coordinates(spatial_data)
  ppp_object <- ppp(coords[, 1], coords[, 2], 
                    window = owin(range(coords[, 1]), range(coords[, 2])))

  # Calculate intensity
  intensity <- density(ppp_object, sigma = parameters$sigma)

  # Calculate nearest neighbor distances
  nn_distances <- nndist(ppp_object)

  # Calculate Ripley's K function
  k_function <- Kest(ppp_object)

  return(list(
    intensity = intensity,
    nn_distances = nn_distances,
    k_function = k_function
  ))
}

#' Analyze spatial autocorrelation
#'
#' @param spatial_data Spatial data object
#' @param parameters Analysis parameters
#' @return Spatial autocorrelation results
analyze_spatial_autocorrelation <- function(spatial_data, parameters) {
  library(spdep)

  # Create spatial weights
  coords <- st_coordinates(spatial_data)
  nb <- knn2nb(knearneigh(coords, k = parameters$k))
  weights <- nb2listw(nb)

  # Calculate Moran's I
  moran_i <- moran.test(spatial_data[[parameters$variable]], weights)

  # Calculate local Moran's I
  local_moran <- localmoran(spatial_data[[parameters$variable]], weights)

  return(list(
    moran_i = moran_i,
    local_moran = local_moran
  ))
}

#' Analyze hotspots
#'
#' @param spatial_data Spatial data object
#' @param parameters Analysis parameters
#' @return Hotspot analysis results
analyze_hotspots <- function(spatial_data, parameters) {
  library(spdep)

  # Create spatial weights
  coords <- st_coordinates(spatial_data)
  nb <- knn2nb(knearneigh(coords, k = parameters$k))
  weights <- nb2listw(nb)

  # Calculate Getis-Ord Gi* statistic
  gi_statistic <- localG(spatial_data[[parameters$variable]], weights)

  # Identify hotspots
  hotspots <- which(gi_statistic > 1.96)

  return(list(
    gi_statistic = gi_statistic,
    hotspots = hotspots
  ))
}

#' Analyze clustering
#'
#' @param spatial_data Spatial data object
#' @param parameters Analysis parameters
#' @return Clustering analysis results
analyze_clustering <- function(spatial_data, parameters) {
  library(cluster)

  # Extract coordinates
  coords <- st_coordinates(spatial_data)

  # Perform clustering
  if (parameters$method == "kmeans") {
    clusters <- kmeans(coords, centers = parameters$k)
  } else if (parameters$method == "hierarchical") {
    dist_matrix <- dist(coords)
    hclust_result <- hclust(dist_matrix)
    clusters <- cutree(hclust_result, k = parameters$k)
  }

  return(list(
    clusters = clusters,
    cluster_centers = if (parameters$method == "kmeans") clusters$centers else NULL
  ))
}

#' Perform spatial interpolation
#'
#' @param spatial_data Spatial data object
#' @param parameters Analysis parameters
#' @return Interpolation results
perform_interpolation <- function(spatial_data, parameters) {
  library(gstat)

  # Create interpolation grid
  bbox <- st_bbox(spatial_data)
  grid <- expand.grid(
    x = seq(bbox[1], bbox[3], length.out = parameters$grid_size),
    y = seq(bbox[2], bbox[4], length.out = parameters$grid_size)
  )

  # Convert to spatial object
  grid_spatial <- st_as_sf(grid, coords = c("x", "y"), crs = st_crs(spatial_data))

  # Perform interpolation
  if (parameters$method == "idw") {
    interpolated <- idw(
      formula = as.formula(paste(parameters$variable, "~ 1")),
      locations = spatial_data,
      newdata = grid_spatial,
      idp = parameters$idp
    )
  } else if (parameters$method == "kriging") {
    interpolated <- krige(
      formula = as.formula(paste(parameters$variable, "~ 1")),
      locations = spatial_data,
      newdata = grid_spatial
    )
  }

  return(interpolated)
}

Spatial Visualization

Static Maps

# R/03-spatial-visualization.R

#' Create comprehensive spatial visualizations
#'
#' @param spatial_data Spatial data object
#' @param visualization_type Type of visualization
#' @param parameters Visualization parameters
#' @return Spatial visualization
create_spatial_visualization <- function(spatial_data, visualization_type, parameters = list()) {
  switch(visualization_type,
    "basic_map" = create_basic_map(spatial_data, parameters),
    "choropleth_map" = create_choropleth_map(spatial_data, parameters),
    "point_map" = create_point_map(spatial_data, parameters),
    "heat_map" = create_heat_map(spatial_data, parameters),
    "density_map" = create_density_map(spatial_data, parameters),
    stop("Unsupported visualization type: ", visualization_type)
  )
}

#' Create basic map
#'
#' @param spatial_data Spatial data object
#' @param parameters Visualization parameters
#' @return Basic map
create_basic_map <- function(spatial_data, parameters) {
  library(ggplot2)

  p <- ggplot(spatial_data) +
    geom_sf() +
    theme_minimal() +
    labs(title = parameters$title)

  return(p)
}

#' Create choropleth map
#'
#' @param spatial_data Spatial data object
#' @param parameters Visualization parameters
#' @return Choropleth map
create_choropleth_map <- function(spatial_data, parameters) {
  library(ggplot2)

  p <- ggplot(spatial_data) +
    geom_sf(aes(fill = !!sym(parameters$variable))) +
    scale_fill_viridis_c(name = parameters$variable) +
    theme_minimal() +
    labs(title = parameters$title)

  return(p)
}

#' Create point map
#'
#' @param spatial_data Spatial data object
#' @param parameters Visualization parameters
#' @return Point map
create_point_map <- function(spatial_data, parameters) {
  library(ggplot2)

  p <- ggplot(spatial_data) +
    geom_sf(aes(color = !!sym(parameters$variable)), size = parameters$point_size) +
    scale_color_viridis_c(name = parameters$variable) +
    theme_minimal() +
    labs(title = parameters$title)

  return(p)
}

#' Create heat map
#'
#' @param spatial_data Spatial data object
#' @param parameters Visualization parameters
#' @return Heat map
create_heat_map <- function(spatial_data, parameters) {
  library(ggplot2)

  # Create grid for heat map
  bbox <- st_bbox(spatial_data)
  grid <- expand.grid(
    x = seq(bbox[1], bbox[3], length.out = parameters$grid_size),
    y = seq(bbox[2], bbox[4], length.out = parameters$grid_size)
  )

  # Convert to spatial object
  grid_spatial <- st_as_sf(grid, coords = c("x", "y"), crs = st_crs(spatial_data))

  # Calculate density
  density <- st_distance(grid_spatial, spatial_data)
  density <- apply(density, 1, function(x) sum(exp(-x / parameters$bandwidth)))

  # Create data frame
  heat_data <- data.frame(
    x = grid$x,
    y = grid$y,
    density = density
  )

  p <- ggplot(heat_data, aes(x = x, y = y, fill = density)) +
    geom_tile() +
    scale_fill_viridis_c(name = "Density") +
    theme_minimal() +
    labs(title = parameters$title)

  return(p)
}

#' Create density map
#'
#' @param spatial_data Spatial data object
#' @param parameters Visualization parameters
#' @return Density map
create_density_map <- function(spatial_data, parameters) {
  library(ggplot2)

  # Extract coordinates
  coords <- st_coordinates(spatial_data)

  p <- ggplot(data.frame(x = coords[, 1], y = coords[, 2])) +
    geom_density_2d(aes(x = x, y = y), alpha = 0.5) +
    geom_point(aes(x = x, y = y), alpha = 0.3) +
    theme_minimal() +
    labs(title = parameters$title)

  return(p)
}

Interactive Maps

# R/03-spatial-visualization.R (continued)

#' Create interactive spatial visualizations
#'
#' @param spatial_data Spatial data object
#' @param visualization_type Type of visualization
#' @param parameters Visualization parameters
#' @return Interactive spatial visualization
create_interactive_spatial_visualization <- function(spatial_data, visualization_type, parameters = list()) {
  switch(visualization_type,
    "leaflet_map" = create_leaflet_map(spatial_data, parameters),
    "plotly_map" = create_plotly_map(spatial_data, parameters),
    "mapview_map" = create_mapview_map(spatial_data, parameters),
    stop("Unsupported visualization type: ", visualization_type)
  )
}

#' Create Leaflet map
#'
#' @param spatial_data Spatial data object
#' @param parameters Visualization parameters
#' @return Leaflet map
create_leaflet_map <- function(spatial_data, parameters) {
  library(leaflet)

  # Create base map
  map <- leaflet() %>%
    addTiles()

  # Add spatial data
  if (st_geometry_type(spatial_data)[1] == "POINT") {
    map <- map %>%
      addCircleMarkers(
        data = spatial_data,
        radius = parameters$radius,
        color = parameters$color,
        popup = parameters$popup
      )
  } else {
    map <- map %>%
      addPolygons(
        data = spatial_data,
        color = parameters$color,
        fillColor = parameters$fill_color,
        popup = parameters$popup
      )
  }

  return(map)
}

#' Create Plotly map
#'
#' @param spatial_data Spatial data object
#' @param parameters Visualization parameters
#' @return Plotly map
create_plotly_map <- function(spatial_data, parameters) {
  library(plotly)

  # Extract coordinates
  coords <- st_coordinates(spatial_data)

  # Create plot
  p <- plot_ly(
    x = coords[, 1],
    y = coords[, 2],
    type = "scatter",
    mode = "markers",
    marker = list(
      size = parameters$size,
      color = parameters$color
    ),
    text = parameters$text
  ) %>%
    layout(
      title = parameters$title,
      xaxis = list(title = "Longitude"),
      yaxis = list(title = "Latitude")
    )

  return(p)
}

#' Create Mapview map
#'
#' @param spatial_data Spatial data object
#' @param parameters Visualization parameters
#' @return Mapview map
create_mapview_map <- function(spatial_data, parameters) {
  library(mapview)

  # Create map
  map <- mapview(
    spatial_data,
    zcol = parameters$zcol,
    col.regions = parameters$col_regions,
    alpha = parameters$alpha
  )

  return(map)
}

Performance Optimization

Spatial Indexing

# R/04-spatial-performance.R

#' Optimize spatial operations for performance
#'
#' @param spatial_data Spatial data object
#' @param optimization_type Type of optimization
#' @param parameters Optimization parameters
#' @return Optimized spatial data
optimize_spatial_operations <- function(spatial_data, optimization_type, parameters = list()) {
  switch(optimization_type,
    "spatial_index" = create_spatial_index(spatial_data, parameters),
    "simplify_geometry" = simplify_geometry(spatial_data, parameters),
    "aggregate_features" = aggregate_features(spatial_data, parameters),
    "crop_data" = crop_spatial_data(spatial_data, parameters),
    stop("Unsupported optimization type: ", optimization_type)
  )
}

#' Create spatial index
#'
#' @param spatial_data Spatial data object
#' @param parameters Optimization parameters
#' @return Spatial data with index
create_spatial_index <- function(spatial_data, parameters) {
  library(sf)

  # Create spatial index
  spatial_data <- st_make_valid(spatial_data)

  # Add spatial index
  spatial_data$spatial_index <- 1:nrow(spatial_data)

  return(spatial_data)
}

#' Simplify geometry
#'
#' @param spatial_data Spatial data object
#' @param parameters Optimization parameters
#' @return Simplified spatial data
simplify_geometry <- function(spatial_data, parameters) {
  library(sf)

  # Simplify geometry
  simplified_data <- st_simplify(spatial_data, dTolerance = parameters$tolerance)

  return(simplified_data)
}

#' Aggregate features
#'
#' @param spatial_data Spatial data object
#' @param parameters Optimization parameters
#' @return Aggregated spatial data
aggregate_features <- function(spatial_data, parameters) {
  library(sf)

  # Aggregate by grouping variable
  if (!is.null(parameters$group_by)) {
    aggregated_data <- spatial_data %>%
      group_by(!!sym(parameters$group_by)) %>%
      summarise(geometry = st_union(geometry))
  } else {
    # Aggregate all features
    aggregated_data <- spatial_data %>%
      summarise(geometry = st_union(geometry))
  }

  return(aggregated_data)
}

#' Crop spatial data
#'
#' @param spatial_data Spatial data object
#' @param parameters Optimization parameters
#' @return Cropped spatial data
crop_spatial_data <- function(spatial_data, parameters) {
  library(sf)

  # Create bounding box
  bbox <- st_bbox(parameters$bbox)
  bbox_polygon <- st_as_sfc(bbox)

  # Crop data
  cropped_data <- st_intersection(spatial_data, bbox_polygon)

  return(cropped_data)
}

TL;DR Runbook

Quick Start

# 1. Import spatial data
spatial_data <- import_spatial_data("data.shp", crs = 4326)

# 2. Transform CRS
transformed_data <- transform_crs(spatial_data, 3857)

# 3. Perform spatial operations
intersection <- perform_spatial_operation(data1, data2, "intersection")

# 4. Calculate spatial statistics
stats <- calculate_spatial_statistics(spatial_data, c("area", "centroid"))

# 5. Create visualizations
map <- create_spatial_visualization(spatial_data, "choropleth_map", list(variable = "value"))

# 6. Optimize performance
optimized_data <- optimize_spatial_operations(spatial_data, "spatial_index")

Essential Patterns

# Complete spatial analysis pipeline
spatial_analysis_pipeline <- function(data_path, analysis_config) {
  # Import data
  spatial_data <- import_spatial_data(data_path, analysis_config$crs)

  # Transform CRS
  if (!is.null(analysis_config$target_crs)) {
    spatial_data <- transform_crs(spatial_data, analysis_config$target_crs)
  }

  # Perform analysis
  analysis_results <- perform_spatial_analysis(spatial_data, analysis_config$analysis_type, analysis_config$parameters)

  # Create visualizations
  visualizations <- create_spatial_visualization(spatial_data, analysis_config$visualization_type, analysis_config$viz_parameters)

  # Optimize performance
  if (analysis_config$optimize) {
    spatial_data <- optimize_spatial_operations(spatial_data, analysis_config$optimization_type, analysis_config$opt_parameters)
  }

  return(list(
    data = spatial_data,
    analysis = analysis_results,
    visualizations = visualizations
  ))
}

This guide provides the complete machinery for comprehensive geospatial analysis in R. Each pattern includes implementation examples, visualization strategies, and real-world usage patterns for enterprise deployment.