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

support MULTILINESTRING #62

Closed
timelyportfolio opened this issue Aug 2, 2017 · 8 comments
Closed

support MULTILINESTRING #62

timelyportfolio opened this issue Aug 2, 2017 · 8 comments

Comments

@timelyportfolio
Copy link
Contributor

@timelyportfolio timelyportfolio commented Aug 2, 2017

promoted from #48

Before I implement the logic into mapedit, I wanted to post the results from my initial exploration.

library(mapview)
library(mapedit)
library(sf)

# @tim-salabim reports, this fails badly
#   and while leaflet draws the multilinestring correctly
#   Leaflet.draw seems to not like it
editFeature(trails[4,])

# we will need to cast to LINESTRING first
#  but be careful to retain some mechanism
#  to preserve the group for proper conversion back
#  to MULTILINESTRING
editFeatures(sf::st_cast(trails[4,], "LINESTRING"))


# one option will be to add a second column identifier
#  after we cast to LINESTRING
#  here is a minimal example before attempting to integrate
#  into the existing module
tr <- trails[c(1,4),]
tr$edit_id <- seq_len(nrow(tr))
# now will need to carefully cast
#  for some reason casting creates sfc
#  so also need to st_sf to get back to sf
tr2 <- st_sf(st_cast(tr, "LINESTRING"))
tr2


# ignore the editMap part for now
#  and see if we can convert back
#  I might be making this way harder than it should be
#  but I could not find a combination of aggregate.sf
#  or dplyr::group_by that would accomplish this
tr3 <- tr
st_geometry(tr3) <- split(tr2, tr2$edit_id) %>%
  lapply(function(x){st_multilinestring(st_geometry(x))}) %>%
  st_sfc
plot(tr3)
tr3

@edzer, is there a way to group_by and then make st_multilinestring on each grouped edit_id? I also tried to do this with aggregate.sf with no luck since it seems the aggregate function could only apply to non-geometry columns.

@tim-salabim
Copy link
Member

@tim-salabim tim-salabim commented Aug 2, 2017

@timelyportfolio for re-casting to MULTILINESTRING you can use do.call(c, lapply(split(tr2, tr2$edit_id), st_combine)).

@timelyportfolio
Copy link
Contributor Author

@timelyportfolio timelyportfolio commented Aug 2, 2017

@tim-salabim, thanks for that bit of code. c will work well in this scenario. In a case with mixed types, won't st_combine convert everything to MULTI*? I will test to make sure that this will not interfere with our cast back to original (which I think is a very nice feature).

@timelyportfolio
Copy link
Contributor Author

@timelyportfolio timelyportfolio commented Aug 8, 2017

Here is my test sf (challenge) with mixed types to get working with edit.

# since we have discovered a way to go from MULTILINESTRING
#   to a group of LINESTRING and back, now the trick will be
#   to perform this magic in a sf with mixed types.
#   let's make a mixed type sf
mixsf <- st_sf(geometry = c(
  st_geometry(franconia[1:2,]),
  st_geometry(trails[1:4,]),
  st_geometry(breweries[1:5,])
))
@tim-salabim
Copy link
Member

@tim-salabim tim-salabim commented Aug 8, 2017

As long as it's not in a GEOMETRYCOLLECTION, st_dimension will show us the different types.

st_dimension(mixsf)
[1] 2 2 1 1 1 1 0 0 0 0 0

When encapsulated within a GEOMETRYCOLLECTION we need to st_cast(gc) first in order to get the individual components.

@timelyportfolio
Copy link
Contributor Author

@timelyportfolio timelyportfolio commented Aug 10, 2017

@tim-salabim, I probably need to clear my head, and I'm guessing the answer is obvious but why does this not work? Never mind, as I thought, was very dumb on my part. I need to st_transform.

library(sf)
library(mapview)
library(mapedit)

mixsf <- st_sf(geometry = c(
  st_geometry(franconia[1:2,]),
  st_transform(st_geometry(trails[1:4,]), crs=4326),
  st_geometry(breweries[1:5,])
))

mapview(mixsf)

The code above will not render the lines.

@tim-salabim
Copy link
Member

@tim-salabim tim-salabim commented Aug 10, 2017

Yeah, that one has caught me several times too. I left it delibarately in non-longlat as a gentle reminder that not all data comes in longlat...

Though this brings up a good point for mapedit *Features. We need to decide what we do with data supplied in non-longlat. mapview::checkAdjustProjection will ensure that data is projected correctly for rendering and drawn/edited features are currently returned in longlat. Should we transform back to initial supplied CRS? Or simply return longlat with a warning?

@timelyportfolio
Copy link
Contributor Author

@timelyportfolio timelyportfolio commented Jan 6, 2019

@tim-salabim looks like the easy solution is to use editor="leafpm", since Leaflet.pm handles MULTILINESTRING.

library(sf)
library(mapview)
library(mapedit)

editFeatures(trails[4,], editor="leafpm")

However, I'm not sure this is an acceptable solution for the project.

@timelyportfolio
Copy link
Contributor Author

@timelyportfolio timelyportfolio commented Jan 21, 2019

0.5.0 will merge in support for leaflet.pm using the new package leafpm. This handles MULTILINESTRING well, so I will consider this issue closed.

Please reopen if anyone would like to discuss further.

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

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.