package transport import ( "bugulma/backend/internal/domain" ) // TransportAnalysis represents transport feasibility and cost analysis type TransportAnalysis struct { Method string `json:"method"` CostPerUnit float64 `json:"cost_per_unit"` FeasibilityScore float64 `json:"feasibility_score"` EstimatedTimeDays int `json:"estimated_time_days"` EnvironmentalImpact float64 `json:"environmental_impact"` } // Service provides transport analysis functionality type Service struct{} // NewService creates a new transport analysis service func NewService() *Service { return &Service{} } // AnalyzeTransport performs transport feasibility and cost analysis func (s *Service) AnalyzeTransport(distanceKm float64, resourceType domain.ResourceType) *TransportAnalysis { analysis := &TransportAnalysis{} // Determine transport method analysis.Method = s.determineTransportMethod(resourceType, distanceKm) // Calculate cost per unit analysis.CostPerUnit = s.calculateTransportCost(distanceKm, resourceType) // Assess feasibility analysis.FeasibilityScore = s.assessTransportFeasibility(distanceKm, resourceType) // Estimate delivery time analysis.EstimatedTimeDays = s.estimateDeliveryTime(distanceKm, analysis.Method) // Calculate environmental impact analysis.EnvironmentalImpact = s.calculateTransportEnvironmentalImpact(distanceKm, analysis.Method) return analysis } func (s *Service) determineTransportMethod(resourceType domain.ResourceType, distanceKm float64) string { if distanceKm < 5 { return "pipeline" } switch resourceType { case domain.TypeHeat, domain.TypeSteam, domain.TypeCooling: if distanceKm < 10 { return "pipeline" } return "no_viable_transport" case domain.TypeWater: return "pipeline" case domain.TypeCO2, domain.TypeBiowaste, domain.TypeMaterials: return "truck" case domain.TypeLogistics: return "various" case domain.TypeService: return "on_site" default: return "truck" } } func (s *Service) calculateTransportCost(distance float64, resourceType domain.ResourceType) float64 { // Transport cost per km based on resource type transportRates := map[domain.ResourceType]float64{ domain.TypeHeat: 0.0005, // €0.5 per km per MWh (piping) domain.TypeWater: 0.001, // €1 per km per m³ domain.TypeSteam: 0.0005, // Similar to heat domain.TypeCO2: 0.002, // Truck/tanker transport domain.TypeBiowaste: 0.003, // Truck transport domain.TypeCooling: 0.0005, // Piping domain.TypeMaterials: 0.002, // Truck transport domain.TypeLogistics: 0.001, // Variable domain.TypeService: 0.0, // No transport for services } rate, exists := transportRates[resourceType] if !exists { rate = 0.001 // Default rate } return distance * rate } func (s *Service) assessTransportFeasibility(distanceKm float64, resourceType domain.ResourceType) float64 { method := s.determineTransportMethod(resourceType, distanceKm) switch method { case "pipeline": if distanceKm < 20 { return 0.9 } return 0.3 case "truck": if distanceKm < 200 { return 0.8 } return 0.4 case "no_viable_transport": return 0.1 case "on_site": return 1.0 default: return 0.7 } } func (s *Service) estimateDeliveryTime(distanceKm float64, method string) int { switch method { case "pipeline": return 0 // Continuous flow case "truck": return int(distanceKm/800) + 1 // Assume 800km/day truck speed case "on_site": return 0 default: return 1 } } func (s *Service) calculateTransportEnvironmentalImpact(distanceKm float64, method string) float64 { switch method { case "truck": return distanceKm * 0.0005 // tonnes CO2 per km for diesel truck case "pipeline": return distanceKm * 0.0001 // Much lower for electricity-powered pumping default: return 0 } }