Skip to content

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:

QueryResult
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=nMultiOrderCellSet 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 haveYou needConversion
A complete or partial grid gA cell-ID vectorCellVector(g)
Sorted unique IDs ids at level lA compressed one-level collectionCellVector(sys, l, ids)
A CellVector cvGrid geometry and queriesPartialGrid(cv)
A grid or CellVectorA dimensional array axisCellLookup(g) or CellLookup(cv), wrapped in Cells
A mixed-level set setA one-level collectionCellVector(set; level=l)
A supported region or stored lookupIts regional collectionregion(x)
A CellVectorIts recorded source setcellset(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
julia
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

methodcontract
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.

source
DiscreteGlobalGrids.Engine.CellVector Type
julia
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.

source
DiscreteGlobalGrids.CellLookups.AbstractCellLookup Type
julia
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.

source
DiscreteGlobalGrids.CellLookups.CellLookup Type
julia
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:

julia
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 deeper level than 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

julia
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 unordered DimensionalData.Categorical of the same ids. The values are right and the selectors work; the type is not CellLookup, 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 becomes NoLookup;

  • rebuild around anything that is not cell ids at this level throws, since a CellLookup has no free fields to put them in. Replacing an axis wholesale is set(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.

source
DiscreteGlobalGrids.region Function
julia
region(x) -> CellVector

The 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.

source

Query functions ​

DiscreteGlobalGrids.query Function
julia
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.

source
DiscreteGlobalGrids.Engine.covering Function
julia
covering(cv::CellVector, target) -> CellVector

The 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.

julia
cv    = CellVector(query(sys, MultiOrderCoverage(canton); level = 9))
basin = covering(cv, watershed)          # a CellVector again
data[covering_indices(cv, watershed)]    # the same selection as indices

covering_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.

source
DiscreteGlobalGrids.Engine.covering_indices Function
julia
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.

source
julia
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.

source
DiscreteGlobalGrids.Engine.cellset Function
julia
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.

source
julia
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.

source

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.

PredicateKeep a cell when…Geometry or lon/lat extentSpherical cap
IntersectsCell and target share a pointYesYes
DisjointCell and target share no pointYesYes
WithinThe cell lies within the targetYesYes; cap boundary contact is accepted
ContainsThe target lies within the cellYesNo
CoveredByThe target covers the cell, including its boundaryYesNo
CoversThe cell covers the target, including its boundaryYesNo
TouchesBoundaries meet without interior intersectionYesNo
OverlapsSame-dimensional interiors partly overlapYesNo
EqualsCell and target are topologically equalYesNo
CrossesNot implemented by this query engineNoNo
CentroidCoveredThe cell's centroid lies on or inside the targetYesYes

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
julia
DE9IMPredicate{T} <: Any

Abstract type for all DE9IM predicates objects.

source
DE9IM.Intersects Type
julia
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.

source
DE9IM.Disjoint Type
julia
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.

source
DE9IM.Contains Type
julia
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.

source
DE9IM.Within Type
julia
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.

source
DE9IM.Covers Type
julia
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.

source
DE9IM.CoveredBy Type
julia
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.

source
DE9IM.Touches Type
julia
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.

source
DE9IM.Crosses Type
julia
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.

source
DE9IM.Overlaps Type
julia
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.

source
DE9IM.Equals Type
julia
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.

source
DiscreteGlobalGrids.Engine.CentroidCovered Type
julia
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:

julia
query(grid, CentroidCovered(county))    # cells centred in a polygon
A[Cells(CentroidCovered(cap))]          # cells centred in a SphericalCap
source

Multi-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
julia
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 level l. 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 by maxlevel. If the initial seed exceeds n, 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.

source
DiscreteGlobalGrids.Engine.MultiOrderCellSet Type
julia
MultiOrderCellSet

A 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.

source
DiscreteGlobalGrids.Engine.level_ranges Function
julia
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.

source
DiscreteGlobalGrids.cellindices Function
julia
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.

source
DiscreteGlobalGrids.Engine.iscontained Function
julia
iscontained(set::MultiOrderCellSet, i::Integer) -> Bool

Whether 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.

source
DiscreteGlobalGrids.Engine.coarsest_contained Function
julia
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.

julia
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.

source
DiscreteGlobalGrids.Engine.cell_polygons Function
julia
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.

julia
poly(GO.transform(GO.GeographicFromUnitSphere(), cell_polygons(set)))
source

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
julia
expand(region, l::Integer) -> CellVector
expand(set::MultiOrderCellSet, l::Integer) -> CellVector

Every 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.

source
DiscreteGlobalGrids.Engine.compact Function
julia
compact(region) -> MultiOrderCellSet

The 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.

source

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
julia
Cells(x)

The DimensionalData dimension of a cube's cell axis: Cells(lk) where lk is a CellLookup, and Cells(selector) when indexing.

julia
A = DimensionalData.DimArray(values, Cells(CellLookup(set)))
A[Cells(Covering(county))]
source
DiscreteGlobalGrids.CellLookups.Covering Type
julia
Covering(target)

Select every stored cell named by MultiOrderCoverage for target at the lookup's level.

julia
A[Cells(Covering(county))]          # a GeoInterface geometry
A[Cells(Covering(extent))]          # a lon/lat Extents.Extent
A[Cells(Covering(cap))]             # a GO.UnitSpherical.SphericalCap

target 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.

source
DiscreteGlobalGrids.Engine.predicate_indices Function
julia
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.

source
julia
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.

source

Index ​