Ejemplo n.º 1
0
def global_intersect_map_geo(parser, griddef, verbose=True):
    '''
    For each pixel, find all gridcells that it intersects

    This function does not compute or save teh fractional 
    overlap of individual pixels.  

    This function is designed to handle grids that span 
    the entire globe, with the cyclic point (the point 
    where longitude "wraps") ocurring at index [*,0]

    The function assumes that the projection performs the wrapping.  
    IE any pixels east of the far east edge of the domain will be
    on the west side of the projection.  The function will NOT
    automatically wrap pixels that fall off the east/west edges
    of the projection.

    Pixels with NaN for any vertex are rejected

    Assumptions:
        - Straight lines in projected space adequately 
        approximate the edges of pixels/gridcells.
        - polar discontinuities aren't of concern
        - we ARE dealing with a global projection that 
        cyclizes at index (*,0)
        - grid is rectilinear
        - pixels are convex polygons
    '''
    if verbose:
        print('Mapping '+parser.name+'\nat '+str(datetime.datetime.now()))  
    outer_indices = griddef.indLims()
    # create the dictionary we'll use as a map
    map = map_helpers.init_output_map(outer_indices)
    map['parser'] = parser
        # we're going to hold onto both the prepared and unprepared versions
    # of the polys, so we can access the fully method set in the unprep
    # polys, but still do fast comparisons
    gridPolys = map_helpers.rect_grid_polys(outer_indices)
    prepPolys = map_helpers.rect_grid_polys(outer_indices)
    if verbose: print('prepping polys in grid')
    for poly in prepPolys.itervalues():
        poly = prep(poly)  # prepare these, they're going to get compared a lot
    if verbose: print('done prepping polys in grid')
    cornersStruct = parser.get_geo_corners()
    (row, col) = griddef.geoToGridded(cornersStruct['lat'], \
                                      cornersStruct['lon']) 
    ind = cornersStruct['ind']
    # reshape the matrixes to make looping workable
    row = row.reshape(-1,4)
    col = col.reshape(-1,4)
    ind = ind.reshape(row.shape[0],-1)
    if verbose: print('Intersecting pixels')
    # create the appropriate pixel(s) depending on whether
    # the pixels span the cyclic point
    minCol = griddef.indLims()[2]
    maxCol = griddef.indLims()[3] + 1
    midCol = (minCol+maxCol)/2.0
    for (pxrow, pxcol, pxind) in izip(row, col, ind):
        if (numpy.any(numpy.isnan(pxrow)) or 
            numpy.any(numpy.isnan(pxcol))):
            continue # skip incomplete pixels
        pointsTup = zip(pxrow, pxcol)
        prelimPoly = geom.MultiPoint(pointsTup).convex_hull
        (bbBot, bbLeft, bbTop, bbRight) = prelimPoly.bounds
        if bbLeft < midCol and bbRight > midCol:
            pointsLeft = [ (r,c) for (r,c) in pointsTup if c < midCol]
            pointsRight = [ (r,c) for (r,c) in pointsTup if c >= midCol]
            pointsLeft += [ (bbBot, minCol), (bbTop, minCol) ]
            pointsRight += [ (bbBot, maxCol), (bbTop, maxCol) ]
            polyLeft = geom.MultiPoint(pointsLeft).convex_hull
            polyRight = geom.MultiPoint(pointsRight).convex_hull
            splitArea = polyLeft.area + polyRight.area
            spanArea = prelimPoly.area
            if splitArea < spanArea:
                pixPolys = [polyLeft, polyRight]
            else:
                pixPolys = [prelimPoly]
        else:
            pixPolys = [prelimPoly]
        # try intersecting the poly(s) with all the grid polygons
        for poly in pixPolys:
            for key in map_helpers.get_possible_cells(outer_indices, poly):
                if prepPolys[key].intersects(poly) and not gridPolys[key].touches(poly):
                    map[key].append((tuple(pxind), None))
    if verbose: print('Done intersecting.')
    return map
