예제 #1
0
 def test_get_area_def_from_raster(self):
     from rasterio.crs import CRS
     from affine import Affine
     from pyresample import utils
     x_size = 791
     y_size = 718
     transform = Affine(300.0379266750948, 0.0, 101985.0, 0.0,
                        -300.041782729805, 2826915.0)
     crs = CRS(init='epsg:3857')
     source = tmptiff(x_size, y_size, transform, crs=crs)
     area_id = 'area_id'
     proj_id = 'proj_id'
     name = 'name'
     area_def = utils.get_area_def_from_raster(source,
                                               area_id=area_id,
                                               name=name,
                                               proj_id=proj_id)
     self.assertEqual(area_def.area_id, area_id)
     self.assertEqual(area_def.proj_id, proj_id)
     self.assertEqual(area_def.name, name)
     self.assertEqual(area_def.x_size, x_size)
     self.assertEqual(area_def.y_size, y_size)
     self.assertDictEqual(crs.to_dict(), area_def.proj_dict)
     self.assertTupleEqual(
         area_def.area_extent,
         (transform.c, transform.f + transform.e * y_size,
          transform.c + transform.a * x_size, transform.f))
예제 #2
0
 def test_get_area_def_from_raster(self):
     from pyresample import utils
     from rasterio.crs import CRS
     from affine import Affine
     x_size = 791
     y_size = 718
     transform = Affine(300.0379266750948, 0.0, 101985.0, 0.0,
                        -300.041782729805, 2826915.0)
     crs = CRS(init='epsg:3857')
     if utils.is_pyproj2():
         # pyproj 2.0+ expands CRS parameters
         from pyproj import CRS
         proj_dict = CRS(3857).to_dict()
     else:
         proj_dict = crs.to_dict()
     source = tmptiff(x_size, y_size, transform, crs=crs)
     area_id = 'area_id'
     proj_id = 'proj_id'
     description = 'name'
     area_def = utils._rasterio.get_area_def_from_raster(source,
                                                         area_id=area_id,
                                                         name=description,
                                                         proj_id=proj_id)
     self.assertEqual(area_def.area_id, area_id)
     self.assertEqual(area_def.proj_id, proj_id)
     self.assertEqual(area_def.description, description)
     self.assertEqual(area_def.width, x_size)
     self.assertEqual(area_def.height, y_size)
     self.assertDictEqual(proj_dict, area_def.proj_dict)
     self.assertTupleEqual(
         area_def.area_extent,
         (transform.c, transform.f + transform.e * y_size,
          transform.c + transform.a * x_size, transform.f))
예제 #3
0
 def test_get_area_def_from_raster(self):
     from pyresample import utils
     from rasterio.crs import CRS
     from affine import Affine
     x_size = 791
     y_size = 718
     transform = Affine(300.0379266750948, 0.0, 101985.0,
                        0.0, -300.041782729805, 2826915.0)
     crs = CRS(init='epsg:3857')
     source = tmptiff(x_size, y_size, transform, crs=crs)
     area_id = 'area_id'
     proj_id = 'proj_id'
     name = 'name'
     area_def = utils._rasterio.get_area_def_from_raster(
         source, area_id=area_id, name=name, proj_id=proj_id)
     self.assertEqual(area_def.area_id, area_id)
     self.assertEqual(area_def.proj_id, proj_id)
     self.assertEqual(area_def.name, name)
     self.assertEqual(area_def.width, x_size)
     self.assertEqual(area_def.height, y_size)
     self.assertDictEqual(crs.to_dict(), area_def.proj_dict)
     self.assertTupleEqual(area_def.area_extent, (transform.c, transform.f + transform.e * y_size,
                                                  transform.c + transform.a * x_size, transform.f))
예제 #4
0
def test_crs_proj_json__from_string():
    aeqd_crs = CRS(proj="aeqd", lon_0=-80, lat_0=40.5)
    assert CRS.from_string(json.dumps(aeqd_crs.to_dict(projjson=True))) == aeqd_crs
예제 #5
0
def test_crs_from_json_dict__init():
    aeqd_crs = CRS(proj="aeqd", lon_0=-80, lat_0=40.5)
    assert CRS(aeqd_crs.to_dict(projjson=True)) == aeqd_crs
예제 #6
0
def test_crs_to_json_dict__empty():
    crs = CRS()
    assert crs.to_dict(projjson=True) == {}
예제 #7
0
def test_crs_to_json_dict():
    aeqd_crs = CRS(proj="aeqd", lon_0=-80, lat_0=40.5)
    json_dict = aeqd_crs.to_dict(projjson=True)
    assert json_dict["type"] == "ProjectedCRS"
