130 lines
4.3 KiB
Go
130 lines
4.3 KiB
Go
package api
|
|
|
|
import (
|
|
"database/sql"
|
|
"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.Load()
|
|
if err != nil {
|
|
log.Fatalf("Error loading configuration: %v", err)
|
|
}
|
|
|
|
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()
|
|
|
|
// Servir les fichiers statiques (index.html, etc.) depuis le répertoire courant.
|
|
router.StaticFS("/", http.Dir("."))
|
|
|
|
// 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)
|
|
}
|
|
}
|