将sf几何图形与转换后的几何图形合并。

huangapple go评论104阅读模式
英文:

Combine sf geometry with transformed geometry

问题

我正在使用R复制xkcd的“Bad Map Projection: ABS(Longitude)”。我已经有了一个不错的开端,但我想用“正确”的方式来完成。

在这里,我使用一个世界地图,并创建一个水平镜像的副本。然后我绘制两个地图,并将视窗裁剪到正经度范围内。

  1. library(ggplot2)
  2. library(sf)
  3. library(rnaturalearth)
  4. library(rnaturalearthdata)
  5. world <- ne_countries(scale = "small", returnclass = "sf") %>%
  6. sf::st_as_sf() %>%
  7. sf::st_set_crs(value = 4326)
  8. # 矩阵乘法反射经度
  9. world_rev <- st_geometry(world) * matrix(c(-1,0,0,1), 2, 2)
  10. world2 <- world |
  11. st_set_geometry(world_rev) |
  12. sf::st_as_sf() |
  13. sf::st_set_crs(value = 4326)
  14. ggplot() +
  15. geom_sf(data = world, fill = "#336666", alpha = 0.5) +
  16. geom_sf(data = world2, fill = "#663366", alpha = 0.5) +
  17. coord_sf(xlim = c(0, 180), expand = 0)

这种方法的不足之处在于我似乎无法应用不同的投影方式。例如,如果我最后使用以下代码:

  1. coord_sf(crs= "+proj=robin", xlim = c(0, 180), expand = 0)

我得到一个空白的图。是否有更可靠的方法来创建反转的对象?

英文:

I am replicating xkcd's "Bad Map Projection: ABS(Longitude)" with R. I have a decent start but I'd like to do it the "right" ways.

