def get_queryset(self): #split params by which it applies to mappoint_params = {} for (param, result) in self.request.query_params.items(): if param in ['max_lat','min_lat','max_lon','min_lon','dataset','tags','tag','state','zipcode']: mappoint_params[param] = result #if none of this is specified, this is just too much if len(mappoint_params) == 0: raise ParseError('Too many results. Please restrict the mappoints.') #now get the queryset points = filter_request(mappoint_params,'mappoint') distances = self.request.GET.getlist('distance') unit = self.request.GET.getlist('unit') if len(unit) > 1: raise ParseError('No more than one unit may be specified.') elif len(unit) == 0: unit = 'mi' elif unit[0] in ['m','km','mi']: unit = unit[0] else: raise ParseError('Accepted units: m, km, mi') if len(distances) == 0: distances = [1,3,5] unit = 'km' else: print distances distances.sort() kwargs = {unit:distances[-1]} take_out = [] for point in points: if point.id in take_out: continue take_out.extend(neighboring_points(point, points, Distance(**kwargs)).exclude(id=point.id).values_list('id',flat=True)) return points.exclude(id__in=take_out).distinct()
def get_queryset(self): #split params by which it applies to mappoint_params = {} for (param, result) in self.request.QUERY_PARAMS.items(): if param in ['max_lat','min_lat','max_lon','min_lon','dataset','tags','tag','state','zipcode']: mappoint_params[param] = result #if none of this is specified, this is just too much if len(mappoint_params) == 0: raise ParseError('Too many results. Please restrict the mappoints.') #now get the queryset points = filter_request(mappoint_params,'mappoint') distances = self.request.GET.getlist('distance') unit = self.request.GET.getlist('unit') if len(unit) > 1: raise ParseError('No more than one unit may be specified.') elif len(unit) == 0: unit = 'mi' elif unit[0] in ['m','km','mi']: unit = unit[0] else: raise ParseError('Accepted units: m, km, mi') if len(distances) == 0: distances = [1,3,5] unit = 'km' else: print distances distances.sort() kwargs = {unit:distances[-1]} take_out = [] for point in points: if point.id in take_out: continue take_out.extend(neighboring_points(point, points, Distance(**kwargs)).exclude(id=point.id).values_list('id',flat=True)) return points.exclude(id__in=take_out).distinct()
def AroundPointView(request, mappoint_id=None): current_site = get_current_site(request) # Site.objects.get_current() context = { 'key': GOOGLE_API_KEY, 'zoom_level': 12, 'lat': 1, 'lon': 45, 'width': 500, 'height': 380, 'root': 'http://' + current_site.domain + '/' } if 'lat' in request.GET: try: context['lat'] = float(request.GET['lat']) except: pass if 'lon' in request.GET: try: context['lon'] = float(request.GET['lon']) except: pass if 'distances' in request.GET: distances = get_distances(request.GET['distances']) elif 'distance' in request.GET: distances = get_distances(request.GET['distance']) else: distances = get_distances(None) if 'unit' in request.GET and request.GET['unit'] in ['mi', 'm']: unit = request.GET['unit'] else: unit = 'km' # dataset = 0 if mappoint_id: try: mappoint = MapPoint.objects.get(id=mappoint_id) if mappoint.point.x != 0: context['lon'] = mappoint.point.x if mappoint.point.y != 0: context['lat'] = mappoint.point.y points = [ (a.point.y, a.point.x, a.name) for a in neighboring_points( mappoint, MapPoint.objects.filter( dataset=mappoint.dataset_id), Distance( km=distances[-1])) ] # dataset = mappoint.dataset_id except Exception: points = [(context['lat'], context['lon'], "")] else: points = [(context['lat'], context['lon'], "")] print context['root'] if context['root'] == 'http://example.com/': context['root'] = 'http://127.0.0.1:8000/' context['circle'] = '' for d in distances: text = '' dist_kwargs = {unit: d} dist = Distance(**dist_kwargs) geometry = circle_as_polygon(lat=points[0][0], lon=points[0][1], distance=dist) for p in points[1:]: geometry = geometry.union( circle_as_polygon(lat=p[0], lon=p[1], distance=dist)) for poly in geometry: text = '' for ring in poly: if type(ring) is tuple: text = text + ', new google.maps.LatLng(%f, %f)\n' % ( ring[1], ring[0]) else: for coord in ring: text = text + ', new google.maps.LatLng(%f, %f)\n' % ( coord[1], coord[0]) context['circle'] = context['circle'] + ',[' + text.strip( ',') + ']' context['circle'] = '[' + context['circle'].strip(',') + ']' context['points'] = str([ 'new google.maps.LatLng(%f,%f)' % (a[0], a[1]) for a in points ]).replace("'", "") context['names'] = str([a[2] for a in points]).replace("u'", "'") context = Context(context) template = """<!DOCTYPE HTML> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="http://maps.googleapis.com/maps/api/js?key={{ key }}&sensor=false"> </script> <script> var map; function initialize() { function add_polygons(){ var polygon = new google.maps.Polygon({ paths: {{ circle }}, strokeColor: '#0033FF', strokeOpacity: 0.8, strokeWeight: 2, fillColor: '#FF0000', fillOpacity: 0.35 }); polygon.setMap(map); } function set_height(){ var h = $(window).height(); $('#googleMap').css('height', h); } $(window).resize(set_height()); set_height(); // Create a simple map. map = new google.maps.Map(document.getElementById('googleMap'), { zoom: {{ zoom_level }}, center: {lat: {{ lat }}, lng:{{ lon }}} }); add_polygons(); // Load a GeoJSON from the same server as our demo. google.maps.event.addListener(map, 'bounds_changed', function() { load_polys("{{ root }}api-poly/?max_lat=" + map.getBounds().getNorthEast().lat() + "&max_lon=" + map.getBounds().getNorthEast().lng() + "&min_lat=" + map.getBounds().getSouthWest().lat() + "&min_lon="+ map.getBounds().getSouthWest().lng()); add_markers("{{ root }}api-mp/?dataset=" + {{ dataset }} +"&max_lat=" + map.getBounds().getNorthEast().lat() + "&max_lon=" + map.getBounds().getNorthEast().lng() + "&min_lat=" + map.getBounds().getSouthWest().lat() + "&min_lon="+ map.getBounds().getSouthWest().lng()); function add_markers(json_next) { $.getJSON(json_next) .done(function(data){ for (var i=0;i<data.results.length;i++){ var marker = new google.maps.Marker({ position: new google.maps.LatLng(data.results[i].latitude, data.results[i].longitude), title: data.results[i].name }); marker.setMap(map); } json_next = data.next; if (data.next != null){ load_polys(data.next); } }); var centers = {{ points }}; var names = {{ names|safe }}; for (var i=0;i<centers.length;i++){ var marker = new google.maps.Marker({ position: centers[i], title: names[i] }); marker.setMap(map); } } function load_polys(json_next) { $.getJSON(json_next) .done(function(data){ map.data.addGeoJson(data.results); json_next = data.next; if (data.next != null){ load_polys(data.next); } }); } var featureStyle = { fillOpacity: 0, strokeWeight: 1 } map.data.setStyle(featureStyle); }); } $( document ).ready(google.maps.event.addDomListener(window, 'load', initialize)); </script> <div id="googleMap" style="width:100%;height:0px;"></div> """ template = Template(template) return HttpResponse(template.render(context))
def AroundPointView(request, mappoint_id = None): current_site = get_current_site(request) #Site.objects.get_current() context = {'key': GOOGLE_API_KEY, 'zoom_level': 12, 'lat': 1, 'lon': 45, 'width': 500, 'height': 380, 'root': 'http://'+ current_site.domain + '/'} if 'lat' in request.GET: try: context['lat'] = float(request.GET['lat']) except: pass if 'lon' in request.GET: try: context['lon'] = float(request.GET['lon']) except: pass if 'distances' in request.GET: distances= get_distances(request.GET['distances']) elif 'distance' in request.GET: distances= get_distances(request.GET['distance']) else: distances = get_distances(None) if 'unit' in request.GET and request.GET['unit'] in ['mi', 'm']: unit = request.GET['unit'] else: unit = 'km' dataset = 0 if mappoint_id: try: mappoint = MapPoint.objects.get(id = mappoint_id) if mappoint.point.x != 0: context['lon'] = mappoint.point.x if mappoint.point.y != 0: context['lat'] = mappoint.point.y points=[(a.point.y,a.point.x,a.name) for a in neighboring_points(mappoint,MapPoint.objects.filter(dataset=mappoint.dataset_id),Distance(km=distances[-1]))] dataset = mappoint.dataset_id except Exception as e: points=[(context['lat'],context['lon'],"")] else: points=[(context['lat'],context['lon'],"")] print context['root'] if context['root'] == 'http://example.com/': context['root'] = 'http://127.0.0.1:8000/' context['circle']='' for d in distances: text = '' dist_kwargs = {unit:d} dist = Distance(**dist_kwargs) geometry = circle_as_polygon(lat = points[0][0], lon = points[0][1], distance = dist) for p in points[1:]: geometry = geometry.union(circle_as_polygon(lat = p[0], lon = p[1], distance = dist)) for poly in geometry: text = '' for ring in poly: if type(ring) is tuple: text = text + ', new google.maps.LatLng(%f, %f)\n' %(ring[1], ring[0]) else: for coord in ring: text = text + ', new google.maps.LatLng(%f, %f)\n' %(coord[1], coord[0]) context['circle'] = context['circle'] + ',['+text.strip(',')+']' context['circle'] = '[' + context['circle'].strip(',') + ']' context['points'] = str(['new google.maps.LatLng(%f,%f)'%(a[0],a[1]) for a in points]).replace("'","") context['names'] = str([a[2] for a in points]).replace("u'","'") context = Context(context) template = """<!DOCTYPE HTML> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="http://maps.googleapis.com/maps/api/js?key={{ key }}&sensor=false"> </script> <script> var map; function initialize() { function add_polygons(){ var polygon = new google.maps.Polygon({ paths: {{ circle }}, strokeColor: '#0033FF', strokeOpacity: 0.8, strokeWeight: 2, fillColor: '#FF0000', fillOpacity: 0.35 }); polygon.setMap(map); } function set_height(){ var h = $(window).height(); $('#googleMap').css('height', h); } $(window).resize(set_height()); set_height(); // Create a simple map. map = new google.maps.Map(document.getElementById('googleMap'), { zoom: {{ zoom_level }}, center: {lat: {{ lat }}, lng:{{ lon }}} }); add_polygons(); // Load a GeoJSON from the same server as our demo. google.maps.event.addListener(map, 'bounds_changed', function() { load_polys("{{ root }}api-poly/?max_lat=" + map.getBounds().getNorthEast().lat() + "&max_lon=" + map.getBounds().getNorthEast().lng() + "&min_lat=" + map.getBounds().getSouthWest().lat() + "&min_lon="+ map.getBounds().getSouthWest().lng()); add_markers("{{ root }}api-mp/?dataset=" + {{ dataset }} +"&max_lat=" + map.getBounds().getNorthEast().lat() + "&max_lon=" + map.getBounds().getNorthEast().lng() + "&min_lat=" + map.getBounds().getSouthWest().lat() + "&min_lon="+ map.getBounds().getSouthWest().lng()); function add_markers(json_next) { $.getJSON(json_next) .done(function(data){ for (var i=0;i<data.results.length;i++){ var marker = new google.maps.Marker({ position: new google.maps.LatLng(data.results[i].latitude, data.results[i].longitude), title: data.results[i].name }); marker.setMap(map); } json_next = data.next; if (data.next != null){ load_polys(data.next); } }); var centers = {{ points }}; var names = {{ names|safe }}; for (var i=0;i<centers.length;i++){ var marker = new google.maps.Marker({ position: centers[i], title: names[i] }); marker.setMap(map); } } function load_polys(json_next) { $.getJSON(json_next) .done(function(data){ map.data.addGeoJson(data.results); json_next = data.next; if (data.next != null){ load_polys(data.next); } }); } var featureStyle = { fillOpacity: 0, strokeWeight: 1 } map.data.setStyle(featureStyle); }); } $( document ).ready(google.maps.event.addDomListener(window, 'load', initialize)); </script> <div id="googleMap" style="width:100%;height:0px;"></div> """ template = Template(template) return HttpResponse(template.render(context))
def get_areaAroundPoint(self, mappoint): request = self.context.get('request', None) years = request.GET.getlist('year') datasets = Dataset.objects.filter(name__icontains='census') if len(years) > 0: d = Dataset.objects.none() for y in years: d = d | datasets.filter(name__contains=y.strip()) datasets = d if len(datasets) == 0: return {} else: dataset_id = datasets[0].id # DISTANCES distances = request.GET.getlist('distance') unit = request.GET.getlist('unit') if len(unit) > 1: return HttpResponseBadRequest('No more than one unit may be specified.') elif len(unit) == 0: unit = 'mi' elif unit[0] in ['m', 'km', 'mi']: unit = unit[0] else: return HttpResponseBadRequest('Accepted units: m, km, mi') if len(distances) == 0: distances = [1, 3, 5] unit = 'km' else: distances.sort() # method is containment or apportionment? method = request.GET.getlist('method') if len(method) > 0 and method[0] == 'apportionment': apportionment = True else: apportionment = False dist_objs = [] for dist in distances: kwargs = {unit: dist} dist_objs.append(Distance(**kwargs)) all_points = neighboring_points(mappoint, MapPoint.objects .filter(dataset_id=mappoint.dataset_id), dist_objs[-1]) # print len(all_points), all_points data_sums = {'points': [], 'view url': 'http://127.0.0.1:8000/around-point/%d/' % (all_points[0].id)} for p in all_points: data_sums['points'].append({'id': p.id, 'name': p.name, 'street': p.mappoint.street, 'city': p.mappoint.city, 'state': p.mappoint.state, 'zipcode': p.mappoint.zipcode, 'county': p.mappoint.county, 'field1': p.mappoint.field1, 'field2': p.mappoint.field2, 'field3': p.mappoint.field3, 'tags': Tag.objects.filter(approved=True, tagindiv__mapelement=mappoint).distinct('tag').values('tag')}) already_accounted = set() boundary = unite_radius_bubbles(all_points, dist_objs) for dist in dist_objs: if unit == 'm': dist_str = '%f m' % (dist.m) elif unit == 'km': dist_str = '%f km' % (dist.km) elif unit == 'mi': dist_str = '%f mi' % (dist.mi) temp_qs = MapPolygon.objects.filter(dataset_id__exact=dataset_id) \ .filter(mpoly__coveredby=boundary[dist]) \ .exclude(remote_id__in=already_accounted) \ .distinct() poly = {x: 1. for x in temp_qs.values_list('remote_id', flat=True)} try: land_area = sum([int(x) for x in temp_qs.values_list('field1', flat=True)]) except Exception: continue # print 'poly', poly maybe_polys = MapPolygon.objects.filter(dataset_id__exact=dataset_id) \ .exclude(remote_id__in=poly) \ .exclude(remote_id__in=already_accounted) \ .filter(mpoly__intersects=boundary[dist]) \ .distinct() # print 'maybes', maybe_polys.values_list('remote_id',flat=True) for polygon in maybe_polys: intersection_area = polygon.mpoly.intersection( boundary[dist]).area / polygon.mpoly.area if apportionment or intersection_area > .5: poly[polygon.remote_id] = intersection_area \ if apportionment else 1. try: land_area += intersection_area*int(polygon.field1) \ if apportionment else int(polygon.field1) except Exception: continue already_accounted = already_accounted | set(poly.keys()) data_sums[dist_str] = {} # data_sums[dist_str]['polygon count'] = len(poly) # data_sums[dist_str]['land area (m2)'] = sum([int(i) # for i in MapPolygon.objects # .filter(dataset_id__exact=dataset_id # ,remote_id__in=poly) # .values_list('field1',flat=True)]) if len(poly) > 0: data_sums[dist_str]['polygons'] = poly data_sums[dist_str]['land_area'] = land_area return data_sums
def get_areaAroundPoint2(self, mappoint): request = self.context.get('request', None) years = request.GET.getlist('year') year = years[0] datasets = Dataset.objects.filter(name__icontains='census') if len(years) > 0: d = Dataset.objects.none() for y in years: d = d | datasets.filter(name__contains=y.strip()) datasets = d if len(datasets) == 0: return {} else: dataset_id = datasets[0].id # DISTANCES distances = request.GET.getlist('distance') unit = request.GET.getlist('unit') if len(unit) > 1: return HttpResponseBadRequest( 'No more than one unit may be specified.') elif len(unit) == 0: unit = 'mi' elif unit[0] in ['m', 'km', 'mi']: unit = unit[0] else: return HttpResponseBadRequest('Accepted units: m, km, mi') if len(distances) == 0: distances = [1, 3, 5] unit = 'km' else: distances.sort() dist_objs = [] for dist in distances: kwargs = {unit: dist} dist_objs.append(Distance(**kwargs)) all_points = neighboring_points(mappoint, MapPoint.objects.filter(dataset=mappoint.dataset_id), dist_objs[-1]) # print all_points # variables = ['Total Population','Area (km2)','Total (Race)', 'White Only', 'African American', 'Hispanic','Asian/Pacific Islander', 'Native American','Total (Poverty)','below 1.00', 'weighted mean of median household income','Mean Housing Value'] # variables = {'B02001_001E':{},'B02001_002E':{},'B02009_001E':{},'B03001_001E':{},'B03001_003E':{},'B02011_001E':{}, 'B02012_001E':{},'B02010_001E':{},'B05010_001E':{},'B05010_002E':{},'B19061_001E':{},'B25105_001E':{},'B25077_001E':{},'B25077_001E':{}} variables = {'B00001_001E': {}, 'B02001_001E': {}, 'B02001_002E': {}, 'B02001_003E': {}, 'B02001_004E': {}, 'B02001_005E': {}, 'B02001_006E': {}, 'B02001_007E': {}, 'B02001_008E': {}, 'B03001_001E': {}, 'B03001_003E': {}, 'C17002_001E': {}, 'C17002_002E': {}, 'C17002_003E': {}} for v in variables: request = 'http://api.census.gov/data/2010/acs5/variables/%s.json?key=%s' \ % (v, CENSUS_API_KEY) try: data = json.loads(urllib.urlopen(request).read()) except Exception as e: print 'variable info for %s failed to load: %s' % (v, request) print e continue variables[v] = data data_sums = {'point id(s)': '', 'view url(s)': []} for p in all_points: data_sums['point id(s)'] = data_sums['point id(s)'] + ',' + str(p.id) data_sums['view url(s)'].append('/around-point/%d/' % (p.id)) data_sums['point id(s)'] = data_sums['point id(s)'].strip(',') already_accounted = set() boundary = unite_radius_bubbles(all_points, dist_objs) for dist in dist_objs: if unit == 'm': dist_str = '%f m' % (dist.m) elif unit == 'km': dist_str = '%f km' % (dist.km) elif unit == 'mi': dist_str = '%f mi' % (dist.mi) poly = set(MapPolygon.objects.filter(dataset_id__exact=dataset_id) .filter(mpoly__covers=boundary[dist]) .exclude(remote_id__in=already_accounted) .values_list('remote_id', flat=True)) maybe_polys = MapPolygon.objects.filter(dataset_id__exact=dataset_id) \ .exclude(mpoly__covers=boundary[dist]) \ .exclude(remote_id__in=already_accounted) \ .filter(mpoly__intersects=boundary[dist]) for polygon in maybe_polys: if polygon.mpoly.intersection(boundary[dist]).area > .5 * polygon.mpoly.area: poly.add(polygon.remote_id) already_accounted = already_accounted | poly data_sums[dist_str] = {} data_sums[dist_str]['polygon count'] = len(poly) data_sums[dist_str]['land area (m2)'] = sum([int(i) for i in MapPolygon.objects .filter(dataset_id__exact=dataset_id, remote_id__in=poly) .values_list('field1', flat=True)]) if data_sums[dist_str]['polygon count'] > 0: data_sums[dist_str]['polygons'] = str(list(poly)) if year == '2010': get = '' for e in variables: get = get + ',' + e get = get.strip(',') tracts = {} for e in poly: if e[:2] not in tracts: tracts[e[:2]] = {} if e[2:5] not in tracts[e[:2]]: tracts[e[:2]][e[2:5]] = '' tracts[e[:2]][e[2:5]] = tracts[e[:2]][e[2:5]] + ',' + e[-6:] for state in tracts: for county in tracts[state]: request = 'http://api.census.gov/data/2010/acs5?key=%s&get=%s,NAME&for=tract:%s&in=state:%s,county:%s' \ % (CENSUS_API_KEY, get, tracts[state][county].strip(','), state, county) try: url = urllib.urlopen(request).read() data = json.loads(url) except Exception as e: print e print url print request continue line = data[0] locations = {} for i in range(len(line)): locations[line[i]] = i if line[i] not in data_sums[dist_str] and line[i] in variables: data_sums[dist_str][line[i]] = copy.deepcopy(variables[line[i]]) data_sums[dist_str][line[i]]['sum'] = 0 for line in data[1:]: # get area for v in variables: try: data_sums[dist_str][v]['sum'] = data_sums[dist_str][v]['sum'] + int(line[locations[v]]) except Exception: continue return data_sums
def get_areaAroundPoint(self, mappoint): request = self.context.get('request', None) years = request.GET.getlist('year') datasets = Dataset.objects.filter(name__icontains='census') if len(years) > 0: d = Dataset.objects.none() for y in years: d = d | datasets.filter(name__contains=y.strip()) datasets = d if len(datasets) == 0: return {} else: dataset_id = datasets[0].id # DISTANCES distances = request.GET.getlist('distance') unit = request.GET.getlist('unit') if len(unit) > 1: return HttpResponseBadRequest('No more than one unit may be specified.') elif len(unit) == 0: unit = 'mi' elif unit[0] in ['m', 'km', 'mi']: unit = unit[0] else: return HttpResponseBadRequest('Accepted units: m, km, mi') if len(distances) == 0: distances = [1, 3, 5] unit = 'km' else: distances.sort() dist_objs = [] for dist in distances: kwargs = {unit: dist} dist_objs.append(Distance(**kwargs)) all_points = neighboring_points(mappoint, MapPoint.objects .filter(dataset_id=mappoint.dataset_id), dist_objs[-1]) data_sums = {'point id(s)': '', 'view url(s)': []} for p in all_points: data_sums['point id(s)'] = data_sums['point id(s)'] + ',' + str(p.id) data_sums['view url(s)'].append('/around-point/%d/' % (p.id)) data_sums['view url(s)'] = str(data_sums['view url(s)']) data_sums['point id(s)'] = data_sums['point id(s)'].strip(',') already_accounted = set() boundary = unite_radius_bubbles(all_points, dist_objs) for dist in dist_objs: if unit == 'm': dist_str = '%f m' % (dist.m) elif unit == 'km': dist_str = '%f km' % (dist.km) elif unit == 'mi': dist_str = '%f mi' % (dist.mi) poly = set(MapPolygon.objects .filter(dataset_id__exact=dataset_id) .filter(mpoly__covers=boundary[dist]) .exclude(remote_id__in=already_accounted) .values_list('remote_id', flat=True)) maybe_polys = MapPolygon.objects.filter(dataset_id__exact=dataset_id) \ .exclude(mpoly__covers=boundary[dist]) \ .exclude(remote_id__in=already_accounted) \ .filter(mpoly__intersects=boundary[dist]) for polygon in maybe_polys: if polygon.mpoly.intersection(boundary[dist]).area > .5 * polygon.mpoly.area: poly.add(polygon.remote_id) already_accounted = already_accounted | poly data_sums[dist_str] = {} data_sums[dist_str]['polygon count'] = len(poly) data_sums[dist_str]['land area (m2)'] = sum([int(i) for i in MapPolygon.objects .filter(dataset_id__exact=dataset_id, remote_id__in=poly) .values_list('field1', flat=True)]) if data_sums[dist_str]['polygon count'] > 0: data_sums[dist_str]['polygons'] = str(list(poly)) datafields = DataField.objects.filter(dataset_id__exact=dataset_id).exclude(field_type__exact=DataField.STRING) for field in datafields: if field.field_longname not in data_sums[dist_str]: data_sums[dist_str][field.field_longname] = {} if field.field_type == DataField.INTEGER: data = DataElement.objects \ .filter(datafield_id=field.id, mapelement__remote_id__in=poly) \ .aggregate(sum=Sum('int_data'), dsum=Sum('denominator__int_data')) # print data['sum'], data['dsum'] elif field.field_type == DataField.FLOAT: data = DataElement.objects \ .filter(datafield_id=field.id, mapelement__remote_id__in=poly) \ .aggregate(sum=Sum('float_data'), dsum=Sum('denominator__float_data')) else: continue data_sums[dist_str][field.field_longname][field.field_en] = data['sum'] data_sums[dist_str][field.field_longname]['total'] = data['dsum'] return data_sums