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

edges() method for counting edges #1674

Merged
merged 1 commit into from
Dec 13, 2024

Conversation

MichaelChirico
Copy link
Contributor

Hi,

This is arising from today's "Advent of Code" problem (Pt. 2):

https://adventofcode.com/2024/day/12

The problem basically gives a raster and asks to find the number of edges for each implied polygon, especially paying mind to holes.

Pt. 1 was particularly well-suited to using {terra} (especially with the new patches(values=TRUE)), since the perim() method immediately answers the "harder" part about the perimeter of the implied polygons.

I was left searching for something in the package to solve Pt. 2 and couldn't see anything (I looked at boundaries() and a few other things but couldn't see how to make it work).

I decided to peek at the source code for perim() and saw that it could easily be tweaked to solve the question of number of edges (as done here).

I leave the question of nomenclature/API up to you -- I chose edges() but am not married to that at all. I think you have much more context about the full API surface of the package, its documentation & use cases, etc, so I trust your judgment on how this should be named, or if perhaps it should just be a new argument to perim().

I left out the NEWS and documentation while this issue of API is pending.

One thing I didn't understand at all was the need to have -1 in the calculations, but I can report this gives the correct answer on the toy examples I've added to the tests, as well as the much more complicated input given by AoC.

Of course, if you think the use case here is too narrow / not likely to be needed in the package generally, feel free to close this PR.

@rhijmans rhijmans merged commit b37b481 into rspatial:master Dec 13, 2024
4 checks passed
@rhijmans
Copy link
Member

rhijmans commented Dec 13, 2024

With your example data from #1671

library(terra)
v <- matrix(c(5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,5,5,4,4,5,5,5,5,4,4,4,5,5,4,4,4,5,5,4,4,4,4,4,5,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5), nrow=6, byrow=TRUE)
r <- rast(v, crs="local")
x <- patches(r, values=TRUE)
p <- as.polygons(x)

edges(p)
#[1] 20  8  8

With other functions you could do

sapply(1:nrow(p), \(i) nrow(disagg(p[i], segments=TRUE)))
#[1] 4 8 8
 
sapply(1:nrow(p), \(i) nrow(disagg(p[i], TRUE)) + nrow(disagg(fillHoles(p[i], TRUE), TRUE)))
#[1] 20  8  8

v <- as.lines(p)
sapply(1:nrow(v), \(i) nrow(disagg(v[i], TRUE)))
#[1] 20  8  8

The -1 in edges_geom is needed because you need (n+1) nodes (coordinates) to make (n) edges.

@MichaelChirico MichaelChirico deleted the raster-edges branch December 20, 2024 07:12
@rhijmans
Copy link
Member

renamed edges to nseg (number of segments) to reserve edges for when I implement spatial graphs.

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Feb 8, 2025
# Version 1.8-15

## Bug Fixes

