Skip to content

Commit

Permalink
Re-structure modules in preparation for accessors (#624)
Browse files Browse the repository at this point in the history
  • Loading branch information
rhugonnet authored Nov 14, 2024
1 parent b98f716 commit c80ef6c
Show file tree
Hide file tree
Showing 67 changed files with 4,091 additions and 3,512 deletions.
33 changes: 19 additions & 14 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ ci:
autoupdate_schedule: quarterly
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
rev: v5.0.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
Expand All @@ -12,10 +12,14 @@ repos:
- id: check-merge-conflict
# Fix common spelling mistakes
- repo: https://github.com/codespell-project/codespell
rev: v2.2.1
rev: v2.3.0
hooks:
- id: codespell
args: [--ignore-words-list=alos, --ignore-regex=\bnin\b]
args: [
'--ignore-words-list', 'alos,inout,vor',
'--ignore-regex', '\bnin\b',
'--'
]
types_or: [python, rst, markdown]
files: ^(geoutils|doc|tests)/

Expand All @@ -27,23 +31,24 @@ repos:

# Format the code aggressively using black
- repo: https://github.com/psf/black
rev: 22.10.0
rev: 24.10.0
hooks:
- id: black
args: [--line-length=120]

# Lint the code using flake8
- repo: https://github.com/pycqa/flake8
rev: 3.9.2
rev: 7.1.1
hooks:
- id: flake8
args: [
--max-line-length=120,
--extend-ignore=E203, # flake8 disagrees with black, so this should be ignored.
'--max-line-length', '120', # we can write dicts however we want
'--extend-ignore', 'E203,B028', # flake8 disagrees with black, so this should be ignored.
'--'
]
additional_dependencies:
- flake8-comprehensions==3.1.0
- flake8-bugbear==21.3.2
- flake8-comprehensions
- flake8-bugbear
files: ^(geoutils|tests)
# Lint the code using mypy
- repo: https://github.com/pre-commit/mirrors-mypy
Expand All @@ -63,26 +68,26 @@ repos:
--disable-error-code=var-annotated,
--disable-error-code=no-any-return
]
additional_dependencies: [tokenize-rt==3.2.0, numpy==1.22]
additional_dependencies: [tokenize-rt==3.2.0, numpy==1.26]
files: ^(geoutils|tests)

# Sort imports using isort
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
rev: 5.13.2
hooks:
- id: isort
args: [ "--profile", "black" ]

# Automatically upgrade syntax to a minimum version
- repo: https://github.com/asottile/pyupgrade
rev: v3.1.0
rev: v3.19.0
hooks:
- id: pyupgrade
args: [--py37-plus]

# Various formattings
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.9.0
rev: v1.10.0
hooks:
# Single backticks should apparently not be used
- id: rst-backticks
Expand All @@ -101,7 +106,7 @@ repos:

# Add custom regex lints (see .relint.yml)
- repo: https://github.com/codingjoe/relint
rev: 2.0.0
rev: 3.3.1
hooks:
- id: relint
- repo: local
Expand Down
2 changes: 1 addition & 1 deletion doc/source/background.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ In details, those mean:

- **Reproducibility:** all code is version-controlled and release-based, to ensure consistency of dependent packages and works;

- **Open-source:** all code is accessible and re-usable to anyone in the community, for transparency and open governance.
- **Open-source:** all code is accessible and reusable to anyone in the community, for transparency and open governance.

```{note}
:class: margin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
ma2 = rast2.read(masked=True)
ma_result = (1 + ma2) / (ma1_reproj)


# Equivalent of saving
# (requires to define a logical
# nodata for the data type)
Expand Down
2 changes: 1 addition & 1 deletion doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def setup(app):
'to update your code see <a href="https://github.com/GlacioHack/geoutils/releases/tag/v0.1.0">here</a>. ⚠️'
"<br>Future changes will come with deprecation warnings! 🙂"
),
"show_toc_level": 3
"show_toc_level": 3,
# "logo_only": True,
# "icon_links": [
# {
Expand Down
2 changes: 1 addition & 1 deletion doc/source/core_array_funcs.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ matching georeferencing or shape, respectively.
These functions inherently support the casting of different {attr}`~geoutils.Raster.dtype` and values masked by {attr}`~geoutils.Raster.nodata` in the
{class}`~numpy.ma.MaskedArray`.

Below, we re-use the same example created in {ref}`core-py-ops`.
Below, we reuse the same example created in {ref}`core-py-ops`.

```{code-cell} ipython3
:tags: [hide-input, hide-output]
Expand Down
2 changes: 1 addition & 1 deletion doc/source/georeferencing.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ vect.get_footprint_projected(vect.crs).plot()
### Grid (only for rasters)

