GeoDecision => Decision-making tools for urban management
Note => This package is mainly use - for now - through dockers
Geodecision is a set of tools to help urban decision-making:
Geodecision inputs and outputs are geospatial data:
/!\ Please read carefully these warnings related to spatial libraries installation
Our package requires libraries with spatial functionality such as GeoPandas. Such libraries depends on on open source libraries (GEOS, GDAL, PROJ). As written in GeoPandas "Those base C libraries can sometimes be a challenge to install. [...] So depending on your platform, you might need to compile and install their C dependencies manually. [...]. Using conda [...] avoids the need to compile the dependencies yourself.".
If you want to read more about it, you may want to read the GeoPandas installation warnings and the blog article on differences between conda and pip. You can also have a look on the table below (from the just quoted blog article)
conda | pip | |
---|---|---|
manages | binaries | wheel or source |
can require compilers | no | yes |
package types | any | Python-only |
create environment | yes, built-in | no, requires virtualenv or venv |
dependency checks | yes | no |
package sources | Anaconda repo and cloud | PyPI |
Regarding these warnings and for purposes of stability and multi-platform installations, we choose to use Conda - an open-source package management system and environment management system - to install and work with our package. Conda is used massively now and especially in the data science, machine learning and AI domains (it includes most of useful packages such as NumPy, Pandas, ...) and for visualization.
We choose to install it through the creation of a conda virtual environment that install and contains all the required libraries as well as our own package.
Disclaimer Geodecision is a conda package but not yet available on Anaconda cloud. So the installation must be set from an offline build package.
***/!\ Disclaimer: The installation process is a little bit more complicated from local than from Anaconda cloud. Normally, the build package should have been uploaded on Anaconda cloud to be available and easily installable with a simple command conda install -c [channel] geodecision
. But this package is still not yet on cloud so we had to make the build package available from a local place. This package is used by UD-geodecision-docker processes and the building process of this package could require a few minutes. So it appeared simpler to make build package (Linux, OSX and Windows versions) available in geodecision.conda.build
directory.
conda create --name [myenv]
Create a directory channel:
Recommended to use a tmp directory and respect the location of this directory
mkdir -p [path/to/new/directory/channel/arch]
mkdir -p /tmp/my-conda-channel/linux-64
cp [path/to/tar.bz2/build/file] [path/to/new/directory/channel/arch/]
cp conda.build/linux-64/geodecision-0.1-0.tar.bz2 /tmp/my-conda-channel/linux-64/
conda index [path/to/new/directory/channel/arch]
conda index /tmp/my-conda-channel/linux-64/
conda install -c file:[path/to/new/directory/channel/] [package_name]=[package_version]
conda install -c file://tmp/my-conda-channel/ geodecision=0.1
To make this package available from Anaconda cloud, these changes will be required:
geodecision.conda.build
directoryconda install -c [channel] geodecision
update the installation process in UD-geodecision-docker:
# Create a directory channel
RUN mkdir -p /tmp/my-conda-channel/linux-64
RUN cp UD-geodecision/geodecision/conda.build/linux-64/geodecision-0.1-0.tar.bz2 /tmp/my-conda-channel/linux-64/ RUN conda install conda-build
RUN conda index /tmp/my-conda-channel/linux-64/
RUN conda create --name geodecision SHELL ["conda", "run", "-n", "geodecision", "/bin/bash", "-c"]
RUN conda config --append channels conda-forge RUN conda install -c file://tmp/my-conda-channel/ geodecision=0.1
* By:
RUN conda create --name geodecision SHELL ["conda", "run", "-n", "geodecision", "/bin/bash", "-c"]
RUN conda install -c [channel] geodecision
Once installed, you can use it as other packages:
import geodecision
from geodecision import [specific]
geodecision/
├── accessibility
│ ├── accessibility.py
│ ├── __init__.py
│ ├── isochrone.py
│ └── schema.py
├── citygml
│ ├── analyseroofs.py
│ ├── categories.py
│ ├── constants.py
│ └── __init__.py
├── classification
│ ├── classification.py
│ ├── constants_vars.py
│ └── __init__.py
├── cli.py
├── geodecision.py
├── graph
│ ├── connectpoints.py
│ ├── __init__.py
│ ├── splittednodes.py
│ └── utils.py
├── __init__.py
├── logger
│ ├── __init__.py
│ └── logger.py
├── osmquery
│ ├── __init__.py
│ └── methods.py
└── spatialops
├── __init__.py
└── operations.py
This method could be compared to the creation of a virtual environment and
pip install -e
command.
dev_env.yml
fileconda env create -f [path/to/geodecision/dev_env.yml]
conda activate dev_env
conda develop [path/to/geodecision]
Our conda geodecision package is structured like this (see below) and you have to respect this organisation if you want to add your own modules and submodules.
geodecision:
|--- AUTHORS.rst
|--- CONTRIBUTING.rst
|--- dev_env.yml
|--- HISTORY.rst
|--- Makefile
|--- MANIFEST.in
|--- README.rst
|--- requirements_dev.text
|--- setup.cfg
|--- setup.py
|--- tox.ini
|--- .editorconfig
|--- .gitignore
|___ conda.recipe
| |--- meta.yml
|___ docs
| |--- authors.rst
| |--- conf.py
| |--- contributing.rst
| |--- history.rst
| |--- index.rst
| |--- installation.rst
| |--- make.bat
| |--- Makefile
| |--- modules.rst
| |--- readme.rst
| |--- usage.rst
|___ geodecision
| ├── accessibility
| │ ├── accessibility.py
| │ ├── __init__.py
| │ ├── isochrone.py
| │ └── schema.py
| ├── citygml
| | │ └── __init__.py
| │ ├── analyseroofs.py
| │ ├── categories.py
| │ ├── constants.py
| │ └── __init__.py
| ├── classification
| │ ├── classification.py
| │ ├── constants_vars.py
| │ └── __init__.py
| ├── cli.py
| ├── geodecision.py
| ├── graph
| │ ├── connectpoints.py
| │ ├── __init__.py
| │ ├── splittednodes.py
| │ └── utils.py
| ├── __init__.py
| ├── logger
| │ ├── __init__.py
| │ └── logger.py
| ├── osmquery
| │ ├── __init__.py
| │ └── methods.py
| └── spatialops
| ├── __init__.py
| └── operations.py
|___ tests
| |--- __init__.py
| |--- test_mymodule.py
|___ .github
If you already have module and sub-modules, put them in:
mymodule
|___ mymodule
Once done, don't forget to check if the import
are done in the right way. Let's say you have this architecture;
mymodule
|___ mymodule
|--- cli.py
|--- __init__.py
|--- mymodule.py
|___ submoduleA
| |--- __init__.py
| |--- submoduleAOne
| |--- submoduleATwo
|___ submoduleB
|--- __init__.py
|--- submoduleBOne
|--- submoduleBTwo
If you want class OneA from submoduleAOne
and class TwoB from submoduleBTwo
to be accessible from your module, you need to edit the __init__.py
:
mymodule
|___ mymodule
|--- __init__.py
You have to add these lines:
from .submoduleA.submoduleAOne import OneA
from .submoduleB.submoduleBTwo import TwoB
If you want to import class OneB from submoduleBOne
in submoduleATwo
you need to add this line in submoduleATwo
:
from ..submoduleB.submoduleBOne import OneB
Follow the process described in this documentation and make the necessary changes/adaptations
We use Sphinx for documentation
/!\ If you use the numpydoc docstrings, add the napoleon sphinx extension in
conf.py
:mymodule: |___ docs |--- conf.py
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.napoleon']
Then generate documentation with command lines. Start a command line inside docs
repository:
sphinx-apidoc -f -o . ../mymodule/
It will generate a bunch of rst files. Then, to get html pages (in a _build
directory for example):
cd ..
sphinx-build -b html docs/ _build/