Пример #1
0
def hob_resid_to_shapefile_all(mf,
                               stress_period=[0, -1],
                               shpname='hob_shapefile.shp'):

    get_vertices = mf.modelgrid.get_cell_vertices

    # get all files
    mfname = os.path.join(mf.model_ws, mf.namefile)
    mf_files = general_util.get_mf_files(mfname)

    # read mf and get spatial reference
    hobdf = hob_util.in_hob_to_df(mfname=mfname, return_model=False)

    # read_hob_out
    hobout_df = None
    for file in mf_files.keys():
        fn = mf_files[file][1]
        basename = os.path.basename(fn)
        if ".hob.out" in basename:
            hobout_df = pd.read_csv(fn, delim_whitespace=True)

    # loop over obs and compute residual error

    obs_names = hobdf['Basename'].unique()
    geoms = []
    all_rec = []
    for obs_ in obs_names:
        curr_hob = hobdf[hobdf['Basename'] == obs_]

        # trim data based on sptress period
        start = stress_period[0]
        endd = stress_period[1]
        if endd < 0:
            endd = hobdf['stress_period'].max()
        curr_hob = curr_hob[(curr_hob['stress_period'] >= start)
                            & (curr_hob['stress_period'] <= endd)]
        curr_hob_out = hobout_df[hobout_df['OBSERVATION NAME'].isin(
            curr_hob['name'].values)]
        err = curr_hob_out['OBSERVED VALUE'] - curr_hob_out[
            'SIMULATED EQUIVALENT']
        curr_hob['OBSERVED VALUE'] = curr_hob_out['OBSERVED VALUE'].values
        curr_hob['SIMULATED EQUIVALENT'] = curr_hob_out[
            'SIMULATED EQUIVALENT'].values
        curr_hob['err'] = err
        # n, mean, mse, mae
        #rec = [obs_, len(err), err.mean(), (err**2.0).mean()**0.5, (err.abs()).mean()]
        rrow = curr_hob['row'].values[0] - 1
        coll = curr_hob['col'].values[0] - 1
        xy = get_vertices(rrow, coll)
        for ierr in err:
            geoms.append(Point(xy[0][0], xy[0][1], 0))
        all_rec.append(curr_hob.copy())
    all_rec = pd.concat(all_rec)
    # here we generate csv file
    all_rec = all_rec.to_records()
    epsg = mf.modelgrid.epsg
    recarray2shp(all_rec, geoms, shpname, epsg=epsg)
    xxx = 1
Пример #2
0
def test_polygon_from_ij():
    """test creation of a polygon from an i, j location using get_vertices()."""
    m = flopy.modflow.Modflow('toy_model', model_ws=mpth)
    botm = np.zeros((2, 10, 10))
    botm[0, :, :] = 1.5
    botm[1, 5, 5] = 4  # negative layer thickness!
    botm[1, 6, 6] = 4
    dis = flopy.modflow.ModflowDis(nrow=10,
                                   ncol=10,
                                   nlay=2,
                                   delr=100,
                                   delc=100,
                                   top=3,
                                   botm=botm,
                                   model=m)

    m.sr = SpatialReference(delr=m.dis.delr * .3048,
                            delc=m.dis.delc * .3048,
                            xul=600000,
                            yul=5170000,
                            proj4_str='EPSG:26715',
                            rotation=-45)

    recarray = np.array([(0, 5, 5, .1, True, 's0'), (1, 4, 5, .2, False, 's1'),
                         (0, 7, 8, .3, True, 's2')],
                        dtype=[('k', '<i8'), ('i', '<i8'), ('j', '<i8'),
                               ('stuff', '<f4'), ('stuf', '|b1'),
                               ('stf', np.object)]).view(np.recarray)

    get_vertices = m.sr.get_vertices  # function to get the referenced vertices for a model cell
    geoms = [
        Polygon(get_vertices(i, j)) for i, j in zip(recarray.i, recarray.j)
    ]

    assert geoms[0].type == 'Polygon'
    assert np.abs(geoms[0].bounds[-1] - 5169784.473861726) < 1e-4
    fpth = os.path.join(mpth, 'test.shp')
    recarray2shp(recarray, geoms, fpth, epsg=26715)
    import epsgref
    reload(epsgref)
    from epsgref import prj
    assert 26715 in prj
    fpth = os.path.join(mpth, 'test.prj')
    fpth2 = os.path.join(mpth, '26715.prj')
    shutil.copy(fpth, fpth2)
    fpth = os.path.join(mpth, 'test.shp')
    recarray2shp(recarray, geoms, fpth, prj=fpth2)

    # test_dtypes
    fpth = os.path.join(mpth, 'test.shp')
    ra = shp2recarray(fpth)
    assert "int" in ra.dtype['k'].name
    assert "float" in ra.dtype['stuff'].name
    assert "bool" in ra.dtype['stuf'].name
    assert "object" in ra.dtype['stf'].name
    assert True
