У меня есть шейп-файл с этого сайта, с которым я работаю. Я бы хотел построить а) слой 30 саженей и б) этот слой только на широте выше 34,4. Мне удалось выделить только слой глубиной 30 саженей, но я не могу выполнить подмножество внутри каждого региона, чтобы включить только определенные широты. Ниже мой текущий код:
packages <- c('rnaturalearth', 'sf', 'tidyverse', 'ggsignif',
'data.table', 'patchwork', 'ggOceanMaps',
"tools", "dplyr", 'sp', 'readr','mapproj',
'cowplot', 'raster')
installed_packages <- packages %in% rownames(installed.packages())
if (any(installed_packages == FALSE)) {
install.packages(packages[!installed_packages])
}
invisible(lapply(packages, library, character.only = TRUE))
path.RCA <- ("~/Downloads/Rockfish_Conservation_Area_-_R7_-_CDFW_[ds3144]/")
fnam.RCA <- "Rockfish_Conservation_Area_-_R7_-_CDFW_[ds3144].shp"
RCA <- st_read(dsn = path.RCA, layer = file_path_sans_ext(fnam.RCA))
dat.RCA <- fortify(RCA)
fathom_30 <- dat.RCA[dat.RCA$area_name %like% "30-fm", ]
fathom_30 <- fathom_30[fathom_30$area_name %like% "Coastwide", ]
world <- ne_countries(scale = "medium", returnclass = "SF")
socal_map <- ggplot() +
geom_sf(data = world) +
geom_sf(data = fathom_30, size = 1, color = 'lightgreen')+
coord_sf(xlim = c(-117, -121.5), ylim = c(31.75, 36), expand = FALSE)+
scale_x_continuous(breaks = c(seq(from = -121, to = -117, by = 2))) +
scale_y_continuous(breaks = c(seq(from = 32, to = 36, by = 2)))+
theme(legend.position = 'bottom',
strip.background = element_blank(),
legend.title = element_blank(),
strip.text.x = element_text(
size = 12, hjust = 0, face = "bold"),
panel.border = element_rect(color = "red",
fill = NA,
linewidth = 1),
axis.line.y = element_blank(), axis.line.x = element_blank(),
axis.title.x=element_blank(),
axis.title.y=element_blank())
socal_map
Заранее спасибо!
Каков ваш желаемый результат? Набор данных включает в себя многострочные строки, при фильтрации по area_name
, как в вашем примере, у нас остается 6 объектов (6 отдельных регионов), 5 из них находятся выше 34,4 широты, а оставшийся "Southern"
пересекает 34,4 широты. Желаемый размер подмножества — 5 или 6? Или вам нужен кадр, который просто вырезает все, что находится ниже 34,4 широты?
Моя карта рассчитана только до 36 лат, поэтому мне бы хотелось, чтобы контурная линия была только от 34,4 до 36. Это означает, что мой участок будет использовать только регион "Southern"
.
Это все еще несколько сбивает с толку, часть региона "Central - North 36°"
также вписывается в пределы широты, которые вы установили coords_sf
, но вы не хотите, чтобы это было на вашем участке? "Southern"
пересекает 34,4 широты, значит, вы идете только после того участка, который находится выше 34,4 широты? Для иллюстрации — i.sstatic.net/XI3zlwDc.png
Сюжет, который вы включили в иллюстрацию, — это именно то, что мне нужно, за исключением того же цвета (хотя я бы хотел, чтобы он появился в легенде)! Извините, я думал, что «Центральный — Северный 36˚» будет только широтой выше 36˚.
Как отметил в комментариях Крис, нужно позаботиться о системе координат (CRS). Поэтому, если вам нужно обрезать объект sf
ограничивающей рамкой или каким-либо другим sf
объектом, оба должны использовать один и тот же CRS. А для трансформации из одного в другое мы используем st_transform()
. Таким образом, вам нужно либо преобразовать границы обрезки в EPSG:3857 ((-124.679 34.4)
переводится как (-13879203 4082640)
), либо преобразовать sf
объект в географические координаты, WGS84. Мы выберем последнее.
Обрезка по географическим координатам может быть немного сложной в sf
, когда s2
включена (геометрия на сфере включена по умолчанию), поэтому мы отключим ее при работе с геометрией. Один из недавних ответов, который пытается объяснить и проиллюстрировать это - https://stackoverflow.com/a/78725088/646761
library(sf)
#> Linking to GEOS 3.12.1, GDAL 3.8.4, PROJ 9.3.1; sf_use_s2() is TRUE
library(dplyr)
library(stringr)
library(ggplot2)
world <- rnaturalearth::ne_countries(scale = "medium")
# underlying GDAL library supports virtual file systems and can read
# zipped shapefiles by prefixing file name with `/vsizip/`
rca_shp <- "/vsizip/Rockfish_Conservation_Area_-_R7_-_CDFW_[ds3144].zip"
# check layers and projection / CRS
st_layers(rca_shp)
#> Driver: ESRI Shapefile
#> Available layers:
#> layer_name geometry_type features fields
#> 1 Rockfish_Conservation_Area_-_R7_-_CDFW_[ds3144] Line String 71 5
#> crs_name
#> 1 WGS 84 / Pseudo-Mercator
# load shapefile, transform from pseudo-mercator (EPSG:3857) to
# geographic coordinates (WGS84)
rca_wgs84 <-
read_sf(rca_shp) |>
st_transform("wgs84")
# use bounding box of sf object for a crop area template, update latitude limits
(bbox <- st_bbox(rca_wgs84))
#> xmin ymin xmax ymax
#> -124.67900 32.35717 -117.25733 42.00000
bbox[["ymin"]] <- 34.4
bbox[["ymax"]] <- 36
# to crop with a bounding box and handle geographic coordinates as
# planar coordinates, we'll crop with s2 (geometries on a sphere) disabled;
# filter by area_name, crop by updated bbox
sf_use_s2(use_s2 = FALSE)
#> Spherical geometry (s2) switched off
fathom_30 <-
rca_wgs84 |>
filter(str_detect(area_name, "30-fm.*Coastwide")) |>
st_crop(bbox)
#> although coordinates are longitude/latitude, st_intersection assumes that they
#> are planar
#> Warning: attribute variables are assumed to be spatially constant throughout
#> all geometries
sf_use_s2(use_s2 = TRUE)
#> Spherical geometry (s2) switched on
# after filtering by area_name and cropping into bbox we are left with
# 2 features:
fathom_30
#> Simple feature collection with 2 features and 5 fields
#> Geometry type: LINESTRING
#> Dimension: XY
#> Bounding box: xmin: -121.5683 ymin: 34.4 xmax: -119.9203 ymax: 36
#> Geodetic CRS: WGS 84
#> # A tibble: 2 × 6
#> OBJECTID area_name START_Fath Region Shape__Len geometry
#> * <int> <chr> <int> <chr> <dbl> <LINESTRING [°]>
#> 1 52 30-fm (55-m) … 30 South… 548019. (-120.5052 34.45, -120.4…
#> 2 53 30-fm (55-m) … 30 Centr… 266038. (-121.5683 36, -121.5635…
# to visualize
# mapview::mapview(fathom_30, zcol = "Region")
# plot
ggplot() +
geom_sf(data = world) +
geom_sf(data = fathom_30, linewidth = 1, aes(color = "fathom_30")) +
scale_color_manual(name = "Legend title", values = c(fathom_30 = "lightgreen")) +
coord_sf(xlim = c(-117, -121.5), ylim = c(31.75, 36), expand = FALSE) +
theme_minimal()
Created on 2024-07-23 with reprex v2.1.0
Спасибо! Мне не удалось построить карту, но, изменив world <- rnaturalearth::ne_countries(scale = "medium")
обратно на world <- ne_countries(scale = "medium", returnclass = "sf")
, ошибка была исправлена.
Интересно... в любом случае приятно знать, что это помогло и что тебе удалось во всем разобраться.
rockfish_lon_lat <- st_transform(rockfish, crs = 'EPSG:4326')
преобразует ваши данные в долготу и широту, которую вы затем можете подставить под свое понятие «выше 34,4». Сейчас он находится вpseudo mercator
, другой проекции.