Here, I take a world map and make a copy with a horizontal reflection. Then I plot both and crop the viewing window to positive longitude.

  1. library(ggplot2)
  2. library(sf)
  3. library(rnaturalearth)
  4. library(rnaturalearthdata)
  5. world &lt;- ne_countries(scale = &quot;small&quot;, returnclass = &quot;sf&quot;) |&gt;
  6. sf::st_as_sf() %&gt;%
  7. sf::st_set_crs(value = 4326)
  8. # matrix multiplication to reflect longitude
  9. world_rev &lt;- st_geometry(world) * matrix(c(-1,0,0,1), 2, 2)
  10. world2 &lt;- world |&gt;
  11. st_set_geometry(world_rev) |&gt;
  12. sf::st_as_sf() |&gt;
  13. sf::st_set_crs(value = 4326)
  14. ggplot() +
  15. geom_sf(data = world, fill = &quot;#336666&quot;, alpha = 0.5) +
  16. geom_sf(data = world2, fill = &quot;#663366&quot;, alpha = 0.5) +
  17. coord_sf(xlim = c(0, 180), expand = 0)

将sf几何图形与转换后的几何图形合并。

A shortfall of this is that I can't seem to apply different projections. For instance, if I end with

  1. coord_sf(crs= &quot;+proj=robin&quot;, xlim = c(0, 180), expand = 0)

I get a blank plot. Is there a more robust way to create the reversed object?

答案1

得分: 2

略微接近,但仍不理想:

  • 将 Robinson 投影中心的经度从默认值 0 移动到 90
  • 为了处理“超出边缘”的几何图形,将其裁剪到 0 ... 180 经度范围内
  • 为了使其工作,禁用 s2
  1. library(ggplot2)
  2. library(sf)
  3. #&gt; Linking to GEOS 3.9.3, GDAL 3.5.2, PROJ 8.2.1; sf_use_s2() is TRUE
  4. library(rnaturalearth)
  5. library(rnaturalearthdata)
  6. world &lt;- ne_countries(scale = &quot;small&quot;, returnclass = &quot;sf&quot;) |&gt;
  7. sf::st_as_sf() %&gt;%
  8. sf::st_set_crs(value = 4326)
  9. # 矩阵乘法反射经度
  10. world_rev &lt;- st_geometry(world) * matrix(c(-1,0,0,1), 2, 2)
  11. world2 &lt;- world |&gt;
  12. st_set_geometry(world_rev) |&gt;
  13. sf::st_as_sf() |&gt;
  14. sf::st_set_crs(value = 4326)
  15. sf_use_s2(use_s2 = FALSE)
  16. #&gt; Spherical geometry (s2) switched off
  17. bbox_0_180 &lt;- st_bbox(c(xmin = 0, ymin = -90, xmax = 180, ymax = 90), crs = 4326)
  18. world_crp &lt;- st_crop(world, bbox_0_180)
  19. world2_crp &lt;- st_crop(world2, bbox_0_180)
  20. ggplot() +
  21. geom_sf(data = world_crp, fill = &quot;#336666&quot;, alpha = 0.5) +
  22. geom_sf(data = world2_crp, fill = &quot;#663366&quot;, alpha = 0.5) +
  23. coord_sf(crs= &quot;+proj=robin +lon_0=90&quot;, expand = FALSE) +
  24. scale_x_continuous(breaks = seq(0,180,30))

将sf几何图形与转换后的几何图形合并。<!-- -->

<sup>Created on 2023-07-27 with reprex v2.0.2</sup>


你使用

  1. coord_sf(crs= &quot;+proj=robin&quot;, xlim = c(0, 180), expand = 0)

得到了空白图,因为 Robinson 投影是投影的,单位是米,xlim 也适用于此,你可以尝试使用以下代码:

  1. coord_sf(crs= &quot;+proj=robin&quot;, xlim = c(-18e6, 18e6), expand = 0)

使用 worldworld2 会产生类似以下的结果:
将sf几何图形与转换后的几何图形合并。

英文:

Somewhat closer, though still not ideal:

  • move longitude of Robinson projection center from default 0 to 90
  • to handle "over the edge" geometries, crop those to 0 ... 180 longitude
  • for this to work, disable s2
  1. library(ggplot2)
  2. library(sf)
  3. #&gt; Linking to GEOS 3.9.3, GDAL 3.5.2, PROJ 8.2.1; sf_use_s2() is TRUE
  4. library(rnaturalearth)
  5. library(rnaturalearthdata)
  6. world &lt;- ne_countries(scale = &quot;small&quot;, returnclass = &quot;sf&quot;) |&gt;
  7. sf::st_as_sf() %&gt;%
  8. sf::st_set_crs(value = 4326)
  9. # matrix multiplication to reflect longitude
  10. world_rev &lt;- st_geometry(world) * matrix(c(-1,0,0,1), 2, 2)
  11. world2 &lt;- world |&gt;
  12. st_set_geometry(world_rev) |&gt;
  13. sf::st_as_sf() |&gt;
  14. sf::st_set_crs(value = 4326)
  15. sf_use_s2(use_s2 = FALSE)
  16. #&gt; Spherical geometry (s2) switched off
  17. bbox_0_180 &lt;- st_bbox(c(xmin = 0, ymin = -90, xmax = 180, ymax = 90), crs = 4326)
  18. world_crp &lt;- st_crop(world, bbox_0_180)
  19. world2_crp &lt;- st_crop(world2, bbox_0_180)
  20. ggplot() +
  21. geom_sf(data = world_crp, fill = &quot;#336666&quot;, alpha = 0.5) +
  22. geom_sf(data = world2_crp, fill = &quot;#663366&quot;, alpha = 0.5) +
  23. coord_sf(crs= &quot;+proj=robin +lon_0=90&quot;, expand = FALSE) +
  24. scale_x_continuous(breaks = seq(0,180,30))

将sf几何图形与转换后的几何图形合并。<!-- -->

<sup>Created on 2023-07-27 with reprex v2.0.2</sup>


You got blank plot with

  1. coord_sf(crs= &quot;+proj=robin&quot;, xlim = c(0, 180), expand = 0)

because Robinson is projected and units are meters, applies for xlim too, you could try this instead:

  1. coord_sf(crs= &quot;+proj=robin&quot;, xlim = c(-18e6, 18e6), expand = 0)

, with world and world2 would produce something like:
将sf几何图形与转换后的几何图形合并。

huangapple
  • 本文由 发表于 2023年7月27日 15:46:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76777538.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定