Пример #3
0
def test_polygon_from_ij():
    """test creation of a polygon from an i, j location using get_vertices()."""
    m = flopy.modflow.Modflow('toy_model', model_ws=mpth)
    botm = np.zeros((2, 10, 10))
    botm[0, :, :] = 1.5
    botm[1, 5, 5] = 4  # negative layer thickness!
    botm[1, 6, 6] = 4
    dis = flopy.modflow.ModflowDis(nrow=10, ncol=10,
                                   nlay=2, delr=100, delc=100,
                                   top=3, botm=botm, model=m)

    ncdf = NetCdf('toy.model.nc', m)
    ncdf.write()

    m.export('toy_model_two.nc')
    dis.export('toy_model_dis.nc')

    mg = m.modelgrid
    mg.set_coord_info(xoff=mg._xul_to_xll(600000.0, -45.0),
                      yoff=mg._yul_to_yll(5170000, -45.0),
                      angrot=-45.0, proj4='EPSG:26715')

    recarray = np.array([(0, 5, 5, .1, True, 's0'),
                         (1, 4, 5, .2, False, 's1'),
                         (0, 7, 8, .3, True, 's2')],
                        dtype=[('k', '<i8'), ('i', '<i8'), ('j', '<i8'),
                               ('stuff', '<f4'), ('stuf', '|b1'),
                               ('stf', np.object)]).view(np.recarray)

    # vertices for a model cell
    geoms = [Polygon(m.modelgrid.get_cell_vertices(i, j)) for i, j in
             zip(recarray.i, recarray.j)]

    assert geoms[0].type == 'Polygon'
    assert np.abs(geoms[0].bounds[-1] - 5169292.893203464) < 1e-4
    fpth = os.path.join(mpth, 'test.shp')
    recarray2shp(recarray, geoms, fpth, epsg=26715)
    ep = epsgRef()
    prj = ep.to_dict()
    assert 26715 in prj
    fpth = os.path.join(mpth, 'test.prj')
    fpth2 = os.path.join(mpth, '26715.prj')
    shutil.copy(fpth, fpth2)
    fpth = os.path.join(mpth, 'test.shp')
    recarray2shp(recarray, geoms, fpth, prj=fpth2)

    # test_dtypes
    fpth = os.path.join(mpth, 'test.shp')
    ra = shp2recarray(fpth)
    assert "int" in ra.dtype['k'].name
    assert "float" in ra.dtype['stuff'].name
    assert "bool" in ra.dtype['stuf'].name
    assert "object" in ra.dtype['stf'].name
    assert True
Пример #4
0
def point_to_shapefile(df, shpfile='temp_shp.shp', xy_field=[], epsg=None):
    """
    Convert a dataframe to shapefile.
    Returns
    -------
    """
    geoms = []
    for irec, rec in df.iterrows():
        x_ = rec[xy_field[0]]
        y_ = rec[xy_field[1]]
        geoms.append(Point(x_, y_, 0))
    att_table = df.to_records()
    recarray2shp(att_table, geoms, shpfile, epsg=epsg)
    pass
