First of all, thanks for the Rust port of the S2 lib! I still have a lot to learn about S2 in general but I'm running into a wall on this and feel like there must be a better way.
The Goal
Traverse multiple cells in any (edge) direction from a given cell.
Quick Example
My API ingests some Polygon shape.
I create a RegionCoverer to collect all cells in the bbox of that shape.
Then I want to traverse those cells and collect the Lat/Lng point every 9 cells in a grid pattern.
Current Implementation
My initial implementation of this essentially called .edge_neighbors over and over n times to get to where I wanted to go. Since looking at source, I think I've moved onto something a little more sophisticated:
// implementation for `TraversalCell`
fn traverse(&mut self, count: u64) {
let face = self.cell.face();
let level = self.cell.level();
let size = (cellid::size_ij(level) * count) as i32;
let (f, cur_i, cur_j, _) = self.cell.face_ij_orientation();
let (next_i, next_j) = match self.dir {
Dir::Up => (cur_i, cur_j + size),
Dir::Right => (cur_i + size, cur_j),
Dir::Down => (cur_i, cur_j - size),
Dir::Left => (cur_i - size, cur_j),
};
// this function was copied from source since it was originally private
self.cell = from_face_ij_wrap(f, next_i, next_j).parent(level);
if self.cell.face() != self.prev_face {
self.prev_face = face;
}
}
This works...okay. When the face stays the same, it's fine. When the face changes after a traversal, that's when things start to fall apart and where I'm running into a wall here.
The Dir enum is somewhat arbitrary, it was originally N, E, S, W, but since S2 cell neighbors don't always necessarily align with that I've swapped to something more generic.
I've looked at all sorts of various ways of manipulating the direction depending on the current face / current dir / previous face and for the most part have found some solutions that probably lean more in the hacky direction for solving most scenarios when there are 2 faces, but I haven't found something that will account for places where there are 3 faces. The issue that I'm running into with this is that some solutions will work for most scenarios but sometimes they have to be adapted entirely for other scenarios that then no longer work for the previously working ones.
Questions
Is there a better way that I should be approaching this problem entirely?
Can you clarify what you meant in the edge_neighbors docs here: Edges 0, 1, 2, 3 are in the down, right, up, left directions? Are down, right, up, left somewhat arbitrary or determined in some way that I don't understand...
And maybe an unnecessary question depending on the answer to the first one, but is there a more reliable way to be setting the dir property depending on the face?
Apologies, I know that's a lot of info but any help is appreciated, thank you!
First of all, thanks for the Rust port of the S2 lib! I still have a lot to learn about S2 in general but I'm running into a wall on this and feel like there must be a better way.
The Goal
Traverse multiple cells in any (edge) direction from a given cell.
Quick Example
Current Implementation
My initial implementation of this essentially called
.edge_neighbors
over and overn
times to get to where I wanted to go. Since looking at source, I think I've moved onto something a little more sophisticated:Structs:
Traversal function:
This works...okay. When the face stays the same, it's fine. When the face changes after a traversal, that's when things start to fall apart and where I'm running into a wall here.
The
Dir
enum is somewhat arbitrary, it was originally N, E, S, W, but since S2 cell neighbors don't always necessarily align with that I've swapped to something more generic.I've looked at all sorts of various ways of manipulating the direction depending on the current face / current dir / previous face and for the most part have found some solutions that probably lean more in the hacky direction for solving most scenarios when there are 2 faces, but I haven't found something that will account for places where there are 3 faces. The issue that I'm running into with this is that some solutions will work for most scenarios but sometimes they have to be adapted entirely for other scenarios that then no longer work for the previously working ones.
Questions
edge_neighbors
docs here:Edges 0, 1, 2, 3 are in the down, right, up, left directions
? Aredown
,right
,up
,left
somewhat arbitrary or determined in some way that I don't understand...dir
property depending on the face?Apologies, I know that's a lot of info but any help is appreciated, thank you!