Open mdsumner opened 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)
A model for sc_path:
sc_path(d, x, y, z, .group = g)
sc_path(d, x, y, z, .group = g, .gorder = z)
Validation stuff must include
this will work to dump ordered segments into ggplot for a lot of data types.
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
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.
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)
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
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))
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))
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