hypertidy / silicate

A general form for complex data
https://hypertidy.github.io/silicate/
54 stars 4 forks source link

Constructors #14

Open mdsumner opened 7 years ago

mdsumner commented 7 years ago

PATH should take x,y DF possibly with groupings/order, so easy to build path lines/polys/points and flip to segment versions. This would be useful for crosstalk testing and straightforward trip structure

mdsumner commented 7 years ago

In sctrip working on sc_path.data.frame(data, x, y, time) thing with NSE.

It breaks the convention of all non-feature columns being called "name_". So we have to think about

the double-join is awkard but it works, is there a two-join convention of some kind?

library(dplyr)

db <- src_sqlite("db.sqlite3")
db
x <- tbl(db, "event_log_interv_nav") %>% 
  filter(event_type == "GENU") %>% 
  mutate(x = start_lon_dec_deg_interp, y = start_lat_dec_deg_interp) %>% 
  select(x, y, utc, event_type, waypoint) %>% 
  collect()

#devtools::install_github("mdsumner/sctrip")
library(sctrip)
p <- sc::PRIMITIVE(sc_path(x, x, y, utc))

## sc needs fixing here
class(p) <- c("PRIMITIVE", "sc")
plot.PRIMITIVE <- function(x, ...) {
  library(ggplot2)
  ggplot(x$vertex, aes(x, y)) + geom_point() + 
    geom_segment(data = p$segment %>% inner_join(p$vertex, c(".vertex1" = "vertex_")) %>% rename(xend = x, yend = y) %>% inner_join(p$vertex, c(".vertex0" = "vertex_")), 
                 aes(x = x, y = y, xend = xend, yend = yend, col = segment_))
}
plot(p)
mdsumner commented 7 years ago

A model for sc_path:

Validation stuff must include

this will work to dump ordered segments into ggplot for a lot of data types.

mdsumner commented 6 years ago

https://github.com/hypertidy/silicate/issues/32

mdsumner commented 6 years ago

Now that we have decido, the constructor for TRI is really obvious, it's the vertex pool and the object groupings, and the triangle indexes in between. That might help define the other cases

mdsumner commented 6 years ago

Some experimental wrappers here: https://github.com/hypertidy/silicate/blob/d6da41740ffa1490b7603470f6ef468f3b629981/R/000_cMESH.R

I like the idea of si_ prefix for constructors, but it's for later.

mdsumner commented 6 years ago

See these for ideas for sf builders

https://github.com/hypertidy/silicate/issues/32

https://github.com/mdsumner/sfcc

https://github.com/SymbolixAU/geojsonsf (and anything related for sf construction)

mdsumner commented 4 years ago

Might as well use the sfheaders format for a df, see PATH0_from_df - could also use a grouped_df to see how x, y are organized


d <- sqrt(3)/2
df <- data.frame(
  x        = c(0, 1, 0.5,   0.25, 0.5, 0.75),
  y        = c(0, 0, d  ,   d/2   , 0  ,    d/2),
  group    = 1L,
  subgroup = c(1, 1, 1  , 2, 2, 2)
)

library(silicate)
library(anglr)
library(sf)
par(mfcol = c(3, 2))
# illegal polygon (sfheaders will auto-close, but the hole intersects its island which is SF-non-compliant)
sfx <- sfheaders::sf_polygon(df, x = "x", y = "y", linestring_id = "subgroup", polygon_id = "group")
plot(sfx$geometry, col = "grey")

## decompose and make valid with sf
sf::st_make_valid(sfx)  ## 3 POLYGON in one MULTIPOLYGON

## silicate is fine {decido}
plot(TRI0(sfx), col = viridis::viridis(3))
## anglr is fine {anglr}
plot(DEL0(sfx), col = viridis::viridis(3))

## what about a crazier "hole"
df2 <- df
df2$x[df$subgroup == 2] <- df2$x[df$subgroup == 2] + c(-0.1, 0, 0.1)
df2$y[df$subgroup == 2] <- df2$y[df$subgroup == 2] + c(0, -0.1, 0)
## illegal polygon (sfheaders will auto-close, but the hole intersects its island which is SF-non-compliant)
sfx2 <- sfheaders::sf_polygon(df2, x = "x", y = "y", linestring_id = "subgroup", polygon_id = "group")
plot(sfx2$geometry, col = "grey")

