Rstats - Как преобразовать километры в градусы, чтобы создать буферы с {sf} / {unit}? - PullRequest
0 голосов
/ 21 января 2019

У меня есть CSV-файл с городами и их координатами в WGS84.Я хотел бы создать буферы по 20 километров вокруг, чтобы найти слишком близкие города.В приведенном ниже примере Исламабад и Равалпинди слишком близки друг к другу.

Я смог создать df и geom, но когда я звоню st_buffer(), он говорит мне, что не может преобразовать км в градусный угол.

Я пытался использовать пакет units, но он не обрабатывает углы в градусах.

library(tidyverse)
library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.2.3, PROJ 4.9.3
library(units)
#> udunits system database from D:/Roelandt/Documents/R/win-library/3.5/units/share/udunits

# Create a tribble from the data

df <- tibble::tribble(
   ~ID,             ~city,     ~lat,    ~lon,
  1172,           "Zaria", 11.11128,   7.7227,
  1173,            "Oslo", 59.91273, 10.74609,
  1174, "Masqat (Muscat)", 23.61387,  58.5922,
  1175,      "Bahawalpur",     29.4, 71.68333,
  1181,"Islamabad",33.70351,73.059373,
  1194,"Rawalpindi",33.6,73.0666667

  )
df
#> # A tibble: 6 x 4
#>      ID city              lat   lon
#>   <dbl> <chr>           <dbl> <dbl>
#> 1  1172 Zaria            11.1  7.72
#> 2  1173 Oslo             59.9 10.7 
#> 3  1174 Masqat (Muscat)  23.6 58.6 
#> 4  1175 Bahawalpur       29.4 71.7 
#> 5  1181 Islamabad        33.7 73.1 
#> 6  1194 Rawalpindi       33.6 73.1

cities_df = st_as_sf(df, coords = c("lon", "lat"), crs = 4326)

# buffer size 
a = as_units(20, "km")

#Create buffers
cities_buffers <- cities_df %>% 
  st_buffer(dist = a)
#> Warning in st_buffer.sfc(st_geometry(x), dist, nQuadSegs, endCapStyle =
#> endCapStyle, : st_buffer does not correctly buffer longitude/latitude data
#> Error: cannot convert km into °
cities_buffers
#> Error in eval(expr, envir, enclos): objet 'cities_buffers' introuvable

Created on 2019-01-21 by the reprex package (v0.2.1)

Я хотел бы знать, есть ли способ преобразования размера буферав географических градусах.

Я думал о преобразовании набора данных в прогнозируемые crs, такие как UTM, но я не уверен, что это хорошая идея для данных по всему миру.

Спасибо,

Николас

1 Ответ

0 голосов
/ 21 января 2019

Из замечательного поста Джесси Садлер (https://www.jessesadler.com/post/simple-feature-objects/):) «Начиная с версии 0.6 пакета sf, st_distance () использует пакет lwgeom, который, в свою очередь, ссылается на геометрические функции из библиотеки liblwgeom, используемой PostGIS, для выполнения геометрических расчетов значений долготы и широты.»

Я бы подошел к этому, получив матрицу расстояний, а не создав буфер.

dist_mat <- st_distance(cities_df)
#> dist_mat
#Units: [m]
#        [,1]    [,2]    [,3]      [,4]       [,5]       [,6]
#[1,]       0 5421407 5550432 6898123.8 7057404.43 7057248.70
#[2,] 5421407       0 5461507 5616666.0 5306301.50 5315880.95
#[3,] 5550432 5461507       0 1452564.2 1799547.86 1793603.09
#[4,] 6898124 5616666 1452564       0.0  494716.65  483860.32
#[5,] 7057404 5306302 1799548  494716.7       0.00   11500.84
#[6,] 7057249 5315881 1793603  483860.3   11500.84       0.00

Из матрицы вы можете определить, какие точки находятся на расстоянии <20000 м друг от друга </p>

> dist_mat < set_units(20000, "m") & dist_mat > set_units(0, "m")
#      [,1]  [,2]  [,3]  [,4]  [,5]  [,6]
#[1,] FALSE FALSE FALSE FALSE FALSE FALSE
#[2,] FALSE FALSE FALSE FALSE FALSE FALSE
#[3,] FALSE FALSE FALSE FALSE FALSE FALSE
#[4,] FALSE FALSE FALSE FALSE FALSE FALSE
#[5,] FALSE FALSE FALSE FALSE FALSE  TRUE
#[6,] FALSE FALSE FALSE FALSE  TRUE FALSE
...