示例#1
0
def _plot_cells(x, y, mask=None, ax=None, **plot_opts):
    fig, ax = validate.mpl_ax(ax)

    ec = plot_opts.pop('edgecolor', None) or plot_opts.pop('ec', '0.125')
    fc = plot_opts.pop('facecolor', None) or plot_opts.pop('fc', '0.875')
    lw = plot_opts.pop('linewidth', None) or plot_opts.pop('lw', 0.75)

    rows, cols = x.shape
    if mask is None:
        if hasattr(x, 'mask'):
            mask = x.mask
        else:
            mask = np.zeros(x.shape)

    for jj in range(rows - 1):
        for ii in range(cols - 1):
            if mask[jj, ii]:
                coords = None

            else:
                coords = misc.make_poly_coords(
                    x[jj:jj + 2, ii:ii + 2],
                    y[jj:jj + 2, ii:ii + 2],
                )

            if coords is not None:
                rect = pyplot.Polygon(coords, edgecolor=ec, facecolor=fc,
                                      linewidth=lw, **plot_opts)
                ax.add_patch(rect)

    ax.margins(0.1, 0.1)

    return fig
示例#2
0
def test_make_poly_coords_base(masked, z, triangles):
    xarr = numpy.array([[1, 2], [1, 2]], dtype=float)
    yarr = numpy.array([[3, 3], [4, 4]], dtype=float)
    if masked is False:
        xarr = numpy.ma.masked_array(xarr, mask=False)
        yarr = numpy.ma.masked_array(yarr, mask=False)

    if z:
        expected = numpy.array([[1, 3, z], [2, 3, z], [2, 4, z], [1, 4, z]],
                               dtype=float)
    elif triangles:
        expected = numpy.array([[1, 3], [2, 4], [1, 4]], dtype=float)
        xarr[0, -1] = nan
        yarr[0, -1] = nan
    else:
        expected = numpy.array([[1, 3], [2, 3], [2, 4], [1, 4]], dtype=float)

    coords = misc.make_poly_coords(xarr, yarr, zpnt=z, triangles=triangles)
    nptest.assert_array_equal(coords, expected)
示例#3
0
def write_cells(X,
                Y,
                mask,
                crs,
                outputfile,
                river=None,
                reach=0,
                elev=None,
                triangles=False):
    """ Saves a GIS file of quadrilaterals representing grid cells.

    Parameters
    ----------
    X, Y : numpy (masked) arrays, same dimensions
        Attributes of the gridgen object representing the x- and y-coords.
    mask : numpy array or None
        Array describing which cells to mask (exclude) from the output.
        Shape should be N-1 by M-1, where N and M are the dimensions of
        `X` and `Y`.
    crs : string
        A geopandas/proj/fiona-compatible string describing the coordinate
        reference system of the x/y values.
    outputfile : string
        Path to the point GIS file to which the data will be written.
    river : optional string (default = None)
        The river to be listed in the GIS file's attribute table.
    reach : optional int (default = 0)
        The reach of the river to be listed in the GIS file's attribute
        table.
    elev : optional array or None (defauly)
        The elevation of the grid cells. Shape should be N-1 by M-1,
        where N and M are the dimensions of `X` and `Y` (like `mask`).
    triangles : optional bool (default = False)
        If True, triangles can be included

    Returns
    -------
    geopandas.GeoDataFrame

    """

    # check X, Y shapes
    Y = validate.elev_or_mask(X, Y, 'Y', offset=0)

    # check elev shape
    elev = validate.elev_or_mask(X, elev, 'elev', offset=0)

    # check the mask shape
    mask = validate.elev_or_mask(X, mask, 'mask', offset=1)

    X = numpy.ma.masked_invalid(X)
    Y = numpy.ma.masked_invalid(Y)
    ny, nx = X.shape

    row = 0
    geodata = []
    for ii in range(nx - 1):
        for jj in range(ny - 1):
            if not (numpy.any(X.mask[jj:jj + 2, ii:ii + 2]) or mask[jj, ii]):
                row += 1
                Z = elev[jj, ii]
                # build the array or coordinates
                coords = misc.make_poly_coords(xarr=X[jj:jj + 2, ii:ii + 2],
                                               yarr=Y[jj:jj + 2, ii:ii + 2],
                                               zpnt=Z,
                                               triangles=triangles)

                # build the attributes
                record = OrderedDict(id=row,
                                     river=river,
                                     reach=reach,
                                     ii=ii + 2,
                                     jj=jj + 2,
                                     elev=Z,
                                     ii_jj='{:02d}_{:02d}'.format(
                                         ii + 2, jj + 2),
                                     geometry=Polygon(shell=coords))

                # append to file is coordinates are not masked
                # (masked = beyond the river boundary)
                if coords is not None:
                    geodata.append(record)

    gdf = geopandas.GeoDataFrame(geodata, crs=crs, geometry='geometry')
    gdf.to_file(outputfile)
    return gdf
