如何在R中旋转地图

5
我想仅旋转地图或更改方向,例如45度,而不旋转其他元素。这可行吗?
例如:
  • 不旋转图像

enter image description here

  • 旋转图像

enter image description here

我的初始代码未进行旋转:

library("maps")
library("mapproj")
library("mapdata")

xlon = seq(-1, 7, 0.01)
xlat = seq(34, 42, 0.01)

map(database = "worldHires",
    xlim = c(min(xlon), max(xlon)), ylim = c(min(xlat),max(xlat)),
    mar = c(0, 0, 0, 0))
text(2, 37, labels = "point1", pos = 4)
points(2, 37)

1
请参见:elide | SO example - hrbrmstr
看起来在 map() 中有一个名为 orientation 的选项可以让你这样做,但是当我尝试使用 orientation = c(median(xlat), median(xlon), degrees = 45) 时,我得到了这个错误信息:Error in plot && coord$error : invalid 'y' type in 'x && y' - ulfelder
3个回答

5

通常情况下,当您调用 maps::map() 时,它会在函数调用期间自动绘制地图,但是您可以传递 plot=F 来防止这种情况发生。同时,您可以将调用的返回值存储在一个变量中,该变量将包含所请求地图轮廓的 x 和 y 坐标。然后,您可以使用一些三角学知识将所有的 x 和 y 坐标围绕一个中心点旋转,并最终使用基本 R 绘图函数手动绘制旋转后的点。

library('maps');
library('mapproj');
library('mapdata');

xlon = seq(-1,7,0.01);
xlat = seq(34,42,0.01);

md <- map('worldHires',xlim=range(xlon),ylim=range(xlat),mar=c(0,0,0,0),plot=F);
md2 <- md;
rot <- -30*pi/180;
about <- c(2,37);
newangles <- atan2(md$y-about[2],md$x-about[1])+rot;
mags <- sqrt((md$x-about[1])^2+(md$y-about[2])^2);
md2$x <- about[1]+cos(newangles)*mags;
md2$y <- about[2]+sin(newangles)*mags;
par(mar=c(0,0,0,0)); plot(md2,type='l',xlim=range(xlon),ylim=range(xlat),axes=F,ann=F);

text(about[1],about[2],labels='point1',pos=4);
points(about[1],about[2]);

rotated


确实不错(+1)。您有没有想法,map中的orientation参数如何使用?“一个向量c(纬度,经度,旋转)描述地图应该居中的位置和绕该中心顺时针旋转的角度(以度为单位)。”听起来很有前途(正如@ulfelder上面所指出的那样),至少对于像我这样的map外行来说。 - Henrik
@Henrik 是的,我在开始我的三角函数解决方案之前就注意到了那个参数,并且我得到了与 @ulfelder 在他的评论中提到的相同的错误。看起来是函数中的一个错误。我刚刚尝试在我的 R 会话中通过计算语言来修复它,我认为我成功了,但是我收到了“某些数据的投影失败”的警告,并且绘图看起来与未指定 orientation 参数时完全相同。可能是无望的事情。 - bgoldst

4

现在是2023年,随着现代化的sf R软件包,这变得更加容易。使用它,您可以在绘图之前旋转底层多边形以达到所需效果。此外,还可以通过rnaturalearth软件包使用自然地球的国家多边形数据。

library(sf)
library(rnaturalearth)
library(ggplot2)


# Rotate an sf geom around a center point. If no center is
# specified then it rotates around the center of the geom.
# This is technically an affine transformation: https://r-spatial.github.io/sf/articles/sf3.html#affine-transformations-1
st_ellide_rotate = function(x, degrees, center_coords=NULL){
  if(degrees < -360 | degrees > 360) stop('Degrees must be in the range -360 to 360')
  x = sf::st_combine(x)
  if(is.null(center_coords)){
    center_coords = sf::st_centroid(x)
  }
  radians = degrees * pi/180
  transform_matrix = matrix(c(cos(radians), sin(radians), -sin(radians), cos(radians)), 2, 2)
  
  return((x-center_coords) * transform_matrix + center_coords)
}


countries = rnaturalearth::ne_countries(scale = 10,returnclass = 'sf')
saved_crs = st_crs(countries)

points = st_sf(name=c('point1'), geometry = st_sfc(st_point(c(2,37)), crs = saved_crs))

countries_rotated = countries %>%
  st_ellide_rotate(-20, center_coords = c(2,37))
# applying an affine transformation nulls the CRS for some reason, so reset it here
st_crs(countries_rotated) <- saved_crs

ggplot() + 
  geom_sf(data=countries_rotated) +
  geom_sf(data=points, size=1) + 
  geom_sf_label(data=points, aes(label=name), nudge_x=1) + 
  coord_sf(xlim = c(-1,7), ylim=c(34,42)) +
  labs(subtitle = 'rotated 20 deg')

ggplot() + 
  geom_sf(data=countries) +
  geom_sf(data=points, size=1) + 
  geom_sf_label(data=points, aes(label=name), nudge_x = 1) + 
  coord_sf(xlim = c(-1,7), ylim=c(34,42)) +
  labs(subtitle = 'original')

image rotated 20 degrees original image


-2

如果您与R集成不紧密,您可以在这里使用emptymap.js探索地图旋转,这是文章解释用法。

免责声明:我是该模块的开发者。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接