Skip to content

AgriTech-WISE est une plateforme web avancée qui révolutionne le monitoring de l'humidité du sol en agriculture grâce à l'imagerie satellite et l'intelligence artificielle.

Notifications You must be signed in to change notification settings

wissalouarda6/AgriTech_WISE

Repository files navigation

🌾 AgriTech-WISE

Water Intelligence System for Agriculture using Earth Observation

Python Flask Earth Engine

Vue d'ensemble

AgriTech-WISE est une plateforme web avancée qui révolutionne le monitoring de l'humidité du sol en agriculture grâce à l'imagerie satellite et l'intelligence artificielle. Le système exploite les données Sentinel-1 (radar) et Sentinel-2 (optique) pour fournir des cartes d'humidité précises et actualisées.

Caractéristiques innovantes

  • Double source satellite : Sentinel-1 (radar, tout temps) et Sentinel-2 (optique, haute résolution)
  • IA adaptative : Sélection automatique du meilleur indice spectral selon les conditions
  • Calibration terrain : Régression linéaire avec vos mesures réelles
  • Visualisation interactive : Cartes dynamiques avec détection de changements temporels
  • Cloud-based : Architecture Firebase pour scalabilité et fiabilité

Cas d'usage

  • Irrigation de précision : Optimiser l'apport en eau selon les besoins réels
  • Gestion parcellaire : Surveiller plusieurs zones simultanément
  • Détection de stress hydrique : Alertes précoces sur les zones problématiques
  • Analyse temporelle : Comparer l'évolution de l'humidité entre périodes
  • Recherche agronomique : Calibration et validation d'indices spectraux

Stack technologique

Backend

  • Python 3.8+ : Langage principal
  • Flask : Framework web
  • Google Earth Engine API : Traitement d'images satellites
  • scikit-learn : Régression et machine learning
  • pandas/numpy : Traitement de données

Cloud & Base de données

  • Firebase Realtime Database : Données utilisateurs et zones
  • Firebase Storage : Fichiers CSV et exports
  • Firebase Authentication : Gestion sécurisée des comptes

Frontend

  • Leaflet.js : Cartographie interactive
  • Bootstrap : Interface responsive
  • JavaScript ES6+ : Interactions dynamiques

Méthodologie scientifique

Indices calculés

Sentinel-2 (optique - 10m résolution)

Indice Formule Usage
NDVI (NIR - Red) / (NIR + Red) Vigueur végétation
NDWI (Green - NIR) / (Green + NIR) Contenu en eau végétation
MNDWI (Green - SWIR) / (Green + SWIR) Eau de surface
MSI SWIR / NIR Stress hydrique

Sentinel-1 (radar SAR - 10m résolution)

Indice Formule Usage
RVI 4 × VH / (VV + VH) Humidité du sol

Pipeline d'analyse

┌─────────────────┐
│ Images satellite│
│ Sentinel-1/2    │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│Calcul d'indices │
│ spectraux       │
└────────┬────────┘
         │
         ▼
┌─────────────────┐     ┌──────────────┐
│ Mesures terrain │────▶│  Régression  │
│     (CSV)       │     │   linéaire   │
└─────────────────┘     └──────┬───────┘
                               │
                               ▼
                     ┌──────────────────┐
                     │Sélection meilleur│
                     │indice (min MSE)  │
                     └────────┬─────────┘
                              │
                              ▼
                    ┌─────────────────────┐
                    │Carte d'humidité     │
                    │calibrée et validée  │
                    └─────────────────────┘

Installation et configuration

Prérequis

  1. Python 3.8+
  2. Compte Google Earth EngineInscription
  3. Projet FirebaseConsole Firebase

Installation étape par étape

1. Cloner le projet

git clone https://github.com/votre-username/agritech-wise.git
cd agritech-wise

2. Environnement virtuel

python -m venv venv

# Linux/Mac
source venv/bin/activate

# Windows
venv\Scripts\activate

3. Dépendances

pip install -r requirements.txt

4. Configuration Earth Engine

earthengine authenticate

Suivre le lien pour autoriser l'accès à votre compte GEE.

Initialiser avec votre projet :