- `Readrds` Failed For Rasters With Timestep="Seconds"
  [#1711](Https://github.com/Rspatial/terra/issues/1711) by Pascal
  Oettli

- `divide<SpatVector>` always returned NULL
  [#1724](rspatial/terra#1724) by Márcia
  Barbosa

- `erase` failed in some cases
  [#1710](rspatial/terra#1710) by
  erkent-carb

## enhancements

- `bestMatch` now has argument "fun" to allow the use of different
  distance measures, and a <matrix> method

- `wrap` (and `writeRDS`) now captures varnames/longnames
  [#1719](rspatial/terra#1719) by Andrew
  Gene Brown

- improved raster metadata writing
  [#1714](rspatial/terra#1714) by Andrew Gene
  Brown

- `vect` and `writeVector` now properly read and write date and
  datetime
  data. [#1718](rspatial/terra#1718) by
  Andrew Gene Brown

- improved estimate of available memory on linux systems
  [#1506](rspatial/terra#1506) by Cedric
  Rossi

# version 1.8-10

Released 2025-01-13

## bug fixes

- `expanse<SpatRaster>(transform=TRUE)` crashed R when the crs was
  "local". [#1671](rspatial/terra#1671) by
  Michael Chirico

- `patches(values=TRUE)` wrapped around the edges
  [#1675](rspatial/terra#1675) by Michael
  Chirico

- `spin` now correctly handles spherical coordinates
  [#1576](rspatial/terra#1576) by jeanlobry

- `mosaic` sometimes crashed R
  [#1524](rspatial/terra#1524) by John
  Baums, Dave Klinges, and Hugh Graham.

- `spatSample` ignored argument "exp" when taking a random sample with
  na.rm=TRUE on a large raster
  [#1437](rspatial/terra#1437) by Babak
  Naimi

- `split<SpatVector,SpatVector>` did not work properly
  [#1619](rspatial/terra#1619) by Michael
  Sumner

- `autocor` improved handling of NA cells for global Moran computation
  [#1992](rspatial/terra#1592) by Nicholas
  Berryman

- `shade` is more
  memory-safe. [#1452](rspatial/terra#1452)
  by Francis van Oordt and Chris English

- fixed bug in `rasterize` revealed when using `crop(mask=TRUE)`
  [#1686](rspatial/terra#1686) by edixon1

- fixed `to_id = NA` bug in `nearest`
  [#1471](rspatial/terra#1471) by Mats
  Blomqvist

- better handling of date/unit
  [#1684](rspatial/terra#1684) and
  [#1688](rspatial/terra#1688) by Andrew
  Gene Brown

- `spatSample(method="regular")` on a raster with one column returned
  too many samples
  [#1362](rspatial/terra#1362) by Daniel R
  Schlaepfer


## enhancements

- `plot<SpatVector>` now uses the same default viridis color palette
  as `plot<SpatRaster>`
  [#1670](rspatial/terra#1670) by Márcia
  Barbosa

- `relate` now accepts relation="equals"
  [#1672](rspatial/terra#1672) by Krzysztof
  Dyba

- `init` now accepts additional arguments for function "fun"

- better handling of the 32 connections limitation set by the HDF4
  library [#1481](rspatial/terra#1481) by
  Dimitri Falk

- When using RStudio a once per session warning is given when using
  draw, sel or click
  [#1063](rspatial/terra#1063) by Sergei
  Kharchenko

- `distance<SpatRaster>` from lon and lat lines/polygons computes
  distance to the edges instead of the nodes
  [#1462](rspatial/terra#1462) by Derek
  Friend

- `distance<SpatVector,SpatVector>` now works for lon/lat data
  [#1615](rspatial/terra#1615) by Wencheng
  Lau-Medrano

- using overviews for faster plotting of COGs over http
  [#1353](rspatial/terra#1353) by Michael
  Sumner and [#1412](rspatial/terra#1412);
  and argument `plot(x, overview=)` to change the default behavior.

- `extract` with points is now faster for rasters accessed over http
  [#1504](rspatial/terra#1504) by Krzysztof
  Dyba

- `extract` with many points on very large rasters was slower in
  compared to doing the same with "raster" (which uses terra for
  that!) [#1584](rspatial/terra#1584) by
  Hassan Masoomi

- `merge` now has three alternative algorithms
  [1366](rspatial/terra#1366) by Hassan
  Masoomi and [#1650](rspatial/terra#1650)
  by Agustin Lobo


## new

- `$<SpatRaster>` can now be used to get a categorical SpatRaster with
  a different active category

- `scale_linear<SpatRaster>` method for linear scaling of cell values
  between a minimum and maximum value such as 0 and 1

- `distance` and related methods get argument "method" to choose the
  distance algorithm for lon/lat data
  [#1677](rspatial/terra#1677) by Márcia
  Barbosa

- `divide<SpatRaster>` and `divide<SpatVector>` methods

- `nseg` counts the number of segments in a SpatVector
  [#1647](rspatial/terra#1674) by Michael
  Chirico

- `extract` argument "search_radius" to extract values from the
  nearest raster cell that is not `NA`
  [#873](rspatial/terra#873) by
  matthewseanmarcus

- `combineLevels` to combine the levels of all layers
  [link](https://stackoverflow.com/questions/79340152/how-to-set-factor-levels-in-a-rast-stack-using-terra-when-different-levels-exi)
  on SO by Sam
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants