Zayeemk commited on
Commit
b645561
·
verified ·
1 Parent(s): 4bb549e

Update route_optimizer/green_route_optimizer.py

Browse files
route_optimizer/green_route_optimizer.py CHANGED
@@ -1,56 +1,71 @@
1
- # route_optimizer/green_route_optimizer.py
2
 
3
  from geopy.geocoders import Nominatim
4
  import math
5
 
6
  class GreenRouteOptimizer:
7
- """
8
- GreenRouteOptimizer calculates optimized routes for rail, road, and ship.
9
- Accepts place names (with optional country/short code) and returns distance and emission estimates.
10
- """
11
-
12
  def __init__(self, user_agent="green_route_app"):
13
  self.geolocator = Nominatim(user_agent=user_agent)
14
- # Emission factors in kg CO2 per km (example values)
15
  self.emission_factors = {
16
- "road": 0.21, # road transport
17
- "rail": 0.041, # rail transport
18
- "ship": 0.014 # shipping
19
  }
20
 
21
  def geocode(self, place_name):
22
- """Returns (latitude, longitude) tuple for a given place name."""
23
- location = self.geolocator.geocode(place_name)
24
- if location is None:
25
- raise ValueError(f"Could not geocode place: '{place_name}'")
26
- return (location.latitude, location.longitude)
27
-
28
- def optimize(self, start_coords, end_coords, mode="road"):
29
- """Calculates Euclidean distance and estimated emissions."""
 
 
30
  if mode not in self.emission_factors:
31
- raise ValueError(f"Invalid mode '{mode}'. Choose from {list(self.emission_factors.keys())}.")
32
 
33
- distance_km = math.dist(start_coords, end_coords) * 111 # approx km per degree
 
 
 
 
 
 
 
 
 
 
 
 
34
  optimized_route = {
35
  "start": start_coords,
36
  "end": end_coords,
37
  "mode": mode,
38
  "optimized_distance_km": round(distance_km, 2),
39
- "estimated_emission_kg": round(distance_km * self.emission_factors[mode], 3)
40
  }
41
  return optimized_route
42
 
43
- def recommend_green_routes(self, start_place, end_place):
44
- """
45
- Returns optimized routes for all transport modes.
46
- start_place and end_place can be:
47
- - "City"
48
- - "City, Country"
49
- - "City, CountryCode" (short form)
50
- """
51
  start_coords = self.geocode(start_place)
 
 
 
52
  end_coords = self.geocode(end_place)
 
 
 
53
  results = {}
54
  for mode in self.emission_factors:
55
- results[mode] = self.optimize(start_coords, end_coords, mode)
56
- return results
 
 
1
+ # route_optimizer/green_route_optimizer.py (Updated to use weight)
2
 
3
  from geopy.geocoders import Nominatim
4
  import math
5
 
6
  class GreenRouteOptimizer:
 
 
 
 
 
7
  def __init__(self, user_agent="green_route_app"):
8
  self.geolocator = Nominatim(user_agent=user_agent)
9
+ # --- NOTE: These factors are now interpreted as kg CO₂ per tonne-km ---
10
  self.emission_factors = {
11
+ "road": 0.21,
12
+ "rail": 0.041,
13
+ "ship": 0.014
14
  }
15
 
16
  def geocode(self, place_name):
17
+ try:
18
+ location = self.geolocator.geocode(place_name, timeout=10)
19
+ if location is None:
20
+ return None
21
+ return (location.latitude, location.longitude)
22
+ except Exception:
23
+ return None
24
+
25
+ # --- CHANGE: Added 'weight_tonnes' as an argument ---
26
+ def optimize(self, start_coords, end_coords, mode, weight_tonnes):
27
  if mode not in self.emission_factors:
28
+ raise ValueError(f"Invalid mode '{mode}'.")
29
 
30
+ R = 6371
31
+ lat1, lon1 = start_coords
32
+ lat2, lon2 = end_coords
33
+
34
+ dlat = math.radians(lat2 - lat1)
35
+ dlon = math.radians(lon2 - lon1)
36
+ a = math.sin(dlat / 2)**2 + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dlon / 2)**2
37
+ c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
38
+ distance_km = R * c
39
+
40
+ # --- CHANGE: Emission calculation now includes weight ---
41
+ estimated_emission = distance_km * self.emission_factors[mode] * weight_tonnes
42
+
43
  optimized_route = {
44
  "start": start_coords,
45
  "end": end_coords,
46
  "mode": mode,
47
  "optimized_distance_km": round(distance_km, 2),
48
+ "estimated_emission_kg": round(estimated_emission, 3)
49
  }
50
  return optimized_route
51
 
52
+ # --- CHANGE: Added 'weight_tonnes' as an argument ---
53
+ def recommend_green_routes(self, start_place, end_place, weight_tonnes):
54
+ if not start_place or not start_place.strip():
55
+ return {"error": "Start place cannot be empty."}
56
+ if not end_place or not end_place.strip():
57
+ return {"error": "End place cannot be empty."}
58
+
 
59
  start_coords = self.geocode(start_place)
60
+ if start_coords is None:
61
+ return {"error": f"Could not find location: '{start_place}'"}
62
+
63
  end_coords = self.geocode(end_place)
64
+ if end_coords is None:
65
+ return {"error": f"Could not find location: '{end_place}'"}
66
+
67
  results = {}
68
  for mode in self.emission_factors:
69
+ # --- CHANGE: Pass 'weight_tonnes' down to the optimize function ---
70
+ results[mode] = self.optimize(start_coords, end_coords, mode, weight_tonnes)
71
+ return results