Пример #5
0
def export_contours(modelgrid,
                    filename,
                    contours,
                    fieldname='level',
                    epsg=None,
                    prj=None,
                    **kwargs):
    """Convert matplotlib contour plot object to shapefile.

    Parameters
    ----------
    filename : str
        path of output shapefile
    contours : matplotlib.contour.QuadContourSet or list of them
        (object returned by matplotlib.pyplot.contour)
    epsg : int
        EPSG code. See https://www.epsg-registry.org/ or spatialreference.org
    prj : str
        Existing projection file to be used with new shapefile.
    **kwargs : key-word arguments to flopy.export.shapefile_utils.recarray2shp

    Returns
    -------
    df : dataframe of shapefile contents
    """
    from flopy.utils.geometry import LineString
    from flopy.export.shapefile_utils import recarray2shp

    if not isinstance(contours, list):
        contours = [contours]

    if epsg is None:
        epsg = modelgrid.epsg
    if prj is None:
        prj = modelgrid.proj4

    geoms = []
    level = []
    for ctr in contours:
        levels = ctr.levels
        for i, c in enumerate(ctr.collections):
            paths = c.get_paths()
            geoms += [LineString(p.vertices) for p in paths]
            level += list(np.ones(len(paths)) * levels[i])

    # convert the dictionary to a recarray
    ra = np.array(level, dtype=[(fieldname, float)]).view(np.recarray)

    recarray2shp(ra, geoms, filename, epsg, prj, **kwargs)
Пример #6
0
def test_polygon_from_ij():
    """test creation of a polygon from an i, j location using get_vertices()."""
    m = flopy.modflow.Modflow('toy_model', model_ws=mpth)
    botm = np.zeros((2, 10, 10))
    botm[0, :, :] = 1.5
    botm[1, 5, 5] = 4  # negative layer thickness!
    botm[1, 6, 6] = 4
    dis = flopy.modflow.ModflowDis(nrow=10, ncol=10,
                                   nlay=2, delr=100, delc=100,
                                   top=3, botm=botm, model=m)

    m.sr = SpatialReference(delr=m.dis.delr * .3048, delc=m.dis.delc * .3048,
                            xul=600000, yul=5170000,
                            proj4_str='EPSG:26715', rotation=-45)

    recarray = np.array([(0, 5, 5, .1, True, 's0'),
                         (1, 4, 5, .2, False, 's1'),
                         (0, 7, 8, .3, True, 's2')],
                        dtype=[('k', '<i8'), ('i', '<i8'), ('j', '<i8'),
                               ('stuff', '<f4'), ('stuf', '|b1'),
                               ('stf', np.object)]).view(np.recarray)

    get_vertices = m.sr.get_vertices  # function to get the referenced vertices for a model cell
    geoms = [Polygon(get_vertices(i, j)) for i, j in
             zip(recarray.i, recarray.j)]

    assert geoms[0].type == 'Polygon'
    assert np.abs(geoms[0].bounds[-1] - 5169784.473861726) < 1e-4
    fpth = os.path.join(mpth, 'test.shp')
    recarray2shp(recarray, geoms, fpth, epsg=26715)
    import epsgref
    reload(epsgref)
    from epsgref import prj
    assert 26715 in prj
    fpth = os.path.join(mpth, 'test.prj')
    fpth2 = os.path.join(mpth, '26715.prj')
    shutil.copy(fpth, fpth2)
    fpth = os.path.join(mpth, 'test.shp')
    recarray2shp(recarray, geoms, fpth, prj=fpth2)

    # test_dtypes
    fpth = os.path.join(mpth, 'test.shp')
    ra = shp2recarray(fpth)
    assert "int" in ra.dtype['k'].name
    assert "float" in ra.dtype['stuff'].name
    assert "bool" in ra.dtype['stuf'].name
    assert "object" in ra.dtype['stf'].name
    assert True
