0Pricing
R Academy · 课时

使用 sf 软件包处理简单要素

使用 sf 标准读取、写入和操作空间几何对象

使用 sf 软件包处理简单要素 是 CoddyKit 上的免费 R Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。

什么是 sf 包

sf(简单要素)包是 R 处理地理空间矢量数据的主要工具。它将几何图形(点、线、多边形)存储为普通数据框中的特殊列表列,因此能够与 dplyr 和 ggplot2 完全兼容。

library(sf)

# sf data frames look like regular data frames
# but have a special 'geometry' column
cat('sf version:', packageVersion('sf'), '\n')

# Supported geometry types
cat('Geometry types: POINT, LINESTRING, POLYGON,\n')
cat('               MULTIPOINT, MULTILINESTRING, MULTIPOLYGON,\n')
cat('               GEOMETRYCOLLECTION\n')

read_sf:加载 Shapefile

read_sf("file.shp") 会将任何 OGR 支持的格式(Shapefile、GeoJSON、GeoPackage、KML 等)读取为 sf 对象。它会自动读取 CRS,以及与几何数据一起存储的属性表。

library(sf)

# Read a GeoJSON file from a URL
url <- 'https://raw.githubusercontent.com/datasets/geo-countries/master/data/countries.geojson'

# For demonstration, use the system example data
nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))

cat('Class:', class(nc), '\n')
cat('Dimensions:', nrow(nc), 'rows x', ncol(nc), 'cols\n')
cat('CRS:', st_crs(nc)$epsg, '\n')
cat('Geometry type:', unique(st_geometry_type(nc)), '\n')
cat('Column names:', paste(names(nc)[1:5], collapse = ', '), '...\n')

st_geometry_type 与结构

st_geometry_type() 会返回每个要素的几何类型。geometry 列是由 sfc 对象组成的列表列。您可以像检查、筛选和操作其他列一样处理它。

library(sf)
nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))

# Geometry type for each feature
types <- st_geometry_type(nc)
cat('Unique types:', unique(as.character(types)), '\n')

# The geometry column
geom_col <- st_geometry(nc)
cat('Geometry class:', class(geom_col), '\n')
cat('First geometry:\n')
print(geom_col[[1]])  # MULTIPOLYGON coordinates

# Access as a normal column
nc$area_est <- st_area(nc)  # adds an area column
cat('\nArea column class:', class(nc$area_est), '\n')

st_coordinates:提取 XY

st_coordinates() 会从任意几何对象中提取原始坐标矩阵。对于点,它会返回一个 2 列矩阵(X、Y)。对于多边形,它会返回所有环的顶点,以及部件和多边形索引列。

library(sf)

# Create simple point features
pts <- st_sfc(
  st_point(c(-80.0, 35.0)),
  st_point(c(-79.5, 35.5)),
  st_point(c(-79.0, 34.8))
)
pts_sf <- st_sf(id = 1:3, geometry = pts)

# Extract coordinates
coords <- st_coordinates(pts_sf)
cat('Coordinates:\n')
print(coords)

# For polygons: includes part (L1) and polygon (L2) columns
nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))
ring_coords <- st_coordinates(nc[1, ])
cat('Polygon ring vertices:', nrow(ring_coords), '\n')
cat('Column names:', colnames(ring_coords), '\n')

从数据框创建 sf

st_as_sf(df, coords = c('lon', 'lat'), crs = 4326) 会将包含坐标列的常规数据框转换为 sf 点对象。coords 参数用于指定 x(经度)列和 y(纬度)列。

library(sf)

# Typical scenario: CSV with lon/lat columns
cities <- data.frame(
  name = c('New York', 'Los Angeles', 'Chicago', 'Houston'),
  lon  = c(-74.006, -118.244, -87.629, -95.369),
  lat  = c(40.713,   34.052,   41.878,  29.760),
  pop  = c(8336817, 3979576, 2693976, 2304580)
)

# Convert to sf
cities_sf <- st_as_sf(
  cities,
  coords = c('lon', 'lat'),
  crs    = 4326
)

print(cities_sf)
cat('\nCRS:', st_crs(cities_sf)$epsg, '(WGS84)\n')

st_point、st_linestring、st_polygon

您可以使用构造函数以编程方式创建几何对象。st_point(c(x,y)) 会创建一个点,st_linestring(matrix) 会根据坐标对创建一条线,st_polygon(list(matrix)) 会根据环的坐标创建一个多边形。

library(sf)

# POINT
p <- st_point(c(-74.006, 40.713))
cat('Point:', class(p), '\n')

# LINESTRING: a route with 4 waypoints
route_coords <- matrix(
  c(-74.0, 40.7,
    -75.0, 41.0,
    -76.0, 41.5,
    -77.0, 42.0),
  ncol = 2, byrow = TRUE
)
line <- st_linestring(route_coords)
cat('Linestring length:', st_length(line), '\n')  # in degrees (no CRS yet)

# POLYGON: a simple bounding box
bbox_ring <- matrix(
  c(0,0, 1,0, 1,1, 0,1, 0,0),
  ncol = 2, byrow = TRUE
)
poly <- st_polygon(list(bbox_ring))
cat('Polygon area:', st_area(poly), '\n')

绘制 sf 对象