earthengine set_project YOUR_EE_PROJECT_ID

5. Configuration Firebase

a) Créer le projet Firebase

  • Aller sur Firebase Console
  • Créer un nouveau projet
  • Activer :
    • Authentication (Email/Password)
    • Realtime Database
    • Storage

b) Télécharger les credentials

  • Project Settings → Service Accounts
  • Generate New Private Key
  • Sauvegarder le JSON dans le dossier racine

c) Configuration des variables

Copier .env.example vers .env :

cp .env.example .env

Remplir avec vos valeurs Firebase (depuis Project Settings → General) :

FIREBASE_API_KEY=AIza...
FIREBASE_AUTH_DOMAIN=votre-projet.firebaseapp.com
FIREBASE_DATABASE_URL=https://votre-projet.firebaseio.com
FIREBASE_PROJECT_ID=votre-projet
FIREBASE_STORAGE_BUCKET=votre-projet.appspot.com
FIREBASE_MESSAGING_SENDER_ID=123456789
FIREBASE_APP_ID=1:123456789:web:abc123
FIREBASE_MEASUREMENT_ID=G-ABC123

EE_PROJECT_ID=votre-projet-ee
FLASK_SECRET_KEY=generer-une-cle-secrete-forte

d) Adapter firebase_config.py

Copier le template :

cp firebase_config.template.py firebase_config.py

Mettre à jour le chemin vers votre fichier credentials JSON.

6. Lancer l'application

python app.py

Accéder à http://localhost:5000

Format des données terrain

Structure CSV requise

Vos mesures terrain doivent être au format CSV avec au minimum :

Colonne Type Description Exemple
0 float Humidité pondérale (%) 85.5
1 float Latitude (WGS84) 41.6367
2 float Longitude (WGS84) -0.9023

Exemple de fichier

85.5,41.6367,-0.9023,2024-05-21,10:30
78.2,41.6377,-0.8990,2024-05-21,10:45
92.1,41.6356,-0.9016,2024-05-21,11:00

Recommandations

  • Nombre de points : Minimum 10-15 pour une régression fiable
  • Distribution spatiale : Couvrir toute la zone d'intérêt
  • Synchronisation temporelle : Mesures ± 3 jours de l'image satellite
  • Profondeur : Cohérente (ex: 0-10cm pour toutes les mesures)

Guide d'utilisation

1️ Créer un compte

  • Cliquer sur "S'inscrire"
  • Renseigner email et mot de passe
  • Validation automatique

2️ Définir une zone d'intérêt

  • Aller dans "Nouvelle Zone"
  • Dessiner le polygone sur la carte (Leaflet Draw)
  • Nommer et décrire la zone
  • Sauvegarder

3️ Uploader les mesures terrain

  • Accéder à "Mes Zones"
  • Cliquer sur la zone créée
  • "Uploader fichier CSV"
  • Sélectionner votre fichier de mesures

4️ Lancer la régression

  • Sélectionner les dates d'images (start/end)
  • Cliquer sur "Lancer les calculs"
  • Le système :
    • Récupère les images Sentinel
    • Calcule tous les indices
    • Effectue les régressions
    • Sélectionne le meilleur modèle (MSE minimum)

5️ Visualiser les résultats

  • Carte d'humidité générée automatiquement
  • Légende : du rouge (sec) au vert (humide)
  • Statistiques : coefficient, intercept, MSE

6️ Détection de changements (optionnel)

  • "Détection des changements"
  • Sélectionner 2 périodes à comparer
  • Visualisation côte-à-côte ou différentielle

Structure du projet

agritech-wise/
│
├── app.py                      # Application Flask principale
├── my_functions.py             # Régression et traitement GEE
├── detection_functions.py      # Détection et visualisation
├── firebase_config.py          # Configuration Firebase (non versionné)
│
├── templates/                  # Templates HTML
│   ├── home.html
│   ├── mes_zones.html
│   ├── nouvelle_zone.html
│   ├── centre_de_apprentissage.html
│   └── detection_des_changements.html
│
├── static/                     # Assets statiques
│   ├── css/
│   ├── js/
│   └── images/
│
├── requirements.txt            # Dépendances Python
├── .gitignore                  # Fichiers à ignorer
├── README.md                   # Ce fichier

