# geotiff
A noGDAL tool for reading geotiff files
> **Warning**
> This package is under development and some features are unstable. Proceed with caution.
Please support this project be giving it a [star on GitHub](https://github.com/Open-Source-Agriculture/geotiff)!
### What is noGDAL?
**[noGDAL](https://kipling.medium.com/nogdal-e5b60b114a1c)** is a philosophy for developing geospatial programs in Python without using GDAL.
### Installation
Installing this package is as easy as:
```
pip install geotiff
```
There is also an Anaconda-based package available, published on [conda-forge](https://conda-forge.org/):
```
conda install -c conda-forge python-geotiff
```
For local development from sources, you can install geotiff with its development requirements using:
```
git clone git@github.com:KipCrossing/geotiff.git
cd geotiff
pip install -e .[dev]
```
### Usage
#### Making the GeoTiff object
```python
from geotiff import GeoTiff
tiff_file = "path/to/tiff/file"
geo_tiff = GeoTiff(tiff_file)
```
This will detect the crs code. If it's 'user defined' and you know what it should be, you may supply a crs code:
```python
geo_tiff = GeoTiff(tiff_file, crs_code=4326)
```
By default, the coordinates will be in WGS 84, however they can be specified by using the `as_crs` param:
```python
geo_tiff = GeoTiff(tiff_file, as_crs=7844)
```
Or you can use the original crs by setting `as_crs` to `None`:
```python
geo_tiff = GeoTiff(tiff_file, as_crs=None)
```
If the geotiff file has multiple bands, you can specify which band to use:
```python
geo_tiff = GeoTiff(tiff_file, band=1)
```
The default band is 0
Get information (properties) about the geotiff:
```python
# the original crs code
geo_tiff.crs_code
# the current crs code
geo_tiff.as_crs
# the shape of the tiff
geo_tiff.tif_shape
# the bounding box in the as_crs CRS
geo_tiff.tif_bBox
# the bounding box as WGS 84
geo_tiff.tif_bBox_wgs_84
# the bounding box in the as_crs converted coordinates
geo_tiff.tif_bBox_converted
```
Get coordinates of a point/pixel:
```python
i=5
j=6
# in the as_crs coords
geo_tiff.get_coords(i, j)
# in WGS 84 coords
geo_tiff.get_wgs_84_coords(i, j)
```
#### Read the data
To read the data, use the `.read()` method. This will return a [Zarr](https://zarr.readthedocs.io/en/stable/api/core.html) array as often geotiff files cannot fit into memory.
```python
zarr_array = geo_tiff.read()
```
If you are confident that the data will fit into memory, you can convert it to a numpy array:
```python
import numpy as np
array = np.array(zarr_array)
```
#### Read a section of a large tiff
In many cases, you are only interested in a section of the tiff. For convenience, you can use the `.read_box()` method. This will return a numpy array.
> **Warning**
> This will fail if the box you are using is too large and the data cannot fit into memory.
```python
from geotiff import GeoTiff
# in WGS 84
area_box = [(138.632071411, -32.447310785), (138.644218874, -32.456979174)]
geo_tiff = GeoTiff(tiff_file)
array = geo_tiff.read_box(area_box)
```
> **Note**
> For the `area_box`, use the same crs as `as_crs`.
In some cases, you may want some extra points/pixels around the outside of your `area_box`. This may be useful if you want to interpolate to points near the area_box boundary. To achieve this, use the `outer_points` param:
array = geo_tiff.read_box(area_box, outer_points=2)
This will get 2 extra perimeters of points around the outside of the the `area_box`.
#### Getting bounding box information
There are also some helper methods to get the bounding box of the resulting cut array:
```python
# col and row indexes of the cut area
int_box = geo_tiff.get_int_box(area_box)
# lon and lat coords of the cut points/pixels
wgs_84_box = geo_tiff.get_bBox_wgs_84(area_box)
```
Again, you can also get bounding box for an extra n layers of points/pixels that directly surround the `area_box`:
```python
# col and row indexes of the cut area
int_box = geo_tiff.get_int_box(area_box, outer_points = 2)
# lon and lat coords of the cut points/pixels
wgs_84_box = geo_tiff.get_bBox_wgs_84(area_box, outer_points = 2)
```
#### Get coordinates of a point/pixel
You may want to get the coordinates of a value in your array:
```python
i=int_box[0][0] + 5
j=int_box[0][1] + 6
geo_tiff.get_wgs_84_coords(i, j)
```
#### Get coordinates of an array
You may want to simply get all the coordinates in the array:
```python
array = geo_tiff.read_box(area_box, outer_points=2)
lon_array, lat_array = geo_tiff.get_coord_arrays(area_box, outer_points=2)
```
This will return two arrays that are in the same shape as the array from the `read_box()` method. The output coords will be in the `as_crs` crs.
If your tiff file is small and can fit into memory, simply:
```python
lon_array, lat_array = geo_tiff.get_coord_arrays()
```
### Contributing
If you would like to contribute to this project, please fork this repo and make a PR with your patches.
You can join the conversation by saying "hi" in the [project discussion board](https://github.com/KipCrossing/geotiff/discussions).
To help users and other contributes, be sure to:
- Make docstrings and documentation blocks, if appropriate
- Use Python typing wherever possible
- Format your code with [Black](https://black.readthedocs.io/en/stable/index.html)
> **Note**
> The continuous integration has lint checking with **mypy**, so be sure to check it yourself before making a PR.
### Project Road Map
#### Core Features
- [x] read tiff files (including BigTiff)
- [ ] write tiff files (including BigTiff)
- [x] convert between epsg coordinate systems
- [ ] read a user defined CRS `32767` from tiff file
- [x] cut a section (bounding box) of the tiff file
- [x] convert the data to numpy arrays
#### Additional features
- [x] **(50%)** Full test coverage
- [x] Typing with lint checking using mypy
- [x] Formatted with black
- [x] Documentation: doc blocs
- [ ] Documentation: readthedocs
Raw data
{
"_id": null,
"home_page": "https://github.com/Open-Source-Agriculture/geotiff",
"name": "geotiff",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "",
"author": "Kipling Crossing",
"author_email": "kip.crossing@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/ba/6e/00d51cd7ade2fd0e960722f090cd3bad0dbbc7206baf2871448a903e40f3/geotiff-0.2.10.tar.gz",
"platform": null,
"description": "# geotiff\n\nA noGDAL tool for reading geotiff files\n\n> **Warning**\n> This package is under development and some features are unstable. Proceed with caution.\n\nPlease support this project be giving it a [star on GitHub](https://github.com/Open-Source-Agriculture/geotiff)!\n\n### What is noGDAL?\n\n**[noGDAL](https://kipling.medium.com/nogdal-e5b60b114a1c)** is a philosophy for developing geospatial programs in Python without using GDAL.\n\n### Installation\n\nInstalling this package is as easy as:\n\n```\npip install geotiff\n```\n\nThere is also an Anaconda-based package available, published on [conda-forge](https://conda-forge.org/):\n\n```\nconda install -c conda-forge python-geotiff\n```\n\nFor local development from sources, you can install geotiff with its development requirements using:\n\n```\ngit clone git@github.com:KipCrossing/geotiff.git\ncd geotiff\npip install -e .[dev]\n```\n\n### Usage\n\n#### Making the GeoTiff object\n\n```python\nfrom geotiff import GeoTiff\n\ntiff_file = \"path/to/tiff/file\"\ngeo_tiff = GeoTiff(tiff_file)\n```\n\nThis will detect the crs code. If it's 'user defined' and you know what it should be, you may supply a crs code:\n\n```python\ngeo_tiff = GeoTiff(tiff_file, crs_code=4326)\n```\n\nBy default, the coordinates will be in WGS 84, however they can be specified by using the `as_crs` param:\n\n```python\ngeo_tiff = GeoTiff(tiff_file, as_crs=7844)\n```\n\nOr you can use the original crs by setting `as_crs` to `None`:\n\n```python\ngeo_tiff = GeoTiff(tiff_file, as_crs=None)\n```\n\nIf the geotiff file has multiple bands, you can specify which band to use:\n\n```python\ngeo_tiff = GeoTiff(tiff_file, band=1)\n```\n\nThe default band is 0\n\n\nGet information (properties) about the geotiff:\n\n```python\n# the original crs code\ngeo_tiff.crs_code\n# the current crs code\ngeo_tiff.as_crs\n# the shape of the tiff\ngeo_tiff.tif_shape\n# the bounding box in the as_crs CRS\ngeo_tiff.tif_bBox\n# the bounding box as WGS 84\ngeo_tiff.tif_bBox_wgs_84\n# the bounding box in the as_crs converted coordinates\ngeo_tiff.tif_bBox_converted\n```\n\nGet coordinates of a point/pixel:\n\n```python\ni=5\nj=6\n# in the as_crs coords\ngeo_tiff.get_coords(i, j)\n# in WGS 84 coords\ngeo_tiff.get_wgs_84_coords(i, j)\n```\n\n#### Read the data\n\nTo read the data, use the `.read()` method. This will return a [Zarr](https://zarr.readthedocs.io/en/stable/api/core.html) array as often geotiff files cannot fit into memory.\n\n```python\nzarr_array = geo_tiff.read()\n```\n\nIf you are confident that the data will fit into memory, you can convert it to a numpy array:\n\n```python\nimport numpy as np\n\narray = np.array(zarr_array)\n```\n\n#### Read a section of a large tiff\n\nIn many cases, you are only interested in a section of the tiff. For convenience, you can use the `.read_box()` method. This will return a numpy array.\n\n> **Warning**\n> This will fail if the box you are using is too large and the data cannot fit into memory.\n\n```python\nfrom geotiff import GeoTiff\n\n# in WGS 84\narea_box = [(138.632071411, -32.447310785), (138.644218874, -32.456979174)]\ngeo_tiff = GeoTiff(tiff_file)\narray = geo_tiff.read_box(area_box)\n```\n\n> **Note**\n> For the `area_box`, use the same crs as `as_crs`.\n\nIn some cases, you may want some extra points/pixels around the outside of your `area_box`. This may be useful if you want to interpolate to points near the area_box boundary. To achieve this, use the `outer_points` param:\n\narray = geo_tiff.read_box(area_box, outer_points=2)\n\nThis will get 2 extra perimeters of points around the outside of the the `area_box`.\n\n#### Getting bounding box information\n\nThere are also some helper methods to get the bounding box of the resulting cut array:\n\n```python\n# col and row indexes of the cut area\nint_box = geo_tiff.get_int_box(area_box)\n# lon and lat coords of the cut points/pixels\nwgs_84_box = geo_tiff.get_bBox_wgs_84(area_box)\n```\n\nAgain, you can also get bounding box for an extra n layers of points/pixels that directly surround the `area_box`:\n\n```python\n# col and row indexes of the cut area\nint_box = geo_tiff.get_int_box(area_box, outer_points = 2)\n# lon and lat coords of the cut points/pixels\nwgs_84_box = geo_tiff.get_bBox_wgs_84(area_box, outer_points = 2)\n```\n\n#### Get coordinates of a point/pixel\n\nYou may want to get the coordinates of a value in your array:\n\n```python\ni=int_box[0][0] + 5\nj=int_box[0][1] + 6\ngeo_tiff.get_wgs_84_coords(i, j)\n```\n\n#### Get coordinates of an array\n\nYou may want to simply get all the coordinates in the array:\n\n```python\narray = geo_tiff.read_box(area_box, outer_points=2)\nlon_array, lat_array = geo_tiff.get_coord_arrays(area_box, outer_points=2)\n```\n\nThis will return two arrays that are in the same shape as the array from the `read_box()` method. The output coords will be in the `as_crs` crs.\n\nIf your tiff file is small and can fit into memory, simply:\n\n```python\nlon_array, lat_array = geo_tiff.get_coord_arrays()\n```\n\n### Contributing\n\nIf you would like to contribute to this project, please fork this repo and make a PR with your patches.\n\nYou can join the conversation by saying \"hi\" in the [project discussion board](https://github.com/KipCrossing/geotiff/discussions).\n\nTo help users and other contributes, be sure to:\n- Make docstrings and documentation blocks, if appropriate\n- Use Python typing wherever possible\n- Format your code with [Black](https://black.readthedocs.io/en/stable/index.html)\n\n> **Note**\n> The continuous integration has lint checking with **mypy**, so be sure to check it yourself before making a PR.\n\n### Project Road Map\n\n#### Core Features\n\n- [x] read tiff files (including BigTiff)\n- [ ] write tiff files (including BigTiff)\n- [x] convert between epsg coordinate systems\n- [ ] read a user defined CRS `32767` from tiff file\n- [x] cut a section (bounding box) of the tiff file\n- [x] convert the data to numpy arrays\n\n#### Additional features\n\n- [x] **(50%)** Full test coverage\n- [x] Typing with lint checking using mypy\n- [x] Formatted with black\n- [x] Documentation: doc blocs\n- [ ] Documentation: readthedocs\n",
"bugtrack_url": null,
"license": "",
"summary": "A noGDAL tool for reading and writing geotiff files",
"version": "0.2.10",
"project_urls": {
"Homepage": "https://github.com/Open-Source-Agriculture/geotiff"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "42451f3fd283de696f421f99dc04d23251dfd10204c098684c3267935118b1cc",
"md5": "a1341db414e5ddfeb8d3382b16e2fd1b",
"sha256": "1c238b1115884a82b0e8b462384828b1bfe2819194f9f16384f517d07ab12e68"
},
"downloads": -1,
"filename": "geotiff-0.2.10-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a1341db414e5ddfeb8d3382b16e2fd1b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 19900,
"upload_time": "2023-08-23T00:47:20",
"upload_time_iso_8601": "2023-08-23T00:47:20.415972Z",
"url": "https://files.pythonhosted.org/packages/42/45/1f3fd283de696f421f99dc04d23251dfd10204c098684c3267935118b1cc/geotiff-0.2.10-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "ba6e00d51cd7ade2fd0e960722f090cd3bad0dbbc7206baf2871448a903e40f3",
"md5": "8e1bfa8ac5516404fa28fd7a74749c97",
"sha256": "36da356d3e2f6e3719bad32212283fe99049373391c7f576c2d6022642ad88d6"
},
"downloads": -1,
"filename": "geotiff-0.2.10.tar.gz",
"has_sig": false,
"md5_digest": "8e1bfa8ac5516404fa28fd7a74749c97",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 2242539,
"upload_time": "2023-08-23T00:47:27",
"upload_time_iso_8601": "2023-08-23T00:47:27.791848Z",
"url": "https://files.pythonhosted.org/packages/ba/6e/00d51cd7ade2fd0e960722f090cd3bad0dbbc7206baf2871448a903e40f3/geotiff-0.2.10.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-08-23 00:47:27",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Open-Source-Agriculture",
"github_project": "geotiff",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "geotiff"
}