R:sfnetworks:如何在同一数据集中查找多个 A 和 B 位置之间的路线
R: sfnetworks: How to find routes between multiple A and B locations in a same dataset
这是我的数据集
df<-tribble(
~"shop.x",~"shop.y", ~"cust.x", ~"cust.y",
78.100378, 9.944226, 78.096318, 9.954789,
78.101155, 9.932190, 78.089824, 9.929975,
78.141887, 9.928319, 78.110863, 9.952235,
78.100381, 9.944226, 78.104066, 9.97013,
78.097206, 9.948872, 78.11631, 9.947862
)
df 数据集包含商店和顾客的位置。
我想在 R 中使用 OSM 地图为每一行(每个商店到客户位置)创建最短路径路线。是否可以使用 sfnetworks?
本地路网数据为here
首先,由于此数据框主要包含商店和客户的 X 和 Y 坐标,我将它们转换为 sf
对象。每组两个对象。
# Load packages
library(tidyverse)
library(sf)
library(sfnetworks)
library(tidygraph)
# Load the data
df <- tribble(
~"shop.x",~"shop.y", ~"cust.x", ~"cust.y",
78.100378, 9.944226, 78.096318, 9.954789,
78.101155, 9.932190, 78.089824, 9.929975,
78.141887, 9.928319, 78.110863, 9.952235,
78.100381, 9.944226, 78.104066, 9.97013,
78.097206, 9.948872, 78.11631, 9.947862
)
# Convert into sf objects
shop = st_as_sf(df[,1:2], crs = 4326, coords = c("shop.x", "shop.y"))
cust = st_as_sf(df[,3:4], crs = 4326, coords = c("cust.x", "cust.y"))
道路是LINESTRINGS
,可以转换成sfnetwork
对象。网络需要清理。有关如何进行网络预处理的更多信息 here。
## I downloaded the data attached and saved it locally
roads_dir = "data/roads.shp"
roads = st_read(roads_dir, crs = 4326)
#> Reading layer `Roads' from data source
#> Simple feature collection with 6915 features and 0 fields
#> Geometry type: LINESTRING
#> Dimension: XY
#> Bounding box: xmin: 78.0217 ymin: 9.832762 xmax: 78.22482 ymax: 10.04193
#> Geodetic CRS: WGS 84
# Convert into an sfnetwork
roads_sfn = as_sfnetwork(roads, directed = FALSE)
# Do some network cleaning
roads_clean = roads_sfn %>%
convert(to_spatial_subdivision, .clean = TRUE) %>%
convert(to_spatial_smooth, .clean = TRUE)
要计算路径,我们可以对 st_network_paths()
函数使用 mapply 函数,将 from 参数传递给商店的位置,将 to 参数传递给客户的位置。因此,路径是按顺序为每个组合计算的。
# Calculate the specified paths.
paths = mapply(
st_network_paths,
from = shop,
to = cust,
MoreArgs = list(x = roads_clean)
)["node_paths", ] %>%
unlist(recursive = FALSE)
#> although coordinates are longitude/latitude, st_nearest_points assumes that they are planar
#> although coordinates are longitude/latitude, st_nearest_points assumes that they are planar
#> Warning: Although argument from has length > 1, only the first element is used
输出是一个包含五个元素的列表,其中包含每条路线的节点索引,对应于原始网络中的节点。
paths[[1]]
#> [1] 1842 1843 12191 12190 232 7977 7843 12174 8244 8205 7914 8139
#> [13] 8209 7958 7957 8229 8230 8328
如果我们想得到路径作为网络本身,我们可以将原始网络切片为:
roads_clean %>%
activate("nodes") %>%
slice(paths[[1]])
#> # A sfnetwork with 18 nodes and 17 edges
#> #
#> # CRS: EPSG:4326
#> #
#> # An unrooted tree with spatially explicit edges
#> #
#> # Node Data: 18 x 1 (active)
#> # Geometry type: POINT
#> # Dimension: XY
#> # Bounding box: xmin: 78.09568 ymin: 9.943727 xmax: 78.10051 ymax: 9.955158
#> geometry
#> <POINT [°]>
#> 1 (78.10001 9.946228)
#> 2 (78.10051 9.943727)
#> 3 (78.10017 9.945039)
#> 4 (78.09918 9.951894)
#> 5 (78.09895 9.953372)
#> 6 (78.09647 9.955099)
#> # ... with 12 more rows
#> #
#> # Edge Data: 17 x 3
#> # Geometry type: LINESTRING
#> # Dimension: XY
#> # Bounding box: xmin: 78.09568 ymin: 9.943727 xmax: 78.10051 ymax: 9.955158
#> from to geometry
#> <int> <int> <LINESTRING [°]>
#> 1 2 3 (78.10051 9.943727, 78.10029 9.944423, 78.10017 9.945039)
#> 2 6 7 (78.09647 9.955099, 78.09877 9.954435)
#> 3 12 13 (78.09569 9.955158, 78.09568 9.954763)
#> # ... with 14 more rows
这是我的数据集
df<-tribble(
~"shop.x",~"shop.y", ~"cust.x", ~"cust.y",
78.100378, 9.944226, 78.096318, 9.954789,
78.101155, 9.932190, 78.089824, 9.929975,
78.141887, 9.928319, 78.110863, 9.952235,
78.100381, 9.944226, 78.104066, 9.97013,
78.097206, 9.948872, 78.11631, 9.947862
)
df 数据集包含商店和顾客的位置。
我想在 R 中使用 OSM 地图为每一行(每个商店到客户位置)创建最短路径路线。是否可以使用 sfnetworks?
本地路网数据为here
首先,由于此数据框主要包含商店和客户的 X 和 Y 坐标,我将它们转换为 sf
对象。每组两个对象。
# Load packages
library(tidyverse)
library(sf)
library(sfnetworks)
library(tidygraph)
# Load the data
df <- tribble(
~"shop.x",~"shop.y", ~"cust.x", ~"cust.y",
78.100378, 9.944226, 78.096318, 9.954789,
78.101155, 9.932190, 78.089824, 9.929975,
78.141887, 9.928319, 78.110863, 9.952235,
78.100381, 9.944226, 78.104066, 9.97013,
78.097206, 9.948872, 78.11631, 9.947862
)
# Convert into sf objects
shop = st_as_sf(df[,1:2], crs = 4326, coords = c("shop.x", "shop.y"))
cust = st_as_sf(df[,3:4], crs = 4326, coords = c("cust.x", "cust.y"))
道路是LINESTRINGS
,可以转换成sfnetwork
对象。网络需要清理。有关如何进行网络预处理的更多信息 here。
## I downloaded the data attached and saved it locally
roads_dir = "data/roads.shp"
roads = st_read(roads_dir, crs = 4326)
#> Reading layer `Roads' from data source
#> Simple feature collection with 6915 features and 0 fields
#> Geometry type: LINESTRING
#> Dimension: XY
#> Bounding box: xmin: 78.0217 ymin: 9.832762 xmax: 78.22482 ymax: 10.04193
#> Geodetic CRS: WGS 84
# Convert into an sfnetwork
roads_sfn = as_sfnetwork(roads, directed = FALSE)
# Do some network cleaning
roads_clean = roads_sfn %>%
convert(to_spatial_subdivision, .clean = TRUE) %>%
convert(to_spatial_smooth, .clean = TRUE)
要计算路径,我们可以对 st_network_paths()
函数使用 mapply 函数,将 from 参数传递给商店的位置,将 to 参数传递给客户的位置。因此,路径是按顺序为每个组合计算的。
# Calculate the specified paths.
paths = mapply(
st_network_paths,
from = shop,
to = cust,
MoreArgs = list(x = roads_clean)
)["node_paths", ] %>%
unlist(recursive = FALSE)
#> although coordinates are longitude/latitude, st_nearest_points assumes that they are planar
#> although coordinates are longitude/latitude, st_nearest_points assumes that they are planar
#> Warning: Although argument from has length > 1, only the first element is used
输出是一个包含五个元素的列表,其中包含每条路线的节点索引,对应于原始网络中的节点。
paths[[1]]
#> [1] 1842 1843 12191 12190 232 7977 7843 12174 8244 8205 7914 8139
#> [13] 8209 7958 7957 8229 8230 8328
如果我们想得到路径作为网络本身,我们可以将原始网络切片为:
roads_clean %>%
activate("nodes") %>%
slice(paths[[1]])
#> # A sfnetwork with 18 nodes and 17 edges
#> #
#> # CRS: EPSG:4326
#> #
#> # An unrooted tree with spatially explicit edges
#> #
#> # Node Data: 18 x 1 (active)
#> # Geometry type: POINT
#> # Dimension: XY
#> # Bounding box: xmin: 78.09568 ymin: 9.943727 xmax: 78.10051 ymax: 9.955158
#> geometry
#> <POINT [°]>
#> 1 (78.10001 9.946228)
#> 2 (78.10051 9.943727)
#> 3 (78.10017 9.945039)
#> 4 (78.09918 9.951894)
#> 5 (78.09895 9.953372)
#> 6 (78.09647 9.955099)
#> # ... with 12 more rows
#> #
#> # Edge Data: 17 x 3
#> # Geometry type: LINESTRING
#> # Dimension: XY
#> # Bounding box: xmin: 78.09568 ymin: 9.943727 xmax: 78.10051 ymax: 9.955158
#> from to geometry
#> <int> <int> <LINESTRING [°]>
#> 1 2 3 (78.10051 9.943727, 78.10029 9.944423, 78.10017 9.945039)
#> 2 6 7 (78.09647 9.955099, 78.09877 9.954435)
#> 3 12 13 (78.09569 9.955158, 78.09568 9.954763)
#> # ... with 14 more rows