2015-11-16 2 views
2

Я хочу построить некоторые пространственные данные с использованием пакета листовки в 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) 

Это производит эту карту, которая хорошо на первый взгляд: enter image description here

Если сетка добавляется к этой карте:

## 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) 

Карта выглядит следующим образом:

enter image description here

Здесь мы видим, что сетки не совпадают. enter image description here

В чем причина этого несоответствия? Как его можно устранить? Я тщетно пробовал разные прогнозы. Единственное, что сработало, это использовать addRectangle вместо addRasterImage, однако это требует гораздо большего количества вычислений и замедляет процесс, поэтому я хочу избежать. Обратите внимание, что в приведенном выше примере addRectangle используется только для ссылки, в конечном коде я не хочу его использовать.

Для карт с большим количеством ячеек (сеток) несоответствие довольно велико, может быть больше размера одной ячейки.

Заранее благодарим за любую помощь.

EDIT

Проблема может быть связана с вопросом проекции между эллипсоида и сферы проекций см последний вопрос here:

конвертировать между WGS84 и Меркатора на сфере будет существенные сдвиги в координатах Y мерцатора. Это связано с тем, что внутренне cs2cs должен отрегулировать координаты lat/long от , находясь на шаре, к тому, чтобы быть на основе WGS84, которая имеет довольно эллипсоид по-разному.

Однако я не смог решить проблему с рекомендуемым «трюком»: [email protected].

ответ

3

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

r1 <- r 
nrow(r1) <- 600 
ncol(r1) <- 600 
r <- resample(r, r1, method = "ngb") 

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

+0

Я думаю, проблема в том, что выполняемая операция проекции ('leaflet :: projectRasterForLeaflet') создает выходной растровый файл с теми же размерами пикселя/ячейки, что и входной растровый (в данном случае 10x10), тогда как обычно вы хотите проект, используя размеры вывода, на которые вы фактически выполняете. Но в этом случае на самом деле отсутствуют фиксированные размеры вывода, так как пользователь может увеличивать и уменьшать масштаб. Я делаю небольшой проецируемый растр, а затем масштабирую его линейно, чтобы соответствовать масштабированию, и это, скорее всего, то, что вводит дрейф. –

+0

Благодарим вас за обход и возможное объяснение! Повторно выбранный растровый 'r' ведет себя странно в' colorNumeric'; Я изменил домен на «значения (r)», но я получаю предупреждение о том, что некоторые значения находятся за пределами цветовой шкалы, и действительно, некоторые пиксели прозрачны (отверстия в растровой графике). Для вышеприведенного примера 'domain = c (1.01 * min (значения (r)), 1.01 * max (значения (r)))' решил проблему, но более элегантное решение было бы лучше. Если у вас есть какие-либо предложения по этому вопросу, это было бы здорово. Благодаря! – Arpi

+0

Хммм. Does 'domain = c (minValue (r), maxValue (r))' не работает (где 'r' - уже измененный растровый файл)? Почему требуется «1.01»? –