Ejemplo n.º 2
0
def regional_intersect_map_geo(parser, griddef, verbose=True):
    '''
    For each pixel, find all gridcells that it intersects

    This function does not compute or save the fractional
    overlap of individual pixels.  It simply stores the
    pixel indices themselves.
    
    This function is currently not configured to operate 
    on a global scale, or near discontinuities. 
    The current kludge to handle discontinuities is 
    relies on the assumption that any pixel of interest 
    will have at least one corner within the bounds of 
    the grid

    Pixels with NaN for any vertex are rejected
    
    Several assumptions are made:
        - Straight lines in projected space adequately 
        approximate the edges of pixels/gridcells.
        - polar discontinuities aren't of concern
        - we AREN'T dealing with a global projection
        - grid is rectilinear
        - pixels are convex polygons
    '''
    
    if verbose:
        print('Mapping '+parser.name+'\nat '+str(datetime.datetime.now()))
    outer_indices = griddef.indLims()
    map = map_helpers.init_output_map(outer_indices)
    map['parser'] = parser
    bounds = prep(map_helpers.rect_bound_poly(outer_indices))
    # we're going to hold onto both the prepared and unprepared versions
    # of the polys, so we can access the fully method set in the unprep
    # polys, but still do fast comparisons
    gridPolys = map_helpers.rect_grid_polys(outer_indices)
    prepPolys = map_helpers.rect_grid_polys(outer_indices)
    if verbose: print('prepping polys in grid')
    for poly in prepPolys.itervalues():
        poly = prep(poly)  # prepare these, they're going to get compared a lot
    if verbose: print('done prepping polys in grid')
    cornersStruct = parser.get_geo_corners()
    (row, col) = griddef.geoToGridded(cornersStruct['lat'], \
                                      cornersStruct['lon']) 
    ind = cornersStruct['ind']
    # reshape the matrixes to make looping workable
    row = row.reshape(-1,4)
    col = col.reshape(-1,4)
    ind = ind.reshape(row.shape[0],-1)
    if verbose:
        griddedPix = 0 
        print('Intersecting pixels')
        sys.stdout.write("Approximately 0 pixels gridded. ")
        sys.stdout.flush()
        for (pxrow, pxcol, pxind) in izip(row, col, ind):
            if numpy.any(numpy.isnan(pxrow)) or numpy.any(numpy.isnan(pxcol)):
                continue  # if we have only a partial pixel, skip
            elif not any([bounds.contains(geom.asPoint((r,c))) \
                       for (r,c) in izip(pxrow, pxcol)]):
                continue  # if none of the corners are in bounds, skip
            griddedPix += 1
            sys.stdout.write("\rApproximately {0} pixels gridded. ".\
                             format(griddedPix))
            sys.stdout.flush()
            pixPoly = geom.MultiPoint(zip(pxrow, pxcol)).convex_hull
            
            for key in map_helpers.get_possible_cells(outer_indices, pixPoly):
                if prepPolys[key].intersects(pixPoly) and not \
                                  gridPolys[key].touches(pixPoly) :
                    map[key].append((tuple(pxind), None))
        print('Done intersecting.')
    else:
        for (pxrow, pxcol, pxind) in izip(row, col, ind):
            if numpy.any(numpy.isnan(pxrow)) or numpy.any(numpy.isnan(pxcol)):
                continue  # if we have only a partial pixel, skip
            elif not any([bounds.contains(geom.asPoint((r,c))) for (r,c) \
                                        in izip(pxrow, pxcol)]):
                continue  # if none of the corners are in bounds, skip
            pixPoly = geom.MultiPoint(zip(pxrow, pxcol)).convex_hull
            for key in map_helpers.get_possible_cells(outer_indices, pixPoly):
                if prepPolys[key].intersects(pixPoly) and not \
                                  gridPolys[key].touches(pixPoly):
                    map[key].append((tuple(pxind), None))
    return map
