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

Interpolation function for finding total corridor width #28

Open
Robinlovelace opened this issue Jan 6, 2025 · 29 comments
Open

Interpolation function for finding total corridor width #28

Robinlovelace opened this issue Jan 6, 2025 · 29 comments

Comments

@Robinlovelace
Copy link
Contributor

Full description + reprex incoming. I think this is an ideal use case highlighting the flexibility of anime so should lead to good docs + content for write-up.

@JosiahParry
Copy link
Owner

A reprex would really help! This is like Latin to me lol!

@Robinlovelace
Copy link
Contributor Author

Illustration as a taster, fully reproducible but let me create a tidy example that generates this plot:

image

@Robinlovelace
Copy link
Contributor Author

Robinlovelace commented Jan 6, 2025

Reprex with input data. Geo challenge (sounds simple): find the widths of the target geometries based only on the source roads:

net_target = sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_target.gpkg")
net_source = sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_source.gpkg")
plot(net_target)

plot(net_source["width"])

Created on 2025-01-06 with reprex v2.1.1

@Robinlovelace
Copy link
Contributor Author

Robinlovelace commented Jan 6, 2025

@wangzhao and I have a slow solution that answers the question with rnet::join() and some post-processing. Can share that, and can have a bash with anime (already have on larger datasets, which show that {anime} is very fast and good at finding the average values with interpolate_intensive())

The answer is not quite the average: when the centerline target geoms have 2 lanes in the source the values should be summed (the value returned by interpolate_intensive() are half the correct width). This can be done using the shared_len outputs in anime objects I think but have not figured out how. I sense a function, e.g. interpolate_widths() (or more general name) coming on. Need to do nursery run now but can provide more info a bit later..

@JosiahParry
Copy link
Owner

JosiahParry commented Jan 6, 2025 via email

@Robinlovelace
Copy link
Contributor Author

Already tried. I'll provide a follow-up reprex with that plus more attempts. interpolate_extensive() then dividing by the lengths could be a good way forward.

@Robinlovelace
Copy link
Contributor Author

Robinlovelace commented Jan 6, 2025

Reprex:

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
net_target = sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_target.gpkg")
net_source = sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_source.gpkg") |>
  sf::st_cast("LINESTRING")
#> Warning in
#> st_cast.sf(sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_source.gpkg"),
#> : repeating attributes for all sub-geometries for which they may not be
#> constant
# plot(net_target)
# plot(net_source["width"])

matches = anime::anime(
  source = net_source, 
  target = net_target, 
  angle_tolerance = 35, 
  distance_tolerance = 10
)
widths_interpolated = net_source |> 
  reframe(width_intensive = anime::interpolate_intensive(width, matches))

widths_extensive = net_source |> 
  reframe(width_extensive = anime::interpolate_extensive(width, matches))

net_joined = bind_cols(net_target, widths_interpolated)
net_joined = bind_cols(net_joined, widths_extensive)
net_joined$diff = net_joined$width_extensive - net_joined$width_intensive

mapview::mapview(net_joined, zcol = "diff") +
  mapview::mapview(net_source, zcol = "width")
#> file:////tmp/Rtmp85U4F6/file19c826a8d1244/widget19c82524a847a.html screenshot completed

Created on 2025-01-06 with reprex v2.1.1

@Robinlovelace
Copy link
Contributor Author

Robinlovelace commented Jan 6, 2025

Neither approach is right but interpolate_intensive() is closer. As shown when you zoom into George Street, for example, the values are way too large for interpolate_extensive(). The values returned by interpolate_intensive() are correct for linestrings with only one match in the source object but half what they should be when the corridor is composed of 2 source linestrings (the fact that some targets are made of 2 sources should be revealed in the anime object):

image

The centerline in the target object is composed of 2 roads in the source object, with values of 8 and 9 m. So the total width should be 17m. The rnet_join() based solution gets that value, can create another reprex to demo, which may show how to use the raw output of anime(), including the valuable shared_len values, to get to the right answer. Make sense?

@Robinlovelace Robinlovelace changed the title Interpolation function for finding total corridor width, with 1 or more lanes Interpolation function for finding total corridor width Jan 6, 2025
@Robinlovelace
Copy link
Contributor Author

Robinlovelace commented Jan 6, 2025