Configuration avancée

Paramètres Sentinel-1

# detection_functions.py
def get_clear_sentinel1_image(start_date, end_date, roi):
    sentinel1 = ee.ImageCollection("COPERNICUS/S1_GRD") \
        .filter(ee.Filter.eq('instrumentMode', 'IW'))  # Mode Interferometric Wide
        .filter(ee.Filter.eq('orbitProperties_pass', 'DESCENDING'))  # Orbite descendante
        .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
        .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'))

Paramètres Sentinel-2

# my_functions.py
def get_clear_sentinel2_image(start_date, end_date, roi, max_cloud_percentage=10):
    sentinel2 = ee.ImageCollection("COPERNICUS/S2") \
        .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', max_cloud_percentage))

Personnalisation de la palette

# detection_functions.py
viz_params = {
    'min': 1.8,  # Humidité minimale (g/g)
    'max': 2.8,  # Humidité maximale (g/g)
    'palette': [
        '#d73027',  # Rouge - Très sec
        '#f46d43',
        '#fdae61',
        '#fee08b',
        '#ffffbf',  # Jaune - Moyen
        '#d9ef8b',
        '#a6d96a',
        '#66bd63',
        '#1a9850'   # Vert foncé - Très humide
    ]
}

Tests et validation

Vérifier l'installation

# Tester Earth Engine
python -c "import ee; ee.Initialize(); print('EE OK')"

# Tester Firebase
python -c "import firebase_admin; print('Firebase OK')"

Exemple de test de régression

# Dans app.py
@app.route('/test_function', methods=['GET'])
def test_function():
    # Utilise des données de test pour valider le pipeline

Guidelines

  • Code Python PEP 8 compliant
  • Docstrings pour toutes les fonctions
  • Tests unitaires si possible
  • Documentation des nouvelles fonctionnalités

Roadmap

  • Support Sentinel-3 (résolution thermique)
  • Modèles ML avancés (Random Forest, XGBoost)
  • API REST pour intégration externe
  • Application mobile (Flutter)
  • Alertes automatiques (email/SMS)
  • Export des données (GeoTIFF, Shapefile)

Limitations et considérations

Limitations techniques

  • Résolution : 10m (Sentinel-1/2) - non adapté aux petites parcelles (<1ha)
  • Revisit : 5-6 jours (combiné) - pas de suivi temps réel
  • Météo : Sentinel-2 limité par la couverture nuageuse
  • Profondeur : Surface seulement (0-5cm pour radar)

Considérations scientifiques

  • La régression linéaire suppose une relation linéaire indice-humidité

  • La calibration est spécifique à chaque zone (texture sol, type culture)

  • Validation recommandée avec mesures indépendantes

  • Google Earth Engine : Pour l'accès gratuit aux données satellites

  • ESA Copernicus : Programme Sentinel-1 et Sentinel-2

  • Firebase : Infrastructure cloud robuste

  • Communauté open-source : Flask, scikit-learn, Leaflet

Ce dépôt ne contient AUCUN credential sensible.

Pour exécuter l'application, vous devez :

  1. Créer vos propres comptes Firebase et Google Earth Engine
  2. Configurer vos propres credentials selon la documentation d'installation
  3. Ne JAMAIS committer de fichiers contenant des clés API ou secrets

Ce projet est fourni à titre éducatif et de démonstration.

Architecture de la Base de Données Firebase - AgriTech-WISE

Schéma Hiérarchique

