Repository: rasterio/rasterio

Issue:
DatasetReader.sample() no longer supports passing a list of points as a numpy array
## Context

When testing [OSMnx](https://osmnx.readthedocs.io/en/stable/), we recently had a test case failure. The test case looks up an address with OSMnx, then uses a raster file to add elevation data to each node. The full OSMnx details are in the linked issue.

## Expected behavior and actual behavior.

We want to be able to use numpy arrays with [DatasetReader.sample()](https://rasterio.readthedocs.io/en/latest/api/rasterio._io.html#rasterio._io.DatasetReaderBase.sample). In versions 1.2.10 and before, that worked.

## Steps to reproduce the problem.

Here is a minimal example of the behavior we're observing.

```
import rasterio
import numpy as np
# Download this file here: https://github.com/gboeing/osmnx/blob/main/tests/input_data/elevation2.tif
f = rasterio.open('./tests/input_data/elevation2.tif')
# A list of points works...
points = [[-122.402, 37.795]]
print(list(f.sample(points)))
# ...but a numpy array does not
points = np.array([[-122.402, 37.795]])
print(list(f.sample(points)))
```

In 1.2.10, this produces the following:

```
[array([36], dtype=int16)]
[array([36], dtype=int16)]
```

In 1.3.0, this produces the following:

```
[array([36], dtype=int16)]
Traceback (most recent call last):
  File "test.py", line 10, in <module>
    print(list(f.sample(points)))
  File "/Users/nick/.anaconda3/anaconda3/envs/osmnx-dev2/lib/python3.8/site-packages/rasterio/sample.py", line 61, in sample_gen
    pts = zip(*filter(None, pts))
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
```

#### Environment Information

##### Nonworking config

```
rasterio info:
  rasterio: 1.3.0
      GDAL: 3.5.0
      PROJ: 9.0.0
      GEOS: 0.0.0
 PROJ DATA: /Users/nick/.anaconda3/anaconda3/envs/osmnx-dev2/share/proj
 GDAL DATA: /Users/nick/.anaconda3/anaconda3/envs/osmnx-dev2/share/gdal

System:
    python: 3.8.13 | packaged by conda-forge | (default, Mar 25 2022, 06:05:47)  [Clang 12.0.1 ]
executable: /Users/nick/.anaconda3/anaconda3/envs/osmnx-dev2/bin/python
   machine: macOS-10.16-x86_64-i386-64bit

Python deps:
    affine: 2.3.1
     attrs: 21.4.0
   certifi: 2022.06.15
     click: 8.1.3
     cligj: 0.7.2
    cython: None
     numpy: 1.23.1
    snuggs: 1.4.7
click-plugins: None
setuptools: 63.1.0
```

##### Working config

- rasterio version 1.2.10
 - GDAL version 3.3.2
 - Python version 3.8.13 | packaged by conda-forge | (default, Mar 25 2022, 06:05:47)  [Clang 12.0.1 ]
 - Operation macOS-10.16-x86_64-i386-64bit


## Installation Method

All versions installed from PyPI using pip 22.1.2

## Related threads

OSMnx fix discussion: https://github.com/gboeing/osmnx/pull/842 (ignore first three comments, they correspond to a different issue)

Last PR changing sample_gen(): https://github.com/rasterio/rasterio/pull/2338


Discussion:

Resolving patch:
diff --git a/rasterio/__init__.py b/rasterio/__init__.py
--- a/rasterio/__init__.py
+++ b/rasterio/__init__.py
@@ -55,7 +55,7 @@ class FilePath:
         have_vsi_plugin = False
 
 __all__ = ['band', 'open', 'pad', 'Env', 'CRS']
-__version__ = "1.3.0.post1"
+__version__ = "1.3.1dev"
 __gdal_version__ = gdal_version()
 __proj_version__ = ".".join([str(version) for version in get_proj_version()])
 __geos_version__ = ".".join([str(version) for version in get_geos_version()])
diff --git a/rasterio/sample.py b/rasterio/sample.py
--- a/rasterio/sample.py
+++ b/rasterio/sample.py
@@ -58,7 +58,7 @@ def sample_gen(dataset, xy, indexes=None, masked=False):
         nodata = np.ma.array(nodata, mask=mask)
 
     for pts in _grouper(xy, 256):
-        pts = zip(*filter(None, pts))
+        pts = zip(*filter(lambda x: x is not None, pts))
 
         for row_off, col_off in zip(*rowcol(dt, *pts)):
             if row_off < 0 or col_off < 0 or row_off >= height or col_off >= width:


Test patch:
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -2,7 +2,7 @@ name: Tests
 
 on:
   push:
-    branches: [ master ]
+    branches: [ maint-1.3 ]
     paths:
       - '.github/workflows/tests.yaml'
       - 'requirements*.txt'
@@ -14,7 +14,7 @@ on:
       - 'rasterio/**'
       - 'tests/**'
   pull_request:
-    branches: [ master ]
+    branches: [ maint-1.3 ]
     paths:
       - '.github/workflows/tests.yaml'
       - 'requirements*.txt'
diff --git a/tests/test_io.py b/tests/test_io.py
--- a/tests/test_io.py
+++ b/tests/test_io.py
@@ -6,7 +6,7 @@
 
 
 httpstif = (
-    "https://github.com/rasterio/rasterio/blob/master/tests/data/float32.tif?raw=true"
+    "https://github.com/rasterio/rasterio/blob/main/tests/data/float32.tif?raw=true"
 )
 
 
diff --git a/tests/test_sampling.py b/tests/test_sampling.py
--- a/tests/test_sampling.py
+++ b/tests/test_sampling.py
@@ -50,3 +50,10 @@ def test_sampling_type():
     with rasterio.open('tests/data/RGB.byte.tif') as src:
         sampler = src.sample([(220650.0, 2719200.0)], indexes=[2])
         assert type(sampler)
+
+
+def test_sampling_ndarray():
+    """sample and sample_gen can take ndarrays of coords."""
+    with rasterio.open('tests/data/RGB.byte.tif') as src:
+        data = next(src.sample(numpy.array([[220650.0, 2719200.0]])))
+        assert list(data) == [18, 25, 14]