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
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
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
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
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
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