-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Write documentation and streamline general behaviour #351
Conversation
sphinx-book-theme
Alright, I have accounted for everything that was do-able without spending days on it! Ready to merge! |
After losing a couple hours on this, the logo problem actually didn't come from our file (SVG is the standard vector format for Sphinx, and ours was fine). |
Fantastic !
Yes, that makes sense. Also in old geoutils there were some zonal statistics tools that we could re-use. But they are based on GDAL/OGR...
👍
Ok to add the mini gallery to the Feature section, and yes to more illustrations in the quickstart !
Haha, I don't know if I'm a pro, but I can have a look later for sure. |
All good on my end, we can always refine later ! Thanks again for all this work ! |
Summary
This PR writes the documentation for GeoUtils! 🥳
It also:
Vector
,This PR is branched from #350 on the
Mask
addition (now closed and everything is in this PR, as someMask
fixes started to depend on new behaviours only available here).This PR also casts single-band raster to 2D following #360 (now closed also).
Documentation
The hidden branch with the rendered documentation is here: https://geoutils-rhugonnet.readthedocs.io/en/docs/index.html
Regarding theme and rendering, this PR:
/doc/code
folder and theliteralinclude:: code/coregistration.py :lines: 5-21
we were using in xDEM, which was a hassle to maintain, thanks to the previous point. Proper errors should be raised by Sphinx or can be tested in the CI directly (we can run the.md
files as a Jupyter notebook).pip
tomambaforge
for the Readthedocs in.readthedocs.yaml
, which was failing and slow. Also addspip -e .
todev-environment.yml
to simplify dev installation of the package.sphinx-design
for rendering nice tables in the documentation.sphinx_gallery_conf
optionremove_config_comments = True
to remove config comments in gallery examples, such as for choosing thumbnails:# sphinx_gallery_thumbnail_number = 2
,subsection_order
andwithin_subsection_order
parameters to properly order gallery example subsections and individual examples,myraster.tif
andmyvector.gpkg
created during the "Open/Save" examples by Sphinx-Gallery, as advised here: ignore code-blocks sphinx-gallery/sphinx-gallery#361,binder/
folder with environment and post-build setup for Binder, usingmyst-nb
andjupytext
, we can now launch any documentation page directly to our Binder (badge added to the README)!Regarding the contents of the docs, I let you have a look there directly!
In short:
Architecture changes
This PR:
satimg
togeoraster/
,georaster.py
andgeovector.py
intoraster.py
andvector.py
(the "geo" already being ingeoutils.raster
, as previously discussed),spatial_tools
intoraster/array.py
,raster/multiraster.py
andraster/sampling.py
,geoviewer.py
to a newbin/
folder.Syntax changes
This PR:
cropGeom
renamed intocrop_geom
),Raster
orVector
object (like an "array" is used for anp.array
), all docstrings start without article (Raster to do that),Changes linked to documentation
This PR:
crs
andtransform
as properties toRaster
, with adata.setter
, to ensure those are consistent and listed as properties in the API,ds
,crs
andbounds
as properties toVector
, also for consistency and API,datetime
, etc... as properties toSatelliteImage
, also for consistency and API,Raster.info()
,__repr__
and modifies__str__
forRaster
andVector
to be consistent with what is done in NumPy and GeoPandas, those now only prints "not_loaded" when the data is unloaded,_repr_html_
inRaster
andVector
for representing rasters and vectors more stylishly in HTML,copy_doc
decorator inmisc.py
to automatically generate the docstring of wrapped GeoPandas functions (their__doc__
) by replacinggeopandas.GeoSeries
orgeopandas.GeoDataFrame
byVector
, and adding an intersphinx link to the GeoPandas API in our doc,Vector.save
as a wrapper aroundGeoDataFrame.to_file
for consistency withRaster
,Vector.show
as a wrapper aroundGeoDataFrame.plot
for consistency withRaster
.Raster.show
andVector.show
recognize and respect the first axis, to be able to plot everything on top by simply doingraster.show(); vector.show()
. Axes can still be passed explicitly throughax=
. To plot on a new axis, one can add aplt.figure()
or simply dorst.show(ax="new")
.Mask
classSee #350, and the documentation. This PR adds tests, fixes behaviour of logical functions and adds overridden
reproject
,crop
,polygonize
andproximity
toMask
.Notable changes for
Raster
include:__eq__
toraster_equal
for consistency with NumPy,__eq__
is now used by logical bitwise operations (see documentation and AddMask
subclass #350) and casts aMask
,equal_georeferenced_grid
togeoreferenced_grid_equal
for naming consistency.Casting single-band
Raster
to 2DSee #360.
GeoPandas functionalities in
Vector
This PR:
geopandas.base.GeoPandasBase
non-public class (inherited by bothGeoSeries
andGeoDataFrame
for geometric functionalities) and thegeopandas.GeoDataFrame
class toVector
. Everything can be called usingVector
, for exampleVector.unary_union
. For the output, three cases: 1/ returns aVector
when it is a geometric output, 2/ proposes to append a non-geometric per-feature output (pandas.Series
) toVector.ds
, and 3/ when it's another type of output, it returns that output directly. Why is this useful? Practicality and consistency: it can be a hassle to work with GeoPandas sometimes as a "geometric" operation on aGeoDataFrame
can return aGeoDataFrame
, aGeoSeries
or ashapely.Geometry
. And "non-geometric per-feature" functions like.area
or.length
return apandas.Series
of the same length. While GeoPandas' team is still improving a couple things upstream, many behaviours are actually intentional and fixed to maintain a lower-level API for all types of user. End-users focusing on analysis like us don't need this, and it slows us down, so it's quite practical to have everything logically and automatically re-cast to aGeoDataFrame
in theVector
, or appended to it! 😄Vector.ds
directly.Vector
for the basic description, and points to GeoPandas's API for details, to ensure a minimal maintenance effort.Feature changes
This PR:
load_data
ofRaster.__init__
toFalse
, and adds a condition to run.load()
when.data
is called (if data is not already loaded). This is, in short, implicit loading! 😄 Adds tests to check this functionality, and modifies a couple things that were breaking this behaviour in.load()
and__init__
. Now implicit loading also works properly with thedownsample
andindexes
arguments! Also fixes the behaviour for multi-band rasters, and adds tests,in_value
ofpolygonize
to"all"
, asMask.polygonize()
now automatically overridesRaster.polygonize
for a boolean input,__getitem__
(i.e., []) possible with booleannp.ndarray
and not onlyMask
,__setitem
(i.e., [] = x) toRaster
,clip
argument toVector.crop
, to optionally clip the geometries to the extent,Raster.subsample
function to perform subsampling directly from the raster,Raster
(e.g.,reduce
as innp.logical_or.reduce()
),Vector.get_bounds_projected()
andRaster.get_bounds_projected()
to automatically derive bounds in any CRS from aRaster
orVector
accouting for densification of footprint edges during reprojection,Vector.get_footprint_projected()
andRaster.get_bounds_projected()
to automatically derive a polygon vector in any CRS from aRaster
orVector
accouting for densification of footprint edges during reprojection,Vector.from_bounds_projected
to automatically create aVector
from projected bounds,Vector.get_metric_crs()
andRaster.get_metric_crs()
to automatically derive a metric CRS from aRaster
orVector
which is UTM or UPS,as_array
argument toVector.create_mask
to return a boolean np.ndarray (returns aMask
by default).Bug fixes and tests
This PR:
value_at_coords
on several bands and adds tests,coords
that returned a wrong output with its defaultgrid=True
argument and adds tests,get_nanarray
to runfilled(np.nan)
when original data was not of float type and adds tests,np.ma
functions onRaster
due to__array__
(not supported by NumPy, they don't have an array interface for masked-array functions),geoviewer.py
and adds tests,Raster.nodata
by defining it astuple
instead oflist
,Raster.to_xarray
,Raster.shift
,misc.diff_yml
, etc...Issues resolved
This PR:
_repr_html_()
function. #225,SatImg
class togeoraster/
folder #260,Raster.show()
does not respect the current axis. #241,geopandas
(and specificallyshapely
) functionalities in theVector
class #337.