Ejemplo n.º 3
0
def global_intersect_map_geo(parser, griddef, verbose=True):
    '''
    For each pixel, find all gridcells that it intersects

    This function does not compute or save the fractional 
    overlap of individual pixels.  

    This function is designed to handle grids that span 
    the entire globe, with the cyclic point (the point 
    where longitude "wraps") ocurring at index [*,0]

    The function assumes that the projection performs the wrapping.  
    IE any pixels east of the far east edge of the domain will be
    on the west side of the projection.  The function will NOT
    automatically wrap pixels that fall off the east/west edges
    of the projection.

    Pixels with NaN for any vertex are rejected

    Assumptions:
        - Straight lines in projected space adequately 
        approximate the edges of pixels/gridcells.
        - polar discontinuities aren't of concern
        - we ARE dealing with a global projection that 
        cyclizes at index (*,0)
        - grid is rectilinear
        - pixels are convex polygons
    '''
    if verbose:
        print('Mapping ' + parser.name + '\nat ' +
              str(datetime.datetime.now()))
    outer_indices = griddef.indLims()
    # create the dictionary we'll use as a map
    map = map_helpers.init_output_map(outer_indices)
    map['parser'] = parser
    # we're going to hold onto both the prepared and unprepared versions
    # of the polys, so we can access the fully method set in the unprep
    # polys, but still do fast comparisons
    gridPolys = map_helpers.rect_grid_polys(outer_indices)
    prepPolys = map_helpers.rect_grid_polys(outer_indices)
    if verbose: print('prepping polys in grid')
    # prepare polygons, they're going to get compared a lot
    for polykey in prepPolys.keys():
        prepPolys[polykey] = prep(prepPolys[polykey])
    if verbose: print('done prepping polys in grid')
    cornersStruct = parser.get_geo_corners()
    (row, col) = griddef.geoToGridded(cornersStruct['lat'], \
                                      cornersStruct['lon'])
    ind = cornersStruct['ind']
    # reshape the matrixes to make looping workable
    row = row.reshape(-1, 4)
    col = col.reshape(-1, 4)
    ind = ind.reshape(row.shape[0], -1)
    if verbose: print('Intersecting pixels')
    # create the appropriate pixel(s) depending on whether
    # the pixels span the cyclic point
    minCol = griddef.indLims()[2]
    maxCol = griddef.indLims()[3] + 1
    midCol = (minCol + maxCol) / 2.0
    for (pxrow, pxcol, pxind) in izip(row, col, ind):
        if (numpy.any(numpy.isnan(pxrow)) or numpy.any(numpy.isnan(pxcol))):
            continue  # skip incomplete pixels
        pointsTup = zip(pxrow, pxcol)
        prelimPoly = geom.MultiPoint(pointsTup).convex_hull
        (bbBot, bbLeft, bbTop, bbRight) = prelimPoly.bounds
        if bbLeft < midCol and bbRight > midCol:
            pointsLeft = [(r, c) for (r, c) in pointsTup if c < midCol]
            pointsRight = [(r, c) for (r, c) in pointsTup if c >= midCol]
            pointsLeft += [(bbBot, minCol), (bbTop, minCol)]
            pointsRight += [(bbBot, maxCol), (bbTop, maxCol)]
            polyLeft = geom.MultiPoint(pointsLeft).convex_hull
            polyRight = geom.MultiPoint(pointsRight).convex_hull
            splitArea = polyLeft.area + polyRight.area
            spanArea = prelimPoly.area
            if splitArea < spanArea:
                pixPolys = [polyLeft, polyRight]
            else:
                pixPolys = [prelimPoly]
        else:
            pixPolys = [prelimPoly]
        # try intersecting the poly(s) with all the grid polygons
        for poly in pixPolys:
            for key in map_helpers.get_possible_cells(outer_indices, poly):
                if prepPolys[key].intersects(
                        poly) and not gridPolys[key].touches(poly):
                    map[key].append((tuple(pxind), None))
    if verbose: print('Done intersecting.')
    return map