示例#4
0
def saveGridShapefile(X, Y, mask, template, outputfile, mode, river=None, reach=0, elev=None, triangles=False):
    """ Saves a shapefile of quadrilaterals representing grid cells.


    Parameters
    ----------
    X, Y : numpy (masked) arrays, same dimensions
        Attributes of the gridgen object representing the x- and y-coords.
    mask : numpy array or None
        Array describing which cells to mask (exclude) from the output.
        Shape should be N-1 by M-1, where N and M are the dimensions of
        `X` and `Y`.
    template : string
        Path to a template shapfiles with the desired schema.
    outputfile : string
        Path to the point shapefile to which the data will be written.
    mode : string
        The mode with which `outputfile` will be written.
        (i.e., 'a' for append and 'w' for write)
    river : optional string (default = None)
        The river to be listed in the shapefile's attribute table.
    reach : optional int (default = 0)
        The reach of the river to be listed in the shapefile's attribute
        table.
    elev : optional array or None (defauly)
        The elevation of the grid cells. Shape should be N-1 by M-1,
        where N and M are the dimensions of `X` and `Y` (like `mask`).
    triangles : optional bool (default = False)
        If True, triangles can be included

    Returns
    -------
    None

    """

    # check that `mode` is valid
    mode = validate.file_mode(mode)

    # check X, Y shapes
    Y = validate.elev_or_mask(X, Y, "Y", offset=0)

    # check elev shape
    elev = validate.elev_or_mask(X, elev, "elev", offset=0)

    # check the mask shape
    mask = validate.elev_or_mask(X, mask, "mask", offset=1)

    X = np.ma.masked_invalid(X)
    Y = np.ma.masked_invalid(Y)
    ny, nx = X.shape

    # load the template
    with fiona.open(template, "r") as src:
        src_driver = src.driver
        src_crs = src.crs
        src_schema = src.schema

    src_schema["geometry"] = "Polygon"

    # start writting or appending to the output
    with fiona.open(outputfile, mode, driver=src_driver, crs=src_crs, schema=src_schema) as out:
        row = 0
        for ii in range(nx - 1):
            for jj in range(ny - 1):
                if not (np.any(X.mask[jj : jj + 2, ii : ii + 2]) or mask[jj, ii]):
                    row += 1
                    Z = elev[jj, ii]
                    # build the array or coordinates
                    coords = misc.make_poly_coords(
                        xarr=X[jj : jj + 2, ii : ii + 2], yarr=Y[jj : jj + 2, ii : ii + 2], zpnt=Z, triangles=triangles
                    )

                    # build the attributes
                    props = OrderedDict(
                        id=row,
                        river=river,
                        reach=reach,
                        ii=ii + 2,
                        jj=jj + 2,
                        elev=Z,
                        ii_jj="{:02d}_{:02d}".format(ii + 2, jj + 2),
                    )

                    # append to file is coordinates are not masked
                    # (masked = beyond the river boundary)
                    if coords is not None:
                        record = misc.make_record(row, coords, "Polygon", props)
                        out.write(record)
示例#5
0
 def test_triangles(self):
     coords = misc.make_poly_coords(self.x_tri, self.y_tri, triangles=True)
     nptest.assert_array_equal(coords, self.known_triangle)
示例#6
0
 def test_with_z(self):
     coords = misc.make_poly_coords(self.xarr, self.yarr, zpnt=self.zpnt)
     nptest.assert_array_equal(coords, self.known_with_z)
示例#7
0
 def test_masked(self):
     xarr = np.ma.MaskedArray(self.xarr, mask=self.mask)
     yarr = np.ma.MaskedArray(self.yarr, mask=self.mask)
     coords = misc.make_poly_coords(xarr, yarr)
     nptest.assert_array_equal(coords, self.known_masked)
示例#8
0
 def test_base(self):
     coords = misc.make_poly_coords(self.xarr, self.yarr)
     nptest.assert_array_equal(coords, self.known_base)