Пример #7
0
    def write_shapefile(self, endpoint_data=None,
                        shpname='endpoings.shp',
                        direction='ending', sr=None, epsg=None,
                        **kwargs):
        """Write particle starting / ending locations to shapefile.

        endpoint_data : np.recarry
            Record array of same form as that returned by EndpointFile.get_alldata.
            (if none, EndpointFile.get_alldata() is exported).
        shpname : str
            File path for shapefile
        direction : str
            String defining if starting or ending particle locations should be
            considered. (default is 'ending')
        sr : flopy.utils.reference.SpatialReference instance
            Used to scale and rotate Global x,y,z values in MODPATH Endpoint file
        epsg : int
            EPSG code for writing projection (.prj) file. If this is not supplied,
            the proj4 string or epgs code associated with sr will be used.
        kwargs : keyword arguments to flopy.export.shapefile_utils.recarray2shp
        """
        from flopy.utils.reference import SpatialReference
        from flopy.utils.geometry import Point
        from flopy.export.shapefile_utils import recarray2shp

        epd = endpoint_data.copy()
        if epd is None:
            epd = self.get_alldata()

        if direction.lower() == 'ending':
            xcol, ycol, zcol = 'x', 'y', 'z'
        elif direction.lower() == 'starting':
            xcol, ycol, zcol = 'x0', 'y0', 'z0'
        else:
            errmsg = 'flopy.map.plot_endpoint direction must be "ending" ' + \
                     'or "starting".'
            raise Exception(errmsg)
        if sr is None:
            sr = SpatialReference()
        x, y = sr.transform(epd[xcol], epd[ycol])
        z = epd[zcol]

        geoms = [Point(x[i], y[i], z[i]) for i in range(len(epd))]
        # convert back to one-based
        for n in self.kijnames:
            epd[n] += 1
        recarray2shp(epd, geoms, shpname=shpname, epsg=epsg, **kwargs)
Пример #8
0
def export_contours(modelgrid, filename, contours,
                    fieldname='level', epsg=None, prj=None,
                    **kwargs):
    """Convert matplotlib contour plot object to shapefile.

    Parameters
    ----------
    filename : str
        path of output shapefile
    contours : matplotlib.contour.QuadContourSet or list of them
        (object returned by matplotlib.pyplot.contour)
    epsg : int
        EPSG code. See https://www.epsg-registry.org/ or spatialreference.org
    prj : str
        Existing projection file to be used with new shapefile.
    **kwargs : key-word arguments to flopy.export.shapefile_utils.recarray2shp

    Returns
    -------
    df : dataframe of shapefile contents
    """
    from flopy.utils.geometry import LineString
    from flopy.export.shapefile_utils import recarray2shp

    if not isinstance(contours, list):
        contours = [contours]

    if epsg is None:
        epsg = modelgrid.epsg
    if prj is None:
        prj = modelgrid.proj4

    geoms = []
    level = []
    for ctr in contours:
        levels = ctr.levels
        for i, c in enumerate(ctr.collections):
            paths = c.get_paths()
            geoms += [LineString(p.vertices) for p in paths]
            level += list(np.ones(len(paths)) * levels[i])

    # convert the dictionary to a recarray
    ra = np.array(level,
                  dtype=[(fieldname, float)]).view(np.recarray)

    recarray2shp(ra, geoms, filename, epsg, prj, **kwargs)
Пример #9
0
def test_polygon_from_ij():
    """test creation of a polygon from an i, j location using get_vertices()."""
    m = flopy.modflow.Modflow("toy_model", model_ws="temp")
    botm = np.zeros((2, 10, 10))
    botm[0, :, :] = 1.5
    botm[1, 5, 5] = 4  # negative layer thickness!
    botm[1, 6, 6] = 4
    dis = flopy.modflow.ModflowDis(nrow=10, ncol=10, nlay=2, delr=100, delc=100, top=3, botm=botm, model=m)

    m.sr = SpatialReference(
        delr=m.dis.delr * 0.3048,
        delc=m.dis.delc * 0.3048,
        xul=600000,
        yul=5170000,
        proj4_str="EPSG:26715",
        rotation=-45,
    )

    recarray = np.array(
        [(0, 5, 5, 0.1, True, "s0"), (1, 4, 5, 0.2, False, "s1"), (0, 7, 8, 0.3, True, "s2")],
        dtype=[("k", "<i8"), ("i", "<i8"), ("j", "<i8"), ("stuff", "<f4"), ("stuf", "|b1"), ("stf", np.object)],
    ).view(np.recarray)

    get_vertices = m.sr.get_vertices  # function to get the referenced vertices for a model cell
    geoms = [Polygon(get_vertices(i, j)) for i, j in zip(recarray.i, recarray.j)]

    assert geoms[0].type == "Polygon"
    assert geoms[0].bounds[-1] - 5169784.473861726 < 1e-6
    recarray2shp(recarray, geoms, "temp/test.shp", epsg=26715)
    import epsgref

    reload(epsgref)
    from epsgref import prj

    assert 26715 in prj
    shutil.copy("temp/test.prj", "temp/26715.prj")
    recarray2shp(recarray, geoms, "temp/test.shp", prj="temp/26715.prj")
