def createMask(xxC, yyC, spatialRefProj): """ This will create a mask for a given basin, which will be defined by grib.basin :param xxC: <np array> The center points of the x grid :param yyC: <np array> The center points in the y grid :param spatialRefProj: <gdal obj> Current Projection Note: Make sure the .geojson basin files exist. The files were created using the USGS streamstats online app: https://water.usgs.gov/osw/streamstats/ :return: <np array> masked array. """ # Get the lat / lon of each grid box's center point. lons_centerPt, lats_centerPt = Proj(spatialRefProj)(xxC, yyC, inverse=True) # given a bunch of lat/lons in the geotiff, we can get the polygon points. try: sf = fiona.open( os.path.join(dir_path, 'Shapefiles', grib.basin, grib.basin + '.geojson')) except: logger.error('No basin shapefile found in ' + dir_path + '/Shapefiles/' + grib.basin + '/' + grib.basin + '.geojson' + '\n A mask was not created.') return geoms = [feature["geometry"] for feature in sf] poly = Polygon( geoms[0]['coordinates'][0] ) # For a simple square, this would be 4 points, but it can be thousands of points for other objects. polyMinLon, polyMinLat, polyMaxLon, polyMaxLat = sf.bounds # Get the bounds to speed up the process of generating a mask. # create a 1D numpy mask filled with zeros that is the exact same size as the lat/lon array from our projection. mask = np.zeros(lons_centerPt.flatten().shape) # Debugging: FOR CENTER POINT OF GRID BOX # These are test variables to see where the center points are (plot with basemaps to prove to yourself they're in the right spot). #debugCenterX = np.zeros(lats_centerPt.flatten().shape) #debugCenterY = np.zeros(lons_centerPt.flatten().shape) # Create Mask by checking whether points in the raster are within the bounds of the polygon. Instead of checking # every single point in the raster, just focus on points within the max/min bounds of the polygon (it's slow as hell # if you don't do that). i = 0 # counter for xp, yp in zip(lons_centerPt.flatten(), lats_centerPt.flatten()): if ((polyMinLon <= xp <= polyMaxLon) and (polyMinLat <= yp <= polyMaxLat)): mask[i] = (Point(xp, yp).within(poly)) # Debugging FOR CENTER POINT OF GRID BOX: If you want to visualize the center point # of each grid box that's found in the polygon, # include this below and then you can put a dot (via m.plot) #if (Point(xp, yp).within(poly)): #debugCenterX[i] = xp #debugCenterY[i] = yp i += 1 # mask = ([Point(xp, yp).within(poly) for xp, yp in zip(lons.flatten(), lats.flatten()) if # ((polyMinLon <= xp <= polyMaxLat) and (polyMinLat <= yp <= polyMaxLat))]) mask = np.reshape(mask, (xxC.shape)) return mask
def createMask(xxC, yyC, spatialRefProj): # Get the lat / lon of each grid box's center point. lons_centerPt, lats_centerPt = Proj(spatialRefProj)(xxC, yyC, inverse=True) # given a bunch of lat/lons in the geotiff, we can get the polygon points. sf = fiona.open(dir_path + '/Shapefiles/' + grib.basin + '/' + grib.basin + '.geojson') geoms = [feature["geometry"] for feature in sf] poly = Polygon( geoms[0]['coordinates'][0] ) # For a simple square, this would be 4 points, but it can be thousands of points for other objects. grib.basinArea = ops.transform( partial( pyproj.transform, pyproj.Proj(init='EPSG:4326'), pyproj.Proj(proj='aea', lat_1=poly.bounds[1], lat_2=poly.bounds[3])), poly).area # NOTE: Calculating area in the mercator projection (ESPG:3587) will lead to large errors due to inaccuracies in # that projections distance measurements. Instead, you must convert over to 4326 or equal area coordinates (whci is best) # For example, if instead of proj='aea' (in code below) you used proj = 'merc' the area for French Meadows # increases from roughly . 30,000 acres to over 50,000 acres. Alternatively, you could calculate the area by # counting the grid boxes in the polygon and summing up the area of one grid where # xres = 0.008333 deg * 111,111 m and yres = 0.008333 deg * 111,111 m * cos(latitude of grid box). # The method below is the easiest way to do this. polyMinLon, polyMinLat, polyMaxLon, polyMaxLat = sf.bounds # Get the bounds to speed up the process of generating a mask. # create a 1D numpy mask filled with zeros that is the exact same size as the lat/lon array from our projection. mask = np.zeros(lons_centerPt.flatten().shape) # Debugging: FOR CENTER POINT OF GRID BOX # These are test variables to see where the center points are (plot with basemaps to prove to yourself they're in the right spot). global debugCenterX, debugCenterY debugCenterX = np.zeros(lats_centerPt.flatten().shape) debugCenterY = np.zeros(lons_centerPt.flatten().shape) # Create Mask by checking whether points in the raster are within the bounds of the polygon. Instead of checking # every single point in the raster, just focus on points within the max/min bounds of the polygon (it's slow as hell # if you don't do that). i = 0 # counter for xp, yp in zip(lons_centerPt.flatten(), lats_centerPt.flatten()): if ((polyMinLon <= xp <= polyMaxLon) and (polyMinLat <= yp <= polyMaxLat)): mask[i] = (Point(xp, yp).within(poly)) # Debugging FOR CENTER POINT OF GRID BOX: If you want to visualize the center point # of each grid box that's found in the polygon, # include this below and then you can put a dot (via m.plot) if (Point(xp, yp).within(poly)): debugCenterX[i] = xp debugCenterY[i] = yp i += 1 mask = np.reshape(mask, (xxC.shape)) return mask
def createMask(xxC, yyC, spatialRefProj): # Get the lat / lon of each grid box's center point. lons_centerPt, lats_centerPt = Proj(spatialRefProj)(xxC, yyC, inverse=True) # given a bunch of lat/lons in the geotiff, we can get the polygon points. sf = fiona.open(dir_path + '/Shapefiles/' + grib.basin + '/' + grib.basin + '.geojson') geoms = [feature["geometry"] for feature in sf] poly = Polygon( geoms[0]['coordinates'][0] ) # For a simple square, this would be 4 points, but it can be thousands of points for other objects. polyMinLon, polyMinLat, polyMaxLon, polyMaxLat = sf.bounds # Get the bounds to speed up the process of generating a mask. # create a 1D numpy mask filled with zeros that is the exact same size as the lat/lon array from our projection. mask = np.zeros(lons_centerPt.flatten().shape) # Debugging: FOR CENTER POINT OF GRID BOX # These are test variables to see where the center points are (plot with basemaps to prove to yourself they're in the right spot). global debugCenterX, debugCenterY debugCenterX = np.zeros(lats_centerPt.flatten().shape) debugCenterY = np.zeros(lons_centerPt.flatten().shape) # Create Mask by checking whether points in the raster are within the bounds of the polygon. Instead of checking # every single point in the raster, just focus on points within the max/min bounds of the polygon (it's slow as hell # if you don't do that). i = 0 # counter for xp, yp in zip(lons_centerPt.flatten(), lats_centerPt.flatten()): if ((polyMinLon <= xp <= polyMaxLon) and (polyMinLat <= yp <= polyMaxLat)): mask[i] = (Point(xp, yp).within(poly)) # Debugging FOR CENTER POINT OF GRID BOX: If you want to visualize the center point # of each grid box that's found in the polygon, # include this below and then you can put a dot (via m.plot) if (Point(xp, yp).within(poly)): debugCenterX[i] = xp debugCenterY[i] = yp i += 1 mask = np.reshape(mask, (xxC.shape)) return mask