Skip to content

from_template() should honor the requested resolution exactly #3494

Description

@brendancol

Reason or Problem

from_template(name, resolution=r) does not honor the requested resolution exactly. It keeps the template's bounding box fixed, divides it by the resolution, rounds the cell count to an integer, then recomputes the realized cell size from the fixed box. When the box extent is not an exact multiple of the resolution, the returned res drifts.

Example:

>>> from xrspatial import from_template
>>> from_template('nyc', resolution=10).attrs['res']
(10.0, 10.000757432304487)

The NYC bbox is 55510 m wide and 52814 m tall. 55510 divides evenly by 10, so res_x stays 10. 52814 does not, so res_y comes back as 10.000757. A user who asked for 10 m cells expects (10.0, 10.0).

Proposal

Honor the requested resolution exactly. Hold the lower-left corner fixed and nudge the far edges (right, top) out to the nearest exact multiple of the cell size, the same way the reproject grid path already does in _compute_output_grid. The grid extent shifts by less than half a cell while res matches the request.

Design:
In from_template, after computing width/height with round(), set right = left + width * res_x and top = bottom + height * res_y, then build the coordinates and the res attr from the requested resolution. This mirrors xrspatial/reproject/_grid.py lines 457-459.

Usage:

>>> from_template('nyc', resolution=10).attrs['res']
(10.0, 10.0)

Value: Resolution becomes a guarantee rather than advisory. Grids from from_template line up with other rasters at the same resolution, which matters for stacking, alignment, and tiling.

Drawbacks

The grid no longer reaches the registry bbox's exact stated far edge; right/top move by up to half a cell. Pixel centers still fall inside the original bbox.

Alternatives

Leave the behavior as is and document the drift. Rejected because it makes resolution advisory rather than a guarantee.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions