pub struct Slicer<V: Vertex = Coord<i32>> { /* private fields */ }Expand description
Slices one geometry at a time into per-tile pieces on an integer grid, lazily.
Coordinates are integers in tile space: a vertex belongs to tile x.div_euclid(extent), whose own
area is [0, extent) in its local frame (x − tile·extent); every tile’s clip box grows buffer
on each side. Slices come in that local frame, so a vertex outside the tile’s own area — in its
buffer, a polygon’s synthetic corner one unit past the buffer, or a line’s first vertex beyond the
box — lies outside [0, extent). Project, simplify, and scale float source data into this space
before slicing.
Generic over the Vertex type V (defaults to Coord<i32>): plain coordinates or
payload-carrying vertices (e.g. a per-vertex M value via Measured), whose
payload rides through slicing unchanged.
The slicer never panics: bad input yields a TileError from the call itself (and, for a polygon
piece too large to index, as an Err item that ends the iteration).
Lines and points take &self, so one slicer can serve many threads. Polygons take &mut self:
they are sliced in the slicer’s reusable working memory, so use one slicer per worker.
Implementations§
Source§impl<V: Vertex> Slicer<V>
impl<V: Vertex> Slicer<V>
Sourcepub fn new(extent: u32, buffer: u16) -> Result<Self, TileError>
pub fn new(extent: u32, buffer: u16) -> Result<Self, TileError>
Create a slicer with the given tile side / per-tile output resolution extent and buffer.
§Errors
TileError::InvalidExtentifextentis0, orextent + bufferexceedsi32::MAX.TileError::BufferTooLargeifbufferis not strictly less than half theextent.
Sourcepub fn extent(&self) -> u32
pub fn extent(&self) -> u32
The tile side / per-tile output resolution: a tile’s own area is 0..extent in its local
frame (its buffer and kept vertices beyond it lie outside).
Sourcepub fn shrink_to_fit(&mut self)
pub fn shrink_to_fit(&mut self)
Release the working memory the slicer keeps between features. It only ever grows to what the largest polygon row or piece needed, but after an outlier a long-lived slicer would otherwise hold that peak forever.
Sourcepub fn line<'a>(&self, line: &'a [V]) -> Result<LineSlices<'a, V>, TileError>
pub fn line<'a>(&self, line: &'a [V]) -> Result<LineSlices<'a, V>, TileError>
Slice a line into every tile it touches.
Yields one LineSlice per run, in no particular order. A line that leaves a tile and comes
back gives that tile several items. Consecutive duplicate vertices are skipped. For a
multi-line, call this for each of its lines.
The call reads every vertex once to bound the line, so that nothing can fail once the iteration starts; the slices themselves are still computed one at a time as it advances.
§Errors
TileError::Overflow if the line lies too close to the i32 limits for this extent and
buffer: a tile box beyond i32, or a vertex more than an i32 span from the origin of a
tile its bounding box reaches. (So a line spanning more than 2^31 units on one axis is
rejected whole, even if each run would fit its tile.)
Sourcepub fn tile_line<'a>(
&self,
tile: TileId,
line: &'a [V],
) -> Result<TileLines<'a, V>, TileError>
pub fn tile_line<'a>( &self, tile: TileId, line: &'a [V], ) -> Result<TileLines<'a, V>, TileError>
Clip a line to one tile: yields its runs there, each in walk order — exactly the runs
line yields for that tile.
Like line, the call reads every vertex once; a line whose bounds miss the
tile’s buffered box yields nothing without being scanned.
§Errors
TileError::Overflow if tile’s buffered box overflows i32 (a tile far outside the
representable range for this extent), or if the line reaches the tile but has a vertex more
than an i32 span from the tile origin.
Sourcepub fn point(&self, point: V) -> Result<PointSlices<V>, TileError>
pub fn point(&self, point: V) -> Result<PointSlices<V>, TileError>
Slice a point into every tile whose buffered box holds it: its own tile, plus up to three
neighbors when it lies within buffer of an edge. Yields one PointSlice per tile. For a
multi-point, call this for each of its points.
§Errors
TileError::Overflow if one of those tiles has a buffered box beyond i32.
Sourcepub fn tile_point(&self, tile: TileId, point: V) -> Result<Option<V>, TileError>
pub fn tile_point(&self, tile: TileId, point: V) -> Result<Option<V>, TileError>
The point in tile’s local frame, if the tile’s buffered box holds it.
§Errors
TileError::Overflow if tile’s buffered box overflows i32.
Source§impl<V: PolyVertex> Slicer<V>
impl<V: PolyVertex> Slicer<V>
Sourcepub fn polygon<'s, R: AsRef<[V]>>(
&'s mut self,
rings: &'s [R],
) -> Result<PolygonSlices<'s, V, R>, TileError>
pub fn polygon<'s, R: AsRef<[V]>>( &'s mut self, rings: &'s [R], ) -> Result<PolygonSlices<'s, V, R>, TileError>
Slice a polygon into every tile it reaches. rings are its rings — the exterior first, then
the holes — each open or closed (a repeated first/last vertex is fine). Rings with fewer than
3 vertices once consecutive duplicates are dropped are ignored, and so is a polygon whose
exterior is. For a multipolygon, call this for each of its polygons.
Yields a PolygonPiece for every tile a ring edge touches (its
edge tiles), exactly what tile_polygon yields there, and a
FillRun for every row span of tiles the polygon covers entirely. Output
rings keep the winding of the input rings (see signed_area_2x to
normalize it first).
Lazy and lending: see PolygonSlices. The call reads the rings once, to bound and index
them (only a ring with consecutive duplicate vertices is copied, to drop them); after that the
iterator holds one tile row of the polygon at a time, and builds each piece as it is reached.
Every row of the polygon’s bounding box is visited, including rows where it yields nothing.
§Errors
TileError::Overflowif the polygon lies too close to thei32limits for thisextentandbuffer: a tile box (grown one unit, for the synthetic corners) beyondi32, or a vertex more than ani32span from the origin of a tile its bounding box reaches.TileError::GeometryTooLargeif there are more thanu32::MAXrings or edges.
The only error left for the iterator is a piece of more than u32::MAX vertices.
Sourcepub fn tile_polygon<'s, R: AsRef<[V]>>(
&'s mut self,
tile: TileId,
rings: &'s [R],
) -> Result<Option<PolygonPiece<'s, V, R>>, TileError>
pub fn tile_polygon<'s, R: AsRef<[V]>>( &'s mut self, tile: TileId, rings: &'s [R], ) -> Result<Option<PolygonPiece<'s, V, R>>, TileError>
Clip a polygon to one tile: its piece there, or None if it leaves nothing — what
polygon yields for that tile, with a covered tile’s
FillRun as its fill ring. The piece borrows the slicer’s working memory
until the next call.
§Errors
TileError::Overflowiftile’s buffered box overflowsi32, or a synthetic corner or kept vertex does.TileError::GeometryTooLargeif there are more thanu32::MAXrings, or the piece has more thanu32::MAXvertices.
Sourcepub fn fill_ring(&self, run: &FillRun) -> [V; 5]
pub fn fill_ring(&self, run: &FillRun) -> [V; 5]
The ring tile_polygon yields for run’s polygon in each tile of the
run: the tile’s buffered box grown by one unit, tile-local and closed (its first vertex
repeated), all synthetic vertices, wound like the polygon’s exterior. See also
PolygonSlices::fill_ring, for use while the iterator borrows the slicer.