conference_footprint

compute the CO2 footprint of an academic conference
git clone https://a3nm.net/git/conference_footprint/
Log | Files | Refs

generate_trips.py (4687B)


      1 #!/usr/bin/env python3
      2 
      3 # Process registration data to generate the list of trip legs
      4 
      5 import csv
      6 import sys
      7 import json
      8 from geopy.distance import geodesic
      9 from collections import defaultdict
     10 from random import uniform
     11 
     12 # place of the conference
     13 origin = (sys.argv[1], sys.argv[2])
     14 noise = float(sys.argv[3]) # how much multiplicative noise to add to distances
     15 
     16 # read locations
     17 location = {}
     18 with open("locations_all.txt", 'r') as floc:
     19     for l in floc.readlines():
     20         f = l.strip().split(' ')
     21         lat = f[0]
     22         lon = f[1]
     23         loc = ' '.join(f[2:])
     24         location[loc] = (lat, lon)
     25 
     26 FNAME = "location_mode.csv"
     27 
     28 modes = ["train", "plane", "bus/coach", "other", ""]
     29 places = defaultdict(lambda : [0, 0, ""])
     30 
     31 def complete_mode(dist):
     32     # from highlights 2025 data, from 600km onwards most trips are by plane
     33     if dist > 600:
     34         return "plane"
     35     else:
     36         return "train"
     37 
     38 # compute trips
     39 with open("trips_anonymized.csv", 'w') as fout:
     40     with open("trips.csv", 'w') as fout2:
     41         with open(FNAME, 'r') as ftrip:
     42             reader = csv.reader(ftrip, delimiter="\t")
     43             for r in reader:
     44                 #university = r[5]
     45                 # first = r[2].replace(',', '')
     46                 # last = r[3].replace(',', '')
     47                 # assert(r[6] == "I'm coming to Bordeaux")
     48                 # assert(r[8] == "External Participant")
     49                 # typ = r[7].replace(',', '')
     50                 if (len(r) < 4):
     51                     print (r)
     52                     assert(False)
     53                 from_place = r[0].strip()
     54                 from_mode = r[1].replace(',', '').lower()
     55                 to_place = r[2].strip()
     56                 to_mode = r[3].replace(',', '').lower()
     57                 #annotation = ' '.join((first, last, university, typ))
     58                 annotation = ''
     59                 if from_mode == "bus":
     60                     from_mode = "bus/coach"
     61                 if to_mode == "bus":
     62                     to_mode = "bus/coach"
     63                 if not (from_mode in modes):
     64                     print (from_mode)
     65                     assert(False)
     66                 assert (from_mode in modes)
     67                 assert (to_mode in modes)
     68                 from_coord = location[from_place]
     69                 to_coord = location[to_place]
     70 
     71                 from_dist = geodesic(origin, from_coord).kilometers
     72                 to_dist = geodesic(origin, to_coord).kilometers
     73                 from_dist_anon = round(uniform(from_dist * (1-noise), from_dist * (1+noise)))
     74                 to_dist_anon = round(uniform(to_dist * (1-noise), to_dist * (1+noise)))
     75                 if from_mode == '' or from_mode == 'other':
     76                     from_mode = complete_mode(from_dist)
     77                 if to_mode == '' or to_mode == 'other':
     78                     to_mode = complete_mode(to_dist)
     79                 
     80                 places[from_coord][1] += 1
     81                 places[to_coord][1] += 1
     82                 places[from_coord][2] += annotation + "\n"
     83                 places[to_coord][2] += annotation + "\n"
     84                 if from_mode == "plane":
     85                     places[from_coord][0] += 1
     86                 if to_mode == "plane":
     87                     places[to_coord][0] += 1
     88 
     89 
     90                 print(','.join((
     91                     from_mode.lower(),
     92                     str(from_dist),
     93                     from_place.replace(',', ''),
     94                     *from_coord, annotation)), file=fout2)
     95                 print(','.join((
     96                     to_mode.lower(),
     97                     str(to_dist),
     98                     to_place.replace(',', ''),
     99                     *to_coord, annotation)), file=fout2)
    100                 print(','.join((
    101                     from_mode.lower(),
    102                     str(from_dist_anon),
    103                     )), file=fout)
    104                 print(','.join((
    105                     to_mode.lower(),
    106                     str(to_dist_anon),
    107                     )), file=fout)
    108 
    109     ## OUTPUT GEOJSON
    110 
    111     features = []
    112     for k in places.keys():
    113         red = int(255.*places[k][0]/places[k][1])
    114         green = 0
    115         blue = int(255.*(places[k][1]-places[k][0])/places[k][1])
    116         color = '#%02X%02X%02X' % (red, green, blue)
    117         feature = {
    118           "type": "Feature",
    119           "properties": {
    120               "name":places[k][2],
    121               "_umap_options": {"color": color}
    122           },
    123           "geometry": {
    124             "type": "Point",
    125             "coordinates": [
    126                 k[1], k[0]
    127             ]
    128           }
    129         }
    130         features.append(feature)
    131 
    132 output = {
    133   "type": "FeatureCollection",
    134   "features": features
    135 }
    136 
    137 with open("map.geojson", 'w') as f:
    138     print (json.dumps(output), file=f)
    139