Ejemplo n.º 4
0
def regional_intersect_map_geo(parser, griddef, verbose=True):
    '''
    For each pixel, find all gridcells that it intersects

    This function does not compute or save the fractional
    overlap of individual pixels.  It simply stores the
    pixel indices themselves.
    
    This function is currently not configured to operate 
    on a global scale, or near discontinuities. 
    The current kludge to handle discontinuities is 
    relies on the assumption that any pixel of interest 
    will have at least one corner within the bounds of 
    the grid

    Pixels with NaN for any vertex are rejected
    
    Several assumptions are made:
        - Straight lines in projected space adequately 
        approximate the edges of pixels/gridcells.
        - polar discontinuities aren't of concern
        - we AREN'T dealing with a global projection
        - grid is rectilinear
        - pixels are convex polygons
    '''

    if verbose:
        print('Mapping ' + parser.name + '\nat ' +
              str(datetime.datetime.now()))
    outer_indices = griddef.indLims()
    map = map_helpers.init_output_map(outer_indices)
    map['parser'] = parser
    bounds = prep(map_helpers.rect_bound_poly(outer_indices))
    # we're going to hold onto both the prepared and unprepared versions
    # of the polys, so we can access the fully method set in the unprep
    # polys, but still do fast comparisons
    gridPolys = map_helpers.rect_grid_polys(outer_indices)
    prepPolys = map_helpers.rect_grid_polys(outer_indices)
    if verbose: print('prepping polys in grid')
    # prepare polygons, they're going to get compared a lot
    for polykey in prepPolys.keys():
        prepPolys[polykey] = prep(prepPolys[polykey])
    if verbose: print('done prepping polys in grid')
    cornersStruct = parser.get_geo_corners()
    (row, col) = griddef.geoToGridded(cornersStruct['lat'], \
                                      cornersStruct['lon'])
    ind = cornersStruct['ind']
    # reshape the matrixes to make looping workable
    row = row.reshape(-1, 4)
    col = col.reshape(-1, 4)
    ind = ind.reshape(row.shape[0], -1)
    if verbose:
        griddedPix = 0
        print('Intersecting pixels')
        sys.stdout.write("Approximately 0 pixels gridded. ")
        sys.stdout.flush()
        for (pxrow, pxcol, pxind) in izip(row, col, ind):
            if numpy.any(numpy.isnan(pxrow)) or numpy.any(numpy.isnan(pxcol)):
                continue  # if we have only a partial pixel, skip
            elif not any([bounds.contains(geom.asPoint((r,c))) \
                       for (r,c) in izip(pxrow, pxcol)]):
                continue  # if none of the corners are in bounds, skip
            griddedPix += 1
            sys.stdout.write("\rApproximately {0} pixels gridded. ".\
                             format(griddedPix))
            sys.stdout.flush()
            pixPoly = geom.MultiPoint(zip(pxrow, pxcol)).convex_hull

            for key in map_helpers.get_possible_cells(outer_indices, pixPoly):
                if prepPolys[key].intersects(pixPoly) and not \
                                  gridPolys[key].touches(pixPoly) :
                    map[key].append((tuple(pxind), None))
        print('Done intersecting.')
    else:
        for (pxrow, pxcol, pxind) in izip(row, col, ind):
            if numpy.any(numpy.isnan(pxrow)) or numpy.any(numpy.isnan(pxcol)):
                continue  # if we have only a partial pixel, skip
            elif not any([bounds.contains(geom.asPoint((r,c))) for (r,c) \
                                        in izip(pxrow, pxcol)]):
                continue  # if none of the corners are in bounds, skip
            pixPoly = geom.MultiPoint(zip(pxrow, pxcol)).convex_hull
            for key in map_helpers.get_possible_cells(outer_indices, pixPoly):
                if prepPolys[key].intersects(pixPoly) and not \
                                  gridPolys[key].touches(pixPoly):
                    map[key].append((tuple(pxind), None))
    return map