The issue with the extensive interpolation, I think, is that small sections have just as much an influence on the value returned as long sections. We can work out the correct width based on

sum(source_values * source_lengths) / target_length

@JosiahParry
Copy link
Owner

I'm not following why you would multiple the value by the length that would make some incredibly large numbers in some cases.

The idea is that the value is equally distributed across the length of the source line and we're summing only the shared portion of that line.

I think it may be handy to see the overlapping bounding boxes that are matched. Would you mind making an issue for that? I can work on a function that would be helpful for debugging these questions.

I actually think the extensive value may be closer to correct than maybe you think? Partially because of the very forgiving angle tolerance you've provided which is picking up the roundabouts.

George has an interpolated value of 30ish. The parallel line south has a value of 8, about all of which should be matched. North of it has 9. Then the northeastern roundabout has a value of 7 (which based on the angle tolerance might be matched almost entirely? hard to know without overlaying bounding boxes)

image

Then south west has a value of 6
image

and northwest has a value of 7

image

Adding all of that up gives us a value of 8 + 9 + 7 + 6 + 7 = 37 now, assuming not everything is a 100% match that seems to be in the right ballpark

@Robinlovelace
Copy link
Contributor Author

George Street has a value of 16.3 according to the rnet_join() method we're using currently:

image

# Solution with rnet_join
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
net_target = sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_target.gpkg")
net_source = sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_source.gpkg") |>
  sf::st_cast("LINESTRING")
#> Warning in
#> st_cast.sf(sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_source.gpkg"),
#> : repeating attributes for all sub-geometries for which they may not be
#> constant
library(stplanr)
net_target$length = sf::st_length(net_target) |>
  as.numeric()
target_joined_rnet = stplanr::rnet_join(
  net_target, 
  net_source, 
  max_angle_diff  = 35, 
  dist            = 10, 
  segment_length  = 10, 
  subset_x        = TRUE, 
  crop            = TRUE
)
#> Warning: attribute variables are assumed to be spatially constant throughout
#> all geometries
#> Warning in st_cast.sf(sf::st_cast(x, "MULTILINESTRING"), "LINESTRING"):
#> repeating attributes for all sub-geometries for which they may not be constant
#> Joining with `by = join_by(id)`
#> Linking to GEOS 3.12.1, GDAL 3.8.4, PROJ 9.3.1; sf_use_s2() is TRUE
#> Warning: st_centroid assumes attributes are constant over geometries
target_joined = dplyr::left_join(
    target_joined_rnet,
    net_target |>
      sf::st_drop_geometry(),
    by = "id"
  )

widths = target_joined |>
  sf::st_drop_geometry() |>
  dplyr::group_by(id) |>
  dplyr::mutate(
    total_length_y   = sum(length_y, na.rm = TRUE),
    length_x_updated = if_else(total_length_y < length, total_length_y, length)
  ) |>
  dplyr::transmute(
    id,
    width = width * length_y / length_x_updated
  ) |>
    dplyr::summarise(avg_road_width = round(sum(width, na.rm = TRUE),2))
net_target_final = dplyr::left_join(
  net_target,
  widths,
  by = "id"
)

mapview::mapview(net_target_final, zcol = "avg_road_width")  
#> file:////tmp/Rtmp9X7zk5/file200095f6ea2e7/widget200097defb16a.html screenshot completed

Created on 2025-01-06 with reprex v2.1.1

@Robinlovelace
Copy link
Contributor Author

Adding all of that up gives us a value of 8 + 9 + 7 + 6 + 7 = 37 now, assuming not everything is a 100% match that seems to be in the right ballpark

Maybe but wouldn't that result change depending on how many short linestrings there that match?

One could make the answer 100+ just by having many 1 mm linestrings anywhere along the line, for example.

@Robinlovelace
Copy link
Contributor Author

George has an interpolated value of 30ish.

It would if there were 5 parallel lines with a value of 6 matching all the way along the target geometry but in this case there are 2 parallel lines that share the majority of the length of the target, and then some small links that share only a small portion that have a disproportionate impact on the result, right?

@Robinlovelace
Copy link
Contributor Author

I think it may be handy to see the overlapping bounding boxes that are matched. Would you mind making an issue for that?

Happy to do so, that would be useful in general, but not sure it's relevant for this issue.

@JosiahParry
Copy link
Owner