Пример #10
0
def mflist_export(f, mfl, **kwargs):
    """
    export helper for MfList instances

    Parameters
    -----------
        f : string (filename) or existing export instance type
        (NetCdf only for now)
        mfl : MfList instance

    """
    assert isinstance(mfl, DataListInterface) and \
           isinstance(mfl, DataInterface) \
        , "mflist_helper only helps instances that support DataListInterface"

    if isinstance(f, str) and f.lower().endswith(".nc"):
        f = NetCdf(f, mfl.model)

    if isinstance(f, str) and f.lower().endswith(".shp"):
        sparse = kwargs.get("sparse", False)
        kper = kwargs.get("kper", 0)
        squeeze = kwargs.get("squeeze", True)

        model_grid = mfl.model.modelgrid

        if model_grid is None:
            raise Exception("MfList.to_shapefile: ModelGrid is not set")
        elif model_grid.grid_type == 'USG-Unstructured':
            raise Exception('Flopy does not support exporting to shapefile '
                            'from a MODFLOW-USG unstructured grid.')

        if kper is None:
            keys = mfl.data.keys()
            keys.sort()
        else:
            keys = [kper]
        if not sparse:
            array_dict = {}
            for kk in keys:
                arrays = mfl.to_array(kk)
                for name, array in arrays.items():
                    for k in range(array.shape[0]):
                        # aname = name+"{0:03d}_{1:02d}".format(kk, k)
                        n = shapefile_utils.shape_attr_name(name, length=4)
                        aname = "{}{}{}".format(n, k + 1, int(kk) + 1)
                        array_dict[aname] = array[k]
            shapefile_utils.write_grid_shapefile2(f, model_grid, array_dict)
        else:
            from ..export.shapefile_utils import recarray2shp
            from ..utils.geometry import Polygon
            #if np.isscalar(kper):
            #    kper = [kper]
            model_grid = mfl.mg
            df = mfl.get_dataframe(squeeze=squeeze)
            if 'kper' in kwargs or df is None:
                ra = mfl[kper]
                verts = np.array(model_grid.get_cell_vertices(ra.i, ra.j))
            elif df is not None:
                verts = np.array([model_grid.get_cell_vertices(i, df.j.values[ix])
                                  for ix, i in enumerate(df.i.values)])
                ra = df.to_records(index=False)
            epsg = kwargs.get('epsg', None)
            prj = kwargs.get('prj', None)
            polys = np.array([Polygon(v) for v in verts])
            recarray2shp(ra, geoms=polys, shpname=f,
                         mg=model_grid, epsg=epsg, prj=prj)

    elif isinstance(f, NetCdf) or isinstance(f, dict):
        base_name = mfl.package.name[0].lower()
        # f.log("getting 4D masked arrays for {0}".format(base_name))
        # m4d = mfl.masked_4D_arrays
        # f.log("getting 4D masked arrays for {0}".format(base_name))

        # for name, array in m4d.items():
        for name, array in mfl.masked_4D_arrays_itr():
            var_name = base_name + '_' + name
            if isinstance(f, dict):
                f[var_name] = array
                continue
            f.log("processing {0} attribute".format(name))

            units = None
            if var_name in NC_UNITS_FORMAT:
                units = NC_UNITS_FORMAT[var_name].format(f.grid_units,
                                                         f.time_units)
            precision_str = NC_PRECISION_TYPE[mfl.dtype[name].type]
            if var_name in NC_LONG_NAMES:
                attribs = {"long_name": NC_LONG_NAMES[var_name]}
            else:
                attribs = {"long_name": var_name}
            attribs["coordinates"] = "time layer latitude longitude"
            attribs["min"] = np.nanmin(array)
            attribs["max"] = np.nanmax(array)
            if np.isnan(attribs["min"]) or np.isnan(attribs["max"]):
                raise Exception(
                    "error processing {0}: all NaNs".format(var_name))

            if units is not None:
                attribs["units"] = units
            try:
                dim_tuple = ("time",) + f.dimension_names
                var = f.create_variable(var_name, attribs,
                                        precision_str=precision_str,
                                        dimensions=dim_tuple)
            except Exception as e:
                estr = "error creating variable {0}:\n{1}".format(var_name,
                                                                  str(e))
                f.logger.warn(estr)
                raise Exception(estr)

            array[np.isnan(array)] = f.fillvalue
            try:
                var[:] = array
            except Exception as e:
                estr = "error setting array to variable {0}:\n{1}".format(
                    var_name, str(e))
                f.logger.warn(estr)
                raise Exception(estr)
            f.log("processing {0} attribute".format(name))

        return f
    else:
        raise NotImplementedError("unrecognized export argument:{0}".format(f))
