R:使用 maptools::elide 缩放阿拉斯加

问题描述

我正在构建一个州的 shapefile,其中阿拉斯加和夏威夷被表示为德克萨斯州以南的某个地方,以便于制作说明性地图。使用 maptools 包和 https://rud.is/b/2014/11/16/moving-the-earth-well-alaska-hawaii-with-r/ 中的一些代码,我已经能够使用 TIGER 中的形状来做到这一点。

但是,我现在遇到了麻烦,因为我想将城市添加到我的地图中。将我的形状制作成 sp 对象,然后使用 maptools::elide 之前对阿拉斯加工作正常,但是在点集合上使用缩放的 elide 的工作方式不同,因此我的城市最终会出现在错误的位置:

library(maptools)
library(sf)
library(tmap)
library(tidyverse)
library(tidygeocoder)

  
ak_city_sf <-
  tribble(~city_name,~city_search_string,"Juneau","Juneau,Alaska,United States","Anchorage","Anchorage,"Utqiagvik","Utqiagvik,"Scammon Bay","Scammon Bay,United States") %>%
  geocode(city_search_string,method = 'osm',lat = latitude,long = longitude) %>%
  st_as_sf(coords = c("longitude","latitude"))

st_crs(ak_city_sf) <- 4326

ak_city_sf <-
  ak_city_sf %>%
  st_transform(2163)
    
ak_state_sf <-
  tigris::states(cb = T) %>%
  filter(STusps == "AK") %>%
  st_transform(2163)

# before transformation,everything looks fine...

tm_shape(ak_state_sf) +
  tm_borders() +
  tm_shape(ak_city_sf) +
  tm_dots(size = .1) +
  tm_text("city_name",size = .5)

SCALE_FACTOR <- 10000


ak_state_sf_scaled <-
  ak_state_sf %>%
  as("Spatial") %>%
  elide(scale = SCALE_FACTOR) %>%
  st_as_sf()

st_crs(ak_state_sf_scaled) <- 2163

ak_city_sf_scaled <-
  ak_city_sf %>%
  as("Spatial") %>%
  elide(scale = SCALE_FACTOR) %>%
  st_as_sf()

st_crs(ak_city_sf_scaled) <- 2163
# after scaling,things don't look so good

tm_shape(ak_state_sf_scaled) +
  tm_borders() +
  tm_shape(ak_city_sf_scaled) +
  tm_dots(size = .1) +
  tm_text("city_name",size = .5)

maptools::elide 似乎是执行此类操作的最佳命令(即使它迫使我转换为 sp 对象)。规模的文档对我来说意义不大。 (我不认为我可以将它们组合在一个对象中,因为它们是城市的点和州的多边形)。如何以与缩放状态相同的方式缩放点?

解决方法

要缩放或旋转两个独立的几何图形以便将它们映射到一起,有必要定义一个质心,您的州几何图形和城市几何图形都将围绕该质心旋转或缩放。这具有一定的逻辑意义,因为除非您定义(隐式或显式)缩放或旋转的中心,否则无法缩放或旋转一组点(在本例中代表城市)。

一旦你定义了一个共同的质心(在我的例子中,我只使用了我正在变换的状态的质心),你可以使用这里显示的仿射变换: https://geocompr.robinlovelace.net/geometric-operations.html#affine-transformations