Commit 5634c975a7d59096bfc18d75005f43f2a0cc1bdd

Authored by Antoine Goutenoir
1 parent 1ae3ccd1
Exists in master

Expose travel distance as output.

/spend 22h
flaskr/controllers/main_controller.py
... ... @@ -262,7 +262,8 @@ def compute(): # process the queue of estimation requests
262 262  
263 263 destinations_by_city_key = {}
264 264  
265   - cities_sum = {}
  265 + cities_sum_foot = {}
  266 + cities_sum_dist = {}
266 267 for model in emission_models:
267 268 cities_dict = {}
268 269 for _destination in _destinations:
... ... @@ -282,11 +283,16 @@ def compute(): # process the queue of estimation requests
282 283 'city': city_key,
283 284 'address': _destination.address,
284 285 'footprint': 0.0,
  286 + 'distance': 0.0,
285 287 }
286   - cities_dict[city_key]['footprint'] += footprint
287   - if city_key not in cities_sum:
288   - cities_sum[city_key] = 0.0
289   - cities_sum[city_key] += footprint
  288 + cities_dict[city_key]['footprint'] += footprint['co2eq_kg']
  289 + cities_dict[city_key]['distance'] += footprint['distance']
  290 + if city_key not in cities_sum_foot:
  291 + cities_sum_foot[city_key] = 0.0
  292 + cities_sum_foot[city_key] += footprint['co2eq_kg']
  293 + if city_key not in cities_sum_dist:
  294 + cities_sum_dist[city_key] = 0.0
  295 + cities_sum_dist[city_key] += footprint['distance']
290 296  
291 297 cities = [cities_dict[k] for k in cities_dict.keys()]
292 298 cities = sorted(cities, key=lambda c: c['footprint'])
... ... @@ -297,17 +303,21 @@ def compute(): # process the queue of estimation requests
297 303  
298 304 _results['footprints'] = footprints
299 305  
300   - total = 0.0
  306 + total_foot = 0.0
  307 + total_dist = 0.0
301 308  
302 309 cities_mean_dict = {}
303   - for city in cities_sum.keys():
304   - city_mean = 1.0 * cities_sum[city] / len(emission_models)
  310 + for city in cities_sum_foot.keys():
  311 + city_mean_foot = 1.0 * cities_sum_foot[city] / len(emission_models)
  312 + city_mean_dist = 1.0 * cities_sum_dist[city] / len(emission_models)
305 313 cities_mean_dict[city] = {
306 314 'address': destinations_by_city_key[city].address,
307 315 'city': city,
308   - 'footprint': city_mean,
  316 + 'footprint': city_mean_foot,
  317 + 'distance': city_mean_dist,
309 318 }
310   - total += city_mean
  319 + total_foot += city_mean_foot
  320 + total_dist += city_mean_dist
311 321  
312 322 cities_mean = [cities_mean_dict[k] for k in cities_mean_dict.keys()]
313 323 cities_mean = sorted(cities_mean, key=lambda c: c['footprint'])
... ... @@ -317,8 +327,10 @@ def compute(): # process the queue of estimation requests
317 327 }
318 328 _results['cities'] = cities_mean
319 329  
320   - _results['total'] = total # DEPRECATED
321   - _results['footprint'] = total
  330 + _results['total'] = total_foot # DEPRECATED
  331 + _results['footprint'] = total_foot
  332 +
  333 + _results['distance'] = total_dist
322 334  
323 335 return _results
324 336  
... ... @@ -433,25 +445,17 @@ def consult_estimation(public_id, extension):
433 445  
434 446 si = StringIO()
435 447 cw = csv.writer(si, quoting=csv.QUOTE_ALL)
436   - cw.writerow([u"city", u"address", u"co2 (g)"])
  448 + cw.writerow([u"city", u"address", u"co2 (kg)", u"distance (km)"])
437 449  
438 450 results = estimation.get_output_dict()
439   - if 'mean_footprint' in results:
440   - for city in results['mean_footprint']['cities']:
441   - cw.writerow([
442   - city['city'].encode(OUT_ENCODING),
443   - city['address'].encode(OUT_ENCODING),
444   - city['footprint']
445   - ])
446   - elif 'cities' in results:
447   - for city in results['cities']:
448   - cw.writerow([
449   - city['city'].encode(OUT_ENCODING),
450   - city['address'].encode(OUT_ENCODING),
451   - city['total']
452   - ])
453   -
454   - # HTTP headers?
  451 + for city in results['cities']:
  452 + cw.writerow([
  453 + city['city'].encode(OUT_ENCODING),
  454 + city['address'].encode(OUT_ENCODING),
  455 + round(city['footprint'], 3),
  456 + round(city['distance'], 3),
  457 + ])
  458 +
