🌍 PandaTree — Système National de Gestion, Cartographie et Reconnaissance des Arbres de Côte d’Ivoire
Projet porté par le CNRA (Centre National de Recherche Agronomique de Côte d’Ivoire) Développé avec Django REST Framework — Architecture modulaire, évolutive et souveraine. Objectif : Créer une plateforme nationale libre pour la cartographie, la reconnaissance et la valorisation du patrimoine végétal ivoirien.
Le projet PandaTree vise à :
- Centraliser les informations botaniques nationales (arbres, régions, familles, usages).
- Offrir aux agents de terrain et chercheurs un outil fiable de collecte et de reconnaissance d’espèces.
- Déployer une application mobile Flutter pour l’enregistrement et la consultation en mobilité.
- Intégrer la reconnaissance de feuilles locale via un moteur KNN interne.
- Permettre la cartographie nationale en temps réel sur base OpenStreetMap.
💡 « Identifier, cartographier et préserver — la nature connectée au service de la recherche ivoirienne. »
| Composant | Technologie | Rôle principal |
|---|---|---|
| Backend API | Django + Django REST Framework | Cœur du système, logique métier et endpoints REST |
| Base de données | PostgreSQL | Données structurées et relations géographiques |
| Application mobile | Flutter (Android / iOS) | Collecte, scan, affichage cartographique |
| Stockage d’images | Django Storage (Media) | Gestion des photos d’arbres et feuilles |
| Reconnaissance IA locale | KNN interne (vectorisation) | Calcul de similarité entre échantillons |
| Documentation API | drf-spectacular + Swagger UI | Interface interactive pour les développeurs |
| Tâches asynchrones | Celery (optionnel) | Reindexation automatique |
- Création, édition et suppression d’un arbre.
- Enregistrement des 3 photos obligatoires : arbre entier, feuille, racine.
- Informations botaniques complètes (nom local, scientifique, famille, région, sol, latitude, longitude).
- Système de likes, de vues, et d’export CSV via l’interface d’administration.
- Visualisation sur carte Leaflet (GeoJSON-like API).
- Sécurisation par utilisateur (seuls les propriétaires ou administrateurs peuvent modifier/supprimer).
- Téléversement d’une photo de feuille (
/api/recognition/predict/) - Calcul de similarité via le KNN interne
- Stockage de l’historique (
LeafRecognition) - Possibilité de feedback utilisateur (confirmation ou correction d’espèce)
- Réindexation automatique des échantillons
- L’utilisateur envoie un formulaire + 3 images via
POST /api/trees/ - Les données sont sauvegardées dans la table
Tree - Un vecteur 544D est calculé automatiquement sur la photo de feuille
- L’utilisateur envoie une image via
POST /api/recognition/predict/ - Le système crée une entrée
LeafRecognition - Le moteur KNN retourne l’arbre le plus similaire
- Le résultat est sauvegardé avec le score de confiance
- L’utilisateur envoie son feedback via
POST /api/recognition/feedback/ - Le système met à jour la prédiction (espèce confirmée ou corrigée)
- Option : ajout automatique de la photo aux échantillons (
LeafSample)
Toutes les routes sont protégées par authentification (Authorization: Bearer <token>).
Les exemples ci-dessous sont adaptés pour Flutter ou Postman.
L’authentification repose sur Django Rest Framework + JWT.
-
Login :
POST /api/auth/login/ -
Register :
POST /api/auth/register/ -
Header commun :
Authorization: Bearer <votre_token_jwt>
| Méthode | Endpoint | Description | Auth |
|---|---|---|---|
GET |
/api/trees/ |
Liste des arbres (filtres disponibles) | ✅ |
GET |
/api/trees/{id}/ |
Détail d’un arbre | ✅ |
POST |
/api/trees/ |
Créer un arbre (avec 3 images obligatoires) | ✅ |
PATCH |
/api/trees/{id}/ |
Modifier un arbre | ✅ (propriétaire/admin) |
DELETE |
/api/trees/{id}/ |
Supprimer un arbre | ✅ (propriétaire/admin) |
GET |
/api/trees/mine/ |
Lister mes arbres | ✅ |
POST |
/api/trees/{id}/like/ |
Liker un arbre | ✅ |
GET |
/api/trees/map/ |
Points carte (GeoJSON-like) | ✅ |
POST /api/trees/
multipart/form-data :
| Champ | Type | Obligatoire | Exemple |
|---|---|---|---|
| name_local | string | ✅ | Iroko |
| latitude | float | ✅ | 5.345678 |
| longitude | float | ✅ | -4.012345 |
| region | string | ✅ | Abidjan |
| photo_tree | image | ✅ | arbre.jpg |
| photo_leaf | image | ✅ | feuille.jpg |
| photo_root | image | ✅ | racine.jpg |
Réponse (201) :
{
"id": 12,
"name_local": "Iroko",
"region": "Abidjan",
"photo_leaf_url": "https://api.pandatree.ci/media/trees/photos/leaf/iroko.jpg"
}| Méthode | Endpoint | Description | Auth |
|---|---|---|---|
POST |
/api/recognition/predict/ |
Envoyer une photo de feuille et obtenir la prédiction | ✅ |
POST |
/api/recognition/feedback/ |
Envoyer un feedback utilisateur | ✅ |
POST |
/api/recognition/samples/ |
Ajouter un échantillon labellisé (LeafSample) | ✅ |
POST |
/api/recognition/reindex/ |
Reconstruire l’index KNN | ✅ |
GET |
/api/recognition/species/ |
Liste ou ajout d’espèces connues | ✅ |
POST /api/recognition/predict/
multipart/form-data :
| Champ | Type | Obligatoire | Exemple |
|---|---|---|---|
| file | image | ✅ | feuille.jpg |
Réponse (200) :
{
"id": 8,
"predicted_species": "Ficus exasperata",
"confidence": 0.92,
"suggestions": [
{"tree_id": 23, "confidence": 0.87, "region": "Bouaké"},
{"tree_id": 45, "confidence": 0.81, "region": "Abidjan"}
],
"top_tree": {
"id": 23,
"name_local": "Figuier",
"region": "Bouaké"
}
}POST /api/recognition/feedback/
{
"recognition_id": 8,
"is_correct": true,
"confirmed_species": 5,
"notes": "Bonne correspondance",
"add_to_samples": true
}Réponse (200) :
{
"success": true,
"id": 8
}| Méthode | Endpoint | Description |
|---|---|---|
GET |
/api/recognition/species/ |
Lister toutes les espèces |
POST |
/api/recognition/species/ |
Créer une nouvelle espèce |
POST |
/api/recognition/samples/ |
Ajouter un nouvel échantillon labellisé |
| Champ | Type | Description |
|---|---|---|
name_local |
str | Nom vernaculaire |
name_scientific |
str | Nom scientifique |
family |
str | Famille botanique |
region |
str | Région géographique |
photo_tree / photo_leaf / photo_root |
image | Photos obligatoires |
latitude / longitude |
float | Coordonnées GPS |
created_by |
FK(User) | Auteur |
vector |
JSON | Vecteur de features (544D) |
| Champ | Type | Description |
|---|---|---|
image |
image | Image envoyée par l’utilisateur |
predicted_species |
str | Nom de l’espèce prédite |
confidence |
float | Score de confiance |
suggestions |
JSON | Liste d’espèces similaires |
confirmed_species |
FK(Species) | Espèce confirmée |
is_correct |
bool | Statut du feedback |
notes |
text | Commentaire utilisateur |
recognition/
├── application/
│ ├── dto/
│ ├── use_cases/
│ └── ...
├── domain/
│ ├── entities/
│ └── enums/
├── infrastructure/
│ ├── db/
│ ├── repositories/
│ └── services/
└── interfaces/
└── rest/
🧠 Use Cases = logique métier 💾 Repositories = interaction avec la base 🌐 Interfaces REST = endpoints DRF
git clone https://github.com/cnra/pandatree.git
cd pandatree
python -m venv venv
source venv/bin/activate
pip install -r requirements.txtDJANGO_DEBUG=True
SECRET_KEY=change-this
DB_NAME=pandatree
DB_USER=postgres
DB_PASSWORD=postgres
DB_HOST=127.0.0.1
EMAIL_HOST_USER=devs.iipea@gmail.com
EMAIL_HOST_PASSWORD=xxxx
TIME_ZONE=Africa/Abidjanpython manage.py migrate
python manage.py runserverAccès Swagger : 👉 http://127.0.0.1:8000/api/schema/swagger/
var request = http.MultipartRequest(
'POST',
Uri.parse('https://api.pandatree.ci/api/recognition/predict/'),
);
request.headers['Authorization'] = 'Bearer $token';
request.files.add(await http.MultipartFile.fromPath('file', imagePath));
var response = await request.send();
print(await response.stream.bytesToString());await http.post(
Uri.parse('https://api.pandatree.ci/api/recognition/feedback/'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
},
body: jsonEncode({
'recognition_id': 8,
'is_correct': true,
'confirmed_species': 5,
'notes': 'Bonne correspondance'
}),
);- Respecter l’architecture Clean / DDD (UseCase ↔ Repository ↔ Interface).
- Toujours écrire des tests unitaires Django (
TestCase). - Éviter les requêtes N+1 → utiliser
select_related. - Centraliser les images dans
/media/. - Documenter chaque endpoint avec
@extend_schema. - Ne jamais stocker d’informations personnelles non nécessaires.
- Ajout d’un système de taxonomie complet (familles, genres, espèces).
- Déploiement de la carte publique interactive (Leaflet).
- Intégration des statistiques régionales (arbres/espèces par région).
- Synchronisation offline-first sur l’application Flutter.
- Export complet (CSV, Excel, PDF) des inventaires régionaux.
“Planter, Identifier, Préserver — PandaTree, la nature connectée.”