Ejemplo n.º 5
0
def global_intersect_map_geo(parser, griddef, verbose=True):
    '''
    For each pixel, find all gridcells that it intersects

    This function does not compute or save the fractional 
    overlap of individual pixels.  

    This function is designed to handle grids that span 
    the entire globe, with the cyclic point (the point 
    where longitude "wraps") ocurring at index [*,0]

    The function assumes that the projection performs the wrapping.  
    IE any pixels east of the far east edge of the domain will be
    on the west side of the projection.  The function will NOT
    automatically wrap pixels that fall off the east/west edges
    of the projection.

    Pixels with NaN for any vertex are rejected

    Assumptions:
        - Straight lines in projected space adequately 
        approximate the edges of pixels/gridcells.
        - polar discontinuities aren't of concern
        - we ARE dealing with a global projection that 
        cyclizes at index (*,0)
        - grid is rectilinear
        - pixels are convex polygons
    '''
    if verbose:
        print('Mapping '+parser.name+'\nat '+str(datetime.datetime.now()))  
    outer_indices = griddef.indLims()
    outer_poly = (geom.Polygon([(outer_indices[0], outer_indices[2]),
                               (outer_indices[0], outer_indices[3]),
                               (outer_indices[1], outer_indices[3]),
                               (outer_indices[1], outer_indices[2])]))
    outer_polyp = prep(outer_poly)              
    # create the dictionary we'll use as a map
    map = map_helpers.init_output_map(outer_indices)
    map['parser'] = parser
    tpreps = []
    tchecks = []
    tskips = []
    # we're going to hold onto both the prepared and unprepared versions
    # of the polys, so we can access the fully method set in the unprep
    # polys, but still do fast comparisons
    gridPolys = map_helpers.rect_grid_polys(outer_indices)
    prepPolys = map_helpers.rect_grid_polys(outer_indices)
    if verbose: print('prepping polys in grid')
    for polyk in prepPolys.keys():
        prepPolys[polyk] = prep(prepPolys[polyk]) # going to get compared a lot
    if verbose: print('done prepping polys in grid')
    cornersStruct = parser.get_geo_corners()
    (row, col) = griddef.geoToGridded(cornersStruct['lat'], \
                                      cornersStruct['lon']) 
    ind = cornersStruct['ind']
    if cornersStruct['lon'].shape[-1] == 4:
        lon = cornersStruct['lon']
        leftlon = lon[..., [0, 3]].max(-1)
        rightlon = lon[..., [1, 2]].min(-1)
        loncheck = (leftlon > rightlon)

    # reshape the matrixes to make looping workable
    row = row.reshape(-1,4)
    col = col.reshape(-1,4)
    loncheck = loncheck.ravel()
    ind = ind.reshape(row.shape[0],-1)
    if verbose: print('Intersecting pixels')
    # create the appropriate pixel(s) depending on whether
    # the pixels span the cyclic point
    minCol = griddef.indLims()[2]
    maxCol = griddef.indLims()[3] + 1
    midCol = (minCol+maxCol)/2.0
    dummy, (colNeg180, colPos180) = griddef.geoToGridded(numpy.array([0, 0]), numpy.array([-180, 180]))
    for (pxrow, pxcol, pxind, pxcheck) in izip(row, col, ind, loncheck):
        if verbose:
            t0 = time.time()
        if (numpy.any(numpy.isnan(pxrow)) or 
            numpy.any(numpy.isnan(pxcol))):
            continue # skip incomplete pixels
        pointsTup = zip(pxrow, pxcol)
        prelimPoly = geom.MultiPoint(pointsTup).convex_hull
        if not outer_polyp.intersects(prelimPoly.envelope):
            if verbose:
                tskips.append(time.time() - t0)
            continue
        (bbBot, bbLeft, bbTop, bbRight) = prelimPoly.bounds
        if bbLeft < midCol and bbRight > midCol:
            pointsLeft = [ (r,c) for (r,c) in pointsTup if c < midCol]
            pointsRight = [ (r,c) for (r,c) in pointsTup if c >= midCol]
            if pxcheck:
                pointsLeft += [ (bbBot, colNeg180), (bbTop, colNeg180) ]
                pointsRight += [ (bbBot, colPos180), (bbTop, colPos180) ]
            else:
                pointsLeft += [ (bbBot, minCol), (bbTop, minCol) ]
                pointsRight += [ (bbBot, maxCol), (bbTop, maxCol) ]
            polyLeft = geom.MultiPoint(pointsLeft).convex_hull
            polyRight = geom.MultiPoint(pointsRight).convex_hull
            splitArea = polyLeft.area + polyRight.area
            spanArea = prelimPoly.area
            if splitArea < spanArea:
                pixPolys = [polyLeft, polyRight]
            else:
                pixPolys = [prelimPoly]
        else:
            pixPolys = [prelimPoly]
        # try intersecting the poly(s) with all the grid polygons
        if verbose:
            t1 = time.time()
        for poly in pixPolys:
            for key in map_helpers.get_possible_cells(outer_indices, poly):
                # Prepped contains is much faster than 
                # than the combination of prepped intersection
                # and unprepped touches
                if prepPolys[key].intersects(poly) and (prepPolys[key].contains(poly) or not gridPolys[key].touches(poly)):
                        map[key].append((tuple(pxind), None))
        if verbose:
            t2 = time.time()
            tprep, tcheck = t1 - t0, t2 - t1
            tpreps.append(tprep)
            tchecks.append(tcheck)
    if verbose:
        print('Checked pixels:', len(tpreps))
        print('Pixel processing:', sum(tpreps))
        print('Pixel checking:', sum(tchecks))
        print('         Total:', sum(tpreps) + sum(tchecks))
        print('Skipped pixels:', len(tskips))
        print('Pixel skip time:',sum(tskips))
        print('Done intersecting.')
    return map
