package main import ( "database/sql" "fmt" "log" "net/http" "forge.cadoles.com/LaCanne/realZ/internal/config" "forge.cadoles.com/LaCanne/realZ/internal/database" "github.com/gin-gonic/gin" _ "github.com/lib/pq" // Driver PostgreSQL ) // GpsCoord représente les coordonnées GPS reçues en entrée. // Les noms de champs commencent par une majuscule pour être exportables // et donc accessibles par le décodeur JSON de Gin. type GpsCoord struct { Lat float64 `json:"lat" binding:"required"` Lon float64 `json:"lon" binding:"required"` SrcProj int `json:"srcProj" binding:"required"` DstProj int `json:"dstProj" binding:"required"` } // GpsCoordWithZ représente les coordonnées GPS et l'altitude reçues pour le calcul de différence. type GpsCoordWithZ struct { Lat float64 `json:"lat" binding:"required"` Lon float64 `json:"lon" binding:"required"` Z float64 `json:"z" binding:"required"` SrcProj int `json:"srcProj" binding:"required"` DstProj int `json:"dstProj" binding:"required"` } // AltitudeResponse représente la réponse JSON retournée par l'API. type AltitudeResponse struct { Z float64 `json:"z"` } // CorrectedAltitudeResponse représente la réponse JSON pour l'altitude corrigée. type CorrectedAltitudeResponse struct { CorrectedZ float64 `json:"corrected_z"` } // getRealZ est le handler pour notre route. Il prend une connexion à la BDD en paramètre. func getOrthometricCorrection(db *database.Service) gin.HandlerFunc { return func(c *gin.Context) { var input GpsCoord // On valide et on lie le JSON d'entrée à notre struct GpsCoord. if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Paramètres invalides: " + err.Error()}) return } // On appelle notre fonction utilitaire pour obtenir l'altitude. correction, err := db.QueryOrthometricCorrection(input.Lat, input.Lon, input.SrcProj, input.DstProj) if err != nil { if err == sql.ErrNoRows { c.JSON(http.StatusNotFound, gin.H{"error": "Aucune donnée de correction trouvée pour ces coordonnées."}) } else { log.Printf("Erreur de la base de données: %v", err) c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur interne du serveur."}) } return } c.IndentedJSON(http.StatusOK, AltitudeResponse{Z: correction}) } } func getCorrectedAltitude(db *database.Service) gin.HandlerFunc { return func(c *gin.Context) { var input GpsCoordWithZ // On valide et on lie le JSON d'entrée à notre struct GpsCoordWithZ. if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Paramètres invalides: " + err.Error()}) return } // On appelle notre fonction utilitaire pour obtenir la correction orthométrique (N). correction, err := db.QueryOrthometricCorrection(input.Lat, input.Lon, input.SrcProj, input.DstProj) if err != nil { if err == sql.ErrNoRows { c.JSON(http.StatusNotFound, gin.H{"error": "Aucune donnée de correction trouvée pour ces coordonnées."}) } else { log.Printf("Erreur de la base de données: %v", err) c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur interne du serveur."}) } return } // On calcule l'altitude corrigée (H = h - N). // input.Z est l'altitude ellipsoïdale (h). // correction est l'ondulation du géoïde (N). correctedAltitude := input.Z - correction c.IndentedJSON(http.StatusOK, CorrectedAltitudeResponse{CorrectedZ: correctedAltitude}) } } func main() { cfg, err := config.LoadConfig(".") if err != nil { log.Fatalf("Error loading configuration: %v", err) } fmt.Printf("Config: %+v\n", cfg) db, err := database.NewService(&cfg.Database) if err != nil { log.Fatalf("Could not initialize database: %v", err) } log.Println("Connected to PostgreSQL database") defer db.Close() router := gin.Default() // Configure les proxies de confiance pour Gin if len(cfg.Server.TrustedProxies) > 0 { router.SetTrustedProxies(cfg.Server.TrustedProxies) log.Printf("Trusted proxies set to: %v", cfg.Server.TrustedProxies) } // Servir les fichiers statiques de l'UI go-app router.Static("/web", "./ui/web") // La route est maintenant un POST pour recevoir un corps de requête JSON. router.POST("/getorthocorrec", getOrthometricCorrection(db)) // Nouvelle route pour obtenir l'altitude corrigée. router.POST("/getcorrectedaltitude", getCorrectedAltitude(db)) log.Printf("Starting server on %s", cfg.Server.Address) if err := router.Run(cfg.Server.Address); err != nil { log.Fatalf("Failed to run server: %v", err) } }