rastr 0.3.0__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rastr might be problematic. Click here for more details.
- {rastr-0.3.0 → rastr-0.5.0}/.github/copilot-instructions.md +1 -1
- {rastr-0.3.0 → rastr-0.5.0}/.github/workflows/ci.yml +19 -22
- {rastr-0.3.0 → rastr-0.5.0}/CONTRIBUTING.md +14 -2
- {rastr-0.3.0 → rastr-0.5.0}/PKG-INFO +10 -4
- {rastr-0.3.0 → rastr-0.5.0}/README.md +8 -2
- {rastr-0.3.0 → rastr-0.5.0}/pyproject.toml +1 -3
- {rastr-0.3.0 → rastr-0.5.0}/src/rastr/_version.py +2 -2
- {rastr-0.3.0 → rastr-0.5.0}/src/rastr/create.py +24 -14
- {rastr-0.3.0 → rastr-0.5.0}/src/rastr/io.py +5 -5
- {rastr-0.3.0 → rastr-0.5.0}/src/rastr/raster.py +579 -102
- rastr-0.5.0/src/scripts/demo_taper_border.py +4 -0
- {rastr-0.3.0 → rastr-0.5.0}/tests/rastr/test_create.py +132 -20
- {rastr-0.3.0 → rastr-0.5.0}/tests/rastr/test_meta.py +7 -7
- rastr-0.5.0/tests/rastr/test_raster.py +2419 -0
- {rastr-0.3.0 → rastr-0.5.0}/uv.lock +23 -22
- rastr-0.3.0/tests/rastr/test_raster.py +0 -1348
- {rastr-0.3.0 → rastr-0.5.0}/.copier-answers.yml +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/.github/ISSUE_TEMPLATE/enhancement.md +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/.github/workflows/release.yml +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/.gitignore +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/.pre-commit-config.yaml +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/.python-version +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/LICENSE +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/docs/index.md +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/docs/logo.svg +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/mkdocs.yml +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/pyrightconfig.json +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/requirements.txt +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/src/archive/.gitkeep +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/src/notebooks/.gitkeep +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/src/rastr/__init__.py +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/src/rastr/arr/__init__.py +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/src/rastr/arr/fill.py +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/src/rastr/gis/__init__.py +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/src/rastr/gis/fishnet.py +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/src/rastr/gis/smooth.py +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/src/rastr/meta.py +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/src/scripts/.gitkeep +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/src/scripts/demo_point_cloud.py +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/ABOUT_TASKS.md +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/dev_sync.ps1 +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/scripts/activate_venv.sh +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/scripts/configure_project.sh +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/scripts/dev_sync.sh +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/scripts/install_backend.sh +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/scripts/install_venv.sh +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/scripts/recover_corrupt_venv.sh +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/scripts/sh_runner.ps1 +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/scripts/sync_requirements.sh +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/scripts/sync_template.sh +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/activate_venv +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/activate_venv.cmd +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/activate_venv.ps1 +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/configure_project +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/configure_project.cmd +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/configure_project.ps1 +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/dev_sync +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/dev_sync.cmd +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/dev_sync.ps1 +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/install_backend +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/install_backend.cmd +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/install_backend.ps1 +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/install_venv +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/install_venv.cmd +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/install_venv.ps1 +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/recover_corrupt_venv +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/recover_corrupt_venv.cmd +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/recover_corrupt_venv.ps1 +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/sync_requirements +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/sync_requirements.cmd +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/sync_requirements.ps1 +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/sync_template +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/sync_template.cmd +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/shims/sync_template.ps1 +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tasks/sync_template.ps1 +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tests/assets/.gitkeep +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tests/assets/pga_g_clipped.grd +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tests/assets/pga_g_clipped.tif +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tests/conftest.py +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tests/rastr/.gitkeep +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tests/rastr/gis/test_fishnet.py +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tests/rastr/gis/test_smooth.py +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tests/rastr/regression_test_data/test_plot_raster.png +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tests/rastr/regression_test_data/test_write_raster_to_file.tif +0 -0
- {rastr-0.3.0 → rastr-0.5.0}/tests/rastr/test_io.py +0 -0
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
- Write unit tests using `pytest` inside `tests/`, structured based on `src/`.
|
|
11
11
|
- Example: `src/x/y/z` → `tests/x/y/test_z.py`
|
|
12
12
|
- Use test fixtures and group tests into classes when appropriate.
|
|
13
|
-
- When testing methods on classes, create nested test classes within the test class associated with the overall tested class (e.g., `TestContour` nested within `
|
|
13
|
+
- When testing methods on classes, create nested test classes within the test class associated with the overall tested class (e.g., `TestContour` nested within `TestRaster` when testing the `contour` method of `Raster`).
|
|
14
14
|
- After modifying a function, run its unit tests using pytest.
|
|
15
15
|
- Run tests in virtual environment: `.\.venv\Scripts\activate; python -m pytest tests/path/to/test_file.py -v`
|
|
16
16
|
|
|
@@ -5,17 +5,17 @@ permissions:
|
|
|
5
5
|
on:
|
|
6
6
|
workflow_dispatch:
|
|
7
7
|
push:
|
|
8
|
-
branches: [
|
|
8
|
+
branches: ["master", "develop"]
|
|
9
9
|
paths-ignore:
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
10
|
+
- "docs/**"
|
|
11
|
+
- "**/*.md"
|
|
12
|
+
- "mkdocs.yml"
|
|
13
13
|
pull_request:
|
|
14
|
-
branches: [
|
|
14
|
+
branches: ["master", "develop"]
|
|
15
15
|
paths-ignore:
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
16
|
+
- "docs/**"
|
|
17
|
+
- "**/*.md"
|
|
18
|
+
- "mkdocs.yml"
|
|
19
19
|
concurrency:
|
|
20
20
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
21
21
|
cancel-in-progress: true
|
|
@@ -39,21 +39,15 @@ jobs:
|
|
|
39
39
|
version: "0.7.13" # Sync with pyproject.toml
|
|
40
40
|
enable-cache: true
|
|
41
41
|
|
|
42
|
-
- name:
|
|
43
|
-
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
|
44
|
-
with:
|
|
45
|
-
python-version: ${{ matrix.python-version }}
|
|
46
|
-
|
|
47
|
-
- name: Setup dependencies
|
|
42
|
+
- name: Setup Python
|
|
48
43
|
run: |
|
|
49
44
|
uv python pin ${{ matrix.python-version }}
|
|
50
|
-
uv
|
|
51
|
-
uv pip install --system -r ci-requirements.txt
|
|
45
|
+
uv python install
|
|
52
46
|
|
|
53
47
|
- name: Run pre-commit
|
|
54
48
|
if: matrix.checks
|
|
55
49
|
run: |
|
|
56
|
-
uv run
|
|
50
|
+
uv run pre-commit run --all-files
|
|
57
51
|
|
|
58
52
|
- name: Run pyright
|
|
59
53
|
if: matrix.checks
|
|
@@ -64,7 +58,10 @@ jobs:
|
|
|
64
58
|
uses: pavelzw/pytest-action@510c5e90c360a185039bea56ce8b3e7e51a16507 # v2.2.0
|
|
65
59
|
if: matrix.pytest
|
|
66
60
|
with:
|
|
61
|
+
custom-pytest: uv run pytest
|
|
67
62
|
custom-arguments: --cov --junitxml=junit.xml -o junit_family=legacy --cov-report=xml
|
|
63
|
+
env:
|
|
64
|
+
MPLBACKEND: Agg # https://github.com/orgs/community/discussions/26434
|
|
68
65
|
|
|
69
66
|
- name: Create test reports directory
|
|
70
67
|
if: matrix.pytest && matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13'
|
|
@@ -96,20 +93,20 @@ jobs:
|
|
|
96
93
|
runs-on: ubuntu-latest
|
|
97
94
|
needs: tests
|
|
98
95
|
if: always() && needs.tests.result == 'success'
|
|
99
|
-
|
|
96
|
+
|
|
100
97
|
steps:
|
|
101
98
|
- name: Checkout code
|
|
102
99
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
103
100
|
with:
|
|
104
|
-
fetch-depth: 0
|
|
105
|
-
|
|
101
|
+
fetch-depth: 0 # Shallow clones should be disabled for better relevancy of analysis
|
|
102
|
+
|
|
106
103
|
- name: Download coverage reports
|
|
107
104
|
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
|
108
105
|
with:
|
|
109
106
|
name: coverage-reports
|
|
110
107
|
path: test-reports/
|
|
111
108
|
continue-on-error: true
|
|
112
|
-
|
|
109
|
+
|
|
113
110
|
- name: Create SonarQube properties
|
|
114
111
|
run: |
|
|
115
112
|
cat > sonar-project.properties << EOF
|
|
@@ -122,7 +119,7 @@ jobs:
|
|
|
122
119
|
sonar.exclusions=**/Dockerfile,**/notebooks/**,**/scripts/**
|
|
123
120
|
sonar.verbose=false
|
|
124
121
|
EOF
|
|
125
|
-
|
|
122
|
+
|
|
126
123
|
- name: Run SonarQube analysis
|
|
127
124
|
uses: SonarSource/sonarqube-scan-action@884b79409bbd464b2a59edc326a4b77dc56b2195 # v3.1.0
|
|
128
125
|
env:
|
|
@@ -55,9 +55,21 @@ uv run detect-test-pollution --fuzz --tests ./tests
|
|
|
55
55
|
|
|
56
56
|
and follow the prompts to bisect the tests.
|
|
57
57
|
|
|
58
|
-
### Profiling Test
|
|
58
|
+
### Profiling the Test Suite
|
|
59
59
|
|
|
60
|
-
To profile the
|
|
60
|
+
To profile the test suite, use `pyinstrument`:
|
|
61
|
+
|
|
62
|
+
```shell
|
|
63
|
+
uv run pyinstrument -m pytest
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
For more in-depth exploration, try the `-r html` option to generate an HTML report:
|
|
67
|
+
|
|
68
|
+
```shell
|
|
69
|
+
uv run pyinstrument -r html -m pytest
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
To profile the speed of test _collection_ (which is mostly related to import times), you can also use `pyinstrument`:
|
|
61
73
|
|
|
62
74
|
```shell
|
|
63
75
|
uv run pyinstrument -m pytest --collect-only
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rastr
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Geospatial Raster datatype library for Python.
|
|
5
5
|
Project-URL: Source Code, https://github.com/tonkintaylor/rastr
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/tonkintaylor/rastr/issues
|
|
7
7
|
Project-URL: Releases, https://github.com/tonkintaylor/rastr/releases
|
|
8
|
-
Project-URL: Source Archive, https://github.com/tonkintaylor/rastr/archive/
|
|
8
|
+
Project-URL: Source Archive, https://github.com/tonkintaylor/rastr/archive/fde05e3c098da7ff9e77a37332d55fb7dbacd873.zip
|
|
9
9
|
Author-email: Tonkin & Taylor Limited <Sub-DisciplineData+AnalyticsStaff@tonkintaylor.co.nz>, Nathan McDougall <nmcdougall@tonkintaylor.co.nz>, Ben Karl <bkarl@tonkintaylor.co.nz>
|
|
10
10
|
License-Expression: MIT
|
|
11
11
|
License-File: LICENSE
|
|
@@ -75,10 +75,10 @@ from pyproj.crs.crs import CRS
|
|
|
75
75
|
from rasterio.transform import from_origin
|
|
76
76
|
from rastr.create import full_raster
|
|
77
77
|
from rastr.meta import RasterMeta
|
|
78
|
-
from rastr.raster import
|
|
78
|
+
from rastr.raster import Raster
|
|
79
79
|
|
|
80
80
|
# Create an example raster
|
|
81
|
-
raster =
|
|
81
|
+
raster = Raster.example()
|
|
82
82
|
|
|
83
83
|
# Basic arithmetic operations
|
|
84
84
|
doubled = raster * 2
|
|
@@ -131,6 +131,12 @@ Current version limitations:
|
|
|
131
131
|
- Square cells only (rectangular cell support planned).
|
|
132
132
|
- Only float dtypes (integer support planned).
|
|
133
133
|
|
|
134
|
+
## Similar Projects
|
|
135
|
+
|
|
136
|
+
- [rasters](https://github.com/python-rasters/rasters) is a project with similar goals of providing a dedicated raster datatype in Python with higher-level interfaces for GIS operations. Unlike `rastr`, it has support for multi-band rasters, and has some more advanced functionality for Earth Science applications. Both projects are relatively new and under active development.
|
|
137
|
+
- [rasterio](https://rasterio.readthedocs.io/) is a core dependency of `rastr` and provides low-level raster I/O and processing capabilities.
|
|
138
|
+
- [rioxarray](https://corteva.github.io/rioxarray/stable/getting_started/getting_started.html) extends [`xarray`](https://docs.xarray.dev/en/stable/index.html) for raster data with geospatial support via `rasterio`.
|
|
139
|
+
|
|
134
140
|
### Contributing
|
|
135
141
|
|
|
136
142
|
See the
|
|
@@ -41,10 +41,10 @@ from pyproj.crs.crs import CRS
|
|
|
41
41
|
from rasterio.transform import from_origin
|
|
42
42
|
from rastr.create import full_raster
|
|
43
43
|
from rastr.meta import RasterMeta
|
|
44
|
-
from rastr.raster import
|
|
44
|
+
from rastr.raster import Raster
|
|
45
45
|
|
|
46
46
|
# Create an example raster
|
|
47
|
-
raster =
|
|
47
|
+
raster = Raster.example()
|
|
48
48
|
|
|
49
49
|
# Basic arithmetic operations
|
|
50
50
|
doubled = raster * 2
|
|
@@ -97,6 +97,12 @@ Current version limitations:
|
|
|
97
97
|
- Square cells only (rectangular cell support planned).
|
|
98
98
|
- Only float dtypes (integer support planned).
|
|
99
99
|
|
|
100
|
+
## Similar Projects
|
|
101
|
+
|
|
102
|
+
- [rasters](https://github.com/python-rasters/rasters) is a project with similar goals of providing a dedicated raster datatype in Python with higher-level interfaces for GIS operations. Unlike `rastr`, it has support for multi-band rasters, and has some more advanced functionality for Earth Science applications. Both projects are relatively new and under active development.
|
|
103
|
+
- [rasterio](https://rasterio.readthedocs.io/) is a core dependency of `rastr` and provides low-level raster I/O and processing capabilities.
|
|
104
|
+
- [rioxarray](https://corteva.github.io/rioxarray/stable/getting_started/getting_started.html) extends [`xarray`](https://docs.xarray.dev/en/stable/index.html) for raster data with geospatial support via `rasterio`.
|
|
105
|
+
|
|
100
106
|
### Contributing
|
|
101
107
|
|
|
102
108
|
See the
|
|
@@ -63,7 +63,7 @@ dev = [
|
|
|
63
63
|
"pre-commit-update>=0.8.0",
|
|
64
64
|
"pyinstrument>=5.1.1",
|
|
65
65
|
"pyright[nodejs]>=1.1.403",
|
|
66
|
-
"ruff>=0.
|
|
66
|
+
"ruff>=0.13.2",
|
|
67
67
|
"tqdm>=4.67.1",
|
|
68
68
|
"usethis>=0.15.2",
|
|
69
69
|
]
|
|
@@ -123,7 +123,6 @@ lint.ignore = [
|
|
|
123
123
|
# In some cases where your code is poorly-performing you might want to enable them again.
|
|
124
124
|
# ##############################
|
|
125
125
|
"PD101", # Harms readability for a performance optimization.
|
|
126
|
-
"PD901", # We often call variables "df" in functions dealing with pandas DataFrames.
|
|
127
126
|
"PERF203", # Too many false positives.
|
|
128
127
|
"PERF401", # This can hurt readability; the performance is not always worth it.
|
|
129
128
|
"PIE804", # This is controversial, some pandas APIs work better with dict approach.
|
|
@@ -182,7 +181,6 @@ lint.per-file-ignores."tests/**/*.py" = [
|
|
|
182
181
|
"PLR0913", # When we use fixtures, our test functions can have many arguments
|
|
183
182
|
"S101", # Using assert is fine in tests
|
|
184
183
|
"SLF001", # Accessing private members is sometimes necessary in tests
|
|
185
|
-
"TID253", # Conditional imports are not banned for tests
|
|
186
184
|
]
|
|
187
185
|
lint.allowed-confusables = [ "ℹ", "–", "σ" ]
|
|
188
186
|
lint.flake8-tidy-imports.banned-api."pytz".msg = "'zoneinfo' should be preferred to 'pytz' when using Python 3.9 and later, see https://tonkintaylor-sonarqube.azurewebsites.net/coding_rules?open=python%3AS6890&rule_key=python%3AS6890"
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.
|
|
32
|
-
__version_tuple__ = version_tuple = (0,
|
|
31
|
+
__version__ = version = '0.5.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 5, 0)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -13,7 +13,7 @@ from shapely.geometry import Point
|
|
|
13
13
|
|
|
14
14
|
from rastr.gis.fishnet import create_point_grid, get_point_grid_shape
|
|
15
15
|
from rastr.meta import RasterMeta
|
|
16
|
-
from rastr.raster import
|
|
16
|
+
from rastr.raster import Raster
|
|
17
17
|
|
|
18
18
|
if TYPE_CHECKING:
|
|
19
19
|
from collections.abc import Iterable
|
|
@@ -49,9 +49,9 @@ def raster_distance_from_polygon(
|
|
|
49
49
|
*,
|
|
50
50
|
raster_meta: RasterMeta,
|
|
51
51
|
extent_polygon: Polygon | None = None,
|
|
52
|
-
snap_raster:
|
|
52
|
+
snap_raster: Raster | None = None,
|
|
53
53
|
show_pbar: bool = False,
|
|
54
|
-
) ->
|
|
54
|
+
) -> Raster:
|
|
55
55
|
"""Make a raster where each cell's value is its centre's distance to a polygon.
|
|
56
56
|
|
|
57
57
|
The raster should use a projected coordinate system.
|
|
@@ -116,7 +116,7 @@ def raster_distance_from_polygon(
|
|
|
116
116
|
distances = np.where(mask, np.array([polygon.distance(pt) for pt in _pts]), np.nan)
|
|
117
117
|
distance_raster = distances.reshape(x.shape)
|
|
118
118
|
|
|
119
|
-
return
|
|
119
|
+
return Raster(arr=distance_raster, raster_meta=raster_meta)
|
|
120
120
|
|
|
121
121
|
|
|
122
122
|
def _pbar(iterable: Iterable[_T], *, desc: str | None = None) -> Iterable[_T]:
|
|
@@ -130,11 +130,11 @@ def full_raster(
|
|
|
130
130
|
*,
|
|
131
131
|
bounds: tuple[float, float, float, float],
|
|
132
132
|
fill_value: float = np.nan,
|
|
133
|
-
) ->
|
|
133
|
+
) -> Raster:
|
|
134
134
|
"""Create a raster with a specified fill value for all cells."""
|
|
135
135
|
shape = get_point_grid_shape(bounds=bounds, cell_size=raster_meta.cell_size)
|
|
136
136
|
arr = np.full(shape, fill_value, dtype=np.float32)
|
|
137
|
-
return
|
|
137
|
+
return Raster(arr=arr, raster_meta=raster_meta)
|
|
138
138
|
|
|
139
139
|
|
|
140
140
|
def rasterize_gdf(
|
|
@@ -142,7 +142,7 @@ def rasterize_gdf(
|
|
|
142
142
|
*,
|
|
143
143
|
raster_meta: RasterMeta,
|
|
144
144
|
target_cols: list[str],
|
|
145
|
-
) -> list[
|
|
145
|
+
) -> list[Raster]:
|
|
146
146
|
"""Rasterize geometries from a GeoDataFrame.
|
|
147
147
|
|
|
148
148
|
Supports polygons, points, linestrings, and other geometry types.
|
|
@@ -205,8 +205,8 @@ def rasterize_gdf(
|
|
|
205
205
|
dtype=np.float32,
|
|
206
206
|
)
|
|
207
207
|
|
|
208
|
-
# Create
|
|
209
|
-
raster =
|
|
208
|
+
# Create Raster
|
|
209
|
+
raster = Raster(arr=raster_array, raster_meta=raster_meta)
|
|
210
210
|
rasters.append(raster)
|
|
211
211
|
|
|
212
212
|
return rasters
|
|
@@ -286,7 +286,7 @@ def raster_from_point_cloud(
|
|
|
286
286
|
*,
|
|
287
287
|
crs: CRS | str,
|
|
288
288
|
cell_size: float | None = None,
|
|
289
|
-
) ->
|
|
289
|
+
) -> Raster:
|
|
290
290
|
"""Create a raster from a point cloud via interpolation.
|
|
291
291
|
|
|
292
292
|
Interpolation is only possible within the convex hull of the points. Outside of
|
|
@@ -320,8 +320,18 @@ def raster_from_point_cloud(
|
|
|
320
320
|
if len(x) != len(y) or len(x) != len(z):
|
|
321
321
|
msg = "Length of x, y, and z must be equal."
|
|
322
322
|
raise ValueError(msg)
|
|
323
|
+
xy_finite_mask = np.isfinite(x) & np.isfinite(y)
|
|
324
|
+
if np.any(~xy_finite_mask):
|
|
325
|
+
msg = "Some (x,y) points are NaN-valued or non-finite. These will be ignored."
|
|
326
|
+
warnings.warn(msg, stacklevel=2)
|
|
327
|
+
x = x[xy_finite_mask]
|
|
328
|
+
y = y[xy_finite_mask]
|
|
329
|
+
z = z[xy_finite_mask]
|
|
323
330
|
if len(x) < 3:
|
|
324
|
-
msg =
|
|
331
|
+
msg = (
|
|
332
|
+
"At least three valid (x, y, z) points are required to triangulate a "
|
|
333
|
+
"surface."
|
|
334
|
+
)
|
|
325
335
|
raise ValueError(msg)
|
|
326
336
|
# Check for duplicate (x, y) points
|
|
327
337
|
xy_points = np.column_stack((x, y))
|
|
@@ -332,8 +342,8 @@ def raster_from_point_cloud(
|
|
|
332
342
|
# Heuristic for cell size if not provided
|
|
333
343
|
if cell_size is None:
|
|
334
344
|
# Half the 5th percentile of nearest neighbor distances between the (x,y) points
|
|
335
|
-
tree = KDTree(
|
|
336
|
-
distances, _ = tree.query(
|
|
345
|
+
tree = KDTree(xy_points)
|
|
346
|
+
distances, _ = tree.query(xy_points, k=2)
|
|
337
347
|
distances: np.ndarray
|
|
338
348
|
cell_size = float(np.percentile(distances[distances > 0], 5)) / 2
|
|
339
349
|
|
|
@@ -378,4 +388,4 @@ def raster_from_point_cloud(
|
|
|
378
388
|
crs=crs,
|
|
379
389
|
transform=transform,
|
|
380
390
|
)
|
|
381
|
-
return
|
|
391
|
+
return Raster(arr=arr, raster_meta=raster_meta)
|
|
@@ -9,7 +9,7 @@ import rasterio.merge
|
|
|
9
9
|
from pyproj.crs.crs import CRS
|
|
10
10
|
|
|
11
11
|
from rastr.meta import RasterMeta
|
|
12
|
-
from rastr.raster import
|
|
12
|
+
from rastr.raster import Raster
|
|
13
13
|
|
|
14
14
|
if TYPE_CHECKING:
|
|
15
15
|
from numpy.typing import NDArray
|
|
@@ -17,7 +17,7 @@ if TYPE_CHECKING:
|
|
|
17
17
|
|
|
18
18
|
def read_raster_inmem(
|
|
19
19
|
raster_path: Path | str, *, crs: CRS | str | None = None
|
|
20
|
-
) ->
|
|
20
|
+
) -> Raster:
|
|
21
21
|
"""Read raster data from a file and return an in-memory Raster object."""
|
|
22
22
|
crs = CRS.from_user_input(crs) if crs is not None else None
|
|
23
23
|
|
|
@@ -35,13 +35,13 @@ def read_raster_inmem(
|
|
|
35
35
|
arr[arr == nodata] = np.nan
|
|
36
36
|
|
|
37
37
|
raster_meta = RasterMeta(cell_size=cell_size, crs=crs, transform=transform)
|
|
38
|
-
raster_obj =
|
|
38
|
+
raster_obj = Raster(arr=arr, raster_meta=raster_meta)
|
|
39
39
|
return raster_obj
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
def read_raster_mosaic_inmem(
|
|
43
43
|
mosaic_dir: Path | str, *, glob: str = "*.tif", crs: CRS | None = None
|
|
44
|
-
) ->
|
|
44
|
+
) -> Raster:
|
|
45
45
|
"""Read a raster mosaic from a directory and return an in-memory Raster object.
|
|
46
46
|
|
|
47
47
|
This assumes that all rasters have the same metadata, e.g. coordinate system,
|
|
@@ -87,7 +87,7 @@ def read_raster_mosaic_inmem(
|
|
|
87
87
|
arr = arr.squeeze().astype(np.float64)
|
|
88
88
|
|
|
89
89
|
raster_meta = RasterMeta(cell_size=cell_size, crs=crs, transform=transform)
|
|
90
|
-
raster_obj =
|
|
90
|
+
raster_obj = Raster(arr=arr, raster_meta=raster_meta)
|
|
91
91
|
return raster_obj
|
|
92
92
|
finally:
|
|
93
93
|
for src in sources:
|