agritech-wise-default-rtdb.firebaseio.com/
│
└── users/                                          # Collection racine des utilisateurs
    │
    ├── {userId}/                                   # Nœud unique par utilisateur (Firebase UID)
    │   │
    │   ├── email: string                          # Email de l'utilisateur
    │   ├── name: string                           # Nom d'affichage
    │   ├── phone: string                          # Numéro de téléphone
    │   │
    │   └── zones/                                  # Collection des zones agricoles
    │       │
    │       ├── {zoneId}/                          # Zone unique (UUID v4)
    │       │   │
    │       │   ├── name: string                   # Nom de la zone
    │       │   ├── description: string            # Description détaillée
    │       │   ├── coordinates: string            # Polygone GeoJSON stringifié
    │       │   │
    │       │   ├── mesures_sur_terrain: boolean   # Statut upload fichier CSV
    │       │   ├── file_url: string               # URL Firebase Storage du CSV
    │       │   ├── prette_a_detecter: boolean     # Zone calibrée et prête
    │       │   ├── programmer_rendez_vous: boolean # Rendez-vous terrain programmé
    │       │   │
    │       │   └── paramettre_de_regression/      # Résultats de l'apprentissage
    │       │       │
    │       │       ├── optimal_index: string      # Indice sélectionné (RVI, NDVI, etc.)
    │       │       ├── coefficient: float         # Coefficient de régression (a)
    │       │       ├── intercept: float           # Ordonnée à l'origine (b)
    │       │       ├── mse: float                 # Erreur quadratique moyenne
    │       │       │
    │       │       ├── INDEX_values: array<float> # Valeurs de l'indice spectral
    │       │       │   ├── 0: 2.5122194205786568
    │       │       │   ├── 1: 2.3456789012345678
    │       │       │   └── ...
    │       │       │
    │       │       └── humidity_values: array<float> # Humidité mesurée (g/g)
    │       │           ├── 0: 1.95
    │       │           ├── 1: 2.12
    │       │           └── ...
    │       │
    │       ├── {zoneId2}/                         # Autre zone
    │       └── ...
    │
    ├── {userId2}/                                  # Autre utilisateur
    └── ...

Description Détaillée des Entités

1️ Niveau Utilisateur : /users/{userId}

Champ Type Description Exemple
userId String (UID) Identifiant unique Firebase Auth omNKKc8Q8WOecpAExmi271x9lCr2
email String Adresse email de connexion [email protected]
name String Nom d'affichage de l'utilisateur test10Q
phone String Numéro de téléphone de contact 123423

Créé lors de : Inscription utilisateur (/signup)
Modifié par : Route /update_contact_info


2️ Niveau Zone : /users/{userId}/zones/{zoneId}

Métadonnées de base

Champ Type Description Exemple
zoneId String (UUID) Identifiant unique de la zone 23dc505c-71ca-4ae9-94aa-2d666325544a
name String Nom personnalisé de la zone test1
description String Informations additionnelles Informations
coordinates String (JSON) Polygone délimitant la zone
Format: Array de [lon, lat]
[[-0.896, 35.582], [-0.902, 35.581], ...]

Créé lors de : Définition de zone (/save-zone)
Modifié par : Route /edit-zone/{zoneId}

Workflow et Statuts

Champ Type Description États possibles
mesures_sur_terrain Boolean Fichier CSV uploadé true / false / absent
programmer_rendez_vous Boolean Rendez-vous terrain planifié true / false / absent
prette_a_detecter Boolean Calibration terminée, détection possible true / false / absent
file_url String URL publique du CSV dans Firebase Storage https://storage.googleapis.com/agritech-wise.appspot.com/terrain1.csv

Workflow typique :

1. mesures_sur_terrain: false  → Upload CSV
2. mesures_sur_terrain: true   → Lancer régression
3. prette_a_detecter: true     → Détection activée

3️ Niveau Régression : /users/{userId}/zones/{zoneId}/paramettre_de_regression

Paramètres du modèle

Champ Type Description Exemple
optimal_index String Indice spectral avec meilleur R² RVI, NDVI_S, MNDWI_S, MSI_S, NDWI_S
coefficient Float Pente de la droite de régression (a) 0.7542
intercept Float Ordonnée à l'origine (b) 1.823
mse Float Mean Squared Error (qualité du modèle) 0.0234

Équation de prédiction :

Humidité_prédite = coefficient × Indice_spectral + intercept

Données d'entraînement

Champ Type Description
INDEX_values Array<Float> Valeurs de l'indice spectral extrait des pixels satellites
humidity_values Array<Float> Humidité mesurée sur terrain (après transformation)

Transformation appliquée :

# my_functions.py ligne 18
humidity_transformed = (humidity_measured * 0.01) + 1.8
# Exemple: 85.5% → 2.655 g/g

