generate_trips.py (4660B)
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_with_latlon.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_extension.csv" 27 28 modes = ["train", "plane", "bus/coach", "other", ""] 29 places = defaultdict(lambda : [0, 0, ""]) 30 31 def complete_mode(dist): 32 if dist > 400: 33 return "plane" 34 else: 35 return "train" 36 37 # compute trips 38 with open("trips_anonymized.csv", 'w') as fout: 39 with open("trips.csv", 'w') as fout2: 40 with open(FNAME, 'r') as ftrip: 41 reader = csv.reader(ftrip, delimiter=";") 42 for r in reader: 43 #university = r[5] 44 # first = r[2].replace(',', '') 45 # last = r[3].replace(',', '') 46 # assert(r[6] == "I'm coming to Bordeaux") 47 # assert(r[8] == "External Participant") 48 # typ = r[7].replace(',', '') 49 from_place = r[0].strip() 50 from_mode = r[1].replace(',', '').lower() 51 to_place = r[2].strip() 52 to_mode = r[3].replace(',', '').lower() 53 if r[4].startswith("Yes"): 54 extended_1 = 'X' 55 else: 56 extended_1 = '' 57 if r[5].startswith("Yes"): 58 extended_2 = 'X' 59 else: 60 extended_2 = '' 61 #annotation = ' '.join((first, last, university, typ)) 62 annotation = '' 63 assert (from_mode in modes) 64 assert (to_mode in modes) 65 from_coord = location[from_place] 66 to_coord = location[to_place] 67 68 from_dist = geodesic(origin, from_coord).kilometers 69 to_dist = geodesic(origin, to_coord).kilometers 70 from_dist_anon = round(uniform(from_dist * (1-noise), from_dist * (1+noise))) 71 to_dist_anon = round(uniform(to_dist * (1-noise), to_dist * (1+noise))) 72 if from_mode == '' or from_mode == 'other': 73 from_mode = complete_mode(from_dist) 74 if to_mode == '' or to_mode == 'other': 75 to_mode = complete_mode(to_dist) 76 77 places[from_coord][1] += 1 78 places[to_coord][1] += 1 79 places[from_coord][2] += annotation + "\n" 80 places[to_coord][2] += annotation + "\n" 81 if from_mode == "plane": 82 places[from_coord][0] += 1 83 if to_mode == "plane": 84 places[to_coord][0] += 1 85 86 87 print(','.join(( 88 from_mode.lower(), 89 str(from_dist), 90 extended_1, extended_2, 91 from_place.replace(',', ''), 92 *from_coord, annotation)), file=fout2) 93 print(','.join(( 94 to_mode.lower(), 95 str(to_dist), 96 extended_1, extended_2, 97 to_place.replace(',', ''), 98 *to_coord, annotation)), file=fout2) 99 print(','.join(( 100 from_mode.lower(), 101 str(from_dist_anon), 102 extended_1, extended_2)), file=fout) 103 print(','.join(( 104 to_mode.lower(), 105 str(to_dist_anon), 106 extended_1, extended_2)), file=fout) 107 108 ## OUTPUT GEOJSON 109 110 features = [] 111 for k in places.keys(): 112 red = int(255.*places[k][0]/places[k][1]) 113 green = 0 114 blue = int(255.*(places[k][1]-places[k][0])/places[k][1]) 115 color = '#%02X%02X%02X' % (red, green, blue) 116 feature = { 117 "type": "Feature", 118 "properties": { 119 "name":places[k][2], 120 "_umap_options": {"color": color} 121 }, 122 "geometry": { 123 "type": "Point", 124 "coordinates": [ 125 k[1], k[0] 126 ] 127 } 128 } 129 features.append(feature) 130 131 output = { 132 "type": "FeatureCollection", 133 "features": features 134 } 135 136 with open("map.geojson", 'w') as f: 137 print (json.dumps(output), file=f) 138