Я хочу построить некоторые пространственные данные с использованием пакета листовки в R, однако генерируемое растровое изображение, кажется, сдвинуто по сравнению с эталонной сеткой. Я подозреваю, что проблема с проекцией карты, но я не эксперт по этой теме, поэтому любая помощь будет оценена.растровые, похоже, сдвинуто с использованием листовки для R
Вот минимальный код для построения карты:
library(leaflet)
library(sp)
library(raster)
set.seed(111)
# create dummy data -rectangular grid with random values
m = 10
n = 10
x = seq(45,48,length.out = m)
y = seq(15,18,length.out = n)
X = matrix(rep(x, each = n), nrow = n)
Y = matrix(rep(y, m), nrow = n)
# collector dataframe
points = data.frame(value = rnorm(n*m), lng = c(Y), lat = c(X))
## create raster grid
s = SpatialPixelsDataFrame(points[,c('lng', 'lat')], data = points)
# set WGS84 projection
crs(s) = sp::CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
r = raster(s)
# add coloring
pal = colorNumeric(c("#0C2C84", "#f7f7f7", "#F98009"), points$value,
na.color = "transparent")
## plot map
leaflet() %>% addProviderTiles("CartoDB.Positron") %>%
addRasterImage(r, colors = pal, opacity = 0.6)
Это производит эту карту, которая хорошо на первый взгляд:
Если сетка добавляется к этой карте:
## grid
dx = diff(x)[1]/2
dy = diff(y)[1]/2
rect_lng = sapply(points$lng, function(t) c(t-dx, t+dx))
rect_lat = sapply(points$lat, function(t) c(t-dy, t+dy))
leaflet() %>% addProviderTiles("CartoDB.Positron") %>%
addRectangles(
lng1=rect_lng[1,], lat1=rect_lat[1,],
lng2=rect_lng[2,], lat2=rect_lat[2,],
fillColor = "transparent",
weight = 1
) %>%
addRasterImage(r, colors = pal, opacity = 0.6)
Карта выглядит следующим образом:
Здесь мы видим, что сетки не совпадают.
В чем причина этого несоответствия? Как его можно устранить? Я тщетно пробовал разные прогнозы. Единственное, что сработало, это использовать addRectangle
вместо addRasterImage
, однако это требует гораздо большего количества вычислений и замедляет процесс, поэтому я хочу избежать. Обратите внимание, что в приведенном выше примере addRectangle
используется только для ссылки, в конечном коде я не хочу его использовать.
Для карт с большим количеством ячеек (сеток) несоответствие довольно велико, может быть больше размера одной ячейки.
Заранее благодарим за любую помощь.
EDIT
Проблема может быть связана с вопросом проекции между эллипсоида и сферы проекций см последний вопрос here:
конвертировать между WGS84 и Меркатора на сфере будет существенные сдвиги в координатах Y мерцатора. Это связано с тем, что внутренне cs2cs должен отрегулировать координаты lat/long от , находясь на шаре, к тому, чтобы быть на основе WGS84, которая имеет довольно эллипсоид по-разному.
Однако я не смог решить проблему с рекомендуемым «трюком»: [email protected]
.
Я думаю, проблема в том, что выполняемая операция проекции ('leaflet :: projectRasterForLeaflet') создает выходной растровый файл с теми же размерами пикселя/ячейки, что и входной растровый (в данном случае 10x10), тогда как обычно вы хотите проект, используя размеры вывода, на которые вы фактически выполняете. Но в этом случае на самом деле отсутствуют фиксированные размеры вывода, так как пользователь может увеличивать и уменьшать масштаб. Я делаю небольшой проецируемый растр, а затем масштабирую его линейно, чтобы соответствовать масштабированию, и это, скорее всего, то, что вводит дрейф. –
Благодарим вас за обход и возможное объяснение! Повторно выбранный растровый 'r' ведет себя странно в' colorNumeric'; Я изменил домен на «значения (r)», но я получаю предупреждение о том, что некоторые значения находятся за пределами цветовой шкалы, и действительно, некоторые пиксели прозрачны (отверстия в растровой графике). Для вышеприведенного примера 'domain = c (1.01 * min (значения (r)), 1.01 * max (значения (r)))' решил проблему, но более элегантное решение было бы лучше. Если у вас есть какие-либо предложения по этому вопросу, это было бы здорово. Благодаря! – Arpi
Хммм. Does 'domain = c (minValue (r), maxValue (r))' не работает (где 'r' - уже измененный растровый файл)? Почему требуется «1.01»? –