Ejemplo n.º 6
0
def global_intersect_map_geo(parser, griddef, verbose=True):
    '''
    For each pixel, find all gridcells that it intersects

    This function does not compute or save the fractional 
    overlap of individual pixels.  

    This function is designed to handle grids that span 
    the entire globe, with the cyclic point (the point 
    where longitude "wraps") ocurring at index [*,0]

    The function assumes that the projection performs the wrapping.  
    IE any pixels east of the far east edge of the domain will be
    on the west side of the projection.  The function will NOT
    automatically wrap pixels that fall off the east/west edges
    of the projection.

    Pixels with NaN for any vertex are rejected

    Assumptions:
        - Straight lines in projected space adequately 
        approximate the edges of pixels/gridcells.
        - polar discontinuities aren't of concern
        - we ARE dealing with a global projection that 
        cyclizes at index (*,0)
        - grid is rectilinear
        - pixels are convex polygons
    '''
    if verbose:
        print('Mapping ' + parser.name + '\nat ' +
              str(datetime.datetime.now()))
    outer_indices = griddef.indLims()
    outer_poly = (geom.Polygon([(outer_indices[0], outer_indices[2]),
                                (outer_indices[0], outer_indices[3]),
                                (outer_indices[1], outer_indices[3]),
                                (outer_indices[1], outer_indices[2])]))
    outer_polyp = prep(outer_poly)
    # create the dictionary we'll use as a map
    map = map_helpers.init_output_map(outer_indices)
    map['parser'] = parser
    tpreps = []
    tchecks = []
    tskips = []
    # we're going to hold onto both the prepared and unprepared versions
    # of the polys, so we can access the fully method set in the unprep
    # polys, but still do fast comparisons
    gridPolys = map_helpers.rect_grid_polys(outer_indices)
    prepPolys = map_helpers.rect_grid_polys(outer_indices)
    if verbose: print('prepping polys in grid')
    for polyk in prepPolys.keys():
        prepPolys[polyk] = prep(
            prepPolys[polyk])  # going to get compared a lot
    if verbose: print('done prepping polys in grid')
    cornersStruct = parser.get_geo_corners()
    (row, col) = griddef.geoToGridded(cornersStruct['lat'], \
                                      cornersStruct['lon'])
    ind = cornersStruct['ind']
    if cornersStruct['lon'].shape[-1] == 4:
        lon = cornersStruct['lon']
        leftlon = lon[..., [0, 3]].max(-1)
        rightlon = lon[..., [1, 2]].min(-1)
        loncheck = (leftlon > rightlon)

    # reshape the matrixes to make looping workable
    row = row.reshape(-1, 4)
    col = col.reshape(-1, 4)
    loncheck = loncheck.ravel()
    ind = ind.reshape(row.shape[0], -1)
    if verbose: print('Intersecting pixels')
    # create the appropriate pixel(s) depending on whether
    # the pixels span the cyclic point
    minCol = griddef.indLims()[2]
    maxCol = griddef.indLims()[3] + 1
    midCol = (minCol + maxCol) / 2.0
    dummy, (colNeg180,
            colPos180) = griddef.geoToGridded(numpy.array([0, 0]),
                                              numpy.array([-180, 180]))
    for (pxrow, pxcol, pxind, pxcheck) in izip(row, col, ind, loncheck):
        if verbose:
            t0 = time.time()
        if (numpy.any(numpy.isnan(pxrow)) or numpy.any(numpy.isnan(pxcol))):
            continue  # skip incomplete pixels
        pointsTup = zip(pxrow, pxcol)
        prelimPoly = geom.MultiPoint(pointsTup).convex_hull
        if not outer_polyp.intersects(prelimPoly.envelope):
            if verbose:
                tskips.append(time.time() - t0)
            continue
        (bbBot, bbLeft, bbTop, bbRight) = prelimPoly.bounds
        if bbLeft < midCol and bbRight > midCol:
            pointsLeft = [(r, c) for (r, c) in pointsTup if c < midCol]
            pointsRight = [(r, c) for (r, c) in pointsTup if c >= midCol]
            if pxcheck:
                pointsLeft += [(bbBot, colNeg180), (bbTop, colNeg180)]
                pointsRight += [(bbBot, colPos180), (bbTop, colPos180)]
            else:
                pointsLeft += [(bbBot, minCol), (bbTop, minCol)]
                pointsRight += [(bbBot, maxCol), (bbTop, maxCol)]
            polyLeft = geom.MultiPoint(pointsLeft).convex_hull
            polyRight = geom.MultiPoint(pointsRight).convex_hull
            splitArea = polyLeft.area + polyRight.area
            spanArea = prelimPoly.area
            if splitArea < spanArea:
                pixPolys = [polyLeft, polyRight]
            else:
                pixPolys = [prelimPoly]
        else:
            pixPolys = [prelimPoly]
        # try intersecting the poly(s) with all the grid polygons
        if verbose:
            t1 = time.time()
        for poly in pixPolys:
            for key in map_helpers.get_possible_cells(outer_indices, poly):
                # Prepped contains is much faster than
                # than the combination of prepped intersection
                # and unprepped touches
                if prepPolys[key].intersects(poly) and (
                        prepPolys[key].contains(poly)
                        or not gridPolys[key].touches(poly)):
                    map[key].append((tuple(pxind), None))
        if verbose:
            t2 = time.time()
            tprep, tcheck = t1 - t0, t2 - t1
            tpreps.append(tprep)
            tchecks.append(tcheck)
    if verbose:
        print('Checked pixels:', len(tpreps))
        print('Pixel processing:', sum(tpreps))
        print('Pixel checking:', sum(tchecks))
        print('         Total:', sum(tpreps) + sum(tchecks))
        print('Skipped pixels:', len(tskips))
        print('Pixel skip time:', sum(tskips))
        print('Done intersecting.')
    return map