def get_shapes(self, max_area, max_distance_meters): "return the shapes [census tracts] that touch the center of max_area + max_distance" query = { 'geometry': { '$near': SON([('$geometry', SON([('type', 'Point'), ('coordinates', [longitude, latitude])])), ('$maxDistance', max_distance_meters)]) } } for shp in self.db.GENZ2010_140.find(query): # add population to properties p = shp['properties'] # for later use p['label'] = "{} {} [{}]".format( state_name(p['STATE']), county_name(p['STATE'], p['COUNTY']), p['TRACT']) pop = {} # lookup population and area raw_pop = int( self.census.sf1.state_county_tract("P0010001", p['STATE'], p['COUNTY'], p['TRACT'])[0]["P0010001"]) pop['raw'] = raw_pop #print("raw population: {}".format(raw_pop)) # compute area in our radius county_shape = shape(shp['geometry']) isect = county_shape.intersection(max_area) # save the intersection for later use. shp['intersection'] = isect pop['area'] = county_shape.area frac_contained = float(isect.area) / float(county_shape.area) pop['frac_contained'] = frac_contained #print("contained: {}".format(frac_contained)) # compute effective population #print("contained population: {}".format(frac_contained * raw_pop)) pop['effective'] = frac_contained * raw_pop p['population'] = pop # filter out areas with very low population # the mongodb geo query may be not exact if frac_contained * raw_pop < 0.1: print("WARN: clipping: {}".format(p['label'])) pprint(pop) continue yield shp
def plot_shapes(ax, shapes, filled=False, show_states=False, fc=None, alpha=0.16): # have to buffer the results to see how many colors to generate if fc == None: if filled: color_list = plt.cm.Dark2(np.linspace(0, 1, len(shapes))) fc = lambda x: color_list[x] else: fc = lambda x: 'none' states = set() geoid = {} # get the shapes covered by the coverage area. for i, shp in enumerate(shapes): p = shp['properties'] #track states we hit if p['STATE'] not in states: states.add(p['STATE']) # also store the goeid so we dont plot again later geoid[p['GEO_ID']] = shp if p['LSAD'] == 'Tract': label = "{} {} [{}]".format(state_name(p['STATE']), county_name(p['STATE'], p['COUNTY']), p['TRACT']) else: label = p['NAME'] #print ("-"*10 + label + "-"*10) #pprint(p['population']) ec = 'black' lw = 1 if 'population' in p: if p['population']['effective'] < 0.01: ec = 'blue' lw = 2 #was fc = color_list[i], patches = make_patch(shp['geometry'], fc=fc(i), lw=lw, ec=ec, label=label, alpha=alpha) for p in patches: ax.add_patch(p)
def _add_pop_to_shape_intersct(self, shp, max_area): "add the population inside the intersection of shp and max_area, shp is assumed to be a census tract." # add population to properties p = shp['properties'] #print(p) # for later use p['label'] = "{} {} [{}]".format(state_name(p['STATE']), county_name(p['STATE'], p['COUNTY']), p['TRACT']) pop = {} # lookup population and area try mongo first. searchdoc = { 'state': p["STATE"], 'county': p['COUNTY'], 'tract': p['TRACT'], 'variable.P0010001': { '$exists': True } } #print("searchdoc: ",end="") #pprint(searchdoc) cdoc = self.census_col.find_one(searchdoc) if cdoc != None: #print("Hit.") raw_pop = cdoc['variable']['P0010001'] else: raw_pop = int( self.census.sf1.state_county_tract("P0010001", p['STATE'], p['COUNTY'], p['TRACT'])[0]["P0010001"]) insdoc = { 'state': p["STATE"], 'county': p['COUNTY'], 'tract': p['TRACT'], 'variable': { 'P0010001': raw_pop } } #print("inserting: ", end="") #pprint(insdoc) self.census_col.insert_one(insdoc) pop['raw'] = raw_pop #print("raw population: {}".format(raw_pop)) county_shape = shape(shp['geometry']) if max_area != None: # compute area in our radius isect = county_shape.intersection(max_area) union = county_shape.union(max_area) # save the intersection for later use. shp['intersection'] = mapping(isect) shp['union'] = mapping(union) pop['area'] = county_shape.area frac_contained = float(isect.area) / float(county_shape.area) pop['frac_contained'] = frac_contained #print("contained: {}".format(frac_contained)) else: shp['intersection'] = shp['geometry'] shp['union'] = shp['geometry'] pop['area'] = county_shape.area frac_contained = 1.0 pop['frac_contained'] = 1.0 # compute effective population #print("contained population: {}".format(frac_contained * raw_pop)) pop['effective'] = frac_contained * raw_pop p['population'] = pop shp['properties'] = p # add area compute_land_area(shp)
# have to buffer the results to see how many colors to generate results = list(pbps.get_shapes(area, dist)) color_list = plt.cm.Dark2(np.linspace(0, 1, len(results))) # get the shapes covered by the coverage area. for i, shp in enumerate(results): p = shp['properties'] #track states we hit if p['STATE'] not in states: states.add(p['STATE']) # also store the goeid so we dont plot again later geoid[p['GEO_ID']] = shp label = "{} {} [{}]".format(state_name(p['STATE']), county_name(p['STATE'], p['COUNTY']), p['TRACT']) #print ("-"*10 + label + "-"*10) #pprint(p['population']) ec = 'black' lw = 2 if p['population']['effective'] < 0.01: ec = 'blue' lw = 4 patches = make_patch(shp['geometry'], fc=color_list[i], lw=lw, ec=ec, label=label)