Как преобразовать CRS окна карты и точек данных, чтобы они соответствовали объекту SF?

Я пытаюсь создать карту тихоокеанского побережья Северной Америки (юг Канады, США, Нижняя Калифорния), на которой будут показаны местоположения сайтов. В идеале картографическая проекция должна сохранять форму / ориентацию береговой линии.

Я использую данные rnaturalearth countries как свои spatialpolygondataframe. Я думаю, что исходная проекция этих данных (EPSG: 4326 proj4string: "+ proj = longlat + datum = WGS84 + no_defs") выглядит не очень хорошо, поэтому я преобразовал данные countries в проекцию конической формы Ламберта (proj4string: + proj = lcc + lat_1 = 20 + lat_2 = 60 + lat_0 = 40 + lon_0 = -96 + x_0 = 0 + y_0 = 0 + датум = NAD83 + единицы = m + no_defs '). Я не уверен, что это лучший прогноз, но я решил, что с него нужно начать, я открыт для предложений.

Я изо всех сил пытаюсь построить преобразованную НФ, чтобы показать тихоокеанское побережье Северной Америки. Я знаю, что мне нужно преобразовать координаты моего окна в соответствии с проекцией LCC North America, а также координаты моего сайта, но Rstudio дает мне пустое окно графика и ошибки.

Я попытался выполнить шаги, изложенные в [https://www.r-bloggers.com/zooming-in-on-maps-with-sf-and-ggplot2/provided[1], но безуспешно после многих попыток и пробуя другие методы. Где я ошибаюсь при преобразовании окна карты? Это моя первая попытка нанести на карту преобразованную проекцию. Любые предложения будут ценны! Заранее спасибо!

library(tidyverse)
library(ggplot2)
library(sf)
library(rnaturalearth) # map data source
library(rgdal)

## Download sf from rnaturalearth
country <- ne_download(scale = 10, type = 'countries', category = 'cultural', returnclass = 'sf')
st_crs(country) # show CRS of data
st_proj_info() # lcc is available

# Lambert Conformal Conic projection proj4 according to https://epsg.io/102009
LCC_North_America <- '+proj=lcc +lat_1=20 +lat_2=60 +lat_0=40 +lon_0=-96 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs'
# transform country data to LCC N. America
country_LCC <- st_transform(country, crs = LCC_North_America)

## site locations, need to transform to LCC N.America and plot
lat <- c(48.98604, 47.72322, 37.96389, 33.61817)
long <- c(-122.7593, -122.6559, -122.4881, -117.9052)

disp_wind_4326 <- st_sfc(st_point(c(-127,49)), st_point(c(-112, 29)), crs = 4326)
disp_wind_LCC <- st_transform(disp_wind_4326, crs = LCC_North_America)
disp_window <- st_coordinates(disp_wind_LCC)

(NOOC_coast_fig <- ggplot() +
   geom_sf(data = country_LCC) +
   coord_sf(xlim = disp_window[,'X'], ylim = disp_window[,'Y'],
            datum = LCC_North_America, expand = FALSE) +
   theme_bw())

person Skiea    schedule 11.12.2019    source источник
comment
Просто обратите внимание - хороший воспроизводимый пример, но вы используете набор естественных данных самого высокого разрешения. При размещении вопросов вы могли бы перейти к данным с действительно низким разрешением (scale=110) - их быстрее загружать и строить.   -  person David_O    schedule 18.12.2019


Ответы (1)


Боюсь, это классика. Ваши широта и долгота неверны. Не помогает то, что широта и долгота являются обычным порядком, в котором люди говорят это - Y, затем X.

disp_wind_4326 <- st_sfc(st_point(c(-127, 49)), st_point(c(-112, 29)), crs = 4326)

Для самопомощи стоит проверить структуру объектов, чтобы убедиться, что они соответствуют вашим ожиданиям. Когда я запустил ваш код, я посмотрел на disp_wind_LCC и увидел следующее:

> disp_wind_LCC
Geometry set for 2 features  (with 2 geometries empty)
geometry type:  POINT
dimension:      XY
bbox:           xmin: NA ymin: NA xmax: NA ymax: NA
epsg (SRID):    102009
proj4string:    +proj=lcc +lat_1=20 +lat_2=60 +lat_0=40 +lon_0=-96 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs
POINT EMPTY
POINT EMPTY

В этот момент ясно, что с входными данными что-то не так, потому что они не создают правильную геометрию. У вас не может быть широты за пределами (-90, 90), поэтому она дает пустую точку.

Следуя вашему комментарию ниже, следующая проблема довольно неясна. Вы преобразуете глобальные данные в свою проекцию LCC. Если бы вы построили график всего country_LCC набора данных, вы бы увидели огромное количество искажений.

В частности, Антарктида совсем не справляется. Это довольно распространенное явление: если вы введете в локальную проекцию географические координаты, которые находятся далеко за пределами домена, для которого она используется, все может пойти не так.

> st_bbox(country_LCC[country_LCC$ADMIN == 'Antarctica',])
      xmin       ymin       xmax       ymax 
-335167885 -226033419   42202752   22626164 
> st_bbox(country_LCC[country_LCC$ADMIN == 'United States of America',])
    xmin     ymin     xmax     ymax 
-6653437 -1523147  2124650  4338858 

Итак, ваш сюжет правильный, но есть неправильно спроектированный многоугольник Антарктиды, который находится поверх всего остального. Итак, здесь и в целом, прежде чем делать какое-либо перепроецирование, сведите глобальные данные к интересующей области:

country <- subset(country, ADM0_A3 %in% c("USA", "CAN", "MEX"))
country_LCC <- st_transform(country, crs = LCC_North_America)

Теперь это должно сработать!

person David_O    schedule 13.12.2019
comment
Спасибо что подметил это! Я обновил свой код, чтобы переключить порядок широты / долготы в disp_wind_4326, что создало две точки с действительными числами. Окно результирующего NOOC_coast_fig графика теперь выглядит лучше, но мультиполигон country_LCC по-прежнему не отображается. Я неправильно понимаю, для чего можно использовать набор данных rnaturalearth, или что-то все еще не так в моем коде / проекциях? - person Skiea; 17.12.2019
comment
См. Обновленный ответ выше - это проблема неверного проецирования, поэтому код и график верны, но поверх них есть неверные данные. - person David_O; 18.12.2019