用于 sf 对象的 plot() 方法会为每个属性列创建一个快速地图。传入 plot(st_geometry(sf_obj)),即可只绘制几何对象而不显示属性面板。

library(sf)
nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))

# Plot all attributes (creates a panel per column)
# plot(nc)  # too many panels

# Plot a single attribute
plot(nc['BIR74'],
     main   = 'North Carolina: Births 1974',
     border = 'white',
     lwd    = 0.5)

# Plot geometry only
plot(st_geometry(nc),
     col    = 'lightblue',
     border = 'gray40',
     main   = 'NC Counties')

筛选 sf 对象

sf 对象的行为类似数据框:您可以使用 [、subset() 或 dplyr::filter() 筛选行。在所有按行筛选的操作中,几何列都会自动随之保留。

library(sf)
library(dplyr)

nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))

# Base R subsetting
western_nc <- nc[nc$CNTY_ID < 1830, ]
cat('Western counties:', nrow(western_nc), '\n')

# dplyr filter works identically
high_birth <- nc |>
  filter(BIR74 > 3000) |>
  select(NAME, BIR74, geometry)

cat('High-birth counties:', nrow(high_birth), '\n')
cat('Names:', paste(high_birth$NAME[1:3], collapse = ', '), '...\n')

sf 与 ggplot2 的集成

ggplot2 通过 geom_sf() 原生支持 sf 对象。该函数会自动处理坐标系并渲染正确的几何类型——点、线或多边形——无需额外准备。

library(sf)
library(ggplot2)

nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))

# Choropleth map with ggplot2
ggplot(nc) +
  geom_sf(aes(fill = BIR74), color = 'white', lwd = 0.2) +
  scale_fill_viridis_c(
    option = 'plasma',
    name   = 'Births (1974)'
  ) +
  labs(
    title    = 'North Carolina Birth Counts, 1974',
    subtitle = 'County-level data'
  ) +
  theme_minimal()

将 sf 写入磁盘

write_sf(sf_obj, 'output.gpkg')(或 st_write())会将几何数据和属性保存到磁盘。GeoPackage(.gpkg)优于 Shapefile,因为它支持较长的列名和 UTF-8,并且会将所有内容存储在一个文件中。

library(sf)

nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))

# Write to GeoPackage
out_path <- tempfile(fileext = '.gpkg')
write_sf(nc, out_path)

cat('Written to:', out_path, '\n')
cat('File size:', file.info(out_path)$size / 1024, 'KB\n')

# Round-trip: read back
nc_rt <- read_sf(out_path)
cat('Round-trip features:', nrow(nc_rt), '\n')
cat('Round-trip CRS match:', identical(st_crs(nc), st_crs(nc_rt)), '\n')

sf 的摘要与检查

使用 print()、st_bbox()、st_crs() 和 summary() 可以快速检查 sf 对象。st_bbox() 会以命名向量的形式返回边界框(xmin、ymin、xmax、ymax),其单位采用对象 CRS 的单位。

library(sf)
nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))

# Bounding box
bbox <- st_bbox(nc)
cat('Bounding box:\n')
cat('  xmin:', bbox['xmin'], ' xmax:', bbox['xmax'], '\n')
cat('  ymin:', bbox['ymin'], ' ymax:', bbox['ymax'], '\n')

# CRS
crs_info <- st_crs(nc)
cat('\nEPSG:', crs_info$epsg, '\n')
cat('Proj4:', crs_info$proj4string, '\n')

# Attribute summary
cat('\nBIR74 range:',
    range(nc$BIR74)[1], 'to',
    range(nc$BIR74)[2], '\n')

快速检查

您有一个包含 longitude 和 latitude 列的数据框,坐标系为 WGS84。哪个函数调用可以将它转换为 sf 点对象?

回顾:sf 软件包

要点:

  • read_sf() 可加载 Shapefile、GeoJSON、GeoPackage 和其他格式
  • st_geometry_type() 会返回每个要素的 POINT、LINESTRING、POLYGON 等类型
  • st_coordinates() 可提取原始 XY 坐标矩阵
  • st_as_sf(df, coords = c('x','y'), crs = 4326) 可根据数据框创建 sf 对象
  • 以编程方式创建几何对象:st_point()、st_linestring()、st_polygon()
  • 可使用 plot(sf_obj),或在 ggplot2 中使用 geom_sf() 进行可视化
  • write_sf() 可将数据保存为 GeoPackage、Shapefile、GeoJSON 等格式
library(sf)

# Quick sf workflow
nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))
cat('Features:', nrow(nc), '\n')
cat('CRS EPSG:', st_crs(nc)$epsg, '\n')
cat('Geom type:', unique(as.character(st_geometry_type(nc))), '\n')
cat('Bbox xmin:', st_bbox(nc)['xmin'], '\n')

常见问题解答

「使用 sf 软件包处理简单要素」课时是免费的吗?

是的 — 「使用 sf 软件包处理简单要素」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。

「使用 sf 软件包处理简单要素」这节课中我会学到什么?

使用 sf 标准读取、写入和操作空间几何对象 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 R Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「使用 sf 软件包处理简单要素」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 R Academy 课中编写并运行代码吗?

能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用 sf 软件包处理简单要素
  2. 坐标参考系与投影
  3. 空间连接与空间操作
  4. 使用 leaflet 创建交互式地图
← 返回 R Academy