Comments (6)
That sounds like a great use-case. I haven't used the exclude_polygons
parameter, so I'll take a look. Can you post what you've tried?
from valhallr.
@jdsher I've pushed an update to GitHub that adds an option exclude_polygons
option to route()
, od_matrix()
, and sources_to_targets()
. You pass it either a tibble or a list of tibbles with lat
and lon
columns. Can you install the dev version and see if this works for you?
In short, exclude_polygons
wasn't a costing option--it was its own high-level option, and needed some specific data parsing.
Here's a reprex (if you have OSM map tiles for Ontario, and if your Valhalla instance is running on IP 192.168.2.39) that shows some sample trips across Ottawa. The first case has no restrictions, the second restricts a section of the major crosstown artery, and the third also restricts the most direct downtown route. The Leaflet maps show the route winding between the polygons, as expected.
library(tidyverse)
library(valhallr)
library(leaflet)
# set up start/stop points (university of ottawa and a sports arena)
ottawa_points <- valhallr::test_data() %>%
filter(lat > 45, lon > -78)
# set up polygons (one blocking major artery, another blocking downtown major street)
poly1 <- tibble::tribble(~lat, ~lon,
45.406729, -75.703046,
45.402346, -75.700519,
45.407185, -75.686590,
45.410834, -75.692833)
poly2 <- tibble::tribble(~lat, ~lon,
45.424620, -75.696708,
45.419283, -75.709161,
45.416166, -75.701505,
45.420895, -75.692013)
# put them in a list to pass multiple at once
e_polys <- list(poly1, poly2)
########### route()
# no exclusion
route_0 <- route(from = ottawa_points[1,],
to = ottawa_points[3,],
hostname = "192.168.2.39")
# 1 polygon passed as tibble
route_1 <- route(from = ottawa_points[1,],
to = ottawa_points[3,],
hostname = "192.168.2.39",
exclude_polygons = exclude_poly_small)
# 2 polygons passed as list
route_2 <- route(from = ottawa_points[1,],
to = ottawa_points[3,],
hostname = "192.168.2.39",
exclude_polygons = e_polys)
# inspect results
map_trip(route_0)
map_trip(route_1) %>%
addPolygons(data = exclude_poly_small, lat = ~lat, lng = ~lon)
map_trip(route_2) %>%
addPolygons(data = exclude_poly_small, lat = ~lat, lng = ~lon) %>%
addPolygons(data = poly_small_2, lat = ~lat, lng = ~lon)
########### Also testing with sources_to_targets
st_0 <- sources_to_targets(froms = ottawa_points[1,],
tos = ottawa_points[3,],
hostname = "192.168.2.39")
st_1 <- sources_to_targets(froms = ottawa_points[1,],
tos = ottawa_points[3,],
hostname = "192.168.2.39",
exclude_polygons = poly1)
st_2 <- sources_to_targets(froms = ottawa_points[1,],
tos = ottawa_points[3,],
hostname = "192.168.2.39",
exclude_polygons = e_polys)
####### Testing with od_table
# no polygons
od_0 <- od_table(froms = ottawa_points[1,],
from_id_col = "name",
tos = ottawa_points[3,],
to_id_col= "name",
hostname = "192.168.2.39")
# 1 polygon passed as tibble
od_1 <- od_table(froms = ottawa_points[1,],
from_id_col = "name",
tos = ottawa_points[3,],
to_id_col= "name",
exclude_polygons = poly1,
hostname = "192.168.2.39")
# 2 polygons passed as list
od_2 <- od_table(froms = ottawa_points[1,],
from_id_col = "name",
tos = ottawa_points[3,],
to_id_col= "name",
exclude_polygons = e_polys,
hostname = "192.168.2.39")
### Make summary table
results <- tibble(polygons = 0:2,
route = c(route_0$summary$length, route_1$summary$length, route_2$summary$length),
od_matrix = c(od_0$distance, od_1$distance, od_2$distance),
sources_to_targets = c(st_0$distance, st_1$distance, st_2$distance)
)
And the results look like this:
polygons | route | od_matrix | sources_to_targets |
---|---|---|---|
0 | 27.157 | 27.157 | 27.157 |
1 | 26.858 | 26.858 | 26.858 |
2 | 27.844 | 27.844 | 27.844 |
The table shows the results match across all 3 functions, and since we've verified the route()
function visually this looks good to me.
EDIT TO ADD: I just realized I could copy/paste images.
Downtown route, no restrictions:
Downtown route, one restriction:
Downtown route, two restrictions:
from valhallr.
Wow, that was fast! I will test the new dev version this week and report back but that seems to be a much simpler method at first glance, thankfully.
I was feeding the arguments like so:
inundation_dists <- sources_to_targets(froms = orig,
tos = dest,
minimum_reachability = 50,
hostname = host,
port = port,
costing_options = list('avoid_polygons' = '[[[-122.443993,47.220645],[-122.443993,47.289334],[-122.318552,47.289334],[-122.318552,47.220645],[-122.443993,47.220645]]]'))
So, small wonder it wasn't working in any format I suppose. Do you happen to know if the call will fail if I feed the argument a multipolygon or list of multipolygons? The Valhalla API docs seem to suggest that might be the case...
from valhallr.
Re. multipolygons, it should be possible with some wrangling. Valhalla only supports lat/lon numbers, not shapefiles, so at present you need to feed the valhallr
functions tibbles with lat
and lon
columns. I don't know if there's an elegant function in sf
to do this, but a combination of unlist()
, matrix()
, and tibble()
will probably get you there in the end.
So if you get the polygons/multipolygons into that format, you can pass od_table()
a list()
of tibbles like I did above in the example with 2 polygons.
Note that I got an error from Valhalla when I used a big polygon (circumference too long, error 167 I think)--there may be internal Valhalla settings you can adjust.
Let me know how it goes!
from valhallr.
I believe I got it working at least with a small singular polygon, but you are right: that perimeter limitation is a real drag. I've tried chopping up my large irregular multipolygons with st_intersection()
on a regular grid and then group_by %>% group_split()
, but the results don't seem quite right. Will maybe try some other methods for now, but thank you again for the quick amendments to the code!
from valhallr.
It looks like you can adjust the max polygon size if you have control over your Valhalla instance. In valhalla.json
(link to default) there's an entry called max_exclude_polygons_length
that's by default set to 10000
. Setting it to 99999999999999
(or something very big) might let you use your original polygons.
Either way good luck! I'm marking this as closed since that's now a Valhalla issue not related to the valhallr package.
If you make something neat please cite the package, and I'd love to see any public or published results.
from valhallr.
Related Issues (5)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from valhallr.