Проекция пузырьков / кругов на картах

Я пытаюсь реализовать некоторые базовые концепции с отображением пространственных данных в R. Я начал с землетрясений, чтобы получить некоторые простые данные для тестирования. Я сначала загрузил базу данных о землетрясениях по этой ссылке:

https://www.ngdc.noaa.gov/nndc/struts/results?type_0=Exact&query_0= $ ID & t = 101650 & s = 13 & d = 189 & dfn = signif.txt

Затем запустил следующий код, чтобы очистить / организовать этот набор данных:

library(dplyr)
library(tmap)
library(sf)
earthquake<-read.table("signif.txt",sep="\t",header=TRUE,fill=TRUE) %>% filter(!is.na(LATITUDE) & !is.na(LONGITUDE)) %>% st_as_sf(coords=c("LONGITUDE","LATITUDE"))

Затем выполнил следующий код, чтобы отобразить карту всех землетрясений магнитудой 9 и более сильных:

tmap_mode("view")
tm_shape(earthquake %>% filter(EQ_PRIMARY > 9))+tm_bubbles(size = "EQ_PRIMARY",col="red",popup.vars=c("EQ_PRIMARY"))

Я получаю это сообщение об ошибке, так как я никогда не назначал проекцию данным: Currect projection of shape earthquake %>% filter(EQ_PRIMARY > 9) unknown. Long-lat (WGS84) is assumed. Это нормально, и я получаю прикрепленное изображение:

введите описание изображения здесь

Проблема в том, что сила землетрясения на Аляске на самом деле составляет 9,2 балла, тогда как сила южного землетрясения в Чили - 9,5, но круг Аляски заметно больше! Иконки пузырей дальше от экватора проецируются и искажаются под проекцией Меркатора.

Поэтому я пытаюсь изменить проекцию моих данных на LAEA:

st_crs(earthquake)<-"+proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m +no_defs "

Но теперь, когда я запускаю ту же карту, что и выше, круги отображаются с правильным размером, но базовая карта не отображается, поскольку я предполагаю, что tmap не имеет базовой карты LAEA? Здесь я заблудился.

введите описание изображения здесь

Кстати, это не проблема для режима рисования, так как я, очевидно, могу разместить под ним свой собственный слой, который имеет ту же проекцию, и все будет отлично. Мое замешательство возникает при взаимодействии с листовкой.

Какое здесь решение? Я хотел бы использовать красивую карту Меркатора, потому что она выглядит красиво, но я не хочу, чтобы она искажала такие вещи, как символы. Нужно ли мне определять новый столбец размера, чтобы противодействовать искажению Меркатора, например earthquake %>% mutate(EQ_PRIMARY1 = EQ_PRIMARY / (abs(LATITUDE)+1)), но заменять его реальной исследуемой функцией, которая будет противодействовать эффекту размера? Это обычная проблема в этой области или этот пакет просто не работает правильно?


person user1871007    schedule 13.06.2019    source источник
comment
Но Меркатор ужасно искажен - как бы вы хотели, чтобы ваша визуализация масштабировалась, если область, на которую вы указываете, намного больше / меньше?   -  person Roman    schedule 20.08.2019


Ответы (2)


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

  1. Добавьте две новые геометрии, основанные на проекции существующей геометрии - спроецируйте одну из них в EQC, а другую - в ту же проекцию EQC, но смещенную на 1 единицу вверх (я сделал это, установив ложное северное положение на 1 в proj4). По сути, нам нужны две геометрии, в которых одна единица расположена к северу от другой.
  2. Преобразуйте эти две геометрии в веб-меркатор с помощью st_transform.
  3. Измерьте расстояние по оси Y между полученными геометрическими формами. Это то, насколько Web Mercator масштабирует 1 единицу расстояния на данной широте. Это очень близко к 1.000 для точек, близких к экватору, и почти к 2.5 вблизи полюсов.
  4. Масштабируйте размер точек на коэффициент, обратный квадрату указанного выше.

Код выглядит так:

earthquake$yeqc0<-earthquake %>% st_transform("+proj=eqc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs") %>% st_geometry()
earthquake$yeqc1<-earthquake %>% st_transform("+proj=eqc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=1 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs") %>% st_geometry()

Обратите внимание на тонкий y_0 = 1 выше.

st_crs(earthquake$yeqc1)<-st_crs(earthquake$yeqc0)
earthquake$ymerc<-st_distance(st_transform(earthquake$yeqc0,crs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs"),st_transform(earthquake$yeqc1,crs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs"),by_element=TRUE)
earthquake<-earthquake %>% mutate(EQ_PRIMARY1 = EQ_PRIMARY * (1 / ymerc)^2)
tm_shape(earthquake %>% filter(EQ_PRIMARY > 9))+tm_bubbles(size = "EQ_PRIMARY1",col="red",popup.vars=c("EQ_PRIMARY","EQ_PRIMARY1"))

введите описание изображения здесь

В результате будет получена карта с точками нужного размера. Код немного неуклюжий, но, думаю, могло быть и хуже. Возможно, что-то, что заслуживает специальной функции, если таковой не существует.

person user1871007    schedule 13.06.2019

Во-первых, вам нужно установить crs для текущей проекции, возможно, WGS84. Затем используйте st_transform для изменения координат. Вот код, но, похоже, он показывает аналогичный результат. Возможно, подойдет другая проекция, или попробуйте изменить проекцию в функции tm_shape.

library(dplyr)
library(tmap)
library(sf)
earthquake<-read.table("https://www.ngdc.noaa.gov/nndc/struts/results?type_0=Exact&query_0=$ID&t=101650&s=13&d=189&dfn=signif.txt",
                       sep="\t",header=TRUE,fill=TRUE) %>%
  filter(!is.na(LATITUDE) & !is.na(LONGITUDE)) %>%
  st_as_sf(coords=c("LONGITUDE","LATITUDE"))
st_crs(earthquake) <- 4326
earthquake <- st_transform(earthquake, "+proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m +no_defs ")
tmap_mode("view")
tm_shape(earthquake %>% filter(EQ_PRIMARY > 9))+
  tm_bubbles(size = "EQ_PRIMARY",col="red",popup.vars=c("EQ_PRIMARY"))
person bischrob    schedule 13.06.2019
comment
Фактически, когда вы используете интерактивный режим (tmap_mode (view)), он всегда проецируется на веб-меркатор. См. Файл справки для функции. - person bischrob; 13.06.2019
comment
Ах, я вижу, что в файле справки конкретно упоминается этот недостаток ... может быть, лучше всего вручную отрегулировать переменную EQ_PRIMARY, чтобы размер после проецирования выглядел правильно ... - person user1871007; 13.06.2019