Пример #11
0
    def write_shapefile(self, pathline_data=None,
                        one_per_particle=True,
                        direction='ending',
                        shpname='endpoings.shp',
                        sr=None, epsg=None,
                        **kwargs):
        """Write pathlines to shapefile.

        pathline_data : np.recarry
            Record array of same form as that returned by EndpointFile.get_alldata.
            (if none, EndpointFile.get_alldata() is exported).
        one_per_particle : boolean (default True)
            True writes a single LineString with a single set of attribute data for each
            particle. False writes a record/geometry for each pathline segment
            (each row in the PathLine file). This option can be used to visualize
            attribute information (time, model layer, etc.) across a pathline in a GIS.
        direction : str
            String defining if starting or ending particle locations should be
            included in shapefile attribute information. Only used if one_per_particle=False.
            (default is 'ending')
        shpname : str
            File path for shapefile
        sr : flopy.utils.reference.SpatialReference instance
            Used to scale and rotate Global x,y,z values in MODPATH Endpoint file
        epsg : int
            EPSG code for writing projection (.prj) file. If this is not supplied,
            the proj4 string or epgs code associated with sr will be used.
        kwargs : keyword arguments to flopy.export.shapefile_utils.recarray2shp
        """
        from flopy.utils.reference import SpatialReference
        from flopy.utils.geometry import LineString
        from flopy.export.shapefile_utils import recarray2shp

        pth = pathline_data
        if pth is None:
            pth = self._data.view(np.recarray)
        pth = pth.copy()
        pth.sort(order=['particleid', 'time'])

        if sr is None:
            sr = SpatialReference()

        particles = np.unique(pth.particleid)
        geoms = []

        # 1 geometry for each path
        if one_per_particle:

            loc_inds = 0
            if direction == 'ending':
                loc_inds = -1

            pthdata = []
            for pid in particles:
                ra = pth[pth.particleid == pid]

                x, y = sr.transform(ra.x, ra.y)
                z = ra.z
                geoms.append(LineString(list(zip(x, y, z))))
                pthdata.append((pid,
                                ra.particlegroup[0],
                                ra.time.max(),
                                ra.k[loc_inds],
                                ra.i[loc_inds],
                                ra.j[loc_inds]))
            pthdata = np.array(pthdata, dtype=[('particleid', np.int),
                                               ('particlegroup', np.int),
                                               ('time', np.float),
                                               ('k', np.int),
                                               ('i', np.int),
                                               ('j', np.int)
                                               ]).view(np.recarray)
        # geometry for each row in PathLine file
        else:
            dtype = pth.dtype
            #pthdata = np.empty((0, len(dtype)), dtype=dtype).view(np.recarray)
            pthdata = []
            for pid in particles:
                ra = pth[pth.particleid == pid]
                x, y = sr.transform(ra.x, ra.y)
                z = ra.z
                geoms += [LineString([(x[i-1], y[i-1], z[i-1]),
                                          (x[i], y[i], z[i])])
                             for i in np.arange(1, (len(ra)))]
                #pthdata = np.append(pthdata, ra[1:]).view(np.recarray)
                pthdata += ra[1:].tolist()
            pthdata = np.array(pthdata, dtype=dtype).view(np.recarray)
        # convert back to one-based
        for n in set(self.kijnames).intersection(set(pthdata.dtype.names)):
            pthdata[n] += 1
        recarray2shp(pthdata, geoms, shpname=shpname, epsg=sr.epsg, **kwargs)
