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