Skip to content

Comments

Update quickstart example raster creation with correct pixel height (not upside down)#3337

Merged
sgillies merged 1 commit intorasterio:mainfrom
tveness:tv/update-docs-with-conventional-ordering
May 9, 2025
Merged

Update quickstart example raster creation with correct pixel height (not upside down)#3337
sgillies merged 1 commit intorasterio:mainfrom
tveness:tv/update-docs-with-conventional-ordering

Conversation

@tveness
Copy link
Contributor

@tveness tveness commented May 9, 2025

I noticed that the example of creating a raster file in the quickstart documents end up with the creation of a raster with "negative pixel height" ("upside down"). Following the steps in the quickstart docs, and then loading the file shows this in two separate ways: we can examine the bounds directly, and also induce an error by attempting to merge just the single file created:

>>> import rasterio
>>> import numpy as np
>>> x = np.linspace(-4.0, 4.0, 240)
>>> y = np.linspace(-3.0, 3.0, 180)
>>> y = np.linspace(-3.0, 3.0, 180)
>>> X, Y = np.meshgrid(x, y)
>>> Z1 = np.exp(-2 * np.log(2) * ((X - 0.5) ** 2 + (Y - 0.5) ** 2) / 1 ** 2)
>>> Z2 = np.exp(-3 * np.log(2) * ((X + 0.5) ** 2 + (Y + 0.5) ** 2) / 2.5 ** 2)
>>> Z = 10.0 * (Z2 - Z1)
>>> from rasterio.transform import Affine
>>> res = (x[-1] - x[0]) / 240.0
>>> transform = Affine.translation(x[0] - res / 2, y[0] - res / 2) * Affine.scale(res, res)
>>> transform
Affine(np.float64(0.03333333333333333), np.float64(0.0), np.float64(-4.016666666666667),
       np.float64(0.0), np.float64(0.03333333333333333), np.float64(-3.0166666666666666))
>>> new_dataset = rasterio.open(
...     '/tmp/new.tif',
...     'w',
...     driver='GTiff',
...     height=Z.shape[0],
...     width=Z.shape[1],
...     count=1,
...     dtype=Z.dtype,
...     crs='+proj=latlong',
...     transform=transform,
... )
>>> new_dataset.write(Z, 1)
>>> new_dataset.close()
>>> dat = rasterio.open("/tmp/new.tif")
>>> dat.bounds
BoundingBox(left=-4.016666666666667, bottom=2.9833333333333334, right=3.9833333333333334, top=-3.0166666666666666)
>>> from pathlib import Path
>>> import rasterio.merge
>>> rasterio.merge.merge([Path("/tmp/new.tif")])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/tom/pyt/.venv/lib/python3.12/site-packages/rasterio/merge.py", line 305, in merge
    raise MergeError(
rasterio.errors.MergeError: Rasters with negative pixel height ("upside down" rasters) cannot be merged.

The changes here modify this to produce the following behaviour:

>>> import rasterio
>>> import numpy as np
>>> x = np.linspace(-4.0, 4.0, 240)
>>> y = np.linspace(-3.0, 3.0, 180)[::-1]
>>> X, Y = np.meshgrid(x, y)
>>> Z1 = np.exp(-2 * np.log(2) * ((X - 0.5) ** 2 + (Y - 0.5) ** 2) / 1 ** 2)
>>> Z2 = np.exp(-3 * np.log(2) * ((X + 0.5) ** 2 + (Y + 0.5) ** 2) / 2.5 ** 2)
>>> Z = 10.0 * (Z2 - Z1)
>>> from rasterio.transform import Affine
>>> res = (x[-1] - x[0]) / 240.0
>>> transform = Affine.translation(x[0] - res / 2, y[0] + res / 2) * Affine.scale(res, -res)
>>> transform
Affine(np.float64(0.03333333333333333), np.float64(0.0), np.float64(-4.016666666666667),
       np.float64(0.0), np.float64(-0.03333333333333333), np.float64(3.0166666666666666))
>>> new_dataset = rasterio.open(
...     '/tmp/new.tif',
...     'w',
...     driver='GTiff',
...     height=Z.shape[0],
...     width=Z.shape[1],
...     count=1,
...     dtype=Z.dtype,
...     crs='+proj=latlong',
...     transform=transform,
... )
>>> new_dataset.write(Z, 1)
>>> new_dataset.close()
>>> dat = rasterio.open('/tmp/new.tif')
>>> dat.bounds
BoundingBox(left=-4.016666666666667, bottom=-2.9833333333333334, right=3.9833333333333334, top=3.0166666666666666)
>>> from pathlib import Path
>>> import rasterio.merge
>>> rasterio.merge.merge([Path('/tmp/new.tif')])
(array([[[0.00288328, 0.00311589, 0.00336475, ..., 0.00024567,
         0.00022248, 0.00020134],
        [0.00311622, 0.00336762, 0.00363659, ..., 0.00026551,
         0.00024046, 0.00021761],
        [0.00336547, 0.00363697, 0.00392745, ..., 0.00028675,
         0.00025969, 0.00023501],
        ...,
        [0.02369399, 0.02560546, 0.02765053, ..., 0.00201881,
         0.00182831, 0.00165456],
        [0.02243408, 0.02424392, 0.02618023, ..., 0.00191146,
         0.00173109, 0.00156658],
        [0.02122529, 0.02293761, 0.0247696 , ..., 0.00180847,
         0.00163782, 0.00148217]]], shape=(1, 180, 240)), Affine(0.03333333333333333, 0.0, -4.016666666666667,
       0.0, -0.03333333333333333, 3.0166666666666666))

Copy link
Member

@sgillies sgillies left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @tveness !

@sgillies sgillies self-assigned this May 9, 2025
@sgillies sgillies merged commit 09acc0c into rasterio:main May 9, 2025
1 check passed
@snowman2 snowman2 added the backport-1.4 To be backported to maint-1.4 label Nov 6, 2025
@snowman2 snowman2 added this to the 1.4.4 milestone Nov 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-1.4 To be backported to maint-1.4 documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants