Skip to content

feat: replace narray with numo-narray - #120

Open
Oleksii Leonov (oleksii-leonov) wants to merge 3 commits into
telus-agcg:developfrom
syngenta:feat/replace-narray-with-numo-narray
Open

feat: replace narray with numo-narray#120
Oleksii Leonov (oleksii-leonov) wants to merge 3 commits into
telus-agcg:developfrom
syngenta:feat/replace-narray-with-numo-narray

Conversation

@oleksii-leonov

@oleksii-leonov Oleksii Leonov (oleksii-leonov) commented Jan 28, 2026

Copy link
Copy Markdown
Contributor

Depends on #151 -- this branch is stacked on test/pin-dataset-to-na-narray-behavior; once #151 merges, the diff here shrinks to the single port commit.

Replacing narray with numo-narray. The narray gem is C code unmaintained for 10 years; numo-narray is its maintained successor. This is a breaking change for consumers -- #151 pins the old behavior in specs first, so every observable change shows up in this PR as an explicit spec diff rather than silent semantics drift.

Behavior changes (each visible as a spec diff)

API narray (old) numo-narray (new)
RasterBand#to_na shape [x, y] [y, x] (row-major)
to_na(:GDT_UInt16) signed NArray::INT (wasted memory) Numo::UInt16
to_na(:GDT_UInt32) signed NArray::INT (values > 2^31 - 1 overflow) Numo::UInt32
to_na(:GDT_Float32) double (NArray::FLOAT aliases DFLOAT) true single precision (Numo::SFloat)
to_na(:GDT_CFloat32) double complex Numo::SComplex
RasterBand#to_nna Numo::NArray[*rows] -- Ruby integers infer Int32 alias of #to_na, honors band data type
RasterBand#projected_points indexed [coord, x, y], nested [line][pixel][coord] same indexing, nested [coord][pixel][line] (doc updated)
Dataset#to_na band-major [band][x][y] nesting, NMatrix upcast byte to int Numo::NArray.dstack: per-pixel tuples [y, x, band], dtype preserved
Grid#create points Array or NArray Array or Numo::NArray
GDAL._narray_from_data_type() (no size) empty shapeless NArray [0]-shaped array

Type-mapping is now exact:

def _gdal_data_type_to_numo_narray_type_constant(data_type)
  case data_type
  when :GDT_Byte                               then Numo::UInt8
  when :GDT_Int16                              then Numo::Int16
  when :GDT_UInt16                             then Numo::UInt16
  when :GDT_Int32                              then Numo::Int32
  when :GDT_UInt32                             then Numo::UInt32
  when :GDT_Float32                            then Numo::SFloat
  when :GDT_Float64                            then Numo::DFloat
  when :GDT_CInt16, :GDT_CInt32, :GDT_CFloat32 then Numo::SComplex
  when :GDT_CFloat64                           then Numo::DComplex
  else
    raise GDAL::InvalidDataType, "Unknown data type: #{data_type}"
  end
end

Notes for reviewers

  • Dataset#to_na had no coverage and its previous doc example promised output no implementation ever produced; it now has specs and honest docs (see test(gdal): pin Dataset#to_na NArray behavior #151 for the archaeology).
  • projected_points still truncates coordinates on integer bands (pre-existing; faithful port). A follow-up PR will switch coordinate storage to Numo::DFloat.
  • Known migration note for consumers: code iterating Dataset#to_na.to_a or projected_points.to_a must swap loop nesting; code using indexed access ([y, x, band] / [coord, x, y]) is unaffected.

Why Dataset#to_na changes shape here, and what is deliberately NOT changed

