code: def reducer_metro(self, metro, values):
          
          lookup = CachedLookup(precision=POI_GEOHASH_PRECISION)
          for i, value in enumerate(values):
              type_tag, lonlat, data = value
              if type_tag == 1:
                  # OSM POI node, construct geojson and add to Rtree index
                  lookup.insert(i, dict(
                      geometry=dict(type='Point', coordinates=project(lonlat)),
                      properties=dict(tags=data)
                  ))
              else:
                  # geotweet, lookup nearest POI from index
                  if not lookup.data_store:
                      return
                  poi_names = []
                  kwargs = dict(buffer_size=POI_DISTANCE, multiple=True)
                  # lookup nearby POI from Rtree index (caching results)
                  # for any tags we care about emit the tags value and 1
                  for poi in lookup.get(lonlat, **kwargs):
                      has_tag = [ tag in poi['tags'] for tag in POI_TAGS ]
                      if any(has_tag) and 'name' in poi['tags']:
                          poi_names.append(poi['tags']['name'])
                  for poi in set(poi_names):
                      yield (metro, poi), 1
docs: Output tags of POI locations nearby tweet locations
  
          Values will be sorted coming into reducer.
          First element in each value tuple will be either 1 (osm POI) or 2 (geotweet).
          Build a spatial index with POI records.
          For each tweet lookup nearby POI, and emit tag values for predefined tags.