Utilisé pour :

  • Validation du modèle (graphiques de régression)
  • Analyse de la qualité de prédiction
  • Amélioration itérative du modèle

Flux de Données et Routes Flask

Phase 1 : Inscription et Gestion Utilisateur

graph LR
    A[POST /signup] --> B[Créer user dans Firebase Auth]
    B --> C[Créer nœud /users/userId]
    C --> D[Stocker email, name, phone]

    E[POST /update_contact_info] --> F[Mettre à jour /users/userId]
Loading

Code correspondant :

# app.py ligne 107
def signup():
    user = auth.create_user_with_email_and_password(email, password)
    create_user(user_id, email)  # → firebase_config.py

Phase 2 : Création de Zone

graph LR
    A[POST /save-zone] --> B[Générer UUID zoneId]
    B --> C[Créer /users/userId/zones/zoneId]
    C --> D[Stocker coordinates, name, description]
    D --> E[Initialiser statuts = false]
Loading

Structure initiale :

{
  "name": "Parcelle Nord",
  "description": "Culture de blé",
  "coordinates": "[[-0.896, 35.582], ...]",
  "mesures_sur_terrain": false,
  "prette_a_detecter": false
}

Phase 3 : Upload Mesures Terrain

graph TD
    A[POST /upload_file/userId/zoneId] --> B[Upload CSV vers Firebase Storage]
    B --> C[Générer URL publique]
    C --> D[Mettre à jour zone:]
    D --> E[mesures_sur_terrain = true]
    D --> F[file_url = URL_public]
Loading

Code correspondant :

# app.py ligne 296
def upload_file(user_id, zone_id):
    blob = bucket.blob(filename)
    blob.upload_from_file(file)
    file_url = blob.public_url
    zone_ref.update({'mesures_sur_terrain': True, 'file_url': file_url})

Phase 4 : Régression et Calibration

graph TD
    A[GET /run_regression] --> B[Télécharger CSV depuis file_url]
    B --> C[Récupérer images Sentinel-1/2]
    C --> D[Calculer indices spectraux]
    D --> E[Régression linéaire]
    E --> F[Sélectionner meilleur indice MSE minimum]
    F --> G[Créer /paramettre_de_regression]
    G --> H[prette_a_detecter = true]
Loading

Données créées :

{
  "paramettre_de_regression": {
    "optimal_index": "RVI",
    "coefficient": 0.7542,
    "intercept": 1.823,
    "mse": 0.0234,
    "INDEX_values": [2.512, 2.345, 2.678, ...],
    "humidity_values": [1.95, 2.12, 2.08, ...]
  },
  "prette_a_detecter": true
}

Code correspondant :

# app.py ligne 409
def run_regression():
    log_data, coefficient, intercept, mse, INDEX_values, humidity_values = \
        get_para_and_apply_regression(polygone, file_path, start_date, end_date)

    regression_data = {
        'optimal_index': log_data,
        'coefficient': coefficient,
        'intercept': intercept,
        'mse': mse,
        'INDEX_values': INDEX_values_list,
        'humidity_values': humidity_values_list
    }
    regression_ref.set(regression_data)

Phase 5 : Détection d'Humidité

graph TD
    A[POST /detect] --> B[Vérifier prette_a_detecter = true]
    B --> C[Récupérer paramettre_de_regression]
    C --> D[Charger image satellite date demandée]
    D --> E[Calculer indice optimal_index]
    E --> F[Appliquer formule: H = coefficient × I + intercept]
    F --> G[Générer carte d'humidité]
    G --> H[Retourner tile_url pour Leaflet]
Loading

Pas de modification de la DB - Lecture seule des paramètres.


Cas d'Usage des Statuts Booléens

mesures_sur_terrain

Valeur Signification Actions possibles
false / absent Pas de données terrain Upload CSV requis
true CSV uploadé et stocké Lancer régression

Utilisé dans :

  • Interface pour afficher/masquer bouton "Lancer calculs"
  • Validation avant régression

prette_a_detecter

Valeur Signification Actions possibles
false / absent Pas de calibration Compléter workflow
true Régression effectuée, modèle validé Détection activée

Utilisé dans :

  • Route /check_prette_a_detecter/{zone_id} (ligne 205)
  • Activer/désactiver page "Détection des changements"

programmer_rendez_vous

Valeur Signification Workflow
false / absent Pas de rendez-vous Planification disponible
true Rendez-vous programmé En attente intervention terrain

Utilisé dans :

  • Gestion des demandes administrateur
  • Suivi des zones en attente de mesures

Règles de Sécurité Firebase Recommandées

{
  "rules": {
    "users": {
      "$userId": {
        ".read": "$userId === auth.uid",
        ".write": "$userId === auth.uid",

        "zones": {
          "$zoneId": {
            ".validate": "newData.hasChildren(['name', 'coordinates'])"
          }
        }
      }
    }
  }
}

Principes :

  • Chaque utilisateur accède uniquement à ses données
  • Validation de la structure minimale des zones
  • Admin peut avoir accès lecture seule (à configurer selon besoins)

📈 Exemple Complet d'une Zone Calibrée

{
  "users": {
    "omNKKc8Q8WOecpAExmi271x9lCr2": {
      "email": "[email protected]",
      "name": "test10Q",
      "phone": "123423",
      "zones": {
        "23dc505c-71ca-4ae9-94aa-2d666325544a": {
          "name": "Parcelle Expérimentale 1",
          "description": "Culture de blé irrigué - Campagne 2024",
          "coordinates": "[[-0.8960151672908979, 35.582239292725276], [-0.902280807549687, 35.581750659855274], [-0.8985042572567182, 35.57295475838894], [-0.8867454529354292, 35.57532835076638]]",

          "mesures_sur_terrain": true,
          "file_url": "https://storage.googleapis.com/agritech-wise.appspot.com/terrain1.csv",
          "prette_a_detecter": true,
          "programmer_rendez_vous": false,

          "paramettre_de_regression": {
            "optimal_index": "RVI",
            "coefficient": 0.7542,
            "intercept": 1.823,
            "mse": 0.0234,

            "INDEX_values": [
              2.5122194205786568, 2.3456789012345678, 2.6789012345678901,
              2.4567890123456789, 2.567890123456789
            ],

            "humidity_values": [1.95, 2.12, 2.08, 2.15, 2.03]
          }
        }
      }
    }
  }
}

Requêtes Firebase Courantes

Récupérer toutes les zones d'un utilisateur

# app.py ligne 182
user_id = session['user']['localId']
zones = get_user_zones(user_id)  # → firebase_config.py
# firebase_config.py
def get_user_zones(user_id):
    zones_ref = db.reference(f'users/{user_id}/zones')
    return zones_ref.get()

Vérifier statut d'une zone

# app.py ligne 197
zone_ref = db.reference(f'users/{user_id}/zones/{zone_id}')
zone_data = zone_ref.get()
prette_a_detecter = zone_data.get('prette_a_detecter', False)

Mettre à jour paramètres de régression

# app.py ligne 428
regression_ref = user_ref.child(f'zones/{zone_id}/paramettre_de_regression')
regression_ref.set(regression_data)

zone_ref.update({'prette_a_detecter': True})

Statistiques et Optimisations

Taille Estimée par Zone

Composant Taille approximative
Métadonnées de base 500 bytes
Coordinates (polygone 10 points) 300 bytes
INDEX_values (50 mesures) 400 bytes
humidity_values (50 mesures) 400 bytes
Total par zone ~1.6 KB

Capacité Firebase :

  • Plan gratuit : 1 GB stockage
  • → ~625,000 zones possibles (limite théorique)

Checklist de Validation d'une Zone

  • name non vide
  • coordinates contient au moins 3 points
  • mesures_sur_terrain = true
  • file_url accessible et CSV valide
  • paramettre_de_regression existe
  • optimal_index dans la liste autorisée
  • mse < 0.1 (seuil de qualité)
  • prette_a_detecter = true

AgriTech_WISE

About

AgriTech-WISE est une plateforme web avancée qui révolutionne le monitoring de l'humidité du sol en agriculture grâce à l'imagerie satellite et l'intelligence artificielle.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published