silicate icon indicating copy to clipboard operation
silicate copied to clipboard

Constructors

Open mdsumner opened this issue 8 years ago • 9 comments

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 avatar Feb 11 '17 22:02 mdsumner

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

  • a system to record a mapping of names to geometries (a la aes())
  • there's got to always be a geometry, unless tools to reconstruct the geometry on primitives is brought forward

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 avatar Feb 20 '17 16:02 mdsumner

A model for sc_path:

  • input a grouped table, split on those groups by the path_ value
  • groups can be specified a la sc_path(d, x, y, z, .group = g)
  • should we have order, within group? sc_path(d, x, y, z, .group = g, .gorder = z)

Validation stuff must include

  • geometric sense for primitives, so downstream classes apply rules for length, increasing etc.
  • rules for missing/Inf
  • number of dims

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

mdsumner avatar Feb 20 '17 16:02 mdsumner

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

mdsumner avatar Nov 29 '17 02:11 mdsumner

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 avatar Feb 26 '18 15:02 mdsumner

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 avatar Oct 30 '18 22:10 mdsumner

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 avatar Oct 30 '18 22:10 mdsumner

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 avatar Sep 30 '20 01:09 mdsumner

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 avatar Sep 30 '20 01:09 mdsumner

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

mdsumner avatar Sep 30 '20 01:09 mdsumner