R

时间:2015-11-16 18:26:52

标签: r leaflet map-projections sp r-raster

我想使用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仅用于引用,在最终代码中我不想使用它。

对于具有更多单元格(网格)的地图,不匹配非常大,可能大于单个单元格的大小。

提前感谢您的帮助。

修改

问题可能与椭圆体和球体投影之间的投影问题有关,请参阅最后一个问题here

  

在球体上转换WGS84和mercator之间会有   Y mercator坐标的实质性变化。这是因为   内部cs2cs必须调整纬度/经度坐标   在球体上是在WGS84基准面上有一个相当的   不同形状的椭圆体。

但是,我无法使用推荐的'技巧'来解决问题:+nadgrids=@null

1 个答案:

答案 0 :(得分:3)

这里的传单R包的作者。在我看来,当源光栅相对于在屏幕上渲染的像素数极少的像素时,我写的栅格图层渲染器开始漂移。您可以通过对栅格进行以下修改来看到这一点:

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

我会看看我是否可以改善渲染方面的问题,但与此同时,这样的重新采样可能是最简单的解决方法,但不可否认它是不优雅的。