This PR's goal is a gem swap that keeps behavior as-is wherever numo permits. Dataset#to_na is the one place a behavior-identical port is impossible:

  • The old implementation depended on NMatrix, which is removed together with narray, so the method had to be rewritten either way (see test(gdal): pin Dataset#to_na NArray behavior #151 for the archaeology: the transpose was a 2014 zip-bands-into-pixels idiom that never actually produced its documented per-pixel output on real 2-D bands).
  • narray and numo disagree on one convention (narray declares dimensions fastest-first, numo fastest-last), so for any 3-D result you can preserve either the indexed access or the nested #to_a representation -- never both.
  • This port preserves indexed access exactly: result[y, x, band] returns the same element before and after (the pinned "is indexed as [y, x, band]" spec passes unchanged on both sides). The nested representation changing from band-major [band][x][y] to per-pixel [y][x][band] tuples is the forced consequence -- which happens to be what the 2014 doc example always promised.

Any further semantic redesign -- ordering guarantees, a different stacking layout, the projected_points coordinate typing/nesting -- is deliberately out of scope and deferred to separate follow-up PRs, so this one stays reviewable as "same behavior, new backing gem, honest specs".

Put concretely for Dataset#to_na consumers: reading one pixel's band values -- result[y, x, true] -- worked before this PR (the old index order accidentally fulfilled the documented "points per pixel" intent) and works identically after it; the pinned spec example for it passes unchanged on both sides of the stack. What this PR changes is only the nested representation: #to_a/iteration used to show band-major [band][x][y] planes and now shows the same per-pixel tuples the indexed access always gave, so the two views of the data finally agree with each other and with the docs.

@oleksii-leonov

Copy link
Copy Markdown
Contributor Author

Issue #55.

end
end

# DEPRECATED: Use Numo::NArray directly instead.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@turboladen

Copy link
Copy Markdown
Contributor

Just a note for any future 👀 that this contains API-breaking changes, so should cause a major version bump.

@kurtronshausen

Copy link
Copy Markdown
Contributor

Just a note for any future 👀 that this contains API-breaking changes, so should cause a major version bump.

Isn't the convention usually to have the maintainers (us) bump the version?

@turboladen

Copy link
Copy Markdown
Contributor

Just a note for any future 👀 that this contains API-breaking changes, so should cause a major version bump.

Isn't the convention usually to have the maintainers (us) bump the version?

Yeah. But just wanted to call this out.

@turboladen

Copy link
Copy Markdown
Contributor

Oleksii Leonov (@oleksii-leonov) could you rebase and we'll get this merged?

Copilot AI review requested due to automatic review settings July 10, 2026 15:11
@oleksii-leonov
Oleksii Leonov (oleksii-leonov) force-pushed the feat/replace-narray-with-numo-narray branch from df08ac8 to 4e35ef6 Compare July 10, 2026 15:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR completes the migration from the discontinued narray gem to numo-narray, updating internal helpers and raster APIs to construct/return Numo::NArray instances with more precise GDAL-to-array type mappings (notably for UInt16/UInt32), and removing the old narray dependency and monkeypatch.

Changes:

  • Replace narray requires/usages with numo-narray across GDAL/OGR extension points.
  • Update GDAL data type → array type mapping to use Numo::* classes with improved precision for unsigned integer types.
  • Update unit specs to reflect numo-narray behavior and APIs.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
spec/unit/gdal/internal_helpers_spec.rb Updates expectations to Numo::* types and Numo::NArray allocation semantics.
spec/unit/gdal/extensions/raster_band/io_extensions_spec.rb Adjusts raster-band IO expectations for Numo::NArray indexing/serialization.
spec/unit/gdal/extensions/raster_band/extensions_spec.rb Updates RasterBand#to_na expectations to Numo::* typed arrays.
spec/unit/gdal/extensions/raster_band_classifier_spec.rb Updates classifier setup away from indgen! for numo-narray.
lib/ogr/coordinate_transformation.rb Removes narray require (no longer needed).
lib/gdal/raster_band.rb Removes narray require (migration cleanup).
lib/gdal/internal_helpers.rb Introduces numo-narray type mapping and deprecates legacy NArray mapping helpers.
lib/gdal/grid.rb Switches to numo/narray and updates type checks/docs.
lib/gdal/extensions/raster_band/extensions.rb Makes to_na/to_nna return Numo::NArray and updates projected-points allocation.
lib/gdal/extensions/gridder.rb Removes narray require (migration cleanup).
lib/gdal/extensions/dataset/extensions.rb Switches dataset-level to_na to build Numo::NArray output.
lib/ffi-gdal.rb Removes ext/narray_ext load.
lib/ext/narray_ext.rb Deletes legacy NArray#type monkeypatch.
ffi-gdal.gemspec Drops narray dependency and adds numo-narray.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/gdal/internal_helpers.rb Outdated
Comment thread lib/gdal/extensions/raster_band/extensions.rb
Comment thread lib/gdal/extensions/dataset/extensions.rb
Comment thread spec/unit/gdal/extensions/raster_band_classifier_spec.rb
Comment thread spec/unit/gdal/extensions/raster_band_classifier_spec.rb
Comment thread spec/unit/gdal/extensions/raster_band_classifier_spec.rb
@tindron

Copy link
Copy Markdown
Contributor

numo-narray hasn't had a release since 2022. numo-narray-alt is a maintained drop in replacement. Should we consider switching?

@kurtronshausen

Copy link
Copy Markdown
Contributor

numo-narray hasn't had a release since 2022. numo-narray-alt is a maintained drop in replacement. Should we consider switching?

sounds good to me.

@oleksii-leonov

Copy link
Copy Markdown
Contributor Author

Yes, numo-narray-alt looks like a good solution.
I will rebase the PR and switch to numo-narray-alt.

@oleksii-leonov
Oleksii Leonov (oleksii-leonov) force-pushed the feat/replace-narray-with-numo-narray branch from 4e35ef6 to 4c85b49 Compare August 14, 2026 11:32
Oleksii Leonov (oleksii-leonov) added a commit to syngenta/ffi-gdal that referenced this pull request Aug 14, 2026
More pins for behavior the narray-to-numo-narray migration (telus-agcg#120)
touches, so its changes surface as explicit spec diffs:

* RasterBand#projected_points (never covered): nested representation is
  [line][pixel][coord] as documented, indexed [coord, x, y], and the
  output is typed after the band's pixel data type -- so integer bands
  truncate fractional projected coordinates (a defect to fix separately);
* RasterBand#to_nna (never covered): Numo::NArray[*rows] infers Int32
  from Ruby integers instead of honoring the band's byte type;
* GDAL._narray_from_data_type: narray has no unsigned types and aliases
  FLOAT/COMPLEX to the double variants, so GDT_UInt16/GDT_UInt32
  allocate signed int (UInt32 > 2**31 - 1 unrepresentable), GDT_Float32
  double, GDT_CFloat32 double-complex. NArray#== ignores types, so the
  existing eq-based examples could not pin any of this;
* Grid#create: points may be a typed NArray, not only a plain Array.
@oleksii-leonov
Oleksii Leonov (oleksii-leonov) force-pushed the feat/replace-narray-with-numo-narray branch from ad38eac to 7277917 Compare August 14, 2026 12:48
@oleksii-leonov

Copy link
Copy Markdown
Contributor Author

Steve Loveless (@turboladen) Randy Stoller (@tindron)

  1. There are some changes in behaviour for code that were not covered by the specs previously. I opened a separate specs-only PR test(gdal): pin Dataset#to_na NArray behavior #151 to document the current behaviour for legacy NArray to create a clean baseline. This makes behaviour changes caused by switching to Numo clearly visible and documented in the specs.
  2. Let's merge and release the switch to numo-narray first. Then we can switch to numo-narray-alt in a separate PR and release. Currently, users of ffi-gdal may have numo-narray as a dependency in their Gemfiles (used for other purposes). And adding numo-narray-alt may cause conflicts/issue if both numo-narray and numo-narray-alt are present.

Oleksii Leonov (oleksii-leonov) added a commit to syngenta/ffi-gdal that referenced this pull request Aug 14, 2026
More pins for behavior the narray-to-numo-narray migration (telus-agcg#120)
touches, so its changes surface as explicit spec diffs:

* RasterBand#projected_points (never covered): nested representation is
  [line][pixel][coord] as documented, indexed [coord, x, y], and the
  output is typed after the band's pixel data type -- so integer bands
  truncate fractional projected coordinates (a defect to fix separately);
* RasterBand#to_nna (never covered): Numo::NArray[*rows] infers Int32
  from Ruby integers instead of honoring the band's byte type;
* GDAL._narray_from_data_type: narray has no unsigned types and aliases
  FLOAT/COMPLEX to the double variants, so GDT_UInt16/GDT_UInt32
  allocate signed int (UInt32 > 2**31 - 1 unrepresentable), GDT_Float32
  double, GDT_CFloat32 double-complex. NArray#== ignores types, so the
  existing eq-based examples could not pin any of this;
* Grid#create: points may be a typed NArray, not only a plain Array.
@oleksii-leonov
Oleksii Leonov (oleksii-leonov) force-pushed the feat/replace-narray-with-numo-narray branch 2 times, most recently from 3ef79c5 to 268bc29 Compare August 14, 2026 13:48
Oleksii Leonov (oleksii-leonov) added a commit to syngenta/ffi-gdal that referenced this pull request Aug 14, 2026
More pins for behavior the narray-to-numo-narray migration (telus-agcg#120)
touches, so its changes surface as explicit spec diffs:

* RasterBand#projected_points (never covered): nested representation is
  [line][pixel][coord] as documented, indexed [coord, x, y], and the
  output is typed after the band's pixel data type -- so integer bands
  truncate fractional projected coordinates (a defect to fix separately);
* RasterBand#to_nna (never covered): Numo::NArray[*rows] infers Int32
  from Ruby integers instead of honoring the band's byte type;
* GDAL._narray_from_data_type: narray has no unsigned types and aliases
  FLOAT/COMPLEX to the double variants, so GDT_UInt16/GDT_UInt32
  allocate signed int (UInt32 > 2**31 - 1 unrepresentable), GDT_Float32
  double, GDT_CFloat32 double-complex. NArray#== ignores types, so the
  existing eq-based examples could not pin any of this;
* Grid#create: points may be a typed NArray, not only a plain Array.
@oleksii-leonov
Oleksii Leonov (oleksii-leonov) force-pushed the feat/replace-narray-with-numo-narray branch from 268bc29 to 6fcc707 Compare August 14, 2026 13:55
Oleksii Leonov (oleksii-leonov) added a commit to syngenta/ffi-gdal that referenced this pull request Aug 14, 2026
More pins for behavior the narray-to-numo-narray migration (telus-agcg#120)
touches, so its changes surface as explicit spec diffs:

* RasterBand#projected_points (never covered): nested representation is
  [line][pixel][coord] as documented, indexed [coord, x, y], and the
  output is typed after the band's pixel data type -- so integer bands
  truncate fractional projected coordinates (a defect to fix separately);
* RasterBand#to_nna (never covered): Numo::NArray[*rows] infers Int32
  from Ruby integers instead of honoring the band's byte type;
* GDAL._narray_from_data_type: narray has no unsigned types and aliases
  FLOAT/COMPLEX to the double variants, so GDT_UInt16/GDT_UInt32
  allocate signed int (UInt32 > 2**31 - 1 unrepresentable), GDT_Float32
  double, GDT_CFloat32 double-complex. NArray#== ignores types, so the
  existing eq-based examples could not pin any of this;
* Grid#create: points may be a typed NArray, not only a plain Array.
@oleksii-leonov
Oleksii Leonov (oleksii-leonov) force-pushed the feat/replace-narray-with-numo-narray branch from 6fcc707 to cf78a87 Compare August 14, 2026 13:56
Oleksii Leonov (oleksii-leonov) added a commit to syngenta/ffi-gdal that referenced this pull request Aug 14, 2026
More pins for behavior the narray-to-numo-narray migration (telus-agcg#120)
touches, so its changes surface as explicit spec diffs:

* RasterBand#projected_points (never covered): nested representation is
  [line][pixel][coord] as documented, indexed [coord, x, y], and the
  output is typed after the band's pixel data type -- so integer bands
  truncate fractional projected coordinates (a defect to fix separately);
* RasterBand#to_nna (never covered): Numo::NArray[*rows] infers Int32
  from Ruby integers instead of honoring the band's byte type;
* GDAL._narray_from_data_type: narray has no unsigned types and aliases
  FLOAT/COMPLEX to the double variants, so GDT_UInt16/GDT_UInt32
  allocate signed int (UInt32 > 2**31 - 1 unrepresentable), GDT_Float32
  double, GDT_CFloat32 double-complex. NArray#== ignores types, so the
  existing eq-based examples could not pin any of this;
* Grid#create: points may be a typed NArray, not only a plain Array.
@oleksii-leonov
Oleksii Leonov (oleksii-leonov) force-pushed the feat/replace-narray-with-numo-narray branch from cf78a87 to e934024 Compare August 14, 2026 14:01
Oleksii Leonov (oleksii-leonov) added a commit to syngenta/ffi-gdal that referenced this pull request Aug 14, 2026
More pins for behavior the narray-to-numo-narray migration (telus-agcg#120)
touches, so its changes surface as explicit spec diffs:

* RasterBand#projected_points (never covered): nested representation is
  [line][pixel][coord] as documented, indexed [coord, x, y], and the
  output is typed after the band's pixel data type -- so integer bands
  truncate fractional projected coordinates (a defect to fix separately);
* RasterBand#to_nna (never covered): Numo::NArray[*rows] infers Int32
  from Ruby integers instead of honoring the band's byte type;
* GDAL._narray_from_data_type: narray has no unsigned types and aliases
  FLOAT/COMPLEX to the double variants, so GDT_UInt16/GDT_UInt32
  allocate signed int (UInt32 > 2**31 - 1 unrepresentable), GDT_Float32
  double, GDT_CFloat32 double-complex. NArray#== ignores types, so the
  existing eq-based examples could not pin any of this;
* Grid#create: points may be a typed NArray, not only a plain Array.
@oleksii-leonov
Oleksii Leonov (oleksii-leonov) force-pushed the feat/replace-narray-with-numo-narray branch from e934024 to 81a4591 Compare August 14, 2026 14:08
Oleksii Leonov (oleksii-leonov) added a commit to syngenta/ffi-gdal that referenced this pull request Aug 14, 2026
More pins for behavior the narray-to-numo-narray migration (telus-agcg#120)
touches, so its changes surface as explicit spec diffs:

* RasterBand#projected_points (never covered): nested representation is
  [line][pixel][coord] as documented, indexed [coord, x, y], and the
  output is typed after the band's pixel data type -- so integer bands
  truncate fractional projected coordinates (a defect to fix separately);
* RasterBand#to_nna (never covered): Numo::NArray[*rows] infers Int32
  from Ruby integers instead of honoring the band's byte type;
* GDAL._narray_from_data_type: narray has no unsigned types and aliases
  FLOAT/COMPLEX to the double variants, so GDT_UInt16/GDT_UInt32
  allocate signed int (UInt32 > 2**31 - 1 unrepresentable), GDT_Float32
  double, GDT_CFloat32 double-complex. NArray#== ignores types, so the
  existing eq-based examples could not pin any of this;
* Grid#create: points may be a typed NArray, not only a plain Array.
@oleksii-leonov
Oleksii Leonov (oleksii-leonov) force-pushed the feat/replace-narray-with-numo-narray branch from 81a4591 to 5d166d2 Compare August 14, 2026 14:30
Oleksii Leonov (oleksii-leonov) added a commit to syngenta/ffi-gdal that referenced this pull request Aug 14, 2026
More pins for behavior the narray-to-numo-narray migration (telus-agcg#120)
touches, so its changes surface as explicit spec diffs:

* RasterBand#projected_points (never covered): nested representation is
  [line][pixel][coord] as documented, indexed [coord, x, y], and the
  output is typed after the band's pixel data type -- so integer bands
  truncate fractional projected coordinates (a defect to fix separately);
* RasterBand#to_nna (never covered): Numo::NArray[*rows] infers Int32
  from Ruby integers instead of honoring the band's byte type;
* GDAL._narray_from_data_type: narray has no unsigned types and aliases
  FLOAT/COMPLEX to the double variants, so GDT_UInt16/GDT_UInt32
  allocate signed int (UInt32 > 2**31 - 1 unrepresentable), GDT_Float32
  double, GDT_CFloat32 double-complex. NArray#== ignores types, so the
  existing eq-based examples could not pin any of this;
* Grid#create: points may be a typed NArray, not only a plain Array.
@oleksii-leonov
Oleksii Leonov (oleksii-leonov) force-pushed the feat/replace-narray-with-numo-narray branch from 5d166d2 to 6bf2fdb Compare August 14, 2026 14:32
Oleksii Leonov (oleksii-leonov) added a commit to syngenta/ffi-gdal that referenced this pull request Aug 14, 2026
More pins for behavior the narray-to-numo-narray migration (telus-agcg#120)
touches, so its changes surface as explicit spec diffs:

* RasterBand#projected_points (never covered): nested representation is
  [line][pixel][coord] as documented, indexed [coord, x, y], and the
  output is typed after the band's pixel data type -- so integer bands
  truncate fractional projected coordinates (a defect to fix separately);
* RasterBand#to_nna (never covered): Numo::NArray[*rows] infers Int32
  from Ruby integers instead of honoring the band's byte type;
* GDAL._narray_from_data_type: narray has no unsigned types and aliases
  FLOAT/COMPLEX to the double variants, so GDT_UInt16/GDT_UInt32
  allocate signed int (UInt32 > 2**31 - 1 unrepresentable), GDT_Float32
  double, GDT_CFloat32 double-complex. NArray#== ignores types, so the
  existing eq-based examples could not pin any of this;
* Grid#create: points may be a typed NArray, not only a plain Array.
@oleksii-leonov
Oleksii Leonov (oleksii-leonov) force-pushed the feat/replace-narray-with-numo-narray branch from 6bf2fdb to 9955be3 Compare August 14, 2026 14:34
Oleksii Leonov (oleksii-leonov) added a commit to syngenta/ffi-gdal that referenced this pull request Aug 14, 2026
More pins for behavior the narray-to-numo-narray migration (telus-agcg#120)
touches, so its changes surface as explicit spec diffs:

* RasterBand#projected_points (never covered): nested representation is
  [line][pixel][coord] as documented, indexed [coord, x, y], and the
  output is typed after the band's pixel data type -- so integer bands
  truncate fractional projected coordinates (a defect to fix separately);
* RasterBand#to_nna (never covered): Numo::NArray[*rows] infers Int32
  from Ruby integers instead of honoring the band's byte type;
* GDAL._narray_from_data_type: narray has no unsigned types and aliases
  FLOAT/COMPLEX to the double variants, so GDT_UInt16/GDT_UInt32
  allocate signed int (UInt32 > 2**31 - 1 unrepresentable), GDT_Float32
  double, GDT_CFloat32 double-complex. NArray#== ignores types, so the
  existing eq-based examples could not pin any of this;
* Grid#create: points may be a typed NArray, not only a plain Array.
@oleksii-leonov
Oleksii Leonov (oleksii-leonov) force-pushed the feat/replace-narray-with-numo-narray branch from 9955be3 to 3cedeb0 Compare August 14, 2026 14:53
Dataset#to_na has never had spec coverage, and its doc example promised
per-pixel band-value tuples ([[0, 10, 99, 2], ...]) that no
implementation in the repo's history ever produced. Pin what the method
actually returns before the narray-to-numo-narray migration changes it,
so that migration's behavior changes show up as explicit spec diffs
rather than silent semantics drift:

* the result is indexed [y, x, band], but its nested (#to_a)
  representation is band-major with x/y swapped: [band][x][y];
* the NMatrix intermediate widens types: byte bands come back as int;
* a :GDT_Float32 conversion comes back double, because narray aliases
  NArray::FLOAT to DFLOAT.

The doc comment is corrected to describe this real behavior.
More pins for behavior the narray-to-numo-narray migration (telus-agcg#120)
touches, so its changes surface as explicit spec diffs:

* RasterBand#projected_points (never covered): nested representation is
  [line][pixel][coord] as documented, indexed [coord, x, y], and the
  output is typed after the band's pixel data type -- so integer bands
  truncate fractional projected coordinates (a defect to fix separately);
* RasterBand#to_nna (never covered): Numo::NArray[*rows] infers Int32
  from Ruby integers instead of honoring the band's byte type;
* GDAL._narray_from_data_type: narray has no unsigned types and aliases
  FLOAT/COMPLEX to the double variants, so GDT_UInt16/GDT_UInt32
  allocate signed int (UInt32 > 2**31 - 1 unrepresentable), GDT_Float32
  double, GDT_CFloat32 double-complex. NArray#== ignores types, so the
  existing eq-based examples could not pin any of this;
* Grid#create: points may be a typed NArray, not only a plain Array.
Replace the unmaintained narray gem with numo-narray across the raster
API. Numo is row-major, so RasterBand#to_na returns [y, x] (was [x, y])
and Dataset#to_na / #projected_points nesting changes accordingly; the
behavior pins added by the preceding test commits turn every observable
change into an explicit spec diff:

* RasterBand#to_na: shape [y, x]; conversions honor the requested type
  exactly -- GDT_UInt16/GDT_UInt32 get real unsigned storage (narray
  allocated signed int; UInt32 > 2**31 - 1 was unrepresentable),
  GDT_Float32 gets true single precision (narray aliased FLOAT to
  double), GDT_CFloat32 gets single-precision complex.
* RasterBand#to_nna: now an alias of #to_na, honoring the band's data
  type (was Numo::NArray[*rows], which let Ruby integers infer Int32).
* RasterBand#projected_points: still indexed [coord, x, y] with
  band-typed (truncating) storage, but the nested representation is now
  [coord][pixel][line]; the doc is corrected to say so.
* Dataset#to_na: stacks bands with Numo::NArray.dstack into documented
  per-pixel band-value tuples, [y, x, band], preserving dtype. The old
  NMatrix construction returned band-major [band][x][y] nesting and
  upcast types; the first numo rewrite of it raised TypeError on every
  call (Array#transpose on Numo arrays) -- it now has spec coverage.
* Grid#create: points may be a typed Numo::NArray (was NArray).
* GDAL._narray_from_data_type with no size args returns a [0]-shaped
  array (was an empty, shapeless NArray).
@oleksii-leonov
Oleksii Leonov (oleksii-leonov) force-pushed the feat/replace-narray-with-numo-narray branch from 3cedeb0 to 911f76c Compare August 14, 2026 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants