Accelerate agroforestry for a future worth living.
screengrab.mp4
Treescape is published under a GNU Affero Public License (AGPL). Other/commercial licensing available upon request.
- Deep QGIS (desktop)/QField (mobile) integration for forest design.
- Plant placement with extensive species data directly available and editable in QGIS.
- Flexible data model to define arbitrary zoning for forest designs.
- Offline-first approach; Spatilalite as storage backend.
- Plant species database, including family and genus, linked to GBIF Backbone Taxonomy and Wikipedia.
- Included extendable list of ~500 species relevant for agroforestry.
- Extended ontology for species data, including climate zones, growth habits, human uses and ecological roles.
- Automated data enrichment using GPT 3.5 based on Wikipedia data.
- Django Admin for browsing species database.
- Minimal REST API to species data.
- Use uuid4 as primary keys to facilitate offline editing.
- Import existing forest design.
- User-friendly web frontend for plant data and forest designs, consider https://wq.io/.
- Multiple data sources, where high confidence trumps low confidence.
- Input data chunking: large context support.
- Improved JSON validation and automated correction.
- Additional sources of plant data:
- USDA Plant Data, specifically USDA Plant Guides.
- Trefle API data (including source traversal).
- Perplexity plus citations.
- EU Plant Variety Database
- FOREMATIS (Forest Reproductive Material Information System)
- FRUMATIS (Fruit Reproductive Material Information System)
- Model additional plant data:
- WRB soil types, including accessible explanations.
- Bioclimatics (rainfall, temperature, sun hours).
- Lifetime and production durations.
- Biotic interactions (plant-plant).
- Plant reproduction methods.
- Plant fertilization vectors.
- Fruiting, planting and other seasonal data.
- Extended varieties ontology and data.
In order to do mapping, we're using geospatial libraries which, annoyingly, have to be installed on your system.
Luckily, there are Installation Instructions. You might also want to install a spatial database, although the default, Spatialite, might just work out of the box.
We're explicitly open to Pull Requests for a docker-compose setup.
We're also explicitly open to a PR for a NixOS package.
The data structure and web-interface are managed as a Django project. All the commands in these instructions are to be executing from within the repository's root.
- Setup virtual environment and install Python dependencies:
poetry install
- Activate virtual environment:
poetry shell
- Copy
.env.distto.envand update local settings. At minimum, setSECRET_KEY,DEBUG=TrueandOPENAI_API_KEY. - Create and/or migrate database:
./manage.py migrate
- Load species data (see 'Load pre-generated data') or generate it ('Generating species data').
- Create Django superuser:
./manage.py createsuperuser
- Start the Django development server:
./manage.py runserver
- Navigate to http://localhost:8000/admin/ to access the Django Admin or to http://localhost:8000/api/ to play with the API.
In the qgis_project folder, a forest_design.qgs template is maintained, which can be directly opened by QGIS.We attempt to keep the QGIS project in sync, as a template, ready to start forest design.
When opening QGIS, make sure to click 'Enable macros' in the notification to enable UI customizations in QGIS.
We're using django-environ for configuration, which reads environment variables from a local .env, which is not checked into version control -- as to guard secrets and keep differences between environments clear.
The following variables can be defined:
DATABASE_URL: https://django-environ.readthedocs.io/en/latest/api.html#environ.Env.db_urlOPENAI_API_KEY: Required for enrichment.SECRET_KEY: Used for security cookies etc. Generate hereDEBUG: Set toTruefor local debugging.
The API supports OAuth authentication for mobile applications using django-allauth and dj-rest-auth. To set up authentication:
-
First, configure the Site model for OAuth callbacks:
# Access Django shell ./manage.py shell # In the shell, set up the site from django.contrib.sites.models import Site site = Site.objects.get(pk=1) site.domain = "yourdomain.com" # Set to your domain or localhost:8000 for testing site.name = "Treescape" site.save()
-
Configure OAuth provider(s) in your
.envfile. For example, to use Google OAuth:GOOGLE_CLIENT_ID=your-google-client-id GOOGLE_CLIENT_SECRET=your-google-secret -
To use other providers, add the appropriate provider package to INSTALLED_APPS in settings.py:
INSTALLED_APPS = [ # ... existing apps "allauth.socialaccount.providers.google", # Already included by default "allauth.socialaccount.providers.microsoft", # Example additional provider "allauth.socialaccount.providers.apple", # Example additional provider ]
-
Then add provider configuration to SOCIALACCOUNT_PROVIDERS in settings.py:
SOCIALACCOUNT_PROVIDERS = { "google": { "APP": { "client_id": env("GOOGLE_CLIENT_ID", default=""), "secret": env("GOOGLE_CLIENT_SECRET", default=""), }, }, "microsoft": { "APP": { "client_id": env("MICROSOFT_CLIENT_ID", default=""), "secret": env("MICROSOFT_CLIENT_SECRET", default=""), }, }, }
Mobile apps can authenticate using the following endpoints:
api/v1/auth/- Token authentication endpointsapi/v1/auth/registration/- Registration endpointsaccounts/- Social authentication callbacks
This API uses standard JWT authentication with the following specifics:
-
Available Authentication Endpoints:
- Login:
POST /api/v1/auth/login/ - Social auth (e.g., Google):
POST /api/v1/auth/google/ - Token refresh:
POST /api/v1/auth/token/refresh/ - Logout:
POST /api/v1/auth/logout/
- Login:
-
Authentication Headers:
Authorization: Bearer <your_jwt_token> -
Token Handling:
- Access tokens expire after 60 minutes
- Refresh tokens are valid for 30 days
- The API uses refresh token rotation for security
For a complete reference on working with the dj-rest-auth and JWT authentication, see:
A pre-generated dataset is maintained for your convenience, which, due to their >5 GB size, are distributed separately. They can be loaded as follows:
-
Ensure the database is fully migrated:
./manage.py migrate
-
Download species data from https://drive.google.com/file/d/1FvZKHtlWXP682dMa1pvhINqdhml5kI_t/view
-
Unarchive data (images and fixtures):
tar xvf plant_species_data.tar
-
Load data:
./manage.py loaddata plant_species_data
-
Optionally, delete fixtures to free disk space:
rm plant_species_data.tar fixtures/plant_species_data.json
To archive current species data, yielding plant_species_data.tar:
./scripts/export_species_data.shA list of ~500 species relevant to agroforestry is provided, data for which is automatically loaded from various sources (currently GBIF and Wikipedia, soon: more). The command below will add the species, genus and family.
./manage.py load_species species_list.txt
Note that loading species is idempotent, meaning that no action is performed trying to load a species twice.
Code for this lives in: plant_species/enrichment.
Images are automatically downloaded to media/plant_species/images.
Your Pull Requests with additional species are greatly appreciated!
Retrieve data from textual sources (currently Wikipedia), process them into structurede data using LLM's:
./manage.py enrich_species_data
This requires you to configure OPENAI_API_KEY in .env.