地图中气泡/圆形对象的投影

时间:2019-06-13 19:12:35

标签: r leaflet gis tmap

我试图通过在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.这很好,并且我得到了所附图片:

enter image description here

与此有关的问题是,阿拉斯加的地震烈度实际上是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底图?这是我迷路的地方。

enter image description here

作为一个旁注,这对于打印模式来说不是问题,因为我显然可以在共享相同投影的下方放置自己的图层,并且所有内容都很花哨。我的困惑在于与传单的互动。

这里的解决方案是什么?我想使用漂亮的Mercator贴图,因为它看起来很漂亮,但是我不希望像符号这样的东西被它扭曲。我是否需要定义一个新的大小列来抵消像earthquake %>% mutate(EQ_PRIMARY1 = EQ_PRIMARY / (abs(LATITUDE)+1))这样的Mercator失真,但被实际研究的函数所抵消,从而抵消大小效应?这是该领域的常见问题,还是此软件包无法正确执行此操作?

2 个答案:

答案 0 :(得分:0)

首先,您需要将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"))

答案 1 :(得分:0)

我确实找到了一些解决方法,如我所描述的,它基于每个点的纬度获取比例因子。如果这是一个怪异的解决方法,请原谅我,但是我对此有些陌生。基本过程是:

  1. 基于现有几何的投影添加两个新几何-将其中一个投影到EQC,将其中一个投影到EQC投影,但是将其向上移动1个单位(我通过在proj4中将false northing设置为1来完成此操作)。我们基本上想要两个几何形状,其中一个单位在另一个单位的北边。
  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"))

enter image description here

这将产生具有点的适当大小的地图。代码有点笨拙,但我猜可能会更糟。如果不存在定制功能,可能会值得。