Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tidy up and add new input dataset (#16) #17

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 23 additions & 126 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,28 @@

Overline is a function that takes overlapping linestrings and converts
them into a route network (Morgan and Lovelace 2020) as illustrated in a
minimal reproducible example below.
minimal reproducible example created with
[ATIP](https://github.com/acteng/atip/).

``` r
library(sf)
library(stplanr)
library(tidyverse)
library(tmap)
sl = routes_fast_sf[2:3, 0]
sl$n = 1:2
plot(sl)
```
The input is a dataset in which some segments overlap:

![](README_files/figure-commonmark/unnamed-chunk-1-1.png)
Reading layer `minimal_2_lines' from data source
`/home/robin/github/acteng/overline/test-data/minimal_2_lines.txt'
using driver `GeoJSON'
Simple feature collection with 2 features and 5 fields
Geometry type: LINESTRING
Dimension: XY
Bounding box: xmin: -1.29569 ymin: 50.69972 xmax: -1.295337 ymax: 50.69987
Geodetic CRS: WGS 84

``` r
rnet = overline(sl, attrib = "n")
plot(rnet)
```
![](README_files/figure-commonmark/unnamed-chunk-1-1.png)

![](README_files/figure-commonmark/unnamed-chunk-1-2.png)
The output is a dataset in which the overlapping segments have been
combined:

``` r
sf::write_sf(sl, "minimal-example-input.geojson", delete_dsn = TRUE)
sf::write_sf(rnet, "minimal-example-output.geojson", delete_dsn = TRUE)
```
![](README_files/figure-commonmark/unnamed-chunk-2-1.png)

The function has been implemented in the [`overline()`
The functionality has been implemented in the [`overline()`
function](https://docs.ropensci.org/stplanr/reference/overline.html) in
the R package `stplanr`. The function works fine for city sized datasets
but for national datasets is slow, buggy and not feature complete, as it
Expand All @@ -41,129 +36,31 @@ In Python, the input and outputs can be visualised as follows:
``` python
import geopandas as gpd
input = gpd.read_file("input.geojson")
input.plot()
# Plot with colour by value:
input.plot(column="value")
```

![](README_files/figure-commonmark/unnamed-chunk-3-1.png)

``` python
output = gpd.read_file("output.geojson")
output.plot()
output.plot(column="value")
```

![](README_files/figure-commonmark/unnamed-chunk-3-3.png)
![](README_files/figure-commonmark/unnamed-chunk-4-3.png)

# Example with road names

The example below takes routes at the segment level and calculates
average gradient for each segment. Road names are NOT currently
implemented in `overline()` in R.

``` r
sl_desire_lines = stplanr::flowlines_sf[2:3, ]
qtm(sl_desire_lines) +
qtm(sl)
```

![](README_files/figure-commonmark/unnamed-chunk-2-1.png)

``` r
route_segments_minimal = stplanr::route(
l = sl_desire_lines,
route_fun = cyclestreets::journey
)
```

Most common output is sf

``` r
names(route_segments_minimal)
```

[1] "Area.of.residence"
[2] "Area.of.workplace"
[3] "All"
[4] "Work.mainly.at.or.from.home"
[5] "Underground..metro..light.rail..tram"
[6] "Train"
[7] "Bus..minibus.or.coach"
[8] "Taxi"
[9] "Motorcycle..scooter.or.moped"
[10] "Driving.a.car.or.van"
[11] "Passenger.in.a.car.or.van"
[12] "Bicycle"
[13] "On.foot"
[14] "Other.method.of.travel.to.work"
[15] "id"
[16] "route_number"
[17] "name"
[18] "distances"
[19] "time"
[20] "busynance"
[21] "elevations"
[22] "start_longitude"
[23] "start_latitude"
[24] "finish_longitude"
[25] "finish_latitude"
[26] "crow_fly_distance"
[27] "event"
[28] "whence"
[29] "speed"
[30] "itinerary"
[31] "plan"
[32] "note"
[33] "length"
[34] "quietness"
[35] "west"
[36] "south"
[37] "east"
[38] "north"
[39] "leaving"
[40] "arriving"
[41] "grammesCO2saved"
[42] "calories"
[43] "edition"
[44] "gradient_segment"
[45] "elevation_change"
[46] "provisionName"
[47] "gradient_smooth"
[48] "geometry"

``` r
tm_shape(route_segments_minimal) +
tm_lines("name")
```

![](README_files/figure-commonmark/unnamed-chunk-2-2.png)

``` r
rnet_from_cyclestreets = overline(
route_segments_minimal,
attrib = c("All", "gradient_smooth", "quietness"),
fun = c(sum = sum, mean = mean)
)
rnet_from_cyclestreets = rnet_from_cyclestreets %>%
transmute(All = All_sum, Gradient = gradient_smooth_mean, Quietness = quietness_mean)
plot(rnet_from_cyclestreets)
```

![](README_files/figure-commonmark/unnamed-chunk-2-3.png)

``` r
sf::write_sf(route_segments_minimal, "route_segments_minimal.geojson", delete_dsn = TRUE)
sf::write_sf(rnet_from_cyclestreets, "rnet_from_cyclestreets.geojson", delete_dsn = TRUE)
```
![](README_files/figure-commonmark/rnet_from_cyclestreets-5.png)

# Large example

A large example plus benchmark is shown below:

``` r
# list.files()
cycle_routes_london = pct::get_pct_routes_fast("london")
sf::write_sf(cycle_routes_london, "cycle_routes_london.geojson")
zip("cycle_routes_london.zip", "cycle_routes_london.geojson")
system("gh release upload v0 cycle_routes_london.zip")
```

``` r
system.time({
cycle_routes_london = geojsonsf::geojson_sf("cycle_routes_london.geojson")
Expand Down
66 changes: 41 additions & 25 deletions README.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,79 @@ bibliography: references.bib

# overline

Overline is a function that takes overlapping linestrings and converts them into a route network [@morgan2020] as illustrated in a minimal reproducible example below.
Overline is a function that takes overlapping linestrings and converts them into a route network [@morgan2020] as illustrated in a minimal reproducible example created with [ATIP](https://github.com/acteng/atip/).

```{r, message=FALSE}
library(sf)
library(stplanr)
The input is a dataset in which some segments overlap:

```{r, message=FALSE, echo=FALSE}
library(tidyverse)
library(tmap)
sl = routes_fast_sf[2:3, 0]
sl$n = 1:2
plot(sl)
rnet = overline(sl, attrib = "n")
plot(rnet)
sf::write_sf(sl, "minimal-example-input.geojson", delete_dsn = TRUE)
sf::write_sf(rnet, "minimal-example-output.geojson", delete_dsn = TRUE)
library(stplanr)
layers = sf::st_layers("test-data/minimal_2_lines.txt")
minimal_2_lines = sf::st_read("test-data/minimal_2_lines.txt", layer = layers[[1]])
minimal_2_lines = minimal_2_lines %>%
transmute(value = c(2, 1), name = c("A", "B"))
sf::write_sf(minimal_2_lines, "input.geojson", delete_dsn = TRUE)
tm_shape(minimal_2_lines) +
tm_lines("name", palette = "Set1", lwd = "value", scale = 9)
```

The output is a dataset in which the overlapping segments have been combined:

```{r, message=FALSE, echo=FALSE}
minimal_2_rnet = overline(minimal_2_lines, attrib = "value")
tm_shape(minimal_2_rnet) +
tm_lines("value", palette = "Set1", lwd = "value", scale = 15)
sf::write_sf(minimal_2_rnet, "output.geojson", delete_dsn = TRUE)
```

The function has been implemented in the [`overline()` function](https://docs.ropensci.org/stplanr/reference/overline.html) in the R package `stplanr`. The function works fine for city sized datasets but for national datasets is slow, buggy and not feature complete, as it does not retain OSM IDs. This repo provides a place to discuss and develop example code to solve this problem.
The functionality has been implemented in the [`overline()` function](https://docs.ropensci.org/stplanr/reference/overline.html) in the R package `stplanr`. The function works fine for city sized datasets but for national datasets is slow, buggy and not feature complete, as it does not retain OSM IDs. This repo provides a place to discuss and develop example code to solve this problem.

In Python, the input and outputs can be visualised as follows:

```python
```{python}
import geopandas as gpd
input = gpd.read_file("input.geojson")
input.plot()
# Plot with colour by value:
input.plot(column="value")
```

```python
```{python}
output = gpd.read_file("output.geojson")
output.plot()
output.plot(column="value")
```
![](README_files/figure-commonmark/unnamed-chunk-3-3.png)


# Example with road names

The example below takes routes at the segment level and calculates average gradient for each segment. Road names are NOT currently implemented in `overline()` in R.

```{r}
```{r rnet_from_cyclestreets, message=FALSE, echo=FALSE}
sl_desire_lines = stplanr::flowlines_sf[2:3, ]
qtm(sl_desire_lines) +
qtm(sl)
# qtm(sl_desire_lines) +
# qtm(sl)
route_segments_minimal = stplanr::route(
l = sl_desire_lines,
route_fun = cyclestreets::journey
)
names(route_segments_minimal)
tm_shape(route_segments_minimal) +
tm_lines("name")
# names(route_segments_minimal)
route_segments_minimal = route_segments_minimal %>%
transmute(All = All, name = name, gradient_smooth = gradient_smooth, quietness = quietness)
rnet_from_cyclestreets = overline(
route_segments_minimal,
attrib = c("All", "gradient_smooth", "quietness"),
fun = c(sum = sum, mean = mean)
)
rnet_from_cyclestreets = rnet_from_cyclestreets %>%
transmute(All = All_sum, Gradient = gradient_smooth_mean, Quietness = quietness_mean)
plot(rnet_from_cyclestreets)
sf::write_sf(route_segments_minimal, "route_segments_minimal.geojson", delete_dsn = TRUE)
sf::write_sf(rnet_from_cyclestreets, "rnet_from_cyclestreets.geojson", delete_dsn = TRUE)
m1 = tm_shape(route_segments_minimal) +
tm_lines("name", lwd = "All", palette = "Set1", scale = 15) +
tm_layout(legend.outside = TRUE)
m2 = tm_shape(rnet_from_cyclestreets) +
tm_lines(lwd = "All", palette = "viridis", scale = 20) +
tm_layout(legend.outside = TRUE)
tmap_arrange(m1, m2)
```

# Large example
Expand All @@ -71,6 +86,7 @@ A large example plus benchmark is shown below:

```{r}
#| eval: false
#| echo: false
# list.files()
cycle_routes_london = pct::get_pct_routes_fast("london")
sf::write_sf(cycle_routes_london, "cycle_routes_london.geojson")
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified README_files/figure-commonmark/unnamed-chunk-1-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed README_files/figure-commonmark/unnamed-chunk-1-2.png
Binary file not shown.
Binary file modified README_files/figure-commonmark/unnamed-chunk-2-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file removed README_files/figure-commonmark/unnamed-chunk-2-3.png
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading