From 499f2f053c567516c3e6ef1521a1d830f6b0a89f Mon Sep 17 00:00:00 2001 From: Steven Pawley Date: Mon, 20 May 2024 10:41:03 -0600 Subject: [PATCH] Bug fix for Raster initiation due to rasterio.Band --- .github/workflows/pythonpublish.yml | 26 +++++ pyspatialml/raster.py | 146 ++++++++++------------------ requirements.txt | 9 ++ setup.py | 46 +++++++++ 4 files changed, 134 insertions(+), 93 deletions(-) create mode 100644 .github/workflows/pythonpublish.yml create mode 100644 requirements.txt create mode 100644 setup.py diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml new file mode 100644 index 0000000..21f2f01 --- /dev/null +++ b/.github/workflows/pythonpublish.yml @@ -0,0 +1,26 @@ +name: Upload Python Package + +on: + release: + types: [created] + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel twine + - name: Build and publish + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + run: | + python setup.py sdist bdist_wheel + twine upload dist/* diff --git a/pyspatialml/raster.py b/pyspatialml/raster.py index 75d36e5..2b3a2c9 100644 --- a/pyspatialml/raster.py +++ b/pyspatialml/raster.py @@ -385,12 +385,11 @@ def __init__( if file_path is None and isinstance(src, np.ndarray): file_path, tfile = self._tempfile(file_path) driver = "GTiff" - + # initiate from numpy array - try: + if isinstance(src, np.ndarray): if src.ndim == 2: src = src[np.newaxis] - count, height, width = src.shape if in_memory is True: @@ -406,7 +405,6 @@ def __init__( nodata=nodata, ) dst.write(src) - else: with rasterio.open( file_path, @@ -421,138 +419,100 @@ def __init__( nodata=nodata, ) as dst: dst.write(src) - dst = rasterio.open(file_path, "r") for i in range(dst.count): band = rasterio.band(dst, i + 1) rasterlayer = RasterLayer(band) - if in_memory is True: rasterlayer.in_memory = True - src_layers.append(rasterlayer) if tfile is not None and in_memory is False: for layer in src_layers: layer._close = tfile.close - self._layers = src_layers return - - except: - pass - + # from a single file path - try: + elif isinstance(src, str): src_layers = [] r = rasterio.open(src, mode="r", driver=driver) - for i in range(r.count): band = rasterio.band(r, i + 1) src_layers.append(RasterLayer(band)) - - self._layers = src_layers - return - - except: - pass - - # from a list of file paths - try: - src_layers = [] - - for f in src: - r = rasterio.open(f, mode="r", driver=driver) - for i in range(r.count): - band = rasterio.band(r, i + 1) - src_layers.append(RasterLayer(band)) - self._layers = src_layers return - except: - pass - - # from a RasterLayer - try: + # from a single RasterLayer + elif isinstance(src, RasterLayer): self._layers = src self._rename_inplace(list(self.names)[0], src.name) return - except: - pass - - # from a list of RasterLayers - try: - self._layers = src - - for old, new in zip(self.names, src): - self._rename_inplace(old, new.name) - return - - except: - pass - - # from a Raster - try: + # from a single Raster + elif isinstance(src, Raster): self._layers = [i for i in src.values()] - for old, new in zip(self.names, list(src.names)): self._rename_inplace(old, new) return - except: - pass - # from a single rasterio.io.datasetreader/writer - try: + elif isinstance(src, rasterio.io.DatasetReader): src_layers = [] - for i in range(src.count): band = rasterio.band(src, i + 1) src_layers.append(RasterLayer(band)) - - self._layers = src_layers - return - - except: - pass - - # from a list of rasterio.io.datasetreader - try: - src_layers = [] - - for r in src: - for i in range(r.count): - band = rasterio.band(r, i + 1) - src_layers.append(RasterLayer(band)) - self._layers = src_layers return - except: - pass - - # from a single rasterio.band objects - try: + # from a single rasterio.band object + elif isinstance(src, rasterio.Band): self._layers = RasterLayer(src) return - except: - pass - - try: - src_layers = [] - - for band in src: - src_layers.append(RasterLayer(band)) - - self._layers = src_layers - return - - except: - pass + # from a list of objects + elif isinstance(src, list): + # list of file paths (str) + if all(isinstance(x, str) for x in src): + src_layers = [] + for f in src: + r = rasterio.open(f, mode="r", driver=driver) + for i in range(r.count): + band = rasterio.band(r, i + 1) + src_layers.append(RasterLayer(band)) + + self._layers = src_layers + return + + # list of RasterLayer objects + elif all(isinstance(x, RasterLayer) for x in src): + self._layers = src + for old, new in zip(self.names, src): + self._rename_inplace(old, new.name) + return + + # list of rasterio.io.datasetreader objects + elif all(isinstance(x, rasterio.io.DatasetReader) for x in src): + src_layers = [] + for r in src: + for i in range(r.count): + band = rasterio.band(r, i + 1) + src_layers.append(RasterLayer(band)) + self._layers = src_layers + return + else: + raise ValueError("Cannot create a Raster object from a mixture of inputs") + + # normal + # try: + # src_layers = [] + # for band in src: + # src_layers.append(RasterLayer(band)) + # self._layers = src_layers + # return + # except: + # pass @property def block_shape(self) -> Tuple[int, int]: diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4361464 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,9 @@ +tqdm +rasterio +geopandas +numpy +scipy +shapely +pandas +matplotlib +scikit-learn diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..083671b --- /dev/null +++ b/setup.py @@ -0,0 +1,46 @@ +import pathlib +from setuptools import setup, find_packages + +# The directory containing this file +HERE = pathlib.Path(__file__).parent + +# The text of the README file +README = (HERE / "README.md").read_text() + +setup( + # package metadata + name="pyspatialml", + version="0.21", + author="Steven Pawley", + author_email="steven.pawley@gmail.com", + description=("Machine learning for GIS spatial modelling"), + long_description=README, + long_description_content_type="text/markdown", + license="GNU", + keywords="GIS", + url="https://github.com/stevenpawley/pyspatialml", + + # files/directories to be installed with package + packages=find_packages(), + package_data={ + '': ['*.tif', '*.dbf', '*.prj', '*.shp', '*.shx'], + }, + include_package_data=True, + + # package dependencies + install_requires=[ + 'numpy', + 'scipy', + 'tqdm', + 'rasterio>=1.0', + 'pandas', + 'shapely', + 'geopandas', + 'matplotlib', + 'scikit-learn'], + python_requires='>=3.9', + + # testing + setup_requires=['pytest-runner'], + tests_require=['pytest'] +)