Skip to content

KipCrossing/geotiff

Repository files navigation

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!

What is noGDAL?

noGDAL 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:

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

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:

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:

geo_tiff = GeoTiff(tiff_file, as_crs=7844)

Or you can use the original crs by setting as_crs to None:

geo_tiff = GeoTiff(tiff_file, as_crs=None)

If the geotiff file has multiple bands, you can specify which band to use:

geo_tiff = GeoTiff(tiff_file, band=1)

The default band is 0

Get information (properties) about the geotiff:

# 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:

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 array as often geotiff files cannot fit into memory.

zarr_array = geo_tiff.read()

If you are confident that the data will fit into memory, you can convert it to a numpy array:

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.

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:

# 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:

# 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:

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:

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:

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.

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

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

  • read tiff files (including BigTiff)
  • write tiff files (including BigTiff)
  • convert between epsg coordinate systems
  • read a user defined CRS 32767 from tiff file
  • cut a section (bounding box) of the tiff file
  • convert the data to numpy arrays

Additional features

  • (50%) Full test coverage
  • Typing with lint checking using mypy
  • Formatted with black
  • Documentation: doc blocs
  • Documentation: readthedocs