예제 #8
0
def zones(
    input,
    output,
    variable,
    attribute,
    like,
    netcdf3,
    zip):

    """
    Create zones in a NetCDF from features in a shapefile.  This is intended
    to be used as input to zonal statistics functions; it is not intended
    as a direct replacement for rasterizing geometries into NetCDF.

    Only handles < 65,535 features for now.

    If --attribute is provided, any features that do not have this will not be
    assigned to zones.

    A values lookup will be used to store values.  The zones are indices of
    the unique values encountered when extracting features.
    The original values are stored in an additional variable with the name of
    the zones variable plus '_values'.

    Template NetCDF dataset must have a valid projection defined or be inferred
    from dimensions (e.g., lat / long).
    """

    with Dataset(like) as template_ds:
        template_varname = list(data_variables(template_ds).keys())[0]
        template_variable = template_ds.variables[template_varname]
        template_crs = get_crs(template_ds, template_varname)

        if template_crs:
            template_crs = CRS.from_string(template_crs)
        elif is_geographic(template_ds, template_varname):
            template_crs = CRS({'init': 'EPSG:4326'})
        else:
            raise click.UsageError('template dataset must have a valid projection defined')

        spatial_dimensions = template_variable.dimensions[-2:]
        out_shape = template_variable.shape[-2:]

        template_y_name, template_x_name = spatial_dimensions
        coords = SpatialCoordinateVariables.from_dataset(
            template_ds,
            x_name=template_x_name,
            y_name=template_y_name,
            projection=Proj(**template_crs.to_dict())
        )


    with fiona.open(input, 'r') as shp:
        if attribute:
            if not attribute in shp.meta['schema']['properties']:
                raise click.BadParameter('{0} not found in dataset'.format(attribute),
                                         param='--attribute', param_hint='--attribute')

            att_dtype = shp.meta['schema']['properties'][attribute].split(':')[0]
            if not att_dtype in ('int', 'str'):
                raise click.BadParameter('integer or string attribute required'.format(attribute),
                                         param='--attribute', param_hint='--attribute')

        transform_required = CRS(shp.crs) != template_crs
        geometries = []
        values = set()
        values_lookup = {}

        # Project bbox for filtering
        bbox = coords.bbox
        if transform_required:
            bbox = bbox.project(Proj(**shp.crs), edge_points=21)

        index = 0
        for f in shp.filter(bbox=bbox.as_list()):
            value = f['properties'].get(attribute) if attribute else int(f['id'])
            if value is not None:
                geom = f['geometry']
                if transform_required:
                    geom = transform_geom(shp.crs, template_crs, geom)

                geometries.append((geom, index))

                if not value in values:
                    values.add(value)
                    values_lookup[index] = value
                    index += 1

            # Otherwise, these will not be rasterized

        num_geometries = len(geometries)
        # Save a slot at the end for nodata
        if num_geometries < 255:
            dtype = numpy.dtype('uint8')
        elif num_geometries < 65535:
            dtype = numpy.dtype('uint16')
        else:
            raise click.UsageError('Too many features to rasterize: {0}, Exceptioning...'.format(num_geometries))

        fill_value = get_fill_value(dtype)

        click.echo('Rasterizing {0} features into zones'.format(num_geometries))

    with rasterio.Env():
        zones = rasterize(
            geometries,
            out_shape=out_shape,
            transform=coords.affine,
            all_touched=False, # True produces undesirable results for adjacent polygons
            fill=fill_value,
            dtype=dtype
        )

    format = 'NETCDF4'
    out_dtype = dtype
    if netcdf3:
        format = 'NETCDF3_CLASSIC'
        if dtype == numpy.uint8:
            out_dtype = numpy.dtype('int16')
        elif dtype == numpy.uint16:
            out_dtype = numpy.dtype('int32')

        # Have to convert fill_value to mask since we changed data type
        zones = numpy.ma.masked_array(zones, mask=(zones == fill_value))


    with Dataset(output, 'w', format=format) as out:
        values_varname = '{0}_values'.format(variable)
        coords.add_to_dataset(out, template_x_name, template_y_name)
        out_var = out.createVariable(variable, out_dtype,
                                     dimensions=spatial_dimensions,
                                     zlib=zip,
                                     fill_value=get_fill_value(out_dtype))
        out_var.setncattr('values', values_varname)
        out_var[:] = zones

        out_values = numpy.array([values_lookup[k] for k in range(0, len(values_lookup))])
        if netcdf3 and out_values.dtype == numpy.int64:
            out_values = out_values.astype('int32')

        out.createDimension(values_varname, len(out_values))
        values_var = out.createVariable(values_varname, out_values.dtype,
                                        dimensions=(values_varname, ),
                                        zlib=zip)
        values_var[:] = out_values
