sta*_*oob 3 r geospatial shapefile
我有兴趣学习如何在 R 中使用道路网络文件。
例如,我有兴趣找出以下两个(加拿大)地址之间的驾驶距离:
过去,我会使用 OpenStreetMap (OSM) 等 API:
library(tmap)
library(tmaptools)
remotes::install_github("riatelab/osrm")
q1 = geocode_OSM("6301 Silver Dart Dr, Mississauga, ON L5P 1B2")
q2 = geocode_OSM("290 Bremner Blvd, Toronto, ON M5V 3L9")
q1 = as.numeric(q1$coords)
q2 = as.numeric(q2$coords)
q1_lat = q1[1]
q1_long = q1[2]
q2_lat = q2[1]
q2_long = q2[2]
route = osrmRoute(src = c(q1[1], q1[2]) , dst = c(q2[1], q2[2]), osrm.profile = "car")
> route$distance
[1] 26.2836
Run Code Online (Sandbox Code Playgroud)
正如我们在这里看到的,这两点之间的行驶距离是 26.2 KM(这与从 Google 地图获得的距离非常接近)
我的问题:我现在想尝试使用道路网络文件做类似的事情。
例如,我发现以下文件包含有关道路网络的信息(https://www12.statcan.gc.ca/census-recensement/2021/geo/sip-pis/rnf-frr/index2021-eng.cfm?年=21)。然后我以 .shp 格式(即 shapefile)将其下载到我的计算机上。
基于这样一份路网文件,是否可以找出任意两个地址之间的“行驶距离”(无论是“语言地址”还是地理坐标)?
谢谢!
注意:此文件似乎相当大,我不确定我的计算机是否可以完全加载它 - 是否可以命令计算机仅导入此文件的较小部分?(例如,导入省份=安大略省,导入城市=多伦多)
是的,您可以下载地图并根据这些文件中有关道路网络的信息计算距离。您已经在使用osrmR 包。这会将请求发送到远程演示服务器,该服务器正是这样做的。然而,包文档指出,
OSRM 演示服务器不允许大型查询(超过 10000 个距离或持续时间)。
相反,您可以安装osrm-backend一个用 C++ 编写的高性能路由引擎。这将允许您根据您提供的地图设置自己的路由服务器。然后,您可以从 R 内部向本地服务器发出与上述相同的请求,没有速率限制。
您可能是正确的,您无法在标准 PC 上轻松构建整个加拿大地图。如果您设置了交换文件,您也许可以,但可能需要很长时间(几小时到几天)。我使用了较小的地图,即由 geofabrik 托管的安大略省开放街道地图数据。您可以在这里下载其他地区的。
最简单的方法是使用 OSRM docker 镜像。安装docker后,以下命令将下载安大略数据和 docker 镜像,并启动服务器。以下内容将在终端中输入,而不是在 R 中输入。这应该适用于 Windows(在 PowerShell 中)、Mac 或 Linux。
# Download the map - may take about 15 mins - from https://download.geofabrik.de/north-america/canada/ontario.html
wget -O ontario-latest.osm.pbf https://download.geofabrik.de/north-america/canada/ontario-latest.osm.pbf
# May take 5-10 mins to download the Docker image the first time
docker run -t -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-extract -p /opt/car.lua /data/ontario-latest.osm.pbf || "osrm-extract failed"
docker run -t -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-partition /data/ontario-latest.osm.pbf || "osrm-partition failed"
docker run -t -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-customize /data/ontario-latest.osm.pbf || "osrm-customize failed"
# Run the image
docker run -t -i -p 5000:5000 -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-routed --algorithm mld /data/ontario-latest.osrm
Run Code Online (Sandbox Code Playgroud)
这将在端口 5000 上启动路由引擎 HTTP 服务器。您应该看到类似以下内容的输出:
[2023-03-27T18:04:02.703986704] [info] starting up engines, v5.27.1
[2023-03-27T18:04:02.704179704] [info] Threads: 8
[2023-03-27T18:04:02.704216504] [info] IP address: 0.0.0.0
[2023-03-27T18:04:02.704250504] [info] IP port: 5000
[2023-03-27T18:04:07.973464309] [info] http 1.1 compression handled by zlib version 1.2.11
[2023-03-27T18:04:07.973828509] [info] Listening on: 0.0.0.0:5000
[2023-03-27T18:04:07.973957909] [info] running and waiting for requests
Run Code Online (Sandbox Code Playgroud)
然后您可以从 R 查询。
重要的是将您的主机设置osrm.server为本地主机:
library(osrm)
options("osrm.server" = "http://127.0.0.1:5000/")
options("osrm.profile" = "car") # Easiest to set this here as well
Run Code Online (Sandbox Code Playgroud)
使用您问题中的示例坐标,我们可以这样做:
osrmRoute(src = src, dst = dst)
# Simple feature collection with 1 feature and 4 fields
# Geometry type: LINESTRING
# Dimension: XY
# Bounding box: xmin: -79.6122 ymin: 43.61352 xmax: -79.38643 ymax: 43.68883
# Geodetic CRS: WGS 84
# src dst duration distance geometry
# 1_1 1 1 23.25667 26.2836 LINESTRING (-79.61214 43.68...
Run Code Online (Sandbox Code Playgroud)
对于多个坐标,您还可以使用osrmTable():
[2023-03-27T18:04:02.703986704] [info] starting up engines, v5.27.1
[2023-03-27T18:04:02.704179704] [info] Threads: 8
[2023-03-27T18:04:02.704216504] [info] IP address: 0.0.0.0
[2023-03-27T18:04:02.704250504] [info] IP port: 5000
[2023-03-27T18:04:07.973464309] [info] http 1.1 compression handled by zlib version 1.2.11
[2023-03-27T18:04:07.973828509] [info] Listening on: 0.0.0.0:5000
[2023-03-27T18:04:07.973957909] [info] running and waiting for requests
Run Code Online (Sandbox Code Playgroud)
一旦你停止了 osrm 服务器 Docker 容器,你只需要最后一行就可以再次运行它,即
docker run -t -i -p 5000:5000 -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-routed --algorithm mld /data/ontario-latest.osrm
Run Code Online (Sandbox Code Playgroud)
如果你有大量的坐标对,你可能会碰到这个max-table-size参数。您可以通过将其作为参数传递给 来增加此值docker run,例如:
docker run -t -i -p 5000:5000 -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-routed --algorithm mld --max-table-size 100000 /data/ontario-latest.osrm
Run Code Online (Sandbox Code Playgroud)
您问题的第二部分是关于将地址反向地理编码为纬度/经度。这是一个完全不同的问题,我不会在这里尝试回答它。然而,好消息是 Nominatim 有一个docker镜像,它是在后台查询的(同样有速率限制)。tmaptools::geocode_OSM()您可以以类似的方式安装它 - 如果遇到问题,请询问另一个问题。