Пример #12
0
def test_polygon_from_ij():
    """test creation of a polygon from an i, j location using get_vertices()."""
    m = flopy.modflow.Modflow("toy_model", model_ws=mpth)
    botm = np.zeros((2, 10, 10))
    botm[0, :, :] = 1.5
    botm[1, 5, 5] = 4  # negative layer thickness!
    botm[1, 6, 6] = 4
    dis = flopy.modflow.ModflowDis(
        nrow=10, ncol=10, nlay=2, delr=100, delc=100, top=3, botm=botm, model=m
    )

    fname = os.path.join(mpth, "toy.model.nc")
    ncdf = NetCdf(fname, m)
    ncdf.write()

    fname = os.path.join(mpth, "toy_model_two.nc")
    m.export(fname)

    fname = os.path.join(mpth, "toy_model_dis.nc")
    dis.export(fname)

    mg = m.modelgrid
    mg.set_coord_info(
        xoff=mg._xul_to_xll(600000.0, -45.0),
        yoff=mg._yul_to_yll(5170000, -45.0),
        angrot=-45.0,
        proj4="EPSG:26715",
    )

    recarray = np.array(
        [
            (0, 5, 5, 0.1, True, "s0"),
            (1, 4, 5, 0.2, False, "s1"),
            (0, 7, 8, 0.3, True, "s2"),
        ],
        dtype=[
            ("k", "<i8"),
            ("i", "<i8"),
            ("j", "<i8"),
            ("stuff", "<f4"),
            ("stuf", "|b1"),
            ("stf", object),
        ],
    ).view(np.recarray)

    # vertices for a model cell
    geoms = [
        Polygon(m.modelgrid.get_cell_vertices(i, j))
        for i, j in zip(recarray.i, recarray.j)
    ]

    assert geoms[0].type == "Polygon"
    assert np.abs(geoms[0].bounds[-1] - 5169292.893203464) < 1e-4
    fpth = os.path.join(mpth, "test.shp")
    recarray2shp(recarray, geoms, fpth, epsg=26715)
    ep = EpsgReference()
    prj = ep.to_dict()
    assert 26715 in prj
    fpth = os.path.join(mpth, "test.prj")
    fpth2 = os.path.join(mpth, "26715.prj")
    shutil.copy(fpth, fpth2)
    fpth = os.path.join(mpth, "test.shp")
    recarray2shp(recarray, geoms, fpth, prj=fpth2)

    # test_dtypes
    fpth = os.path.join(mpth, "test.shp")
    ra = shp2recarray(fpth)
    assert "int" in ra.dtype["k"].name
    assert "float" in ra.dtype["stuff"].name
    assert "bool" in ra.dtype["stuf"].name
    assert "object" in ra.dtype["stf"].name
    assert True
