sc_filter
Mike,
I'm jumping ahead of myself just a little here, but as soon as osmdata_sc() is finished, dodgr is going to need some kind of sc_filter() function. The whole purpose of silicate is to take advantage of the power of dplyr-type filter (join, ...) verbs. While this is pretty easy to implement with a few lines of code, I can see a case for a generic sc_filter() function to ease general use.
Imagine:
pts <- st_multipoint (matrix(1:10, , 2))
mp <- st_sfc (pts, pts) %>% st_sf (data = 7:8)
s <- SC (mp)
s %>% sc_filter (vertex %in% bbox)
s %>% sc_filter (data <= 7)
And note especially that it will often be necessary / supremely cool to implement recursive filtering. Consider a slightly more complex example
> pts1 <- st_multipoint (matrix(1:10, , 2))
> pts2 <- st_multipoint (matrix(3:13, , 2))
> pts3 <- st_multipoint (matrix(3:13, , 2))
> mp <- st_sfc (pts1, pts2) %>% st_sf (data = 7:9)
> s <- SC (mp)
> s %>% sc_filter (vertex %in% c (2, 7, 4, 10)) # interpret operand as a bbox
> s
$object
# A tibble: 2 x 2
data object_
* <int> <chr>
1 7 02b0ccbb7e
2 8 706a1c35e7
$object_link_edge
# A tibble: 16 x 2
edge_ object_
<chr> <chr>
1 ec72d5c2bb 02b0ccbb7e
2 9d856f76f2 02b0ccbb7e
3 711217a8a7 02b0ccbb7e
4 4cf1076ebc 02b0ccbb7e
5 d18e7c98cc 02b0ccbb7e
6 d71176486b 706a1c35e7
7 c32facc994 706a1c35e7
8 1be4cc0e41 706a1c35e7
9 2343fe725f 706a1c35e7
10 b7263464b4 706a1c35e7
11 afc82431e8 706a1c35e7
$edge
# A tibble: 16 x 3
.vertex0 .vertex1 edge_
<chr> <chr> <chr>
1 289d4aca53 289d4aca53 ec72d5c2bb
2 c2330e9dc7 c2330e9dc7 9d856f76f2
3 c8bb154a6a c8bb154a6a 711217a8a7
4 2ab381ff00 2ab381ff00 4cf1076ebc
5 5c9f1f521d 5c9f1f521d d18e7c98cc
6 848271ad14 848271ad14 d71176486b
7 a94890b816 a94890b816 c32facc994
8 012eb88470 012eb88470 1be4cc0e41
9 ac4f870999 ac4f870999 2343fe725f
10 1e75de6a00 1e75de6a00 b7263464b4
11 97af153d2c 97af153d2c afc82431e8
$vertex [7/143]
# A tibble: 16 x 3
x_ y_ vertex_
<int> <int> <chr>
1 1 6 289d4aca53
2 2 7 c2330e9dc7
3 3 8 c8bb154a6a
4 4 9 2ab381ff00
5 5 10 5c9f1f521d
6 2 8 848271ad14
7 3 9 a94890b816
8 4 10 012eb88470
9 5 11 ac4f870999
10 6 12 1e75de6a00
11 7 13 97af153d2c
$meta
# A tibble: 1 x 2
proj ctime
<chr> <chr>
1 NA 2018-10-29 14:36:40
attr(,"join_ramp")
[1] "object" "object_link_edge" "edge" "vertex"
attr(,"class")
[1] "SC" "sc"
The filtering in that case is first done by filtering all vertices in that bbox, then using those to (re-)filter all higher-level objects that include those vertices. I suspect that that kind of operation will find very general use (and is certainly something that I desperately need), yet is not really so trivial to implement by hand-coding the dplyr::filter() lines of code oneself. What do you think?
My current osmdata_sc() is just going in the master branch because it's all new code with neither overlap nor conflict, but I reckon as soon as that's done I'll start a branch to start exploring ideas like this. I could use that to sketch out a basic implementation of sc_filter() for your perusal if that would help.
It's definitely not too early, I had these filter propagators to push a filter through the tables:
https://github.com/hypertidy/silicate/blob/9956caf4aa60a0ba00cc1b619c3067b6c631e84c/R/SC-model.R#L148-L176
That worked great for PATH, and for edges with link tables - because you don't have to match .vx0 and .vx1 to vertex_,.
If you inner_join with reduce the idea was you would get an equivalent to the output of fortify, but the "semi cascade" thing means "propagate the filter but keep all tables".
Example
library(osmdata)
dat <- opq ("hobart au") %>%
add_osm_feature ("highway") %>%
osmdata_sc()
library(silicate)
plot(filter(dat, key == "maxspeed" & value > 50))

That is fabulous!