예제 #9
0
파일: mask.py 프로젝트: icpac-igad/trefoil
def mask(input, output, variable, like, netcdf3, all_touched, invert, zip):
    """
    Create a NetCDF mask from a shapefile.

    Values are equivalent to a numpy mask: 0 for unmasked areas, and 1 for masked areas.

    Template NetCDF dataset must have a valid projection defined or be inferred from dimensions (e.g., lat / long)
    """

    with Dataset(like) as template_ds:
        template_varname = data_variables(template_ds).keys()[0]
        template_variable = template_ds.variables[template_varname]
        template_crs = get_crs(template_ds, template_varname)

        if template_crs:
            template_crs = CRS.from_string(template_crs)
        elif is_geographic(template_ds, template_varname):
            template_crs = CRS({'init': 'EPSG:4326'})
        else:
            raise click.UsageError(
                'template dataset must have a valid projection defined')

        spatial_dimensions = template_variable.dimensions[-2:]
        mask_shape = template_variable.shape[-2:]

        template_y_name, template_x_name = spatial_dimensions
        coords = SpatialCoordinateVariables.from_dataset(
            template_ds,
            x_name=template_x_name,
            y_name=template_y_name,
            projection=Proj(**template_crs.to_dict()))

    with fiona.open(input, 'r') as shp:
        transform_required = CRS(shp.crs) != template_crs

        # Project bbox for filtering
        bbox = coords.bbox
        if transform_required:
            bbox = bbox.project(Proj(**shp.crs), edge_points=21)

        geometries = []
        for f in shp.filter(bbox=bbox.as_list()):
            geom = f['geometry']
            if transform_required:
                geom = transform_geom(shp.crs, template_crs, geom)

            geometries.append(geom)

    click.echo('Converting {0} features to mask'.format(len(geometries)))

    if invert:
        fill_value = 0
        default_value = 1
    else:
        fill_value = 1
        default_value = 0

    with rasterio.Env():
        # Rasterize features to 0, leaving background as 1
        mask = rasterize(geometries,
                         out_shape=mask_shape,
                         transform=coords.affine,
                         all_touched=all_touched,
                         fill=fill_value,
                         default_value=default_value,
                         dtype=numpy.uint8)

    format = 'NETCDF3_CLASSIC' if netcdf3 else 'NETCDF4'
    dtype = 'int8' if netcdf3 else 'uint8'

    with Dataset(output, 'w', format=format) as out:
        coords.add_to_dataset(out, template_x_name, template_y_name)
        out_var = out.createVariable(variable,
                                     dtype,
                                     dimensions=spatial_dimensions,
                                     zlib=zip,
                                     fill_value=get_fill_value(dtype))
        out_var[:] = mask
예제 #10
0
파일: mask.py 프로젝트: consbio/clover
def mask(
    input,
    output,
    variable,
    like,
    netcdf3,
    all_touched,
    invert,
    zip):

    """
    Create a NetCDF mask from a shapefile.

    Values are equivalent to a numpy mask: 0 for unmasked areas, and 1 for masked areas.

    Template NetCDF dataset must have a valid projection defined or be inferred from dimensions (e.g., lat / long)
    """

    with Dataset(like) as template_ds:
        template_varname = data_variables(template_ds).keys()[0]
        template_variable = template_ds.variables[template_varname]
        template_crs = get_crs(template_ds, template_varname)

        if template_crs:
            template_crs = CRS.from_string(template_crs)
        elif is_geographic(template_ds, template_varname):
            template_crs = CRS({'init': 'EPSG:4326'})
        else:
            raise click.UsageError('template dataset must have a valid projection defined')

        spatial_dimensions = template_variable.dimensions[-2:]
        mask_shape = template_variable.shape[-2:]

        template_y_name, template_x_name = spatial_dimensions
        coords = SpatialCoordinateVariables.from_dataset(
            template_ds,
            x_name=template_x_name,
            y_name=template_y_name,
            projection=Proj(**template_crs.to_dict())
        )


    with fiona.open(input, 'r') as shp:
        transform_required = CRS(shp.crs) != template_crs

        # Project bbox for filtering
        bbox = coords.bbox
        if transform_required:
            bbox = bbox.project(Proj(**shp.crs), edge_points=21)

        geometries = []
        for f in shp.filter(bbox=bbox.as_list()):
            geom = f['geometry']
            if transform_required:
                geom = transform_geom(shp.crs, template_crs, geom)

            geometries.append(geom)

    click.echo('Converting {0} features to mask'.format(len(geometries)))

    if invert:
        fill_value = 0
        default_value = 1
    else:
        fill_value = 1
        default_value = 0

    with rasterio.Env():
        # Rasterize features to 0, leaving background as 1
        mask = rasterize(
            geometries,
            out_shape=mask_shape,
            transform=coords.affine,
            all_touched=all_touched,
            fill=fill_value,
            default_value=default_value,
            dtype=numpy.uint8
        )

    format = 'NETCDF3_CLASSIC' if netcdf3 else 'NETCDF4'
    dtype = 'int8' if netcdf3 else 'uint8'

    with Dataset(output, 'w', format=format) as out:
        coords.add_to_dataset(out, template_x_name, template_y_name)
        out_var = out.createVariable(variable, dtype, dimensions=spatial_dimensions, zlib=zip,
                                     fill_value=get_fill_value(dtype))
        out_var[:] = mask