## silicate can't handle
plot(df2[1:2]); plot(TRI0(sfx2), col = viridis::viridis(6), add = TRUE)
## anglr is fine 
plot(DEL0(sfx2), col = viridis::viridis(6))

sf::st_make_valid(sfx2)  ## 6 POLYGON in one MULTIPOLYGON

image

mdsumner commented 4 years ago

Mike's examples (he misses the need for multipolygon_id, but that only affects TRI0

polygons_df <-  data.frame(
  x        = c(4, 8, 8, 4,   6, 7, 7, 6),
  y        = c(4, 4, 8, 8,   6, 6, 7, 7),
  group    = c(1, 1, 1, 1,   1, 1, 1, 1),
  subgroup = c(1, 1, 1, 1,   2, 2, 2, 2)
)
polygons_df <- data.frame(
  x        = c(4, 8, 8, 4,   6, 7, 7, 6,  4.5,   5, 5, 4.5),
  y        = c(4, 4, 8, 8,   6, 6, 7, 7,  4.5, 4.5, 5, 5),
  group    = c(1, 1, 1, 1,   1, 1, 1, 1,    1,   1, 1, 1),
  subgroup = c(1, 1, 1, 1,   2, 2, 2, 2,    3,   3, 3, 3)
)
polygons_df <- data.frame(
  x        = c(1, 4, 4, 1,  2, 3, 3, 2,      5, 8, 8, 5,  6, 7, 7, 6),
  y        = c(1, 1, 4, 4,  2, 2, 3, 3,      5, 5, 8, 8,  6, 6, 7, 7),
  group    = c(1, 1, 1, 1,  1, 1, 1, 1,      1, 1, 1, 1,  1, 1, 1, 1),
  subgroup = c(1, 1, 1, 1,  2, 2, 2, 2,      3, 3, 3, 3,  4, 4, 4, 4)
)

polygons_df <- data.frame(
  x        = c(0, 1, 2, 2, 1, 1),
  y        = c(0, 1, 1, 2, 2, 1),
  group    = 1,
  subgroup = 1
)

set.seed(1)
polygons_df <- data.frame(
  x        = runif(10),
  y        = runif(10),
  group    = 1,
  subgroup = 1
)
# illegal polygon (sfheaders will auto-close, but the hole intersects its island which is SF-non-compliant)
sfx <- sfheaders::sf_polygon(polygons_df, x = "x", y = "y", linestring_id = "subgroup", polygon_id = "group")
plot(sfx$geometry, col = "grey")

plot(TRI0(sfx), col = viridis::viridis(3))
plot(DEL0(sfx), col = viridis::viridis(3))
mdsumner commented 4 years ago

e.g. for multi

polygons_df <- data.frame(
  x        = c(1, 4, 4, 1,  2, 3, 3, 2,      5, 8, 8, 5,  6, 7, 7, 6),
  y        = c(1, 1, 4, 4,  2, 2, 3, 3,      5, 5, 8, 8,  6, 6, 7, 7),
  ## needs to be unique to be multipolygon per sfheaders (not grouped together by subgroup)
  group    = c(1, 1, 1, 1,  1, 1, 1, 1,      2, 2, 2, 2,  2, 2, 2, 2),
#  group    = c(1, 1, 1, 1,  1, 1, 1, 1,      1, 1, 1, 1,  1, 1, 1, 1),
  subgroup = c(1, 1, 1, 1,  2, 2, 2, 2,      3, 3, 3, 3,  4, 4, 4, 4)
)
sfx <- sfheaders::sf_polygon(polygons_df, x = "x", y = "y", linestring_id = "subgroup", polygon_id = "group")
plot(sfx$geometry, col = "grey")

plot(TRI0(sfx), col = viridis::viridis(3))
plot(DEL0(sfx), col = viridis::viridis(3))

image