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

Interactive web app to try out #4

Open
dabreegster opened this issue Dec 22, 2024 · 2 comments
Open

Interactive web app to try out #4

dabreegster opened this issue Dec 22, 2024 · 2 comments

Comments

@dabreegster
Copy link

To help users understand the results for this library and tune parameters, a web tool could be quite handy. I started one for my simpler linestring matching implementation at https://nptscot.github.io/match_linestrings/. On the cycleway example that @Robinlovelace made, it performs quite poorly:
image
Only the darker blue cycleway segments matched to the red roads. You can hover on one of them to see the matching red line.

There are two steps to mocking up a tool like this. The WASM bindings for use in JS are in https://github.com/nptscot/match_linestrings/tree/main/backend -- some boilerplate, but mostly just reading/writing the geometry and transforming coordinate systems. Then https://github.com/nptscot/match_linestrings/tree/main/web is a small Svelte frontend, using svelte-maplibre to conveniently set up a map and draw things. This can all be deployed to GH pages using https://github.com/nptscot/match_linestrings/tree/main/.github/workflows.

If you have any interest in adapting this for your library and hit issues, let me know -- I'd also generally like to spread the knowledge about how to do this kind of thing, in case it's useful in other projects. When I get some spare time, I could also start it -- it'd be useful for me to work through anime's API, although it seems pretty straightforward.

@JosiahParry
Copy link
Owner

hmm! Visualization might actually be fairly tricky because this is not just a 1:1 pairing. Each line can match to as many as all n lines in the other line set.

So I'm not sure how this would work. Ideally it would be something like:

  • click a source line
  • the matched lines are made opaque and symbolized by % match
  • non-matched lines are more transparent

or something like that.

here is a really rough R application to do so

image
library(shiny)
library(bslib)
library(mapgl)
library(sf)
library(anime)

source <- sf::read_sf("https://raw.githubusercontent.com/nptscot/match_linestrings/refs/heads/main/tests/southwark/source.geojson") |> 
  sf::st_transform(27700) |> 
  dplyr::mutate(id = dplyr::row_number())

target <- sf::read_sf("https://raw.githubusercontent.com/nptscot/match_linestrings/refs/heads/main/tests/southwark/target.geojson") |> 
  sf::st_transform(27700) |> 
  dplyr::mutate(id = dplyr::row_number())

matches <- anime(source, target, distance_tolerance = 50, angle_tolerance = 5)

match_tbl <- get_matches(matches)


ui <- page_sidebar(
  title = "mapgl with Shiny",
  sidebar = sidebar(verbatimTextOutput("clicked_feature")),
  card(
    full_screen = TRUE,
    maplibreOutput("map")
  )
)

server <- function(input, output, session) {

  source_id <- reactive({
    feat <- input$map_feature_click
    if (!is.null(feat)) {
      if (feat$layer == "source_lines") {
        input$map_feature_click$properties$id
      } else {
        integer()
      }
    } else {
      integer()
    }
  })

  target_ids <- reactive({
    sid <- source_id()
    res <- dplyr::filter(match_tbl, source_id %in% sid) |> 
      dplyr::pull(target_id)
    str(res)
    res
  })

  output$map <- renderMaplibre({
    maplibre(style = carto_style("positron")) |> 
      fit_bounds(target, animate = FALSE) |> 
      add_line_layer(id = "source_lines", source = source, line_color = "blue", line_width = 4) |>
      add_line_layer(id = "target_lines", source = dplyr::filter(target, id %in% target_ids()), line_width = 4) |> 
      add_line_layer(id = "tl", source = target, line_color ="gray") 
  })

  output$clicked_feature <- renderPrint({
    req(input$map_feature_click)    
    input$map_feature_click
  })
}

shinyApp(ui, server)

@Robinlovelace
Copy link
Contributor

The visualisation shows the benefits of partial matching by overlapping line length. Now I'm able to get the package installed again I plan to do some tests. Hoping they will be of use for the package, if I manage to make seemingly good changes watch out for a PR (the next one will actually be useful hopefully). Would be great to have a live demo of it in action so will give the Shiny app a spin.

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

3 participants