Skip to content

mdsumner/simpler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

simpler

The goal of simpler is to provide the Visvalingam algorithm to simplifying paths.

Very much WIP!

TODO:

  • distinguish shared boundaries from isolated lines, and drop short one

  • provide methods for various formats, especially polygons to shared boundaries

  • methods to recompose shared paths as polygons

  • avoid recalculating every triangle area every iteration

    fixed by vectorizing removal, rather than tricky in-place re-indexing

Notes:

  • calculating triangle area is fast, the slowness comes from iterating over removals of focal points
  • how to avoid intersections that might occur (need examples)

Installation

You can install this R package with remotes using:

remotes::install_github("mdsumner/simpler")

If you don’t have the remotes package, that can be installed with:

install.packages("remotes")

Example

The USA example, from Natural Earth. See https://bost.ocks.org/mike/simplify/

library(simpler)
w <- rnaturalearth::ne_countries(scale = 10, country = "United States of America", returnclass = "sf")
x <- w$geometry[[1]][[1]][[1]]


op <- par(mfrow = c(3, 3), mar = rep(0, 4))
plot(x, type = "l", axes = FALSE)
text(-100, 40, sprintf("vertices: %i",  nrow(x)))
for (kpc in c(0.4, rep(0.6, 7))) {
  x <- simplify_path(x, keep_pc = kpc)
  plot(x, type = "l", axes = FALSE)
  text(-100, 40, sprintf("vertices: %i",  nrow(x)))

}

par(op)

Simplify a bunch of shared lines (need better examples).

library(sf)
#> Linking to GEOS 3.6.2, GDAL 2.3.2, PROJ 4.9.3
library(silicate)
#> 
#> Attaching package: 'silicate'
#> The following object is masked from 'package:stats':
#> 
#>     filter
get_pts <- function(x, i) {
  x$arc_link_vertex %>% dplyr::filter(arc_ == x$object_link_arc$arc_[i]) %>% 
    dplyr::inner_join(x$vertex, "vertex_") %>% dplyr::select(x_, y_) %>% as.matrix()
}
nc <- read_sf(system.file("gpkg/nc.gpkg", package = "sf"))

nc1 <- nc[c(1, 2, 3, 10, 19, 18, 23, 25, 22, 34, 41, 42, 32, 34, 41, 39, 50, 43, 46, 52), ]
x <- ARC(nc1)
sfx <- vector("list", nrow(x$object_link_arc))
op <- par(mar = rep(0, 4))
#plot(x$vertex$x_, x$vertex$y_, pch = ".", asp = "")
plot(nc1$geom, reset = FALSE)
for (i in seq_along(x$object_link_arc$arc_)) {
  pts <- get_pts(x, i)
    path <- simplify_path(pts, keep_pc = 0.1)
  
  lines(path, col = rainbow(10)[i %% 10 + 1], lwd = 2)
  sfx[[i]] <- sf::st_linestring(path)
}
par(op)
points(x$vertex$x_, x$vertex$y_, pch = 19, cex = 0.3)

x <- ARC(inlandwaters)
plot(x)

sfx <- vector("list", nrow(x$object_link_arc))
plot(x$vertex$x_, x$vertex$y_, pch = ".", asp = 1, xlim = c(4e5, 2e6), ylim = c(-1e6, 0))
for (i in seq_along(x$object_link_arc$arc_)) {
 pts <- get_pts(x, i)
 path <- simplify_path(pts, keep_pc = 0.001)
 lines(path, col = rainbow(10)[i %% 10 + 1], lwd = 3)
 sfx[[i]] <- sf::st_linestring(path)
}

## this is a cheat because the polygons have to store any shared boundaries twice, 
pryr::object_size(sf::st_sfc(sfx))
#> 332 kB
pryr::object_size(inlandwaters)
#> 586 kB


plot(sf::st_sfc(sfx))

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages