You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中优化佛蒙特州水文地图,隐藏州界外数据?

解决佛蒙特州水文地图边界外区域隐藏问题

方法一:过滤佛蒙特州范围内的水文数据

直接保留州界内的河流数据,从根源上避免显示邻州内容,是更高效的方案。

关键步骤:

  • 获取佛蒙特州的边界矢量数据,并转换为与河流数据一致的坐标系
  • 通过空间交集操作,只保留完全或部分位于州界内的河段

修改后的完整代码:

library(osmdata)
library(ggplot2)
library(tidyverse)
require(sf)
require(tigris)
library(httr)

bbx <- getbb("VT")

url <- "https://data.hydrosheds.org/file/HydroRIVERS/HydroRIVERS_v10_na_shp.zip"

res <- GET(url,
           write_disk("na_rivers.zip"),
           progress())
unzip("na_rivers.zip")
filenames <- list.files("HydroRIVERS_v10_na_shp", pattern="*.shp", full.names=T)

list_riv <- lapply(filenames, sf::st_read)
na_riv <- list_riv[[1]] %>%
  sf::st_cast("MULTILINESTRING")

na_riv_width <- na_riv %>%
  dplyr::mutate(
    width = as.numeric(ORD_FLOW),
    width = dplyr::case_when(
      width == 3 ~ 1,
      width == 4 ~ 0.8,
      width == 5 ~ 0.6,
      width == 6 ~ 0.4,
      width == 7 ~ 0.2,
      width == 8 ~ 0.2,
      width == 9 ~ 0.1,
      width == 10 ~ 0.1,
      TRUE ~ 0
    )
  ) %>%
  sf::st_as_sf()

# 获取佛蒙特州边界并转换坐标系
vt_boundary <- states(cb = TRUE) %>% 
  filter(NAME == "Vermont") %>% 
  st_transform(st_crs(na_riv_width))

# 过滤出佛蒙特州范围内的河流
vt_riv_width <- na_riv_width %>% 
  st_intersection(vt_boundary)

get_river_map <- function() {
  p <- 
    ggplot() +
    geom_sf(
      data = vt_riv_width,  # 使用过滤后的河流数据
      aes(
        color = factor(ORD_FLOW), size = width,
        alpha = factor(ORD_FLOW)
      )
    ) +
    coord_sf(xlim = c(min(bbx[1,]), max(bbx[1,])),
             ylim = c(min(bbx[2,]), max(bbx[2,])),
             expand = FALSE)  +
    labs(
      y = "", subtitle = "",
      x = "",
      title = "",
      caption = ""
    ) +
    scale_color_manual(
      name = "",
      values = c(
        "#08306b", "#08519c", "#2171b5",
                 "#4292c6", "#6baed6", "#9ecae1",
                 "#c6dbef", "#deebf7", "white"
      )
    ) +
    scale_size(range = c(0, .3)) +
    scale_alpha_manual(values = c(
      "3" = 1, "4" = 1, "5" = .7, "6" = .6,
      "7" = .4, "8" = .3, "9" = .2, "10" = .1
    )) +
    theme_minimal() +
    theme(
      panel.background = element_blank(),
      legend.background = element_blank(),
      legend.position = "none",
      panel.border = element_blank(),
      panel.grid.minor = element_blank(),
      panel.grid.major = element_blank(),
      plot.title = element_text(
        size = 40, color = "#2171b5", hjust = 0.5, vjust = 0
      ),
      plot.subtitle = element_text(
        size = 14, color = "#ac63a0", hjust = 0.5, vjust = 0
      ),
      plot.caption = element_text(
        size = 10, color = "grey60", hjust = 0.5, vjust = 10
      ),
      axis.title.x = element_text(
        size = 10, color = "grey20", hjust = 0.5, vjust = -6
      ),
      legend.text = element_text(
        size = 9, color = "grey20"
      ),
      legend.title = element_text(size = 10, color = "grey20"),
      strip.text = element_text(size = 12),
      plot.margin = unit(c(t = 1, r = -2, b = -1, l = -2), "lines"),
      axis.title.y = element_blank(),
      axis.ticks = element_blank(),
      axis.text.x = element_blank(),
      axis.text.y = element_blank()
    )
  
  return(p)
}

p1 <- get_river_map()

方法二:叠加白色遮罩层

如果不想修改原始河流数据集,可以在地图最上层添加一个白色多边形,覆盖佛蒙特州边界外的区域,实现“遮罩”效果。