Пример #13
0
def mflist_export(f, mfl, **kwargs):
    """ export helper for MfList instances

    Parameters
    -----------
        f : string (filename) or existing export instance type (NetCdf only for now)
        mfl : MfList instance

    """
    assert isinstance(mfl, DataListInterface) and \
           isinstance(mfl, DataInterface) \
        , "mflist_helper only helps instances that support DataListInterface"

    if isinstance(f, str) and f.lower().endswith(".nc"):
        f = NetCdf(f, mfl.model)

    if isinstance(f, str) and f.lower().endswith(".shp"):
        sparse = kwargs.get("sparse", False)
        kper = kwargs.get("kper", 0)
        squeeze = kwargs.get("squeeze", True)

        model_grid = mfl.model.modelgrid

        if model_grid is None:
            raise Exception("MfList.to_shapefile: ModelGrid is not set")
        import flopy.utils.flopy_io as fio
        if kper is None:
            keys = mfl.data.keys()
            keys.sort()
        else:
            keys = [kper]
        if not sparse:
            array_dict = {}
            for kk in keys:
                arrays = mfl.to_array(kk)
                for name, array in arrays.items():
                    for k in range(array.shape[0]):
                        # aname = name+"{0:03d}_{1:02d}".format(kk, k)
                        n = shapefile_utils.shape_attr_name(name, length=4)
                        aname = "{}{}{}".format(n, k + 1, int(kk) + 1)
                        array_dict[aname] = array[k]
            shapefile_utils.write_grid_shapefile2(f, model_grid, array_dict)
        else:
            from ..export.shapefile_utils import recarray2shp
            from ..utils.geometry import Polygon
            #if np.isscalar(kper):
            #    kper = [kper]
            model_grid = mfl.mg
            df = mfl.get_dataframe(squeeze=squeeze)
            if 'kper' in kwargs or df is None:
                ra = mfl[kper]
                verts = np.array(model_grid.get_cell_vertices(ra.i, ra.j))
            elif df is not None:
                verts = np.array([model_grid.get_cell_vertices(i, df.j.values[ix])
                                  for ix, i in enumerate(df.i.values)])
                ra = df.to_records(index=False)
            epsg = kwargs.get('epsg', None)
            prj = kwargs.get('prj', None)
            polys = np.array([Polygon(v) for v in verts])
            recarray2shp(ra, geoms=polys, shpname=f,
                         mg=model_grid, epsg=epsg, prj=prj)

    elif isinstance(f, NetCdf) or isinstance(f, dict):
        base_name = mfl.package.name[0].lower()
        # f.log("getting 4D masked arrays for {0}".format(base_name))
        # m4d = mfl.masked_4D_arrays
        # f.log("getting 4D masked arrays for {0}".format(base_name))

        # for name, array in m4d.items():
        for name, array in mfl.masked_4D_arrays_itr():
            var_name = base_name + '_' + name
            if isinstance(f, dict):
                f[var_name] = array
                continue
            f.log("processing {0} attribute".format(name))

            units = None
            if var_name in NC_UNITS_FORMAT:
                units = NC_UNITS_FORMAT[var_name].format(f.grid_units,
                                                         f.time_units)
            precision_str = NC_PRECISION_TYPE[mfl.dtype[name].type]
            if var_name in NC_LONG_NAMES:
                attribs = {"long_name": NC_LONG_NAMES[var_name]}
            else:
                attribs = {"long_name": var_name}
            attribs["coordinates"] = "time layer latitude longitude"
            attribs["min"] = np.nanmin(array)
            attribs["max"] = np.nanmax(array)
            if np.isnan(attribs["min"]) or np.isnan(attribs["max"]):
                raise Exception(
                    "error processing {0}: all NaNs".format(var_name))

            if units is not None:
                attribs["units"] = units
            try:
                dim_tuple = ("time",) + f.dimension_names
                var = f.create_variable(var_name, attribs,
                                        precision_str=precision_str,
                                        dimensions=dim_tuple)
            except Exception as e:
                estr = "error creating variable {0}:\n{1}".format(var_name,
                                                                  str(e))
                f.logger.warn(estr)
                raise Exception(estr)

            array[np.isnan(array)] = f.fillvalue
            try:
                var[:] = array
            except Exception as e:
                estr = "error setting array to variable {0}:\n{1}".format(
                    var_name, str(e))
                f.logger.warn(estr)
                raise Exception(estr)
            f.log("processing {0} attribute".format(name))

        return f
    else:
        raise NotImplementedError("unrecognized export argument:{0}".format(f))