455 459 # return si.getvalue().strip('\r\n')
456 460 return Response(
457 461 response=si.getvalue().strip('\r\n'),
... ...
flaskr/laws/travel_emission_linear_fit.py
... ... @@ -2,6 +2,7 @@ import numpy as np
2 2 from geopy.distance import great_circle
3 3  
4 4  
  5 +# @abc
5 6 class BaseEmissionModel():
6 7 def __init__(self, config): # Constructor
7 8 self.name = config.name
... ... @@ -29,9 +30,10 @@ class EmissionModel(BaseEmissionModel):
29 30 prefer_train_under_distance=0, # meters
30 31 ):
31 32 footprint = 0.0
  33 + distance = 0.0
32 34  
33 35 #############################################
34   - # TODO: find closest airport(s) and pick one
  36 + # TODO: find closest airport(s) and pick one?
35 37 # We're going to need caching here as well.
36 38 from collections import namedtuple
37 39 origin_airport = namedtuple('Position', [
... ... @@ -55,34 +57,33 @@ class EmissionModel(BaseEmissionModel):
55 57 # ... TODO
56 58  
57 59 # I.b Airplane travel footprint
58   - footprint += self.compute_airplane_footprint(
  60 + great_circle_distance = self.get_distance_between(
59 61 origin_latitude=origin_airport.latitude,
60 62 origin_longitude=origin_airport.longitude,
61 63 destination_latitude=destination_airport.latitude,
62 64 destination_longitude=destination_airport.longitude,
63 65 )
  66 + footprint += self.compute_airplane_footprint(
  67 + distance=great_circle_distance
  68 + )
  69 + distance += great_circle_distance
64 70  
65   - # II.a Double the footprint if it's a round-trip
  71 + # II.a Double it up since it's a round-trip
66 72 footprint *= 2.0
  73 + distance *= 2.0
67 74  
68   - return footprint
  75 + return {
  76 + 'distance': distance,
  77 + 'co2eq_kg': footprint,
  78 + }
  79 + # return footprint
69 80  
70 81 def compute_airplane_footprint(
71 82 self,
72   - origin_latitude,
73   - origin_longitude,
74   - destination_latitude,
75   - destination_longitude
  83 + distance
76 84 ):
77 85 config = self.config.plane_emission_linear_fit
78 86  
79   - great_circle_distance = self.get_distance_between(
80   - origin_latitude, origin_longitude,
81   - destination_latitude, destination_longitude
82   - )
83   -
84   - distance = great_circle_distance
85   -
86 87 distance = config.connecting_flights_scale * distance
87 88  
88 89 footprint = self.compute_airplane_distance_footprint(distance, config)
... ... @@ -111,7 +112,7 @@ class EmissionModel(BaseEmissionModel):
111 112 """
112 113 :param distance: in km
113 114 :param config:
114   - :return:
  115 + :return: float
115 116 """
116 117 footprint = distance
117 118 for interval in config.intervals:
... ...
flaskr/templates/estimation.html
... ... @@ -193,7 +193,7 @@ jQuery(document).ready(function($){
193 193 var vizid = "#cities_footprints_d3viz";
194 194 var csvUrl = "/estimation/{{ estimation.public_id }}.csv";
195 195 var x_key = 'city';
196   - var y_key = 'co2 (g)';
  196 + var y_key = 'co2 (kg)';
197 197  
198 198 // Set the dimensions and margins of the graph
199 199 var margin = {top: 10, right: 30, bottom: 150, left: 150},
... ... @@ -214,7 +214,7 @@ jQuery(document).ready(function($){
214 214 d3.csv(csvUrl, function(data) {
215 215  
216 216 // Extrema
217   - var data_y_max = d3.max(data, function(d) { return parseFloat(d['co2 (g)']); });
  217 + var data_y_max = d3.max(data, function(d) { return parseFloat(d[y_key]); });
218 218 var axis_y_max = ceil_value_to_magnitude(data_y_max);
219 219  
220 220 // X axis
... ... @@ -266,7 +266,7 @@ jQuery(document).ready(function($){
266 266 var vizid = "#cities_footprints_d3viz_lollipop";
267 267 var csvUrl = "/estimation/{{ estimation.public_id }}.csv";
268 268 var y_key = 'city';
269   - var x_key = 'co2 (g)';
  269 + var x_key = 'co2 (kg)';
270 270  
271 271 var margin = {top: 10, right: 30, bottom: 150, left: 150},
272 272 height = Math.max(300, 100+16*plots_config['cities_count']) - margin.top - margin.bottom;
... ...