The question is more or less how you interpret the value in those portions. We assume with the extensive interpolation that each variable is equally distributed along the line.

For example we have a source line that is 10 units long and a value of 100. Our target line overlaps 3 units. We extract the value 30 from the source and assign it to the target.

Do we then want to scale that assigned value by something to assign the value equally over the whole distance of the target?
image

@Robinlovelace
Copy link
Contributor Author

Robinlovelace commented Jan 6, 2025

I think we do want to distribute the value of 100 in that case. The question is more about what to do when you have many source geometries matching each target, with some source geometries having a large amount of overlap and some having small amounts of overlap. That's what's happening in the reprex above and explains the unwanted result stating that the corridor is 30 m wide despite there only being 2 lanes ~8 m wide each (not real data but has the same structure as the data we're using). Can show with another image building on that if that would be helpful, do you have a link on excalidraw/similar?

@JosiahParry
Copy link
Owner

It sums it up for each of the overlapping lines
image

Using the same george street example, if you reduce the angle_tolerance = 2 the value is much more like what you're after.

image

The challenge that you're running into is that the interpolation is including the widths of the roundabouts which it seems you don't want.

@Robinlovelace
Copy link
Contributor Author

That does look right in that case but imagine a small section that had exactly the same angle and a very short length, e.g. 1% of the length, that has a width of 20. We don't want the value 20 to be added to the entire section, but we don't want to ignore it completely. The solution we're after, which is implemented in the reprex in #28 (comment), is for the influence of the value of each source to vary depending on its length, if that makes sense.

As far as I understand it, with interpolate_extensive() the impact of each source object bears no relation to its length or shared length with each target geometry, right?

@JosiahParry
Copy link
Owner

interpolate_extensive() is scaled based on the shared length divided by the total length of the source line. If 1% of the line is overlapping with the target line the value that would be contributed to the target line would be 20 * 0.01

@Robinlovelace
Copy link
Contributor Author

I think it's just a question of multiplying the value by the target weight for our use case:

library(dplyr)
net_target = sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_target.gpkg")
net_source = sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_source.gpkg") |>
  sf::st_cast("LINESTRING")
# plot(net_target)
# plot(net_source["width"])

matches = anime::anime(
  source = net_source, 
  target = net_target, 
  angle_tolerance = 35, 
  distance_tolerance = 10
)

matches_df = anime::get_matches(matches)
summary(matches_df$source_id)
net_source_matches = left_join(
  net_source |>
    mutate(source_id = row_number()),
  matches_df
)

net_target_aggregated = net_source_matches |>
  sf::st_drop_geometry() |>
  group_by(row_number = target_id) |>
  summarise(
    v_weighted = sum(width * target_weighted, na.rm = TRUE),
    v_max_shared = sum(width * shared_len) / max(shared_len)
  )

net_target_joined = left_join(
  net_target |>
    mutate(row_number = row_number()),
  net_target_aggregated
)

summary(net_target_joined$v_weighted)
summary(net_target_joined$v_max_shared)

mapview(net_target_joined, zcol = "v_weighted") +
  mapview(net_source, zcol = "width")

Which generates the correct value for George Street, even using the deliberately forgiving angle_tolerance value of 35:

image

Robinlovelace added a commit to Robinlovelace/anime that referenced this issue Jan 7, 2025
@Robinlovelace
Copy link
Contributor Author

Robinlovelace commented Jan 7, 2025

See minimal example in #30 for how I got there, useful to break it down into the basics and starting from simple examples. Question for you on that, what should the value of the centreline be in this case?

image

And can you see that there are use cases in which the value needed is different from the simple sum of all matching source values (13 = 10 + 1 + 2)?

@JosiahParry
Copy link
Owner

And can you see that there are use cases in which the value needed is different from the simple sum of all matching source values (13 = 10 + 1 + 2)?

Of course, but I'm trying to make sure that the math is interpretable.

Can you try this:

library(dplyr)
net_target = sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_target.gpkg")
net_source = sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_source.gpkg") |>
  sf::st_cast("LINESTRING")


matches = anime::anime(
  source = net_source, 
  target = net_target, 
  angle_tolerance = 35, 
  distance_tolerance = 10
)

matches_df = anime::get_matches(matches)

matches_df |> 
  mutate(
    target_len = target_len[target_id]
  ) |> 
  left_join(mutate(net_source, source_id = row_number())) |> 
  group_by(target_id) |> 
  filter(shared_len > 0) |> 
  print(n = Inf) |> 
  summarise(v_ext_int = sum(width * source_weighted * target_weighted), source_widths = toString(width)) |> 
  inner_join(mutate(net_target, target_id = row_number())) |> 
  sf::st_as_sf() |> 
  mapview::mapview(zcol = "v_ext_int") +
  mapview::mapview(net_source, zcol = "width")

The important part here is :

summarise(v_ext_int = sum(width * source_weighted * target_weighted))

The idea here is two fold—which is what I think you're getting at.

  1. We take the value from the source line string assuming it is equally distributed across the length of the string.
  2. Then we scale that value by the shared length of the target string. Effectively scaling the interpolation.
  • We're scaling the source value by how much overlap there is in the source linestring
  • then we scale the interpolated value by how much overlap there is in the target linestring

this is keeping same angle tolerance etc

image

@Robinlovelace
Copy link
Contributor Author

Looks promising and nice and simple, will give it a bash and report back.

@Robinlovelace
Copy link
Contributor Author

I get this error:

Error in `mutate()`:
ℹ In argument: `target_len = target_len[target_id]`.
Caused by error:
! object 'target_len' not found
Run `rlang::last_trace()` to see where the error occurred.

@Robinlovelace
Copy link
Contributor Author

Did you mean shared_len?

@Robinlovelace
Copy link
Contributor Author

Robinlovelace commented Jan 7, 2025

The results after fixing the error look better than those returned by interpolate_intensive() and interpolate_extensive(). But the values returned seem too low in some cases. In the example below, I would expect the value returned to be between 9 and 10, the values of the 2 roads that run either side of that bit of the centerline:

image

Reprex in details.

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
net_target = sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_target.gpkg")
net_source = sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_source.gpkg") |>
  sf::st_cast("LINESTRING")
#> Warning in
#> st_cast.sf(sf::read_sf("https://github.com/nptscot/osmactive/releases/download/v0.1/net_source.gpkg"),
#> : repeating attributes for all sub-geometries for which they may not be
#> constant


matches = anime::anime(
  source = net_source, 
  target = net_target, 
  angle_tolerance = 35, 
  distance_tolerance = 10
)

matches_df = anime::get_matches(matches)

matches_df |> 
  mutate(
    target_len = shared_len[target_id]
  ) |> 
  left_join(mutate(net_source, source_id = row_number())) |> 
  group_by(target_id) |> 
  filter(shared_len > 0) |> 
  print(n = Inf) |> 
  summarise(v_ext_int = sum(width * source_weighted * target_weighted), source_widths = toString(width)) |> 
  inner_join(mutate(net_target, target_id = row_number())) |> 
  sf::st_as_sf() |> 
  mapview::mapview(zcol = "v_ext_int") +
  mapview::mapview(net_source, zcol = "width")
#> Joining with `by = join_by(source_id)`
#> # A tibble: 266 × 9
#> # Groups:   target_id [107]
#>     target_id source_id shared_len source_weighted target_weighted target_len
#>         <int>     <int>      <dbl>           <dbl>           <dbl>      <dbl>
#>   1         2        63     30.7          0.848           0.579        31.4  
#>   2         3        46     31.4          0.502           0.955         6.11 
#>   3         4        60      6.11         0.833           0.0846       32.7  
#>   4         4       124     32.7          1.00            0.452        32.7  
#>   5         6        23    147.           0.975           0.900        74.5  
#>   6         7        80     74.5          0.929           0.882         0    
#>   7         7       180      4.55         0.375           0.0539        0    
#>   8         9        36     70.0          0.976           0.638        70.0  
#>   9         9        31     19.1          0.799           0.174        70.0  
#>  10        10       149      0.675        0.0576          0.0269       19.1  
#>  11        14       114      7.78         0.0796          0.996        19.7  
#>  12        14        33     19.7          0.200           2.53         19.7  
#>  13        15       107      0.338        0.0155          0.00626       0.338
#>  14        15       114     54.2          0.555           1.00          0.338
#>  15        16       126      4.14         0.593           0.432        54.2  
#>  16        16        63      5.50         0.152           0.574        54.2  
#>  17        18        80      5.70         0.0711          0.0852        5.50 
#>  18        19       173      1.89         0.249           0.00927       5.70 
#>  19        19         7    186.           1               0.914         5.70 
#>  20        19       178      4.15         0.440           0.0204        5.70 
#>  21        19         8    188.           1               0.922         5.70 
#>  22        20        99    152.           0.991           0.816         1.89 
#>  23        20       106     33.7          0.935           0.181         1.89 
#>  24        20       112     33.9          1.00            0.182         1.89 
#>  25        20       109      4.45         0.0707          0.0239        1.89 
#>  26        23        81      9.62         0.170           0.692       188.   
#>  27        23        69      4.29         0.0584          0.309       188.   
#>  28        23         3     11.8          0.208           0.846       188.   
#>  29        23        74      2.02         0.0272          0.146       188.   
#>  30        24       147     10.8          0.897           0.0870        0    
#>  31        25        13     73.4          0.649           0.896       152.   
#>  32        26        15     10.1          0.200           0.222        33.7  
#>  33        26       164     37.2          0.740           0.821        33.7  
#>  34        27        25     26.7          1               0.316        33.9  
#>  35        28        96     56.7          0.735           1.05          0    
#>  36        29        87     78.7          1               0.648         4.45 
#>  37        30        15     40.3          0.800           0.971         9.62 
#>  38        30       150      0.641        0.0559          0.0154        9.62 
#>  39        31       137     74.1          0.992           0.372         4.29 
#>  40        31        38     17.6          1               0.0886        4.29 
#>  41        31       167     12.8          1               0.0643        4.29 
#>  42        31        12     94.2          0.941           0.474         4.29 
#>  43        32        43      4.58         0.311           0.0762       11.8  
#>  44        32       105      3.62         0.210           0.0602       11.8  
#>  45        32       116     34.0          1               0.565        11.8  
#>  46        32       209      2.22         0.0437          0.0369       11.8  
#>  47        35        12      5.94         0.0593          0.675        10.8  
#>  48        36        90     35.5          1               0.951        73.4  
#>  49        36        94      3.17         0.0495          0.0849       73.4  
#>  50        37        16     40.1          0.593           0.859        10.1  
#>  51        38        91     85.8          0.547           0.972        37.2  
#>  52        38        41      3.45         0.344           0.0391       37.2  
#>  53        39        72    419.           0.995           0.999         0    
#>  54        39       122      5.15         0.336           0.0123        0    
#>  55        39        19    413.           1               0.984         0    
#>  56        39         4      0.948        0.00512         0.00226       0    
#>  57        41         9     21.1          0.109           0.871        56.7  
#>  58        43       125     22.4          1               0.109        40.3  
#>  59        43         9    194.           1               0.947        40.3  
#>  60        43       169      2.10         0.307           0.0103       40.3  
#>  61        43       175    157.           1               0.767        40.3  
#>  62        43        10     12.5          0.836           0.0608       40.3  
#>  63        44        59     49.1          0.884           0.785         0.641
#>  64        44        62      8.07         1               0.129         0.641
#>  65        44       126      0.841        0.120           0.0134        0.641
#>  66        45        77     71.9          0.955           0.958        74.1  
#>  67        45        89      2.66         0.187           0.0355       74.1  
#>  68        46        50     16.4          0.311           0.301        17.6  
#>  69        48        82     11.5          0.494           0.676        94.2  
#>  70        48        29      3.33         0.0279          0.195        94.2  
#>  71        49        91     71.0          0.453           0.849         4.58 
#>  72        50       160      2.95         0.0834          0.0739        3.62 
#>  73        50        92     35.1          0.798           0.880         3.62 
#>  74        50        28     27.1          1.00            0.680         3.62 
#>  75        50        98      0.457        0.0121          0.0115        3.62 
#>  76        50        95     11.1          1               0.279         3.62 
#>  77        50       137      0.594        0.00795         0.0149        3.62 
#>  78        50       151      4.34         0.252           0.109         3.62 
#>  79        51        55      0.318        0.00635         0.00676      34.0  
#>  80        51       141     33.1          1.00            0.704        34.0  
#>  81        51       142     14.0          0.429           0.299        34.0  
#>  82        52        46     30.2          0.484           0.994         2.22 
#>  83        56       113     15.4          1               0.398        40.1  
#>  84        56        99      1.45         0.00944         0.0373       40.1  
#>  85        57        33     78.9          0.800           0.822        85.8  
#>  86        58       152     47.7          0.978           0.971         3.45 
#>  87        58       147      1.24         0.103           0.0253        3.45 
#>  88        59        39     32.0          0.677           0.708       419.   
#>  89        59        30     12.3          0.317           0.271       419.   
#>  90        60       160     32.4          0.917           0.870         0    
#>  91        60        98     37.0          0.975           0.992         0    
#>  92        60        64      4.62         0.0404          0.124         0    
#>  93        61         5     26.0          0.937           0.127         5.15 
#>  94        61       200     19.2          1               0.0938        5.15 
#>  95        61        61    171.           1               0.838         5.15 
#>  96        61       159      4.76         0.250           0.0233        5.15 
#>  97        61       130    171.           1               0.836         5.15 
#>  98        61        88      2.06         0.158           0.0101        5.15 
#>  99        61       181      5.99         0.392           0.0293        5.15 
#> 100        63        89     11.6          0.813           0.251         0    
#> 101        64       154      4.96         0.0868          0.143         0.948
#> 102        64        86     12.6          0.291           0.362         0.948
#> 103        64       156     11.0          0.413           0.316         0.948
#> 104        65        13     23.2          0.205           0.562        21.1  
#> 105        65       185     27.0          0.581           0.654        21.1  
#> 106        65       165      9.33         0.201           0.226        21.1  
#> 107        67        70     29.3          0.550           0.716       194.   
#> 108        67       111     23.1          0.436           0.564       194.   
#> 109        67       120      8.52         0.751           0.208       194.   
#> 110        68        88      6.69         0.514           0.0328        2.10 
#> 111        68         6    190.           1               0.933         2.10 
#> 112        68       181      2.43         0.159           0.0119        2.10 
#> 113        68        79    189.           1.00            0.928         2.10 
#> 114        68       148      2.20         0.250           0.0108        2.10 
#> 115        68       178      2.92         0.309           0.0143        2.10 
#> 116        68       182      5.28         0.601           0.0259        2.10 
#> 117        70        52     98.6          0.969           0.811        12.5  
#> 118        71       133      5.85         0.157           0.0774       49.1  
#> 119        73         2    116.           1.00            0.411         0.841
#> 120        73        68     83.6          0.914           0.297         0.841
#> 121        73        57      4.23         0.0244          0.0150        0.841
#> 122        73        73      9.32         0.0410          0.0331        0.841
#> 123        73        71     11.3          0.715           0.0400        0.841
#> 124        73         4     12.9          0.0697          0.0458        0.841
#> 125        76       123     30.0          1.00            0.319        16.4  
#> 126        76       154     11.5          0.201           0.122        16.4  
#> 127        76       155     51.7          1.00            0.549        16.4  
#> 128        76        70     23.9          0.450           0.254        16.4  
#> 129        76       111      4.43         0.0838          0.0470       16.4  
#> 130        76       156      9.11         0.343           0.0966       16.4  
#> 131        77       139      3.08         0.0936          0.0461       11.5  
#> 132        77       138     42.0          1               0.628        11.5  
#> 133        77       206     22.2          1               0.332        11.5  
#> 134        77        34      0.526        0.126           0.00787      11.5  
#> 135        79        73     10.1          0.0446          0.851         0    
#> 136        79        71      4.10         0.261           0.344         0    
#> 137        79         4      0.283        0.00153         0.0237        0    
#> 138        79        13      4.39         0.0388          0.368         0    
#> 139        79        18      9.56         0.0445          0.803         0    
#> 140        81       209     13.4          0.264           0.719         0    
#> 141        81       129      4.53         0.146           0.243         0    
#> 142        82        29    102.           0.855           0.714         0    
#> 143        84        36      1.71         0.0239          0.190        35.1  
#> 144        84       201      7.12         0.410           0.790        35.1  
#> 145        85       106      2.35         0.0651          0.105        27.1  
#> 146        85        20     20.2          0.681           0.899        27.1  
#> 147        85       109     22.3          0.355           0.997        27.1  
#> 148        87       204     81.8          0.941           0.891        11.1  
#> 149        87       192      5.56         0.546           0.0605       11.1  
#> 150        88        75     98.8          0.992           0.984         0.594
#> 151        89       207    133.           1               0.363         4.34 
#> 152        89        66     68.6          1.00            0.188         4.34 
#> 153        89        27      9.40         1.00            0.0257        4.34 
#> 154        90       114     35.7          0.365           0.911         0.318
#> 155        90        77      3.36         0.0447          0.0859        0.318
#> 156        90        33     41.4          0.419           1.06          0.318
#> 157        91        21    115.           0.561           0.885        33.1  
#> 158        91        22      2.16         0.0482          0.0166       33.1  
#> 159        93        81     46.9          0.830           0.576        30.2  
#> 160        93         3     44.9          0.792           0.551        30.2  
#> 161        93        64     34.8          0.304           0.427        30.2  
#> 162        93        65     37.0          0.331           0.454        30.2  
#> 163        95       165     33.0          0.711           0.774        15.4  
#> 164        95       185     14.8          0.319           0.346        15.4  
#> 165        96       157     36.5          0.974           0.230         1.45 
#> 166        96       158     36.0          0.937           0.227         1.45 
#> 167        96        14     61.5          1.00            0.388         1.45 
#> 168        98        58    132.           0.997           0.993         0    
#> 169        99       211      2.42         0.0963          0.0153       47.7  
#> 170       100        21     84.9          0.414           0.945         0    
#> 171       104        45     99.6          0.996           0.982        32.4  
#> 172       105       166      0.222        0.0165          0.000795     37.0  
#> 173       105       213     14.4          1               0.0515       37.0  
#> 174       105       190     13.5          1               0.0485       37.0  
#> 175       105       212      0.521        1               0.00186      37.0  
#> 176       106        30     26.2          0.677           0.419         4.62 
#> 177       106       198     23.3          1               0.373         4.62 
#> 178       106       197      6.24         0.217           0.0997        4.62 
#> 179       107        72      1.84         0.00436         0.0100        0    
#> 180       107        57    173.           1               0.942         0    
#> 181       107         4    184.           0.993           1.00          0    
#> 182       107        73      9.32         0.0410          0.0507        0    
#> 183       108        50     35.0          0.663           0.315        26.0  
#> 184       109        69     69.2          0.942           0.947        19.2  
#> 185       109        73      3.54         0.0156          0.0485       19.2  
#> 186       109        74     72.1          0.970           0.987        19.2  
#> 187       110       203    125.           1.00            0.317         0    
#> 188       110       194     18.3          0.603           0.0463        0    
#> 189       110       202     30.3          1               0.0768        0    
#> 190       110       193     37.7          0.582           0.0956        0    
#> 191       110        49      5.87         0.126           0.0149        0    
#> 192       110        82      7.43         0.318           0.0188        0    
#> 193       112        22     42.6          0.952           0.780         4.76 
#> 194       113        73    215.           0.943           1.00        171.   
#> 195       113         4      0.283        0.00153         0.00132     171.   
#> 196       113        18    215.           1               1.00        171.   
#> 197       113        74      0.209        0.00281         0.000973    171.   
#> 198       114        11      9.17         0.0687          0.0958        2.06 
#> 199       116        96     20.5          0.265           0.612         5.99 
#> 200       117       201     10.2          0.590           0.0839       11.6  
#> 201       117        32     26.6          0.953           0.218        11.6  
#> 202       117       128     86.4          1               0.708        11.6  
#> 203       118        64     75.1          0.656           0.997         0    
#> 204       118        65     74.9          0.669           0.995         0    
#> 205       118        98      0.479        0.0126          0.00636       0    
#> 206       120       129     26.5          0.854           0.408        12.6  
#> 207       120        37     22.5          1.00            0.347        12.6  
#> 208       120       127     13.1          1.00            0.201        12.6  
#> 209       120        60      1.22         0.167           0.0189       12.6  
#> 210       123       142     18.7          0.571           0.184        23.2  
#> 211       123       161     33.2          1.00            0.327        23.2  
#> 212       123       210     14.9          1.00            0.147        23.2  
#> 213       123        40     20.9          1.00            0.206        23.2  
#> 214       123       104      7.99         1               0.0786       23.2  
#> 215       124       139     29.8          0.906           0.210        27.0  
#> 216       126       126      2.00         0.286           1.02         29.3  
#> 217       131       209     35.2          0.692           1.07          0    
#> 218       132        85     28.7          0.437           0.274         2.43 
#> 219       133        11    124.           0.931           0.940       189.   
#> 220       135       199     20.6          1               0.489         2.92 
#> 221       135        20      9.43         0.319           0.223         2.92 
#> 222       135       109     36.1          0.574           0.856         2.92 
#> 223       135       121     12.5          0.644           0.296         2.92 
#> 224       135        26      6.27         0.0897          0.149         2.92 
#> 225       137       120      2.82         0.249           0.0385       98.6  
#> 226       137        67     66.3          1               0.905        98.6  
#> 227       137       121      6.91         0.356           0.0943       98.6  
#> 228       137        26     63.7          0.910           0.870        98.6  
#> 229       137        72      0.331        0.000785        0.00451      98.6  
#> 230       137       115      4.07         0.178           0.0555       98.6  
#> 231       137       122     10.2          0.664           0.139        98.6  
#> 232       138       119     73.2          1               0.445         0    
#> 233       138       186     46.5          0.968           0.283         0    
#> 234       138       145     28.7          1               0.174         0    
#> 235       138       187     14.8          0.952           0.0901        0    
#> 236       141       164     13.1          0.260           0.597         0    
#> 237       141        59      6.44         0.116           0.293         0    
#> 238       145        16     17.4          0.257           0.906         9.32 
#> 239       145        52      3.11         0.0306          0.162         9.32 
#> 240       146        55     49.7          0.994           0.670        11.3  
#> 241       146         1     13.4          0.587           0.181        11.3  
#> 242       147        94     59.1          0.923           0.952        12.9  
#> 243       148        24    172.           1               1.00         30.0  
#> 244       149       184     13.2          0.570           0.339        11.5  
#> 245       149       183      5.82         0.217           0.149        11.5  
#> 246       151        17    118.           0.894           0.954        23.9  
#> 247       151       152      1.07         0.0220          0.00863      23.9  
#> 248       151       189      6.16         1               0.0497       23.9  
#> 249       153       179      4.24         0.333           0.0505        9.11 
#> 250       153       146     27.9          1.00            0.332         9.11 
#> 251       154       107     21.4          0.984           0.795         3.08 
#> 252       154       108      7.18         0.657           0.267         3.08 
#> 253       156       154      5.06         0.0887          0.0755       22.2  
#> 254       156        86     30.5          0.704           0.455        22.2  
#> 255       156       208     29.8          0.701           0.445        22.2  
#> 256       156       162      4.92         1               0.0735       22.2  
#> 257       158        50      1.36         0.0258          0.0253       10.1  
#> 258       158        51     52.2          0.284           0.972        10.1  
#> 259       159       211     22.7          0.904           0.180         4.10 
#> 260       159        54     15.2          1.00            0.120         4.10 
#> 261       160        56     17.1          1               0.251         0.283
#> 262       160        97     11.9          0.573           0.174         0.283
#> 263       160        35     19.2          1.00            0.282         0.283
#> 264       161       204      0.615        0.00708         0.00943       4.39 
#> 265       161       118     12.1          1.00            0.186         4.39 
#> 266       161        47      4.07         1.00            0.0624        4.39 
#> # ℹ 3 more variables: osm_id <chr>, width <dbl>, geom <LINESTRING [m]>
#> Joining with `by = join_by(target_id)`
#> file:////tmp/RtmpdgHUKP/file6d9512ddb8860/widget6d9515483be73.html screenshot completed

Created on 2025-01-07 with reprex v2.1.1

@Robinlovelace
Copy link
Contributor Author

The result of the

    width = sum(width * target_weighted, na.rm = TRUE),

method I used isn't much different:

image

@Robinlovelace
Copy link
Contributor Author

Another avenue that I'm interested in trying: dividing the total shared length by the the length of the target geometries. Tried but failed that somewhere else but can have another bash.

In terms of the theory underlying this approach, to the limited extent that there is any, is this interpolation approach somewhat of a halfway house between extensive and intensive, or is it just length-weighted extensive?

@Robinlovelace
Copy link
Contributor Author

Robinlovelace commented Jan 7, 2025

Are there any cases where using

sum(width * source_weighted * target_weighted)

Rather than just

sum(width * target_weighted, na.rm = TRUE),

leads to a substantially different and potentially better/worse result?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants