Files
geo/app/docs/GESTION-SECTEURS.md
pierre 1018b86537 feat: Gestion des secteurs et migration v3.0.4+304
- Ajout système complet de gestion des secteurs avec contours géographiques
- Import des contours départementaux depuis GeoJSON
- API REST pour la gestion des secteurs (/api/sectors)
- Service de géolocalisation pour déterminer les secteurs
- Migration base de données avec tables x_departements_contours et sectors_adresses
- Interface Flutter pour visualisation et gestion des secteurs
- Ajout thème sombre dans l'application
- Corrections diverses et optimisations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-07 11:01:45 +02:00

453 lines
15 KiB
Markdown

# Gestion des Secteurs et de la Carte
Ce document centralise toutes les règles de gestion des secteurs et de la carte dans l'application Geosector.
**Dernière mise à jour** : Décembre 2024 - Améliorations de la détection d'adjacence et de l'ergonomie du drag
## Table des matières
1. [Vue d'ensemble](#vue-densemble)
2. [Structure des données](#structure-des-données)
3. [Modes de la carte](#modes-de-la-carte)
4. [Création d'un secteur](#création-dun-secteur)
5. [Gestion des secteurs adjacents](#gestion-des-secteurs-adjacents)
6. [Modification d'un secteur](#modification-dun-secteur)
7. [Suppression d'un secteur](#suppression-dun-secteur)
8. [Affichage des secteurs](#affichage-des-secteurs)
9. [Affichage des passages](#affichage-des-passages)
10. [Permissions et rôles](#permissions-et-rôles)
11. [Synchronisation API/Hive](#synchronisation-apihive)
12. [Interactions utilisateur](#interactions-utilisateur)
13. [Bonnes pratiques](#bonnes-pratiques)
## Vue d'ensemble
La carte administrative (`AdminMapPage`) permet aux administrateurs de gérer les secteurs géographiques d'une opération. Chaque secteur est un polygone défini par des coordonnées GPS et peut contenir des passages (adresses à visiter).
### Technologies utilisées
- **flutter_map** avec **MapBox** pour l'affichage de la carte
- **Hive** pour le stockage local des données
- **ValueListenableBuilder** pour la mise à jour réactive de l'interface
## Structure des données
### SectorModel
```dart
{
id: int, // Identifiant unique
libelle: String, // Nom du secteur
color: String, // Couleur hexadécimale (#RRGGBB)
sector: String // Coordonnées "lat/lng#lat/lng#..."
}
```
### PassageModel
```dart
{
id: int,
fk_sector: int, // ID du secteur
fk_user: int, // ID de l'utilisateur assigné
fk_type: int, // Type de passage (1-6)
gps_lat: String, // Latitude
gps_lng: String, // Longitude
numero: String, // Numéro de rue
rue: String, // Nom de la rue
ville: String, // Ville
// ... autres champs
}
```
### Types de passages
- **1** : Effectué (vert)
- **2** : À finaliser (orange)
- **3** : Refusé (rouge)
- **4** : Don (bleu)
- **5** : Lot (violet)
- **6** : Maison vide (gris)
## Modes de la carte
La carte peut être dans l'un des modes suivants :
### MapMode.view (Mode visualisation)
- Mode par défaut
- Permet de naviguer sur la carte
- Affiche les secteurs et passages
- Permet la sélection d'un secteur via la combobox
### MapMode.drawing (Mode création)
- Activé par le bouton "Créer un secteur"
- Affiche une carte d'aide explicative
- Permet de dessiner un nouveau secteur en cliquant sur la carte
- Points verts pour le premier point, bleus pour les suivants
- Fermeture du polygone en cliquant sur le premier point
### MapMode.editing (Mode édition)
- Activé par le bouton "Modifier un secteur"
- Permet de modifier les contours d'un secteur existant
- Sélectionner un secteur par clic ou via la combobox puis cliquer "Modifier"
- Points orange draggables avec magnétisme automatique
- Ajout de points via les points intermédiaires gris
- Suppression de points avec clic droit ou Ctrl+clic
### MapMode.deleting (Mode suppression)
- Activé par le bouton "Supprimer un secteur"
- Affiche une carte d'aide avec avertissements
- Permet de sélectionner un secteur à supprimer en cliquant dessus
- Le secteur sélectionné apparaît en rouge
## Création d'un secteur
### Processus de création
1. **Dessin du secteur**
- L'administrateur clique sur le bouton "Créer un secteur"
- Il dessine le contour en cliquant sur la carte (minimum 3 points)
- Il ferme le polygone en cliquant sur le premier point
2. **Dialog de création**
- Nom du secteur (obligatoire)
- Couleur du secteur (sélection dans une palette)
- Sélection des membres assignés (au moins un obligatoire)
3. **Envoi à l'API**
```json
{
"id": 0,
"libelle": "Nom du secteur",
"color": "#2196F3",
"sector": "lat/lng#lat/lng#...",
"operation_id": 3124,
"fk_entite": 5,
"users": [9999980, 9999985]
}
```
4. **Réponse de l'API**
```json
{
"status": "success",
"sector": { /* ou sector_id */ },
"passages_sector": [...],
"passages_created": 86,
"passages_integrated": 0,
"users_sectors": [...],
"warning": "Avertissement si débordement départemental",
"intersecting_departments": [
{
"code_dept": "35",
"nom_dept": "Ille-et-Vilaine",
"percentage_overlap": 85.2
}
]
}
```
5. **Traitement de la réponse**
- Le secteur est sauvegardé dans Hive
- Les passages sont créés avec les coordonnées GPS
- Les associations utilisateur-secteur sont traitées
- La carte se centre sur le nouveau secteur
### Règles de création
- Un secteur doit avoir au moins 3 points
- Le nom est obligatoire
- Au moins un membre doit être assigné
- Les coordonnées sont au format "latitude/longitude"
- Le dernier point doit fermer le polygone
- Les secteurs adjacents sont automatiquement corrigés (voir section dédiée)
## Gestion des secteurs adjacents
### Vue d'ensemble
L'application gère automatiquement la création de secteurs adjacents (partageant une bordure commune) sans générer d'erreur de chevauchement. Cette fonctionnalité est cruciale pour permettre un découpage précis du territoire.
### Correction automatique des points
#### Méthode `_correctPointsForAdjacency`
Cette méthode est appelée automatiquement lors de :
- La validation d'un nouveau secteur (création)
- La validation d'un secteur modifié (modification)
**Paramètres de correction :**
- **Distance de détection** : 10 mètres
- **Décalage de correction** : 2 mètres vers l'intérieur
- **Décalage fort** : 5 mètres (si chevauchement persistant)
**Processus en deux passes :**
1. **Première passe - Détection et correction des segments adjacents**
```dart
// Pour chaque segment du nouveau secteur
// Vérifier s'il est proche d'un segment existant
// Si oui, corriger les deux points du segment
```
2. **Deuxième passe - Vérification et correction forte**
```dart
// Appel à _ensureNoIntersection
// Si chevauchement détecté → _applyStrongerCorrection
```
### Calcul du décalage vers l'intérieur
#### Méthode `_offsetPointInward`
**Principe :**
- Calcule la bissectrice des segments adjacents
- Utilise le produit vectoriel pour déterminer la direction intérieure
- Applique un décalage en tenant compte de la latitude
**Formule de conversion :**
```dart
offsetDegreesLat = offsetMeters / 111320.0
offsetDegreesLng = offsetMeters / (111320.0 * cos(latitude))
```
### Détection intelligente des chevauchements
#### Méthode `_doPolygonsOverlap`
**Tolérance d'adjacence** : 2 mètres
**Règles de détection améliorées :**
1. **Points intérieurs** : Un point est considéré à l'intérieur seulement s'il est à plus de 2m du bord
2. **Vertices partagés** : Les vertices à moins de 5m de distance sont considérés comme partagés et ignorés
3. **Segments adjacents** : Deux segments alignés et proches ne sont pas considérés comme un chevauchement
4. **Seuil de détection** : Il faut au moins 3 points intérieurs ou 3 intersections pour détecter un chevauchement réel
5. **Exclusion du secteur en cours** : Lors de la modification, le secteur lui-même est exclu de la détection
#### Méthode `_areSegmentsAdjacent`
Détermine si deux segments sont adjacents (partagent une partie commune) :
- Vérifie l'alignement des segments
- Vérifie la proximité des points aux lignes opposées
- Retourne `true` si les segments sont sur la même ligne
### Magnétisme automatique
Lors de la sélection d'un secteur pour modification :
- Application automatique du magnétisme aux points proches
- Visualisation immédiate des ajustements
- Message d'information si des points ont été magnétisés
### Exemple de création de secteurs adjacents
```
Secteur A (existant) : Nouveau secteur B :
+--------+ +--------+
| | | |
| A | <-- bordure --> | B |
| | commune | |
+--------+ +--------+
```
**Résultat après correction automatique :**
- Les points de B sur la bordure commune sont décalés de 2m vers l'intérieur
- Aucune erreur de chevauchement
- Les secteurs restent visuellement adjacents
### Messages utilisateur
- **Correction appliquée** : "Les points ont été ajustés automatiquement pour éviter les chevauchements" (bleu)
- **Chevauchement détecté** : "Le nouveau secteur chevauche avec le secteur [nom]" (rouge)
- **Logging détaillé** : En cas de chevauchement détecté, les coordonnées des zones problématiques sont loggées
## Modification d'un secteur
### Processus de modification
1. **Sélection du secteur**
- Via la combobox ou clic sur la carte
- Bouton "Modifier" dans la barre d'outils
2. **Mode édition**
- Application automatique du magnétisme dès la sélection
- Points draggables instantanément (clic et drag immédiat)
- Points orange avec zone de détection élargie (50x50px)
- Ajout de points via les points intermédiaires gris
- Suppression avec clic droit ou Ctrl+clic
- Désactivation du drag de la carte pendant le déplacement d'un point
3. **Validation**
- Mêmes vérifications que pour la création
- Application de `_correctPointsForAdjacency` avec exclusion du secteur en cours
- Dialog pour modifier nom, couleur et membres
- Les membres déjà affectés sont automatiquement présélectionnés
- Affichage d'un dialog récapitulatif avec statistiques
### Règles de modification
- Minimum 3 points maintenu
- Correction automatique des adjacences
- Même processus de validation que la création
- Les passages sont automatiquement réaffectés selon le nouveau contour
## Suppression d'un secteur
### Processus de suppression
1. **Sélection du secteur**
- L'administrateur clique sur "Supprimer un secteur"
- Il clique sur le secteur à supprimer (surbrillance rouge)
2. **Dialog de confirmation**
- Affichage du nom du secteur
- Avertissements sur les conséquences
3. **Règles de suppression des passages**
- Passages "à finaliser" (type 2) sans nom d'habitant → **supprimés**
- Autres passages → **conservés mais réassignés au secteur 0**
4. **Réponse de l'API**
```json
{
"status": "success",
"passages_deleted": 45,
"passages_reassigned": 125
}
```
5. **Mise à jour locale**
- Suppression du secteur de Hive
- Mise à jour des passages selon les règles
- Actualisation automatique de la carte
## Affichage des secteurs
### Représentation visuelle
- **Polygones colorés** avec transparence (30% en normal, 50% si sélectionné)
- **Bordure** de la couleur du secteur (épaisseur 2px, 3px si sélectionné)
- **Mode suppression** : secteur en rouge avec bordure épaisse (4px)
### Filtrage par secteur
- Combobox en haut à gauche
- "Tous les secteurs" par défaut
- Sélection d'un secteur → zoom et centrage automatique
- Filtrage des passages affichés
## Affichage des passages
### Représentation visuelle
- **Marqueurs circulaires** de 14x14 pixels
- **Couleur principale** selon le type de passage
- **Bordure blanche** de 1px
- **Cliquables** pour afficher les détails
### Conditions d'affichage
- Coordonnées GPS valides (gps_lat et gps_lng)
- Type de passage reconnu (1-6)
- Appartenance au secteur sélectionné (si filtre actif)
### Informations au clic
- Adresse complète
- Nom de l'habitant (si disponible)
- Type de passage
- Informations de règlement (si applicable)
- Boutons d'édition/suppression
## Permissions et rôles
### Accès à la carte administrative
- **Rôle minimum requis** : Admin Amicale (rôle > 1)
- **Rôle 1 (Membre)** : Pas d'accès à la carte admin
- **Rôle 2+ (Admin)** : Accès complet aux fonctionnalités
### Actions autorisées
- **Création de secteur** : Admin+
- **Modification de secteur** : Admin+
- **Suppression de secteur** : Admin+
- **Visualisation** : Admin+
## Synchronisation API/Hive
### Principe "API First"
1. Toute modification passe d'abord par l'API
2. En cas de succès, mise à jour de Hive
3. En cas d'échec, aucune modification locale
### Flux de données
#### Chargement initial
```
API (login) → Secteurs/Passages → Hive → ValueListenableBuilder → UI
```
#### Création de secteur
```
UI → API → Réponse (secteur + passages) → Hive → Auto-refresh UI
```
#### Suppression de secteur
```
UI → API → Réponse (stats) → Mise à jour Hive → Auto-refresh UI
```
### Gestion des erreurs
- Affichage de SnackBar avec message d'erreur
- Pas de modification locale en cas d'échec API
- Log des erreurs pour debug
### Performance
- Utilisation de box caching dans les repositories
- ValueListenableBuilder pour éviter les rebuilds inutiles
- Chargement asynchrone des données
## Interactions utilisateur
### Gestion du drag des points
**Technologie utilisée** : `Listener` avec `onPointerDown`/`onPointerMove`/`onPointerUp`
**Avantages :**
- Démarrage instantané du drag au clic (onPointerDown)
- Pas de conflit avec les gestes de la carte
- Conversion directe des coordonnées écran en coordonnées géographiques
**Interactions supportées :**
- **Clic gauche** : Démarre le drag immédiatement
- **Clic droit / Ctrl+clic** : Supprime le point
- **Clic sur premier point (mode dessin)** : Ferme le polygone si 3+ points
- **Drag** : Déplace le point avec magnétisme en temps réel
### Dialog récapitulatif
Après chaque opération (création/modification/suppression), un dialog affiche :
- **Statistiques des passages** : créés, mis à jour, orphelins, total
- **Avertissements départementaux** : si le secteur est à cheval sur plusieurs départements
- **Icônes et couleurs** adaptées selon le type d'opération
## Bonnes pratiques
### Pour les développeurs
1. **Toujours passer par l'API** pour les modifications
2. **Utiliser les repositories** pour l'accès aux données
3. **Ne pas faire de setState** dans les ValueListenableBuilder
4. **Gérer les erreurs** avec ApiException
5. **Valider les données** avant envoi à l'API
6. **Logger les actions importantes** pour le debug
7. **Utiliser les mêmes méthodes de validation** pour création et modification :
- `_correctPointsForAdjacency` pour la correction automatique
- `_doPolygonsOverlap` pour la détection de chevauchement
- `_isValidPolygon` pour la validation de base
8. **Sauvegarder le contexte parent** avant d'ouvrir des dialogs pour éviter les erreurs de contexte
9. **Implémenter le chargement des associations** (ex: UserSectorModel) pour présélectionner les données
### Pour les utilisateurs
1. **Dessiner des secteurs cohérents** (pas de croisements)
2. **Nommer clairement** les secteurs
3. **Assigner les bons membres** dès la création
4. **Vérifier avant suppression** (action irréversible)
5. **Utiliser des couleurs distinctes** pour différencier les secteurs
6. **Pour les secteurs adjacents** :
- Dessiner normalement sans se soucier de la précision
- Le système ajuste automatiquement les bordures
- Vérifier le résultat après la correction automatique
7. **Pour la modification des secteurs** :
- Cliquer directement sur un point pour le déplacer (pas besoin de maintenir)
- Utiliser les points gris intermédiaires pour ajouter des sommets
- Clic droit ou Ctrl+clic pour supprimer un point
- Le magnétisme s'applique automatiquement aux bordures adjacentes