Selecting cells
Select cells by their spatial relationship to a point, polygon or spherical cap. query returns cells matching a predicate, such as intersection or containment. covering finds cells covering a region, and covering_indices returns positions in a cell collection.
The relation is a DE9IM predicate — Intersects, Within, Disjoint and the rest — read with spherical semantics rather than planar ones. The result depends on the query form:
| Query | Result |
|---|---|
query(grid, predicate) or query(sys, predicate; level=l) | Sorted Vector of typed cell IDs at one level |
query(sys, MultiOrderCoverage(target); level=l) or maxcells=n | MultiOrderCellSet with cells at several levels |
A query result contains identities, not field values. Use the collection conversions below to attach values or apply region operations.
Cell collections
A CellVector holds cells at one level, and a CellLookup connects them to a Cells dimension. region obtains the cell collection used by regional operations, including for a stored axis.
| You have | You need | Conversion |
|---|---|---|
A complete or partial grid g | A cell-ID vector | CellVector(g) |
Sorted unique IDs ids at level l | A compressed one-level collection | CellVector(sys, l, ids) |
A CellVector cv | Grid geometry and queries | PartialGrid(cv) |
A grid or CellVector | A dimensional array axis | CellLookup(g) or CellLookup(cv), wrapped in Cells |
A mixed-level set set | A one-level collection | CellVector(set; level=l) |
| A supported region or stored lookup | Its regional collection | region(x) |
A CellVector | Its recorded source set | cellset(cv) |
CellVector preserves canonical cell order. Keep values in that same order; these conversions do not sort an unrelated data array for you. Expansion from a mixed-level set uses hierarchy membership, which need not equal the union of its drawn polygons.
PartialGrid(sys, l, ids) requires canonical, strictly ascending, unique IDs at the stated level. It retains ids by reference: later mutation can invalidate the region. It does not provide an owning constructor that normalizes ordinary unsorted input. CellVector(sys, l, ids) also requires strictly ascending IDs.
DiscreteGlobalGrids.AbstractCellVector Type
abstract type AbstractCellVector{ID} <: AbstractVector{ID}An ascending collection of cells from one system and one level, addressed by local index. This is the region contract in vector form: the four region verbs (halo, border, interior, adjacency), the neighbourhood sweeps, regridding and plotting are all written against it, so a new backing gets the whole surface by subtyping rather than by reimplementing it.
Two backings ship. CellVector COMPUTES its ids from compressed index windows; ChunkedCellVector reads the ids a store WROTE, from its chunk manifest. What differs is where element k comes from and what it costs, not what it means.
Required interface
| method | contract |
|---|---|
system(cv) | the grid system the cells belong to |
level(cv) | the single level they are all at |
Base.size(cv) | (n,) — the number of cells |
Base.getindex(cv, k::Int) | local index k → typed cell id, 1-based |
localindex(cv, c) | cell id → local index, or nothing |
getindex and localindex are inverses over 1:length(cv), and the ids they range over are strictly ascending. A subtype that cannot promise ascent is not a cell vector; it is an unordered list of cells.
Cost is a property of the backing, not of the contract
localindex is closed-form arithmetic on one backing and may decode a stored chunk on another. Generic code that resolves indices in an order the backing did not choose is correct on both and cheap on only one, which is what chunkplan exists to fix: it names the traversal order that keeps a chunk-backed vector reading each chunk once.
See also AbstractCellLookup, the DimensionalData face of the same contract, and PartialGrid, the grid-shaped sibling.
DiscreteGlobalGrids.Engine.CellVector Type
CellVector(set::MultiOrderCellSet; level = set's reference level)
CellVector(grid::AbstractGrid)
CellVector(sys, level, ids::AbstractVector)A read-only AbstractVector of canonical cell IDs at one level of one system. cv[i] returns an ID; localindex(cv, cell) returns its position or nothing. collect(cv) creates an ordinary vector. CellVector(cv) returns cv unchanged.
The explicit-ID form requires strictly ascending IDs and validates their level. The grid form accepts complete levels and PartialGrid regions. The mixed-level form expands hierarchy membership at the requested level; that membership can differ from the union of the original cell polygons.
Use CellLookup(cv) for a Cells dimension, PartialGrid(cv) for a grid view, and cellset(cv) to inspect its recorded source. Store field values in the same order as cv.
IDs are stored as compressed index windows where possible. Storage can still grow to one index per cell, and A5 expansion visits every descendant. See Collection and traversal contracts for costs and implementation details.
sourceDiscreteGlobalGrids.CellLookups.AbstractCellLookup Type
abstract type AbstractCellLookup{ID} <: DimensionalData.Lookups.Lookup{ID,1}A DimensionalData lookup naming cells at one level — the cube face of AbstractCellVector. Base.parent returns that vector, and every cell verb a cube supports is defined once here and forwarded to it.
Two lookups ship, one per backing: CellLookup over a computed CellVector, and ChunkedCellLookup over a stored ChunkedCellVector. Code that means "the cell dimension of this cube" dispatches on this type and accepts both; naming either concrete type accepts only cubes from one source, which is how a cube from dggread comes to be refused by an operation that works on the identical cube built in memory.
Required interface
Base.parent(lk) returns an AbstractCellVector, and the lookup's getindex, length and eltype agree with it. Everything else — system, level, localindex, the neighbourhood and region verbs, PartialGrid, regridding and plotting — is generic over that one method.
A subtype still writes its own Lookups.rebuild and Lookups.selectindices, because what a SUBSET of it should be is a property of the backing: a computed window set stays compressed, and a stored axis stops being stored.
DiscreteGlobalGrids.CellLookups.CellLookup Type
CellLookup(cv::CellVector)
CellLookup(set::MultiOrderCellSet; level = set's reference level)
CellLookup(grid::AbstractGrid)A DimensionalData lookup naming cells at one level. Pair it with Cells to make a cube axis:
set = query(sys, MultiOrderCoverage(region); level = 9)
lk = CellLookup(set)
A = DimensionalData.DimArray(values, Cells(lk))Semantically lk is the leaf id vector: length(lk) is the number of leaf cells, lk[k] is the kth of them, collect(lk) is the vector itself.
CellLookup stores only a CellVector. The vector represents the set as sorted, disjoint index windows at the leaf level (level_ranges), using O(number of windows) memory instead of O(number of leaf cells). Lookup operations delegate to the vector's methods, including lk[k], localindex, cellset, covering, and PartialGrid.
Base.parent returns the lookup's VALUES, as DimensionalData requires: the CellVector, which is an AbstractVector of the ids, is O(#windows) and materialises nothing. cellset returns the backing — the set, or the grid — for running a second coverage operation against without unpacking the lookup.
Accepted inputs are:
a
MultiOrderCellSet, optionally re-expanded to a deeperlevelthan the set's own reference level;levelgrid(sys, l), a whole level, which is one window;a
PartialGrid, an arbitrary ascending subset, which is that subset's indices — one window when the subset is a subtree, and the explicit list when it is scattered.
All forms construct a CellVector; an existing vector can be passed directly.
Selectors
A[Cells(DimensionalData.At(c))] # a typed cell id
A[Cells(DimensionalData.Contains(8.0, 46.5))] # a lon/lat point, through `cellat`
A[Cells(Covering(polygon))] # a region, through `MultiOrderCoverage`At and Contains resolve to one index; Covering to the indices of every stored cell the region's coverage names, and the view it produces carries a CellLookup again. Outside a cube those three are localindex(cv, c), localindex(cv, lon, lat) and covering(cv, polygon).
At and Contains are referenced as DD.At and DD.Contains. They are not re-exported because this package exports DE9IM's unrelated Contains geometry predicate. Covering is exported by this package.
DD.Near throws: cell ids ascend along a space-filling curve, so snapping to the nearest id is not snapping to the nearest cell on the sphere, and this lookup has no nearest-member search to offer instead. Contains(lon, lat) answers the question Near is usually reached for.
What the cube's own operations do to it
Indexing, concatenation, and reductions preserve the most specific valid lookup:
an ASCENDING subset — a range, a sorted index vector, a boolean mask, a selector's result, or a concatenation of disjoint ascending axes — is a window set again, so it is a
CellLookup;a REORDERED one —
lk[[3, 1]],reverse(A; dims = Cells)— is not, and falls back to an unorderedDimensionalData.Categoricalof the same ids. The values are right and the selectors work; the type is notCellLookup, so reversing twice restores the data but not the axis's type;a reduction (
sum(A; dims = Cells)) collapses to a single element that no cell id names, so the axis becomesNoLookup;rebuildaround anything that is not cell ids at this level throws, since aCellLookuphas no free fields to put them in. Replacing an axis wholesale isset(A, Cells => NoLookup()).
Systems without sorted subtrees (A5) are built by selection
level_ranges throws where has_sorted_subtrees is false, because a cell's descendants are not one interval of their level. The lookup is then built by selection: descendants names the leaves, they are resolved to indices and sorted, and the result is run-compressed like any other index list. Every method above is unchanged and every law still holds. CellVector documents what that costs, and the one consequence it inherits: on A5 a Covering selection is a superset of the cells that meet the region, by the same margin the refinement is.
DiscreteGlobalGrids.region Function
region(x) -> CellVectorThe compressed CellVector a region is answered as — the container the four region verbs, the neighbourhood sweeps, regridding and plotting are all written against.
On a CellVector or a CellLookup this is the identity: they already are that container. On a stored axis (ChunkedCellVector, ChunkedCellLookup) it is the conversion, built on first call and kept, so the cost is paid once however many verbs are asked afterwards. What that costs depends on the encoding and is documented on CellVector(::ChunkedCellVector).
Index order is preserved: local index k of the result is local index k of x, which is what lets a result computed through it be written back against x's own axis without a permutation.
Query functions
DiscreteGlobalGrids.query Function
query(grid::AbstractGrid, pred) -> Vector{<:AbstractCellIndex}
query(sys::AbstractHierarchicalGridSystem, pred; level::Integer) -> Vector{<:AbstractCellIndex}Every cell satisfying the spatial predicate pred, as a sorted Vector of typed cell ids.
Predicates
Predicates are the re-exported DE9IM.jl wrappers (Intersects(target), Covers(target), Touches(target), ...) and the centroid rule CentroidCovered(target), given spherical semantics by this package.
The target is a GeoInterface geometry, an Extents.Extent, or a GO.UnitSpherical.SphericalCap; Base.parent(pred) returns it. Lon/lat targets are lifted to the unit sphere once, at the boundary of the call.
Semantics
Tree pruning may over-select candidates; prepared spherical predicates determine the exact result.
The sys method answers at the requested level without materialising the level grid.
DiscreteGlobalGrids.Engine.covering Function
covering(cv::CellVector, target) -> CellVectorThe cells of cv that a MultiOrderCoverage of target names, at cv's own level — the region selector, as a CellVector again, so what a subset stores is windows rather than an id vector.
target is anything query accepts: a GeoInterface geometry, an Extents.Extent in lon/lat degrees, or a GO.UnitSpherical.SphericalCap.
cv = CellVector(query(sys, MultiOrderCoverage(canton); level = 9))
basin = covering(cv, watershed) # a CellVector again
data[covering_indices(cv, watershed)] # the same selection as indicescovering_indices is the index-space form, for indexing a data array laid out against cv. This is what the DimensionalData selector Covering is spelled as outside DimensionalData.
Selection visits each leaf named by the coverage, even though the result is stored compactly. Select at the level being read to avoid unnecessary expansion.
This operation uses fixed-level coverage at level(cv). Within cv, its result includes the cells meeting target; noncongruent refinement can add extra cells. With congruent refinement the selection equals intersection. These are fixed-level guarantees, not guarantees for a maxcells query.
DiscreteGlobalGrids.Engine.covering_indices Function
covering_indices(cv::CellVector, target) -> Vector{Int}The indices in cv of the cells covering selects, ascending — for indexing a data array laid out against cv without building the sub-vector.
covering(cv, target) and cv[covering_indices(cv, target)] name the same cells; this form is the one a cube's getindex needs, and is what the Covering selector resolves to.
covering_indices(axis::ChunkedCellVector, target) -> Vector{Int}The indices in axis of the cells a MultiOrderCoverage of target names, ascending — the index-space form of the Covering selector.
The coverage is walked in ascending index order, so a chunk-backed axis touches each chunk the region meets once.
This is the same verb CellVector answers, on a stored axis instead of a computed one.
DiscreteGlobalGrids.Engine.cellset Function
cellset(lk::AbstractCellLookup)Return the MultiOrderCellSet or grid used to construct the lookup.
Base.parent(lk) returns the logical values as an AbstractCellVector. A subset produced by indexing or selection reports its PartialGrid, as does a lookup over a stored axis, which was constructed from no set at all.
cellset(cv::CellVector)
cellset(lk::CellLookup)Return the MultiOrderCellSet or grid used to build the collection.
A collection derived from another one, by indexing or by covering, has no such origin and reports the PartialGrid describing it instead.
For CellLookup, Base.parent returns the logical values as a CellVector.
The predicates
The DE9IM types are DE9IM.jl's and CentroidCovered is this package's; the semantics throughout are this package's, evaluated on the sphere. Every one of them takes the target geometry as its argument, and Base.parent gives it back.
Read Predicate(target) as cell RELATION target. The DE9IM predicates test the cell footprint; CentroidCovered tests the cell's centroid.
| Predicate | Keep a cell when… | Geometry or lon/lat extent | Spherical cap |
|---|---|---|---|
Intersects | Cell and target share a point | Yes | Yes |
Disjoint | Cell and target share no point | Yes | Yes |
Within | The cell lies within the target | Yes | Yes; cap boundary contact is accepted |
Contains | The target lies within the cell | Yes | No |
CoveredBy | The target covers the cell, including its boundary | Yes | No |
Covers | The cell covers the target, including its boundary | Yes | No |
Touches | Boundaries meet without interior intersection | Yes | No |
Overlaps | Same-dimensional interiors partly overlap | Yes | No |
Equals | Cell and target are topologically equal | Yes | No |
Crosses | Not implemented by this query engine | No | No |
CentroidCovered | The cell's centroid lies on or inside the target | Yes | Yes |
For polygon targets, Within and Contains require the relevant interiors to intersect. CoveredBy and Covers include boundary-only containment. Thus Within(zone) asks for cells inside a zone; Contains(zone) asks for cells large enough to contain the zone. CoveredBy(zone) and Covers(zone) reverse direction in the same way.
CentroidCovered(zone) selects cells by centroid containment, the raster zonal rule boundary = :center of Rasterize, extract, and zonal; Within(zone) selects a subset of it and Intersects(zone) a superset.
Unsupported query predicates raise ArgumentError.
DE9IM.DE9IMPredicate Type
DE9IMPredicate{T} <: AnyAbstract type for all DE9IM predicates objects.
sourceDE9IM.Intersects Type
Intersects{T} <: DE9IMPredicate{T}
Intersects(b)
Intersects()Intersects: Two geometries intersect if they have any point in common.
An Intersects predicate returns true if the two geometries have at least one point in common.
If Intersects wraps an object passed to a predicate function, it must be the second argument B.
DE9IM.Disjoint Type
Disjoint{T} <: DE9IMPredicate{T}
Disjoint(b)
Disjoint()Disjoint: Two geometries are disjoint if their intersection is empty.
A Disjoint predicate returns true if the two geometries have no points in common.
If Disjoint wraps an object passed to a predicate function, it must be the second argument B.
DE9IM.Contains Type
Contains{T} <: DE9IMPredicate{T}
Contains(b)
Contains()Contains: Geometry A contains geometry B if and only if all points of B lie in the interior of A.
A Contains predicate returns true if all points of the second geometry lie in the interior of the first geometry.
If Contains wraps an object passed to a predicate function, it must be the second argument B.
DE9IM.Within Type
Within{T} <: DE9IMPredicate{T}
Within(b)
Within() = Within(nothing)Within: Geometry A is within geometry B if and only if all points of A lie in the interior of B.
A Within predicate returns true if all points of the first geometry lie in the interior of the second geometry.
If Within wraps an object passed to a predicate function, it must be the second argument B.
DE9IM.Covers Type
Covers{T} <: DE9IMPredicate{T}
Covers(b)
Covers()Covers: Geometry A covers geometry B if and only if the intersection of A and B is equal to B.
A Covers predicate returns true if the intersection of the two geometries is equal to the second geometry.
If Covers wraps an object passed to a predicate function, it must be the second argument B.
DE9IM.CoveredBy Type
CoveredBy{T} <: DE9IMPredicate{T}
CoveredBy(b)
CoveredBy()CoveredBy: Geometry A is covered by geometry B if and only if the intersection of A and B is equal to A.
A CoveredBy predicate returns true if the intersection of the two geometries is equal to the first geometry.
If CoveredBy wraps an object passed to a predicate function, it must be the second argument B.
DE9IM.Touches Type
Touches{T} <: DE9IMPredicate{T}
Touches(b)
Touches()Touches: Two geometries touch if they have at least one point in common, but their interiors do not intersect.
A Touches predicate returns true if the two geometries have at least one point in common, but their interiors do not intersect.
DE9IM.Crosses Type
Crosses{T} <: DE9IMPredicate{T}
Crosses(b)
Crosses()Crosses: Geometry A crosses geometry B if and only if they have some but not all interior points in common.
A Crosses predicate returns true if the two geometries have some but not all interior points in common.
DE9IM.Overlaps Type
Overlaps{T} <: DE9IMPredicate{T}
Overlaps() = Overlaps(nothing)Overlaps: Geometry A overlaps geometry B if and only if they have some interior points in common.
An Overlaps predicate returns true if the two geometries have some interior points in common.
DE9IM.Equals Type
Equals{T} <: DE9IMPredicate{T}
Equals() = Equals(nothing)Equals: Two geometries are equal if and only if they have the same boundary and interior points.
An Equals predicate returns true if the two geometries have the same boundary and interior points.
DiscreteGlobalGrids.Engine.CentroidCovered Type
CentroidCovered(region)A query predicate selecting every cell whose cell_centroid lies on or inside region (cell centroid COVERED BY region, the raster boundary = :center rule), so Within ⊆ CentroidCovered ⊆ Intersects.
region is any target query accepts (geometry, Extents.Extent, or SphericalCap); Base.parent(pred) gives it back. It works through query and as a Cells selector:
query(grid, CentroidCovered(county)) # cells centred in a polygon
A[Cells(CentroidCovered(cap))] # cells centred in a SphericalCapMulti-order answers
MultiOrderCoverage queries a region using cells at several levels and returns a MultiOrderCellSet. See Multi-order coverage for a worked example.
DiscreteGlobalGrids.Engine.MultiOrderCoverage Type
MultiOrderCoverage(target)Request cells at several levels through query. target accepts a GeoInterface geometry, a longitude/latitude extent in degrees, or a spherical cap. Supply exactly one mode to query:
level=l: refine boundary crossings to levell. Expanding the result at that level includes every intersecting cell. With congruent refinement, the expansion equals the fixed-level intersection result.maxcells=n: refine within a cell budget, optionally limited bymaxlevel. If the initial seed exceedsn, it is returned over budget. On noncongruent systems, this mode does not guarantee full polygon or reference-level coverage.
HEALPix, S2, and ISEA4R have congruent refinement. IGeo7, H3, and A5 do not: a parent's polygon can differ from the union of its descendants. Use iscontained for proven containment and level_ranges for represented leaves where sorted subtrees are available. See Multi-order coverage for the mode comparison and examples.
DiscreteGlobalGrids.Engine.MultiOrderCellSet Type
MultiOrderCellSetA mixed-level cell set returned by MultiOrderCoverage. Iteration yields typed ids in descendant-range order at the reference level; systems without sorted subtrees use (level, id) order. level_ranges expands it to sorted, disjoint ranges at one level.
iscontained reports which cells were proven to fit inside the target — not which ones do; that docstring draws the line. cell_polygon and cell_polygons read mixed-level geometry without the caller resolving a level grid per cell.
The REFERENCE LEVEL is the depth the set speaks about — the level the query was given, or in maxcells mode the deepest level the budget reached. It is the default expansion level for level_ranges, cellindices and CellLookup. Coverage at that level depends on the query mode and refinement traits; see MultiOrderCoverage.
Expansion needs sorted subtrees
level_ranges throws where has_sorted_subtrees is false (A5), because a cell's descendants do not occupy one interval of their level. descendants(sys, c, l) still names them, as a list rather than ranges.
DiscreteGlobalGrids.Engine.level_ranges Function
level_ranges(set::MultiOrderCellSet, l::Integer) -> Vector{UnitRange{Int}}Expand the set to sorted, disjoint index ranges in levelgrid(sys, l), merging adjacent ranges. Requires sorted subtrees and l no shallower than any cell in the set.
Two things the expansion is not
Not universal: it throws where has_sorted_subtrees is false (A5). Branch on the trait, or expand with descendants(sys, c, l).
Not a covering. A cell is in the set because the cell is inside the target; under non-congruent refinement its descendants need not be, so the expansion can name leaves the target does not touch — most visibly inside a hole. See MultiOrderCoverage.
DiscreteGlobalGrids.cellindices Function
cellindices(set::MultiOrderCellSet, l::Integer) -> Vector{<:AbstractCellIndex}The set expanded to level l as typed ids, ascending — level_ranges resolved through cellindex. O(cells at l), so reach for the ranges instead wherever the indices are what is wanted.
DiscreteGlobalGrids.Engine.iscontained Function
iscontained(set::MultiOrderCellSet, i::Integer) -> BoolWhether the set's ith cell was proven to lie inside the coverage target: Within was asked of it and held. false means one of two things, told apart by the cell's level:
above the traversal's maximum depth, the cell was asked and the target's boundary crosses it — exact, in both directions.
at the maximum depth, the cell was never asked: the traversal ran out of depth and emitted it to cover. It may or may not fit.
In level mode the maximum depth is the reference level. In maxcells mode the maximum depth is the maxlevel cap, and a budget that stopped short of it — the ordinary case — carries an exact flag on every member.
The asymmetry is the contract: Within allocates ~48 KB per call against ~600 B for Intersects, and labelling thousands of reference-level cells exactly changes no member of the set. true implies inside; code needing exact containment asks Within of the few cells it cares about.
argmin(level, set) is therefore not "the coarsest cell inside the target": every emission can be unproven. coarsest_contained reads this flag.
DiscreteGlobalGrids.Engine.coarsest_contained Function
coarsest_contained(set::MultiOrderCellSet) -> cell id or `nothing`The shallowest cell of set proven inside the coverage target, or nothing when none was — see iscontained for what "proven" leaves out. Maximum-depth cells are never tested, so a set of nothing but those answers nothing even where some fit. A budget set answers nothing while nothing has been refined far enough to fit inside the target; the answer appears as the budget grows.
set = query(sys, MultiOrderCoverage(tile); level = 12)
cell = coarsest_contained(set) # `nothing`, or a cell that fits in `tile`Ties go to the first such cell in the set's own order.
sourceDiscreteGlobalGrids.Engine.cell_polygons Function
cell_polygons(set::MultiOrderCellSet) -> Vector{<:GI.Polygon}Every cell of the set as a unit-sphere polygon, in the set's own order: what a plot of a coverage needs, in one call.
poly(GO.transform(GO.GeographicFromUnitSphere(), cell_polygons(set)))Region algebra
Use expand to obtain cells at a chosen level and compact to merge complete sibling groups. grow, documented with region boundaries, adds neighbouring cells to a region.
DiscreteGlobalGrids.Engine.expand Function
expand(region, l::Integer) -> CellVector
expand(set::MultiOrderCellSet, l::Integer) -> CellVectorEvery level-l descendant of the region's cells, as one CellVector. l equal to the region's own level returns it unchanged; a coarser l (l < level(region)) throws.
The expansion never assumes a cell's descendants are contiguous or ascending in the deeper level. Where has_sorted_subtrees holds it merges one descendant_range per cell; elsewhere (A5) it resolves descendants to indices and sorts them. Both paths visit every cell of the region, and the second visits every leaf it names.
The set form is CellVector(set; level = l) — the same expansion, from the mixed-level side.
Descendants of a member need not lie inside the member's own footprint under non-congruent refinement, so an expanded coverage over-covers exactly where the refinement does; MultiOrderCoverage sizes that margin per system.
DiscreteGlobalGrids.Engine.compact Function
compact(region) -> MultiOrderCellSetThe region as a mixed-level set, with every complete sibling group replaced by its parent, recursively. The result names the same leaves at the region's own level, which becomes the set's reference level: expand(compact(cv), level(cv)) is cv again.
Ascent runs level by level and costs O(k log k) in the k cells still standing at that level; a region with no complete sibling group stops after one pass. A group counts as complete against length(children(sys, parent)), the parent's own child count — pentagon parents are not assumed to have the hexagonal one.
iscontained is false on every member: compaction has no coverage target, so nothing was proven to lie inside anything.
The DimensionalData layer
A cube over cells carries a Cells dimension, whose lookup is a CellLookup. Covering is the selector that turns a geometry into a selection on that dimension, so A[Cells(Covering(geom))] is the cube spelling of query.
DiscreteGlobalGrids.CellLookups.Cells Type
Cells(x)The DimensionalData dimension of a cube's cell axis: Cells(lk) where lk is a CellLookup, and Cells(selector) when indexing.
A = DimensionalData.DimArray(values, Cells(CellLookup(set)))
A[Cells(Covering(county))]DiscreteGlobalGrids.CellLookups.Covering Type
Covering(target)Select every stored cell named by MultiOrderCoverage for target at the lookup's level.
A[Cells(Covering(county))] # a GeoInterface geometry
A[Cells(Covering(extent))] # a lon/lat Extents.Extent
A[Cells(Covering(cap))] # a GO.UnitSpherical.SphericalCaptarget is anything query accepts. The result is the intersection of the coverage's leaf expansion with the lookup, in ascending index order. The resulting view retains a CellLookup.
Outside a cube, the equivalent selection is covering(cv, target), which returns a CellVector, or covering_indices(cv, target) for the indices alone. See that docstring for what the selection costs and for the over-covering it inherits from the coverage itself.
A query predicate — Cells(Intersects(target)), Cells(Within(target)) — is the exact selection the coverage over-covers; see Cells.
DiscreteGlobalGrids.Engine.predicate_indices Function
predicate_indices(cv::CellVector, pred) -> Vector{Int}The indices in cv of the cells that satisfy pred at cv's level, ascending — query(system(cv), pred; level = level(cv)) intersected with cv, answered in index space so a data array laid out against cv can be indexed by it.
pred is any predicate query implements, over any target it accepts; cv[predicate_indices(cv, Within(cap))] names the cells of cv lying wholly inside cap. This is what a predicate used as a Cells selector resolves to. Unlike covering_indices, the answer is exact: it inherits no over-covering from a coverage.
predicate_indices(axis::ChunkedCellVector, pred) -> Vector{Int}The indices in axis of the cells that satisfy pred at the axis's level, ascending — the index-space form of a predicate used as a Cells selector, on a stored axis instead of a computed one.
query answers in ascending id order, so a chunk-backed axis touches each chunk the matching cells fall in once.