关键步骤:

  • 创建覆盖当前绘图范围的矩形多边形
  • 用佛蒙特州边界“挖空”该矩形,得到边界外的区域
  • 将这个区域填充白色,放在所有图层的最上方

修改后的完整代码:

library(osmdata)
library(ggplot2)
library(tidyverse)
require(sf)
require(tigris)
library(httr)

bbx <- getbb("VT")

url <- "https://data.hydrosheds.org/file/HydroRIVERS/HydroRIVERS_v10_na_shp.zip"

res <- GET(url,
           write_disk("na_rivers.zip"),
           progress())
unzip("na_rivers.zip")
filenames <- list.files("HydroRIVERS_v10_na_shp", pattern="*.shp", full.names=T)

list_riv <- lapply(filenames, sf::st_read)
na_riv <- list_riv[[1]] %>%
  sf::st_cast("MULTILINESTRING")

na_riv_width <- na_riv %>%
  dplyr::mutate(
    width = as.numeric(ORD_FLOW),
    width = dplyr::case_when(
      width == 3 ~ 1,
      width == 4 ~ 0.8,
      width == 5 ~ 0.6,
      width == 6 ~ 0.4,
      width == 7 ~ 0.2,
      width == 8 ~ 0.2,
      width == 9 ~ 0.1,
      width == 10 ~ 0.1,
      TRUE ~ 0
    )
  ) %>%
  sf::st_as_sf()

# 获取佛蒙特州边界
vt_boundary <- states(cb = TRUE) %>% 
  filter(NAME == "Vermont") %>% 
  st_transform(st_crs(na_riv_width))

# 创建绘图范围的矩形多边形
bbox_poly <- st_bbox(c(xmin = min(bbx[1,]), xmax = max(bbx[1,]),
                       ymin = min(bbx[2,]), ymax = max(bbx[2,]))) %>% 
  st_as_sfc() %>% 
  st_transform(st_crs(vt_boundary))

# 生成遮罩:矩形减去佛蒙特州区域
mask <- st_difference(bbox_poly, vt_boundary)

get_river_map <- function() {
  p <- 
    ggplot() +
    geom_sf(
      data = na_riv_width,
      aes(
        color = factor(ORD_FLOW), size = width,
        alpha = factor(ORD_FLOW)
      )
    ) +
    coord_sf(xlim = c(min(bbx[1,]), max(bbx[1,])),
             ylim = c(min(bbx[2,]), max(bbx[2,])),
             expand = FALSE)  +
    # 添加白色遮罩层,放在最上层
    geom_sf(data = mask, fill = "white", color = NA) +
    labs(
      y = "", subtitle = "",
      x = "",
      title = "",
      caption = ""
    ) +
    scale_color_manual(
      name = "",
      values = c(
        "#08306b", "#08519c", "#2171b5",
                 "#4292c6", "#6baed6", "#9ecae1",
                 "#c6dbef", "#deebf7", "white"
      )
    ) +
    scale_size(range = c(0, .3)) +
    scale_alpha_manual(values = c(
      "3" = 1, "4" = 1, "5" = .7, "6" = .6,
      "7" = .4, "8" = .3, "9" = .2, "10" = .1
    )) +
    theme_minimal() +
    theme(
      panel.background = element_blank(),
      legend.background = element_blank(),
      legend.position = "none",
      panel.border = element_blank(),
      panel.grid.minor = element_blank(),
      panel.grid.major = element_blank(),
      plot.title = element_text(
        size = 40, color = "#2171b5", hjust = 0.5, vjust = 0
      ),
      plot.subtitle = element_text(
        size = 14, color = "#ac63a0", hjust = 0.5, vjust = 0
      ),
      plot.caption = element_text(
        size = 10, color = "grey60", hjust = 0.5, vjust = 10
      ),
      axis.title.x = element_text(
        size = 10, color = "grey20", hjust = 0.5, vjust = -6
      ),
      legend.text = element_text(
        size = 9, color = "grey20"
      ),
      legend.title = element_text(size = 10, color = "grey20"),
      strip.text = element_text(size = 12),
      plot.margin = unit(c(t = 1, r = -2, b = -1, l = -2), "lines"),
      axis.title.y = element_blank(),
      axis.ticks = element_blank(),
      axis.text.x = element_blank(),
      axis.text.y = element_blank()
    )
  
  return(p)
}

p1 <- get_river_map()

内容的提问来源于stack exchange,提问作者Quinterpret

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 00:47:04