- 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>
15 KiB
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
- Vue d'ensemble
- Structure des données
- Modes de la carte
- Création d'un secteur
- Gestion des secteurs adjacents
- Modification d'un secteur
- Suppression d'un secteur
- Affichage des secteurs
- Affichage des passages
- Permissions et rôles
- Synchronisation API/Hive
- Interactions utilisateur
- 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
{
id: int, // Identifiant unique
libelle: String, // Nom du secteur
color: String, // Couleur hexadécimale (#RRGGBB)
sector: String // Coordonnées "lat/lng#lat/lng#..."
}
PassageModel
{
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
-
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
-
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)
-
Envoi à l'API
{ "id": 0, "libelle": "Nom du secteur", "color": "#2196F3", "sector": "lat/lng#lat/lng#...", "operation_id": 3124, "fk_entite": 5, "users": [9999980, 9999985] } -
Réponse de l'API
{ "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 } ] } -
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 :
-
Première passe - Détection et correction des segments adjacents
// Pour chaque segment du nouveau secteur // Vérifier s'il est proche d'un segment existant // Si oui, corriger les deux points du segment -
Deuxième passe - Vérification et correction forte
// 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 :
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 :
- Points intérieurs : Un point est considéré à l'intérieur seulement s'il est à plus de 2m du bord
- Vertices partagés : Les vertices à moins de 5m de distance sont considérés comme partagés et ignorés
- Segments adjacents : Deux segments alignés et proches ne sont pas considérés comme un chevauchement
- Seuil de détection : Il faut au moins 3 points intérieurs ou 3 intersections pour détecter un chevauchement réel
- 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
truesi 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
-
Sélection du secteur
- Via la combobox ou clic sur la carte
- Bouton "Modifier" dans la barre d'outils
-
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
-
Validation
- Mêmes vérifications que pour la création
- Application de
_correctPointsForAdjacencyavec 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
-
Sélection du secteur
- L'administrateur clique sur "Supprimer un secteur"
- Il clique sur le secteur à supprimer (surbrillance rouge)
-
Dialog de confirmation
- Affichage du nom du secteur
- Avertissements sur les conséquences
-
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
-
Réponse de l'API
{ "status": "success", "passages_deleted": 45, "passages_reassigned": 125 } -
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"
- Toute modification passe d'abord par l'API
- En cas de succès, mise à jour de Hive
- 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
- Toujours passer par l'API pour les modifications
- Utiliser les repositories pour l'accès aux données
- Ne pas faire de setState dans les ValueListenableBuilder
- Gérer les erreurs avec ApiException
- Valider les données avant envoi à l'API
- Logger les actions importantes pour le debug
- Utiliser les mêmes méthodes de validation pour création et modification :
_correctPointsForAdjacencypour la correction automatique_doPolygonsOverlappour la détection de chevauchement_isValidPolygonpour la validation de base
- Sauvegarder le contexte parent avant d'ouvrir des dialogs pour éviter les erreurs de contexte
- Implémenter le chargement des associations (ex: UserSectorModel) pour présélectionner les données
Pour les utilisateurs
- Dessiner des secteurs cohérents (pas de croisements)
- Nommer clairement les secteurs
- Assigner les bons membres dès la création
- Vérifier avant suppression (action irréversible)
- Utiliser des couleurs distinctes pour différencier les secteurs
- 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
- 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