A raster's grid origin and resolution are defined by its geotransform attribute, {attr}`~geoutils.Raster.transform`.
Comined with the 2D shape of the data array {attr}`~geoutils.Raster.shape` (and independently of the number of
Combined with the 2D shape of the data array {attr}`~geoutils.Raster.shape` (and independently of the number of
bands {attr}`~geoutils.Raster.bands`), these two attributes define the georeferenced grid of a raster.

From it are derived the resolution {attr}`~geoutils.Raster.res`, and {attr}`~geoutils.Raster.height` and
Expand Down
2 changes: 2 additions & 0 deletions doc/source/sphinxext.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Functions for documentation configuration only, importable by sphinx"""


# To reset resolution setting for each sphinx-gallery example
def reset_mpl(gallery_conf, fname):
# To get a good resolution for displayed figures
Expand Down
1 change: 1 addition & 0 deletions examples/analysis/array_numerics/numpy_interfacing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates NumPy interfacing with rasters on :class:`Rasters<geoutils.Raster>`. See :ref:`core-array-funcs` for more details.
"""

# %%
# We open a raster.

Expand Down
1 change: 1 addition & 0 deletions examples/analysis/array_numerics/python_arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates arithmetic operations using raster arithmetic on :class:`Rasters<geoutils.Raster>`. See :ref:`core-py-ops` for more details.
"""

# %%
# We open a raster

Expand Down
1 change: 1 addition & 0 deletions examples/analysis/geospatial/buffer_voronoi.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates the metric buffering of a vector using :func:`~geoutils.Vector.buffer_metric` and :func:`~geoutils.Vector.buffer_without_overlap`.
"""

# %%
# We open an example vector

Expand Down
1 change: 1 addition & 0 deletions examples/analysis/geospatial/proximity_metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates the calculation of proximity distances to a raster or vector using :func:`~geoutils.Raster.proximity`.
"""

# %%
# We open an example raster, and a vector for which we select a single feature

Expand Down
1 change: 1 addition & 0 deletions examples/analysis/point_extraction/interpolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates the 2D interpolation of raster values to points using :func:`~geoutils.Raster.interp_points`.
"""

# %%
# We open an example raster, a digital elevation model in South America.

Expand Down
1 change: 1 addition & 0 deletions examples/analysis/point_extraction/reduction.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates the reduction of windowed raster values around a point using :func:`~geoutils.Raster.value_at_coords`.
"""

# %%
# We open an example raster, a digital elevation model in South America.

Expand Down
1 change: 1 addition & 0 deletions examples/handling/georeferencing/crop_raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates the cropping of a raster using :func:`geoutils.Raster.crop`.
"""

# %%
# We open a raster and vector, and subset the latter.

Expand Down
1 change: 1 addition & 0 deletions examples/handling/georeferencing/crop_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates the cropping of a vector using :func:`geoutils.Vector.crop`.
"""

# %%
# We open a raster and vector.

Expand Down
1 change: 1 addition & 0 deletions examples/handling/georeferencing/reproj_raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates the reprojection of a raster using :func:`geoutils.Raster.reproject`.
"""

# %%
# We open two example rasters.

Expand Down
1 change: 1 addition & 0 deletions examples/handling/georeferencing/reproj_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates the reprojection of a vector using :func:`geoutils.Vector.reproject`.
"""

# %%
# We open a raster and vector.

Expand Down
1 change: 1 addition & 0 deletions examples/handling/interface/create_mask.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates the creation of a mask from a vector using :func:`geoutils.Vector.create_mask`.
"""

# %%
# We open a raster and vector.

Expand Down
1 change: 1 addition & 0 deletions examples/handling/interface/polygonize.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates the polygonizing of a raster using :func:`geoutils.Raster.polygonize` and :func:`geoutils.Mask.polygonize`.
"""

# %%
# We open a raster.

Expand Down
1 change: 1 addition & 0 deletions examples/handling/interface/rasterize.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates the rasterizing of a vector using :func:`geoutils.Vector.rasterize`.
"""

# %%
# We open a raster and vector.

Expand Down
1 change: 1 addition & 0 deletions examples/handling/interface/topoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This example demonstrates the conversion of a raster to point vector using :func:`geoutils.Raster.to_points`.
"""

# %%
# We open a raster.

Expand Down
1 change: 1 addition & 0 deletions geoutils/_config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Setup of runtime-compile configuration of GeoUtils."""

from __future__ import annotations

import configparser
Expand Down
1 change: 1 addition & 0 deletions geoutils/_typing.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Typing aliases for internal use."""

from __future__ import annotations

import sys
Expand Down
1 change: 1 addition & 0 deletions geoutils/examples.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Utility functions to download and find example data."""

import os
import tarfile
import tempfile
Expand Down
5 changes: 5 additions & 0 deletions geoutils/interface/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from geoutils.interface.distance import * # noqa
from geoutils.interface.gridding import * # noqa
from geoutils.interface.interpolate import * # noqa
from geoutils.interface.raster_point import * # noqa
from geoutils.interface.raster_vector import * # noqa
88 changes: 88 additions & 0 deletions geoutils/interface/distance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""Functionalities related to distance operations."""

from __future__ import annotations

import warnings
from typing import Literal

import geopandas as gpd
import numpy as np
from scipy.ndimage import distance_transform_edt

import geoutils as gu
from geoutils._typing import NDArrayNum


def _proximity_from_vector_or_raster(
raster: gu.Raster,
vector: gu.Vector | None = None,
target_values: list[float] | None = None,
geometry_type: str = "boundary",
in_or_out: Literal["in"] | Literal["out"] | Literal["both"] = "both",
distance_unit: Literal["pixel"] | Literal["georeferenced"] = "georeferenced",
) -> NDArrayNum:
"""
(This function is defined here as mostly raster-based, but used in a class method for both Raster and Vector)
Proximity to a Raster's target values if no Vector is provided, otherwise to a Vector's geometry type
rasterized on the Raster.
:param raster: Raster to burn the proximity grid on.
:param vector: Vector for which to compute the proximity to geometry,
if not provided computed on the Raster target pixels.
:param target_values: (Only with a Raster) List of target values to use for the proximity,
defaults to all non-zero values.
:param geometry_type: (Only with a Vector) Type of geometry to use for the proximity, defaults to 'boundary'.
:param in_or_out: (Only with a Vector) Compute proximity only 'in' or 'out'-side the geometry, or 'both'.
:param distance_unit: Distance unit, either 'georeferenced' or 'pixel'.
"""

# 1/ First, if there is a vector input, we rasterize the geometry type
# (works with .boundary that is a LineString (.exterior exists, but is a LinearRing)
if vector is not None:

# TODO: Only when using centroid... Maybe we should leave this operation to the user anyway?
warnings.filterwarnings("ignore", message="Geometry is in a geographic CRS.*")

# We create a geodataframe with the geometry type
boundary_shp = gpd.GeoDataFrame(geometry=vector.ds.__getattr__(geometry_type), crs=vector.crs)
# We mask the pixels that make up the geometry type
mask_boundary = gu.Vector(boundary_shp).create_mask(raster, as_array=True)

else:
# We mask target pixels
if target_values is not None:
mask_boundary = np.logical_or.reduce([raster.get_nanarray() == target_val for target_val in target_values])
# Otherwise, all non-zero values are considered targets
else:
mask_boundary = raster.get_nanarray().astype(bool)

# 2/ Now, we compute the distance matrix relative to the masked geometry type
if distance_unit.lower() == "georeferenced":
sampling: int | tuple[float | int, float | int] = raster.res
elif distance_unit.lower() == "pixel":
sampling = 1
else:
raise ValueError('Distance unit must be either "georeferenced" or "pixel".')

# If not all pixels are targets, then we compute the distance
non_targets = np.count_nonzero(mask_boundary)
if non_targets > 0:
proximity = distance_transform_edt(~mask_boundary, sampling=sampling)
# Otherwise, pass an array full of nodata
else:
proximity = np.ones(np.shape(mask_boundary)) * np.nan

# 3/ If there was a vector input, apply the in_and_out argument to optionally mask inside/outside
if vector is not None:
if in_or_out == "both":
pass
elif in_or_out in ["in", "out"]:
mask_polygon = gu.Vector(vector.ds).create_mask(raster, as_array=True)
if in_or_out == "in":
proximity[~mask_polygon] = 0
else:
proximity[mask_polygon] = 0
else:
raise ValueError('The type of proximity must be one of "in", "out" or "both".')

return proximity
2 changes: 1 addition & 1 deletion geoutils/pointcloud.py → geoutils/interface/gridding.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Module for point cloud manipulation."""
"""Functionalities for gridding points (point cloud to raster)."""

import warnings
from typing import Literal
Expand Down
Loading

0 comments on commit c80ef6c

Please sign in to comment.