Соедините SpatialPointsDataFrame и SpatialLinesDataFrame, используя over (), R - PullRequest
0 голосов
/ 30 ноября 2018

Я застрял с чем-то, что, кажется, должно быть довольно простым.Извините, я новичок в использовании пространственных данных в R.

Я пытаюсь отобразить городские данные на карту мировых береговых линий.Я взял береговые линии из набора данных о естественной земле (https://www.naturalearthdata.com/downloads/) 1: 110 м и сгенерировал кадр данных пространственных линий:

coast_rough_sldf
class       : SpatialLinesDataFrame 
features    : 134 
extent      : -180, 180, -85.60904, 83.64513  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
variables   : 3
names       : scalerank, featurecla, min_zoom 
min values  :         0,  Coastline,      0.0 
max values  :         1,    Country,      1.5 

. У меня также есть набор данных по городам, образец котороговыглядит следующим образом:

city_coast <- data.frame(Latitude = c(-34.60842, -34.47083, -34.55848, -34.76200, -34.79658, -34.66850), 
              Longitude = c(-58.37316, -58.52861, -58.73540, -58.21130, -58.27601, -58.72825), 
              Name1 = c("Buenos Aires", "San Isidro", "San Miguel", "Berazategui", "Florencio Varela", "Merlo"), 
              distance = c(7970.091,  5313.518, 26156.700, 11670.274, 18409.738, 33880.259))
city_coast

Latitude Longitude            Name1  distance
1 -34.60842 -58.37316     Buenos Aires  7970.091
2 -34.47083 -58.52861       San Isidro  5313.518
3 -34.55848 -58.73540       San Miguel 26156.700
4 -34.76200 -58.21130      Berazategui 11670.274
5 -34.79658 -58.27601 Florencio Varela 18409.738
6 -34.66850 -58.72825            Merlo 33880.259

Затем я успешно создаю фрейм данных пространственных точек:

city_spdf <- SpatialPointsDataFrame(coords = select(city_coast, c("Longitude", "Latitude")),
                                    proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84"),
                                    data = select(city_coast, c("Name1", "distance")))

city_spdf

class       : SpatialPointsDataFrame 
features    : 6 
extent      : -58.7354, -58.2113, -34.79658, -34.47083  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
variables   : 2
names       :       Name1,  distance 
min values  : Berazategui,  5313.518 
max values  :  San Miguel, 33880.259 

Теперь я хочу объединить city_spdf с coast_sldf, чтобы я мог построить их, используя tmapГлядя на учебники, кажется, что я должен использовать over ():

city_coast_shp <- over(coast_rough_sldf, city_spdf)

city_coast_shp

Name1 distance
1  <NA>       NA

Что явно не так. Переключение порядка объектов меняет вещи, но все равно не дает мне то, что мне нужно.

Может кто-нибудь сказать мне, что я не правильно понимаю с этой функцией? В каждом примере, который я видел, просто люди присоединяются к двум пространственным объектам. Извинения, если я упускаю что-то чрезвычайно простое.

1 Ответ

0 голосов
/ 01 декабря 2018

Как @elmuertefurioso указывает в комментариях, я думаю, что одна из причин, почему это не работает так, как вы ожидаете, - это путаница типов геометрии.

Поскольку данные coastline представляют собой линии, ине полигоны, такие как data(World) из tmap, вы немного ограничены в вычислениях и сравнениях, которые вы можете провести с cities, то есть точками.

Считывание данных способом sf:

library(sf)

# downloaded from https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/110m/physical/ne_110m_coastline.zip
coastline <- read_sf("~/Downloads/ne_110m_coastline/ne_110m_coastline.shp")

cities <- data.frame(
  Latitude = c(-34.60842, -34.47083, -34.55848, -34.76200, -34.79658, -34.66850), 
  Longitude = c(-58.37316, -58.52861, -58.73540, -58.21130, -58.27601, -58.72825), 
  Name1 = c("Buenos Aires", "San Isidro", "San Miguel", "Berazategui", "Florencio Varela", "Merlo"), 
  distance = c(7970.091,  5313.518, 26156.700, 11670.274, 18409.738, 33880.259)
  )

Для сравнения объектов sf они должны иметь одинаковую систему координат.Поэтому, как мы читаем в cities, мы установим CRS равным coastline.

cities <- st_as_sf(
  cities,
  coords = c("Longitude", "Latitude"), # must be x, y order
  crs = st_crs(coastline) # must be equivilant between objects
  )

Теперь вы можете проводить сравнения, используя семейство функций st_{comparison}().

Функция over() и ее sf аналог st_intersects() будут работать с множеством точек и многоугольников, но здесь этого нет.Мы можем использовать функции расстояния, такие как st_nearest_feature() с точками и линиями, чтобы получить ближайшую геометрию из coastline для каждого города.

st_nearest_feature(cities, coastline)

Возвращает индекс строки для ближайшей геометрии в coastlines, котораяслучается, то же самое для всех городов здесь, потому что они все в Аргентине.Порядок имеет значение в функции, потому что он определяет задаваемый вопрос. Если мы перевернем его на st_nearest_feature(coastline, cities), он вернет ближайший город для каждой геометрии в coastline, поэтому в возвращении будет 134 элемента.

Всеэто означает, что на самом деле вам не нужно делать какие-либо объединения или сравнения, чтобы построить ваши точки на одном и том же tmap.

library(tmap)

tmap_mode("view")

tm_shape(coastline) +
  tm_lines() +
tm_shape(cities) +
  tm_bubbles("distance")

Я не пользователь tmap, но я просто увеличил масштабщелкнул этот снимок экрана, чтобы показать его работу.

enter image description here

...