コード例 #1
1
def test_export():
    fm = flopy.modflow
    m = fm.Modflow()
    dis = fm.ModflowDis(m, 1, 10, 10, lenuni=2, itmuni=4)
    m.sr = SpatialReference(delr=m.dis.delr.array, delc=m.dis.delc.array)
    m.sr.write_shapefile(os.path.join(outpath, 'grid.shp'))
    r, d = create_sfr_data()
    sfr = flopy.modflow.ModflowSfr2(m, reach_data=r, segment_data={0: d})
    sfr.segment_data[0]['flow'][-1] = 1e4
    sfr.stress_period_data.export(os.path.join(outpath, 'sfr.shp'),
                                  sparse=True)
    sfr.export_linkages(os.path.join(outpath, 'linkages.shp'))
    sfr.export_outlets(os.path.join(outpath, 'outlets.shp'))
    sfr.export_transient_variable(os.path.join(outpath, 'inlets.shp'), 'flow')

    from flopy.export.shapefile_utils import shp2recarray
    ra = shp2recarray(os.path.join(outpath, 'inlets.shp'))
    assert ra.flow0[0] == 1e4
    ra = shp2recarray(os.path.join(outpath, 'outlets.shp'))
    assert ra.iseg[0] + ra.ireach[0] == 5
    ra = shp2recarray(os.path.join(outpath, 'linkages.shp'))
    crds = np.array(list(ra.geometry[2].coords))
    assert np.array_equal(crds, np.array([[2.5, 4.5], [3.5, 5.5]]))
    ra = shp2recarray(os.path.join(outpath, 'sfr.shp'))
    assert ra.iseg0.sum() == sfr.reach_data.iseg.sum()
    assert ra.ireach0.sum() == sfr.reach_data.ireach.sum()
    y = np.concatenate([np.array(g.exterior)[:, 1] for g in ra.geometry])
    x = np.concatenate([np.array(g.exterior)[:, 0] for g in ra.geometry])
    assert (x.min(), y.min(), x.max(), y.max()) == m.sr.bounds
    assert ra[(ra.iseg0 == 2) & (ra.ireach0 == 1)]['geometry'][0].bounds \
        == (6.0, 2.0, 7.0, 3.0)
コード例 #2
0
ファイル: t007_test.py プロジェクト: yinzongmin/flopy
def test_get_vertices():
    from flopy.utils.reference import SpatialReference
    from flopy.discretization import StructuredGrid
    m = flopy.modflow.Modflow(rotation=20.)
    nrow, ncol = 40, 20
    dis = flopy.modflow.ModflowDis(m,
                                   nlay=1,
                                   nrow=nrow,
                                   ncol=ncol,
                                   delr=250.,
                                   delc=250.,
                                   top=10,
                                   botm=0)
    xul, yul = 500000, 2934000
    sr = SpatialReference(delc=m.dis.delc.array,
                          xul=xul,
                          yul=yul,
                          rotation=45.)
    mg = StructuredGrid(delc=m.dis.delc.array,
                        delr=m.dis.delr.array,
                        xoff=sr.xll,
                        yoff=sr.yll,
                        angrot=sr.rotation)

    xgrid = mg.xvertices
    ygrid = mg.yvertices
    # a1 = np.array(mg.xyvertices)
    a1 = np.array([[xgrid[0, 0], ygrid[0, 0]], [xgrid[0, 1], ygrid[0, 1]],
                   [xgrid[1, 1], ygrid[1, 1]], [xgrid[1, 0], ygrid[1, 0]]])

    a2 = np.array(mg.get_cell_vertices(0, 0))
    assert np.array_equal(a1, a2)
コード例 #3
0
ファイル: t007_test.py プロジェクト: brclark-usgs/flopy
def test_read_usgs_model_reference():
    nlay, nrow, ncol = 1, 30, 5
    delr, delc = 250, 500
    #xll, yll = 272300, 5086000
    model_ws = os.path.join('temp', 't007')
    shutil.copy('../examples/data/usgs.model.reference', model_ws)
    fm = flopy.modflow
    m = fm.Modflow(modelname='junk', model_ws=model_ws)
    # feet and days
    dis = fm.ModflowDis(m, nlay=nlay, nrow=nrow, ncol=ncol, delr=delr,
                        delc=delc, lenuni=1, itmuni=4)
    m.write_input()

    # test reading of SR information from usgs.model.reference
    m2 = fm.Modflow.load('junk.nam', model_ws=os.path.join('temp', 't007'))
    from flopy.utils.reference import SpatialReference
    d = SpatialReference.read_usgs_model_reference_file(os.path.join('temp', 't007', 'usgs.model.reference'))
    assert m2.sr.xul == d['xul']
    assert m2.sr.yul == d['yul']
    assert m2.sr.rotation == d['rotation']
    assert m2.sr.lenuni == d['lenuni']
    assert m2.sr.epsg == d['epsg']
    # have to delete this, otherwise it will mess up other tests
    if os.path.exists(os.path.join(tpth, 'usgs.model.reference')):
        os.remove(os.path.join(tpth, 'usgs.model.reference'))
コード例 #4
0
    def _set_spatialreference(self):
        """
        Define structured or unstructured spatial reference based on
        MODFLOW 6 discretization type.
        Returns
        -------
        sr : SpatialReference
        """
        sr = None
        try:
            if self._grid == 'DISV' or self._grid == 'DISU':
                try:
                    iverts, verts = self.get_verts()
                    vertc = self.get_centroids()
                    xc = vertc[:, 0]
                    yc = vertc[:, 1]
                    sr = SpatialReferenceUnstructured(xc, yc, verts, iverts,
                                                      [xc.shape[0]])
                except:
                    msg = 'could not set spatial reference for ' + \
                          '{} discretization '.format(self._grid) + \
                          'defined in {}'.format(self.file.name)
                    print(msg)
            elif self._grid == 'DIS':
                delr, delc = self._datadict['DELR'], self._datadict['DELC']
                xorigin, yorigin, rot = self._datadict['XORIGIN'], \
                                        self._datadict['YORIGIN'], \
                                        self._datadict['ANGROT']
                sr = SpatialReference(delr=delr, delc=delc,
                                      xll=xorigin, yll=yorigin, rotation=rot)
        except:
            print('could not set spatial reference for {}'.format(
                self.file.name))

        return sr
コード例 #5
0
ファイル: modpathfile.py プロジェクト: emorway-usgs/flopy
    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)
コード例 #6
0
ファイル: t032_test.py プロジェクト: verkaik/flopy
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 test_read_usgs_model_reference():
    nlay, nrow, ncol = 1, 30, 5
    delr, delc = 250, 500
    #xll, yll = 272300, 5086000
    model_ws = os.path.join('temp', 't007')
    mrf = os.path.join(model_ws, 'usgs.model.reference')
    shutil.copy('../examples/data/usgs.model.reference', mrf)
    fm = flopy.modflow
    m = fm.Modflow(modelname='junk', model_ws=model_ws)
    # feet and days
    dis = fm.ModflowDis(m,
                        nlay=nlay,
                        nrow=nrow,
                        ncol=ncol,
                        delr=delr,
                        delc=delc,
                        lenuni=1,
                        itmuni=4)
    m.write_input()

    # test reading of SR information from usgs.model.reference
    m2 = fm.Modflow.load('junk.nam', model_ws=os.path.join('temp', 't007'))
    from flopy.utils.reference import SpatialReference
    d = SpatialReference.read_usgs_model_reference_file(mrf)
    assert m2.sr.xul == d['xul']
    assert m2.sr.yul == d['yul']
    assert m2.sr.rotation == d['rotation']
    assert m2.sr.lenuni == d['lenuni']
    assert m2.sr.epsg == d['epsg']

    # test reading non-default units from usgs.model.reference
    shutil.copy(mrf, mrf + '_copy')
    with open(mrf + '_copy') as src:
        with open(mrf, 'w') as dst:
            for line in src:
                if 'time_unit' in line:
                    line = line.replace('days', 'seconds')
                elif 'length_units' in line:
                    line = line.replace('feet', 'meters')
                dst.write(line)
    m2 = fm.Modflow.load('junk.nam', model_ws=os.path.join('temp', 't007'))
    assert m2.tr.itmuni == 1
    assert m2.sr.lenuni == 2
    # have to delete this, otherwise it will mess up other tests
    to_del = glob.glob(mrf + '*')
    for f in to_del:
        if os.path.exists(f):
            os.remove(os.path.join(f))
    assert True
コード例 #8
0
ファイル: itobes.py プロジェクト: mattijn/HL_FloPyCourse
    def init_model(self, bron_data):
        """
        Initiziation of the model starts with the Modflow object and spatial and 
        temporal discretization parameters of the DIS package
        
        Parameters
        ----------
        bron_data : dict
            dictionary containing data to build up the model        
        """

        mf = flopy.modflow.Modflow(
            bron_data["modelname"],
            exe_name=bron_data["exe_name"],
            model_ws=bron_data["model_ws"],
        )  # --> needed when using UPW insted of LPF, version='mfnwt')

        # apply the spatial and temporal discretization parameters to the DIS package
        mf_dis = flopy.modflow.ModflowDis(
            mf,
            nlay=self.dis["nlays"],
            nrow=self.dis["nrow"],
            ncol=self.dis["ncol"],
            delr=self.dis["delr"],
            delc=self.dis["delc"],
            top=self.dis["top"],
            botm=self.dis["botm"],
            nper=self.dis["nper"],
            perlen=self.dis["perlen"],
            nstp=self.dis["nstp"],
            steady=self.dis["steady"],
        )

        mf.dis.sr = SpatialReference(
            delr=self.dis["delr"],
            delc=self.dis["delc"],
            xul=self.dis["bbox_large"][0],
            yul=self.dis["bbox_large"][3],
            epsg=28992,
        )

        mf.modelgrid.set_coord_info(
            xoff=self.dis["bbox_large"][0],
            yoff=self.dis["bbox_large"][3] - self.dis["delc"].sum(),
            epsg=28992,
        )

        self.mf = mf
コード例 #9
0
ファイル: map.py プロジェクト: emorway-usgs/flopy
    def __init__(self, sr=None, ax=None, model=None, dis=None, layer=0,
                 extent=None,
                 xul=None, yul=None, xll=None, yll=None, rotation=0., length_multiplier=1.):
        self.model = model
        self.layer = layer
        self.dis = dis
        self.sr = None
        if sr is not None:
            self.sr = copy.deepcopy(sr)
        elif dis is not None:
            # print("warning: the dis arg to model map is deprecated")
            self.sr = copy.deepcopy(dis.parent.sr)
        elif model is not None:
            # print("warning: the model arg to model map is deprecated")
            self.sr = copy.deepcopy(model.sr)
        else:
            self.sr = SpatialReference(xll, yll, xul, yul, rotation, length_multiplier)

        # model map override spatial reference settings
        if any(elem is not None for elem in (xul, yul, xll, yll)) or rotation != 0 or length_multiplier != 1.:
            self.sr.set_spatialreference(xul, yul, xll, yll, rotation, length_multiplier)
        '''
        if xul is not None and yul is not None:
            self.sr.xul = xul
        if yul is not None:
            self.sr.yul = yul
        if rotation is not None:
            self.sr.rotation = rotation
        '''
        if ax is None:
            try:
                self.ax = plt.gca()
                self.ax.set_aspect('equal')
            except:
                self.ax = plt.subplot(1, 1, 1, aspect='equal', axisbg="white")
        else:
            self.ax = ax
        if extent is not None:
            self._extent = extent
        else:
            self._extent = None

        # why is this non-default color scale used??
        #  This should be passed as a kwarg by the user to the indivudual plotting method.
        # self.cmap = plotutil.viridis

        return
コード例 #10
0
    def _set_spatialreference(self):
        """
        Define structured or unstructured spatial reference based on
        MODFLOW 6 discretization type.
        Returns
        -------
        sr : SpatialReference
        """
        sr = None
        try:
            if self._grid == "DISV" or self._grid == "DISU":
                try:
                    iverts, verts = self.get_verts()
                    vertc = self.get_centroids()
                    xc = vertc[:, 0]
                    yc = vertc[:, 1]
                    sr = SpatialReferenceUnstructured(
                        xc, yc, verts, iverts, [xc.shape[0]]
                    )
                except:
                    msg = (
                        "could not set spatial reference for "
                        + "{} discretization ".format(self._grid)
                        + "defined in {}".format(self.file.name)
                    )
                    print(msg)
            elif self._grid == "DIS":
                delr, delc = self._datadict["DELR"], self._datadict["DELC"]
                xorigin, yorigin, rot = (
                    self._datadict["XORIGIN"],
                    self._datadict["YORIGIN"],
                    self._datadict["ANGROT"],
                )
                sr = SpatialReference(
                    delr=delr,
                    delc=delc,
                    xll=xorigin,
                    yll=yorigin,
                    rotation=rot,
                )
        except:
            print(
                "could not set spatial reference for {}".format(self.file.name)
            )

        return sr
コード例 #11
0
def test_write_shapefile():
    from flopy.utils.reference import SpatialReference
    from flopy.export.shapefile_utils import shp2recarray
    from flopy.export.shapefile_utils import write_grid_shapefile, write_grid_shapefile2

    sr = SpatialReference(
        delr=np.ones(10) * 1.1,  # cell spacing along model rows
        delc=np.ones(10) * 1.1,  # cell spacing along model columns
        epsg=26715,
        lenuni=1  # MODFLOW length units
    )
    vrts = copy.deepcopy(sr.vertices)
    outshp1 = os.path.join(tpth, 'junk.shp')
    outshp2 = os.path.join(tpth, 'junk2.shp')
    write_grid_shapefile(outshp1, sr, array_dict={})
    write_grid_shapefile2(outshp2, sr, array_dict={})

    # test that vertices aren't getting altered by writing shapefile
    assert np.array_equal(vrts, sr.vertices)
    for outshp in [outshp1, outshp2]:
        # check that pyshp reads integers
        # this only check that row/column were recorded as "N"
        # not how they will be cast by python or numpy
        import shapefile as sf
        sfobj = sf.Reader(outshp)
        for f in sfobj.fields:
            if f[0] == 'row' or f[0] == 'column':
                assert f[1] == 'N'
        recs = list(sfobj.records())
        for r in recs[0]:
            assert isinstance(r, int)

        # check that row and column appear as integers in recarray
        ra = shp2recarray(outshp)
        assert np.issubdtype(ra.dtype['row'], np.integer)
        assert np.issubdtype(ra.dtype['column'], np.integer)

        try:  # check that fiona reads integers
            import fiona
            with fiona.open(outshp) as src:
                meta = src.meta
                assert 'int' in meta['schema']['properties']['row']
                assert 'int' in meta['schema']['properties']['column']
        except:
            pass
コード例 #12
0
def test_const():

    fm = flopy.modflow
    m = fm.Modflow()
    dis = fm.ModflowDis(m, 1, 10, 10, lenuni=2, itmuni=4)
    m.sr = SpatialReference()
    r, d = create_sfr_data()
    sfr = flopy.modflow.ModflowSfr2(m, reach_data=r, segment_data={0: d})
    assert sfr.const == 86400.
    m.dis.itmuni = 1.
    m.sfr.const = None
    assert sfr.const == 1.
    m.dis.lenuni = 1.
    m.sfr.const = None
    assert sfr.const == 1.486
    m.dis.itmuni = 4.
    m.sfr.const = None
    assert sfr.const == 1.486 * 86400.
    assert True
コード例 #13
0
ファイル: t007_test.py プロジェクト: aleaf/flopy
def test_read_usgs_model_reference():
    nlay, nrow, ncol = 1, 30, 5
    delr, delc = 250, 500
    #xll, yll = 272300, 5086000
    model_ws = os.path.join('temp', 't007')
    mrf = os.path.join(model_ws, 'usgs.model.reference')
    shutil.copy('../examples/data/usgs.model.reference', mrf)
    fm = flopy.modflow
    m = fm.Modflow(modelname='junk', model_ws=model_ws)
    # feet and days
    dis = fm.ModflowDis(m, nlay=nlay, nrow=nrow, ncol=ncol, delr=delr,
                        delc=delc, lenuni=1, itmuni=4)
    m.write_input()

    # test reading of SR information from usgs.model.reference
    m2 = fm.Modflow.load('junk.nam', model_ws=os.path.join('temp', 't007'))
    from flopy.utils.reference import SpatialReference
    d = SpatialReference.read_usgs_model_reference_file(mrf)
    assert m2.sr.xul == d['xul']
    assert m2.sr.yul == d['yul']
    assert m2.sr.rotation == d['rotation']
    assert m2.sr.lenuni == d['lenuni']
    assert m2.sr.epsg == d['epsg']

    # test reading non-default units from usgs.model.reference
    shutil.copy(mrf, mrf+'_copy')
    with open(mrf+'_copy') as src:
        with open(mrf, 'w') as dst:
            for line in src:
                if 'time_unit' in line:
                    line = line.replace('days', 'seconds')
                elif 'length_units' in line:
                    line = line.replace('feet', 'meters')
                dst.write(line)
    m2 = fm.Modflow.load('junk.nam', model_ws=os.path.join('temp', 't007'))
    assert m2.tr.itmuni == 1
    assert m2.sr.lenuni == 2
    # have to delete this, otherwise it will mess up other tests
    to_del = glob.glob(mrf + '*')
    for f in to_del:
        if os.path.exists(f):
            os.remove(os.path.join(f))
    assert True
コード例 #14
0
nlay = 1
nrow, ncol = 51, 51
delr, delc = int(Lx / ncol), int(Ly / nrow)
delv = (ztop - zbot) / nlay
botm = np.linspace(ztop, zbot, nlay + 1)
nper = 10  # annual for 10 years, find a way to do a steady-state period and then pipe in the values
perlen = 365.2

# make a circle!
offset = 160 / 2
proj4 = '+proj=aea +lat_1=27.5 +lat_2=35 +lat_0=31.25 +lon_0=-100 +x_0=1500000 +y_0=6000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=us-ft +no_defs'
xul, yul = 5661342.80316535942256451 - offset, 19628009.74438977241516113 + offset
# get the row/column!
delcl = np.ones(nrow) * (int(Lx / ncol))
delrl = delcl
sr = SpatialReference(delr=delrl, delc=delcl, xul=xul, yul=yul)
mf.sr = sr
yll = yul - 8000.  # measure from the bottom up
well3x = 3840. + offset
well3y = 8000. - 4640. - offset  # measure from the bottom up


def PointsInCircum(xul, yll, r, n=100):
    a = [[np.cos(2 * np.pi / n * i) * r,
          np.sin(2 * np.pi / n * i) * r] for i in range(0, n)]
    x0 = np.array([i[0] for i in a])
    y0 = np.array([i[1] for i in a])
    return [x0 + xul + well3x, y0 + yll + well3y]


test = PointsInCircum(xul, yll, 50, 100)
コード例 #15
0
ファイル: hydrodem.py プロジェクト: alemood/TreasureValley
fig.subplots_adjust(right=0.8)
cbar_ax = fig.add_axes([0.85, 0.2, 0.02, 0.6]) #l, b, w, h
fig.colorbar(im,cax=cbar_ax)

#%%
## 4. Export to model top
# Spatial Reference Module
xll, yll = 2247000.00, 1330950.00 # origin of the model [m] (lower left corner)
dxdy = 1609.344 # grid spacing (in model units) 
delc = np.ones(nrow, dtype=float) * dxdy
delr = np.ones(ncol, dtype=float) * dxdy
nrow , ncol = npDEM.shape
rot = -2 # rotation (positive ccw)
# Specify coordinate system with custom Proj4 string for IDTM83
model_proj4 = '+proj=tmerc +lat_0=42 +lon_0=-114 +k=0.9996 +x_0=2500000 +y_0=1200000 +ellps=GRS80 +units=m +no_defs'
sr = SpatialReference(delr=delr, delc=delc, xll=xll, yll=yll, rotation=rot, proj4_str = model_proj4)

# Modflow discretization
# row and column spacings
# (note that delc is column spacings along a row; delr the row spacings along a column)
nlay = 1
delr = dxdy
delc = dxdy
# Top of model is the DEM we just created
ztop = npDEM
botm = np.stack( (DEMbottom1,DEMbottom2))
botm = DEMbottom2
# Initialize model objext
ml = flopy.modflow.Modflow(modelname = 'TV', exe_name = 'mf2005', model_ws = root )
dis = flopy.modflow.ModflowDis(ml, nlay ,nrow, ncol , delr=delr, delc=delc ,top=ztop, botm=botm)
コード例 #16
0
ファイル: modpathfile.py プロジェクト: emorway-usgs/flopy
    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)
コード例 #17
0
def test_get_destination_data():
    m = flopy.modflow.Modflow.load('EXAMPLE.nam', model_ws=path)

    m.sr = SpatialReference(delr=m.dis.delr,
                            delc=m.dis.delc,
                            xul=0,
                            yul=0,
                            rotation=30)
    sr = SpatialReference(delr=list(m.dis.delr),
                          delc=list(m.dis.delc),
                          xul=1000,
                          yul=1000,
                          rotation=30)
    sr2 = SpatialReference(xll=sr.xll, yll=sr.yll, rotation=-30)
    m.dis.export(path + '/dis.shp')

    pthld = PathlineFile(os.path.join(path, 'EXAMPLE-3.pathline'))
    epd = EndpointFile(os.path.join(path, 'EXAMPLE-3.endpoint'))

    well_epd = epd.get_destination_endpoint_data(dest_cells=[(4, 12, 12)])
    well_pthld = pthld.get_destination_pathline_data(dest_cells=[(4, 12, 12)],
                                                     to_recarray=True)

    # same particle IDs should be in both endpoint data and pathline data
    tval = len(set(well_epd.particleid).difference(set(well_pthld.particleid)))
    msg = 'same particle IDs should be in both endpoint data and pathline data'
    assert tval == 0, msg

    # check that all starting locations are included in the pathline data
    # (pathline data slice not just endpoints)
    starting_locs = ra_slice(well_epd, ['k0', 'i0', 'j0'])
    pathline_locs = np.array(np.array(well_pthld)[['k', 'i', 'j']].tolist(),
                             dtype=starting_locs.dtype)
    assert np.all(np.in1d(starting_locs, pathline_locs))

    # test writing a shapefile of endpoints
    epd.write_shapefile(well_epd,
                        direction='starting',
                        shpname=os.path.join(path, 'starting_locs.shp'),
                        sr=m.sr)

    # test writing shapefile of pathlines
    fpth = os.path.join(path, 'pathlines_1per.shp')
    pthld.write_shapefile(well_pthld,
                          one_per_particle=True,
                          direction='starting',
                          sr=m.sr,
                          shpname=fpth)
    fpth = os.path.join(path, 'pathlines_1per_end.shp')
    pthld.write_shapefile(well_pthld,
                          one_per_particle=True,
                          direction='ending',
                          sr=m.sr,
                          shpname=fpth)
    # test writing shapefile of pathlines
    fpth = os.path.join(path, 'pathlines_1per2.shp')
    pthld.write_shapefile(well_pthld,
                          one_per_particle=True,
                          direction='starting',
                          sr=sr,
                          shpname=fpth)
    # test writing shapefile of pathlines
    fpth = os.path.join(path, 'pathlines_1per2_ll.shp')
    pthld.write_shapefile(well_pthld,
                          one_per_particle=True,
                          direction='starting',
                          sr=sr2,
                          shpname=fpth)
    fpth = os.path.join(path, 'pathlines.shp')
    pthld.write_shapefile(well_pthld,
                          one_per_particle=False,
                          sr=m.sr,
                          shpname=fpth)

    # test that endpoints were rotated and written correctly
    from flopy.export.shapefile_utils import shp2recarray
    ra = shp2recarray(os.path.join(path, 'starting_locs.shp'))
    p3 = ra.geometry[ra.particleid == 4][0]
    xorig, yorig = m.sr.transform(well_epd.x0[0], well_epd.y0[0])
    assert p3.x - xorig + p3.y - yorig < 1e-4
    xorig, yorig = m.sr.xcentergrid[3, 4], m.sr.ycentergrid[3, 4]
    assert np.abs(p3.x - xorig + p3.y -
                  yorig) < 1e-4  # this also checks for 1-based

    # test that particle attribute information is consistent with pathline file
    ra = shp2recarray(os.path.join(path, 'pathlines.shp'))
    inds = (ra.particleid == 8) & (ra.i == 12) & (ra.j == 12)
    assert ra.time[inds][0] - 20181.7 < .1
    assert ra.xloc[inds][0] - 0.933 < .01

    # test that k, i, j are correct for single geometry pathlines, forwards
    # and backwards
    ra = shp2recarray(os.path.join(path, 'pathlines_1per.shp'))
    assert ra.i[0] == 4, ra.j[0] == 5
    ra = shp2recarray(os.path.join(path, 'pathlines_1per_end.shp'))
    assert ra.i[0] == 13, ra.j[0] == 13

    # test use of arbitrary spatial reference and offset
    ra = shp2recarray(os.path.join(path, 'pathlines_1per2.shp'))
    p3_2 = ra.geometry[ra.particleid == 4][0]
    assert np.abs(p3_2.x[0] - sr.xcentergrid[3, 4] + p3_2.y[0] -
                  sr.ycentergrid[3, 4]) < 1e-4

    # arbitrary spatial reference with ll specified instead of ul
    ra = shp2recarray(os.path.join(path, 'pathlines_1per2_ll.shp'))
    p3_2 = ra.geometry[ra.particleid == 4][0]
    sr3 = SpatialReference(xll=sr.xll,
                           yll=sr.yll,
                           rotation=-30,
                           delr=list(m.dis.delr),
                           delc=list(m.dis.delc))
    assert np.abs(p3_2.x[0] - sr3.xcentergrid[3, 4] + p3_2.y[0] -
                  sr3.ycentergrid[3, 4]) < 1e-4

    xul = 3628793
    yul = 21940389

    m = flopy.modflow.Modflow.load('EXAMPLE.nam', model_ws=path)

    m.sr = flopy.utils.reference.SpatialReference(delr=m.dis.delr,
                                                  delc=m.dis.delc,
                                                  lenuni=1,
                                                  xul=xul,
                                                  yul=yul,
                                                  rotation=0.0)
    fpth = os.path.join(path, 'dis2.shp')
    m.dis.export(fpth)
    pthobj = flopy.utils.PathlineFile(os.path.join(path, 'EXAMPLE-3.pathline'))
    fpth = os.path.join(path, 'pathlines_1per3.shp')
    pthobj.write_shapefile(shpname=fpth, direction='ending', sr=m.sr)
コード例 #18
0
name = 'map_test'
epsg = 5070
xul, yul = 520487.3, 1194668.3
nrow, ncol = 20, 20
dxy = 5280 * .3048
buf = 1e4
bounds = xul - buf, \
         yul - dxy * nrow - buf, \
         xul + dxy * ncol + buf, \
         yul + buf

# make version of preprocessed flowlines filtered to bounding box
df = shp2df('/Users/aleaf/Documents/MAP/repos/sfr_output/preprocessed/flowlines_gt20km/flowlines_gt20km_edited.shp',
            filter=bounds)
df2shp(df, 'data/{}_flowlines.shp'.format(name), epsg=epsg)

# make a spatial reference object defining the grid
sr = SpatialReference(delr=np.ones(ncol, dtype=float) * dxy,
                      delc=np.ones(nrow, dtype=float) * dxy,
                      xul=xul, yul=yul, epsg=epsg)
# export sr info to json file
model_info = sr.attribute_dict
model_info['nrow'] = sr.nrow
model_info['ncol'] = sr.ncol
model_info['delr'] = sr.delr[0]
model_info['delc'] = sr.delc[0]
model_info['epsg'] = sr.epsg

with open('data/{}_grid.json'.format(name), 'w') as output:
    json.dump(model_info, output, indent=4, sort_keys=True)
コード例 #19
0
def test_freyberg_export():
    from flopy.utils.reference import SpatialReference
    namfile = 'freyberg.nam'

    # steady state
    model_ws = '../examples/data/freyberg'
    m = flopy.modflow.Modflow.load(namfile,
                                   model_ws=model_ws,
                                   check=False,
                                   verbose=False)
    # test export at model, package and object levels
    m.export('{}/model.shp'.format(spth))
    m.wel.export('{}/wel.shp'.format(spth))
    m.lpf.hk.export('{}/hk.shp'.format(spth))
    m.riv.stress_period_data.export('{}/riv_spd.shp'.format(spth))

    # transient
    # (doesn't work at model level because the total size of
    #  the attribute fields exceeds the shapefile limit)
    model_ws = '../examples/data/freyberg_multilayer_transient/'
    m = flopy.modflow.Modflow.load(
        namfile,
        model_ws=model_ws,
        verbose=False,
        load_only=['DIS', 'BAS6', 'NWT', 'OC', 'RCH', 'WEL', 'DRN', 'UPW'])
    # test export without instantiating an sr
    outshp = os.path.join(spth, namfile[:-4] + '_drn_sparse.shp')
    m.drn.stress_period_data.export(outshp, sparse=True)
    assert os.path.exists(outshp)
    remove_shp(outshp)
    m.sr = SpatialReference(delr=m.dis.delr.array,
                            delc=m.dis.delc.array,
                            epsg=5070)
    # test export with an sr, regardless of whether or not wkt was found
    m.drn.stress_period_data.export(outshp, sparse=True)
    assert os.path.exists(outshp)
    remove_shp(outshp)
    m.sr = SpatialReference(delr=m.dis.delr.array,
                            delc=m.dis.delc.array,
                            epsg=3070)
    # if wkt text was fetched from spatialreference.org
    if m.sr.wkt is not None:
        # test default package export
        outshp = os.path.join(spth, namfile[:-4] + '_dis.shp')
        m.dis.export(outshp)
        prjfile = outshp.replace('.shp', '.prj')
        with open(prjfile) as src:
            prjtxt = src.read()
        assert prjtxt == m.sr.wkt
        remove_shp(outshp)

        # test default package export to higher level dir
        outshp = os.path.join('..', namfile[:-4] + '_dis.shp')
        m.dis.export(outshp)
        prjfile = outshp.replace('.shp', '.prj')
        with open(prjfile) as src:
            prjtxt = src.read()
        assert prjtxt == m.sr.wkt
        remove_shp(outshp)

        # test sparse package export
        outshp = os.path.join(spth, namfile[:-4] + '_drn_sparse.shp')
        m.drn.stress_period_data.export(outshp, sparse=True)
        prjfile = outshp.replace('.shp', '.prj')
        with open(prjfile) as src:
            prjtxt = src.read()
        assert prjtxt == m.sr.wkt
        remove_shp(outshp)
コード例 #20
0
# ### Define the Model Extent, Grid Resolution, and Characteristics
# It is normally good practice to group things that you might want to change into a single code block.  This makes it easier to make changes and rerun the code.

# In[5]:

fb = flopy.modflow.Modflow.load(os.path.join(modelname + '.nam'),
                                version='mf2005',
                                model_ws=modelpath,
                                verbose=True)

lowerleft = [6436682.01941381, 1791562.92451396]

fb.sr = SpatialReference(delr=fb.dis.delr,
                         delc=fb.dis.delc,
                         xll=lowerleft[0],
                         yll=lowerleft[1],
                         units='feet',
                         proj4_str='EPSG:2871',
                         rotation=23)

fb.sr

# ## Flopy Tutorial 1: Running the Model
#
# Flopy has several methods attached to the model object that can be used to run the model.  They are run_model, run_model2, and run_model3.  Here we use run_model3, which will write output to the notebook.

# In[6]:

# Imports for plotting and reading the MODFLOW binary output file

import flopy.utils.binaryfile as bf
コード例 #21
0
ファイル: map.py プロジェクト: emorway-usgs/flopy
class ModelMap(object):
    """
    Class to create a map of the model.

    Parameters
    ----------
    sr : flopy.utils.reference.SpatialReference
        The spatial reference class (Default is None)
    ax : matplotlib.pyplot axis
        The plot axis.  If not provided it, plt.gca() will be used.
        If there is not a current axis then a new one will be created.
    model : flopy.modflow object
        flopy model object. (Default is None)
    dis : flopy.modflow.ModflowDis object
        flopy discretization object. (Default is None)
    layer : int
        Layer to plot.  Default is 0.  Must be between 0 and nlay - 1.
    xul : float
        x coordinate for upper left corner
    yul : float
        y coordinate for upper left corner.  The default is the sum of the
        delc array.
    rotation : float
        Angle of grid rotation around the upper left corner.  A positive value
        indicates clockwise rotation.  Angles are in degrees.
    extent : tuple of floats
        (xmin, xmax, ymin, ymax) will be used to specify axes limits.  If None
        then these will be calculated based on grid, coordinates, and rotation.

    Notes
    -----
    ModelMap must know the position and rotation of the grid in order to make
    the plot.  This information is contained in the SpatialReference class
    (sr), which can be passed.  If sr is None, then it looks for sr in dis.
    If dis is None, then it looks for sr in model.dis.  If all of these
    arguments are none, then it uses xul, yul, and rotation.  If none of these
    arguments are provided, then it puts the lower-left-hand corner of the
    grid at (0, 0).

    """

    def __init__(self, sr=None, ax=None, model=None, dis=None, layer=0,
                 extent=None,
                 xul=None, yul=None, xll=None, yll=None, rotation=0., length_multiplier=1.):
        self.model = model
        self.layer = layer
        self.dis = dis
        self.sr = None
        if sr is not None:
            self.sr = copy.deepcopy(sr)
        elif dis is not None:
            # print("warning: the dis arg to model map is deprecated")
            self.sr = copy.deepcopy(dis.parent.sr)
        elif model is not None:
            # print("warning: the model arg to model map is deprecated")
            self.sr = copy.deepcopy(model.sr)
        else:
            self.sr = SpatialReference(xll, yll, xul, yul, rotation, length_multiplier)

        # model map override spatial reference settings
        if any(elem is not None for elem in (xul, yul, xll, yll)) or rotation != 0 or length_multiplier != 1.:
            self.sr.set_spatialreference(xul, yul, xll, yll, rotation, length_multiplier)
        '''
        if xul is not None and yul is not None:
            self.sr.xul = xul
        if yul is not None:
            self.sr.yul = yul
        if rotation is not None:
            self.sr.rotation = rotation
        '''
        if ax is None:
            try:
                self.ax = plt.gca()
                self.ax.set_aspect('equal')
            except:
                self.ax = plt.subplot(1, 1, 1, aspect='equal', axisbg="white")
        else:
            self.ax = ax
        if extent is not None:
            self._extent = extent
        else:
            self._extent = None

        # why is this non-default color scale used??
        #  This should be passed as a kwarg by the user to the indivudual plotting method.
        # self.cmap = plotutil.viridis

        return

    @property
    def extent(self):
        if self._extent is None:
            self._extent = self.sr.get_extent()
        return self._extent

    def plot_array(self, a, masked_values=None, **kwargs):
        """
        Plot an array.  If the array is three-dimensional, then the method
        will plot the layer tied to this class (self.layer).

        Parameters
        ----------
        a : numpy.ndarray
            Array to plot.
        masked_values : iterable of floats, ints
            Values to mask.
        **kwargs : dictionary
            keyword arguments passed to matplotlib.pyplot.pcolormesh

        Returns
        -------
        quadmesh : matplotlib.collections.QuadMesh
        """
        if a.ndim == 3:
            plotarray = a[self.layer, :, :]
        elif a.ndim == 2:
            plotarray = a
        else:
            raise Exception('Array must be of dimension 2 or 3')
        if masked_values is not None:
            for mval in masked_values:
                plotarray = np.ma.masked_equal(plotarray, mval)
        if 'ax' in kwargs:
            ax = kwargs.pop('ax')
        else:
            ax = self.ax
        quadmesh = ax.pcolormesh(self.sr.xgrid, self.sr.ygrid, plotarray,
                                 **kwargs)
        ax.set_xlim(self.extent[0], self.extent[1])
        ax.set_ylim(self.extent[2], self.extent[3])
        return quadmesh

    def contour_array(self, a, masked_values=None, **kwargs):
        """
        Contour an array.  If the array is three-dimensional, then the method
        will contour the layer tied to this class (self.layer).

        Parameters
        ----------
        a : numpy.ndarray
            Array to plot.
        masked_values : iterable of floats, ints
            Values to mask.
        **kwargs : dictionary
            keyword arguments passed to matplotlib.pyplot.pcolormesh

        Returns
        -------
        contour_set : matplotlib.pyplot.contour

        """
        if a.ndim == 3:
            plotarray = a[self.layer, :, :]
        elif a.ndim == 2:
            plotarray = a
        else:
            raise Exception('Array must be of dimension 2 or 3')
        if masked_values is not None:
            for mval in masked_values:
                plotarray = np.ma.masked_equal(plotarray, mval)
        if 'ax' in kwargs:
            ax = kwargs.pop('ax')
        else:
            ax = self.ax
        if 'colors' in kwargs.keys():
            if 'cmap' in kwargs.keys():
                cmap = kwargs.pop('cmap')
            cmap = None
        contour_set = ax.contour(self.sr.xcentergrid, self.sr.ycentergrid,
                                 plotarray, **kwargs)
        ax.set_xlim(self.extent[0], self.extent[1])
        ax.set_ylim(self.extent[2], self.extent[3])

        return contour_set

    def plot_inactive(self, ibound=None, color_noflow='black', **kwargs):
        """
        Make a plot of inactive cells.  If not specified, then pull ibound from the
        self.ml

        Parameters
        ----------
        ibound : numpy.ndarray
            ibound array to plot.  (Default is ibound in 'BAS6' package.)
        color_noflow : string
            (Default is 'black')

        Returns
        -------
        quadmesh : matplotlib.collections.QuadMesh

        """
        if 'ax' in kwargs:
            ax = kwargs.pop('ax')
        else:
            ax = self.ax

        if ibound is None:
            bas = self.model.get_package('BAS6')
            ibound = bas.ibound.array

        plotarray = np.zeros(ibound.shape, dtype=np.int)
        idx1 = (ibound == 0)
        plotarray[idx1] = 1
        plotarray = np.ma.masked_equal(plotarray, 0)
        cmap = matplotlib.colors.ListedColormap(['0', color_noflow])
        bounds = [0, 1, 2]
        norm = matplotlib.colors.BoundaryNorm(bounds, cmap.N)
        quadmesh = self.plot_array(plotarray, cmap=cmap, norm=norm, **kwargs)
        return quadmesh

    def plot_ibound(self, ibound=None, color_noflow='black', color_ch='blue',
                    **kwargs):
        """
        Make a plot of ibound.  If not specified, then pull ibound from the
        self.ml

        Parameters
        ----------
        ibound : numpy.ndarray
            ibound array to plot.  (Default is ibound in 'BAS6' package.)
        color_noflow : string
            (Default is 'black')
        color_ch : string
            Color for constant heads (Default is 'blue'.)

        Returns
        -------
        quadmesh : matplotlib.collections.QuadMesh

        """
        if 'ax' in kwargs:
            ax = kwargs.pop('ax')
        else:
            ax = self.ax

        if ibound is None:
            bas = self.model.get_package('BAS6')
            ibound = bas.ibound.array
        plotarray = np.zeros(ibound.shape, dtype=np.int)
        idx1 = (ibound == 0)
        idx2 = (ibound < 0)
        plotarray[idx1] = 1
        plotarray[idx2] = 2
        plotarray = np.ma.masked_equal(plotarray, 0)
        cmap = matplotlib.colors.ListedColormap(['0', color_noflow, color_ch])
        bounds = [0, 1, 2, 3]
        norm = matplotlib.colors.BoundaryNorm(bounds, cmap.N)
        quadmesh = self.plot_array(plotarray, cmap=cmap, norm=norm, **kwargs)
        return quadmesh

    def plot_grid(self, **kwargs):
        """
        Plot the grid lines.

        Parameters
        ----------
        kwargs : ax, colors.  The remaining kwargs are passed into the
            the LineCollection constructor.

        Returns
        -------
        lc : matplotlib.collections.LineCollection

        """
        if 'ax' in kwargs:
            ax = kwargs.pop('ax')
        else:
            ax = self.ax

        if 'colors' not in kwargs:
            kwargs['colors'] = '0.5'

        lc = self.get_grid_line_collection(**kwargs)
        ax.add_collection(lc)
        ax.set_xlim(self.extent[0], self.extent[1])
        ax.set_ylim(self.extent[2], self.extent[3])

        return lc

    def plot_bc(self, ftype=None, package=None, kper=0, color=None,
                plotAll=False,
                **kwargs):
        """
        Plot boundary conditions locations for a specific boundary
        type from a flopy model

        Parameters
        ----------
        ftype : string
            Package name string ('WEL', 'GHB', etc.). (Default is None)
        package : flopy.modflow.Modflow package class instance
            flopy package class instance. (Default is None)
        kper : int
            Stress period to plot
        color : string
            matplotlib color string. (Default is None)
        plotAll : bool
            Boolean used to specify that boundary condition locations for all
            layers will be plotted on the current ModelMap layer.
            (Default is False)
        **kwargs : dictionary
            keyword arguments passed to matplotlib.collections.PatchCollection

        Returns
        -------
        quadmesh : matplotlib.collections.QuadMesh

        """
        if 'ax' in kwargs:
            ax = kwargs.pop('ax')
        else:
            ax = self.ax

        # Find package to plot
        if package is not None:
            p = package
            ftype = p.name[0]
        elif self.model is not None:
            if ftype is None:
                raise Exception('ftype not specified')
            ftype = ftype.upper()
            p = self.model.get_package(ftype)
        else:
            raise Exception('Cannot find package to plot')

        # Get the list data
        try:
            mflist = p.stress_period_data[kper]
        except Exception as e:
            raise Exception('Not a list-style boundary package:' + str(e))

        # Return if MfList is None
        if mflist is None:
            return None
        nlay = self.model.nlay
        # Plot the list locations
        plotarray = np.zeros((nlay, self.sr.nrow, self.sr.ncol), dtype=np.int)
        if plotAll:
            idx = [mflist['i'], mflist['j']]
            # plotarray[:, idx] = 1
            pa = np.zeros((self.sr.nrow, self.sr.ncol), dtype=np.int)
            pa[idx] = 1
            for k in range(nlay):
                plotarray[k, :, :] = pa.copy()
        else:
            idx = [mflist['k'], mflist['i'], mflist['j']]

            plotarray[idx] = 1
        plotarray = np.ma.masked_equal(plotarray, 0)
        if color is None:
            if ftype in bc_color_dict:
                c = bc_color_dict[ftype]
            else:
                c = bc_color_dict['default']
        else:
            c = color
        cmap = matplotlib.colors.ListedColormap(['0', c])
        bounds = [0, 1, 2]
        norm = matplotlib.colors.BoundaryNorm(bounds, cmap.N)
        quadmesh = self.plot_array(plotarray, cmap=cmap, norm=norm, **kwargs)
        return quadmesh

    def plot_shapefile(self, shp, **kwargs):
        """
        Plot a shapefile.  The shapefile must be in the same coordinates as
        the rotated and offset grid.

        Parameters
        ----------
        shp : string
            Name of the shapefile to plot

        kwargs : dictionary
            Keyword arguments passed to plotutil.plot_shapefile()

        """
        if 'ax' in kwargs:
            ax = kwargs.pop('ax')
        else:
            ax = self.ax
        patch_collection = plotutil.plot_shapefile(shp, ax, **kwargs)
        return patch_collection

    def plot_cvfd(self, verts, iverts, **kwargs):
        """
        Plot a cvfd grid.  The vertices must be in the same coordinates as
        the rotated and offset grid.

        Parameters
        ----------
        verts : ndarray
            2d array of x and y points.
        iverts : list of lists
            should be of len(ncells) with a list of vertex number for each cell

        kwargs : dictionary
            Keyword arguments passed to plotutil.plot_cvfd()

        """
        if 'ax' in kwargs:
            ax = kwargs.pop('ax')
        else:
            ax = self.ax
        patch_collection = plotutil.plot_cvfd(verts, iverts, ax, self.layer,
                                              **kwargs)
        return patch_collection


    def contour_array_cvfd(self, vertc, a, masked_values=None, **kwargs):
        """
        Contour an array.  If the array is three-dimensional, then the method
        will contour the layer tied to this class (self.layer).

        Parameters
        ----------
        vertc : np.ndarray
            Array with centroid location of cvfd
        a : numpy.ndarray
            Array to plot.
        masked_values : iterable of floats, ints
            Values to mask.
        **kwargs : dictionary
            keyword arguments passed to matplotlib.pyplot.pcolormesh

        Returns
        -------
        contour_set : matplotlib.pyplot.contour

        """
        if 'ncpl' in kwargs:
            nlay = self.layer + 1
            ncpl = kwargs.pop('ncpl')
            if isinstance(ncpl, int):
                i = int(ncpl)
                ncpl = np.ones((nlay), dtype=np.int) * i
            elif isinstance(ncpl, list) or isinstance(ncpl, tuple):
                ncpl = np.array(ncpl)
            i0 = 0
            i1 = 0
            for k in range(nlay):
                i0 = i1
                i1 = i0 + ncpl[k]
            # retain vertc in selected layer
            vertc = vertc[i0:i1, :]
        else:
            i0 = 0
            i1 = vertc.shape[0]

        plotarray = a[i0:i1]

        if masked_values is not None:
            for mval in masked_values:
                plotarray = np.ma.masked_equal(plotarray, mval)
        if 'ax' in kwargs:
            ax = kwargs.pop('ax')
        else:
            ax = self.ax
        if 'colors' in kwargs.keys():
            if 'cmap' in kwargs.keys():
                cmap = kwargs.pop('cmap')
            cmap = None
        contour_set = ax.tricontour(vertc[:, 0], vertc[:, 1],
                                    plotarray, **kwargs)

        return contour_set

    def plot_discharge(self, frf, fff, dis=None, flf=None, head=None, istep=1,
                       jstep=1, normalize=False, **kwargs):
        """
        Use quiver to plot vectors.

        Parameters
        ----------
        frf : numpy.ndarray
            MODFLOW's 'flow right face'
        fff : numpy.ndarray
            MODFLOW's 'flow front face'
        flf : numpy.ndarray
            MODFLOW's 'flow lower face' (Default is None.)
        head : numpy.ndarray
            MODFLOW's head array.  If not provided, then will assume confined
            conditions in order to calculated saturated thickness.
        istep : int
            row frequency to plot. (Default is 1.)
        jstep : int
            column frequency to plot. (Default is 1.)
        normalize : bool
            boolean flag used to determine if discharge vectors should
            be normalized using the magnitude of the specific discharge in each
            cell. (default is False)
        kwargs : dictionary
            Keyword arguments passed to plt.quiver()

        Returns
        -------
        quiver : matplotlib.pyplot.quiver
            Vectors of specific discharge.

        """
        # remove 'pivot' keyword argument
        # by default the center of the arrow is plotted in the center of a cell
        if 'pivot' in kwargs:
            pivot = kwargs.pop('pivot')
        else:
            pivot = 'middle'

        # Calculate specific discharge
        # make sure dis is defined
        if dis is None:
            if self.model is not None:
                dis = self.model.dis
            else:
                print(
                    "ModelMap.plot_quiver() error: self.dis is None and dis arg is None ")
                return
        ib = self.model.bas6.ibound.array
        delr = dis.delr.array
        delc = dis.delc.array
        top = dis.top.array
        botm = dis.botm.array
        nlay, nrow, ncol = botm.shape
        laytyp = None
        hnoflo = 999.
        hdry = 999.
        if self.model is not None:
            lpf = self.model.get_package('LPF')
            if lpf is not None:
                laytyp = lpf.laytyp.array
                hdry = lpf.hdry
            bas = self.model.get_package('BAS6')
            if bas is not None:
                hnoflo = bas.hnoflo

        # If no access to head or laytyp, then calculate confined saturated
        # thickness by setting laytyp to zeros
        if head is None or laytyp is None:
            head = np.zeros(botm.shape, np.float32)
            laytyp = np.zeros((nlay), dtype=np.int)
        sat_thk = plotutil.saturated_thickness(head, top, botm, laytyp,
                                               [hnoflo, hdry])

        # Calculate specific discharge
        qx, qy, qz = plotutil.centered_specific_discharge(frf, fff, flf, delr,
                                                          delc, sat_thk)

        # Select correct slice
        u = qx[self.layer, :, :]
        v = qy[self.layer, :, :]
        # apply step
        x = self.sr.xcentergrid[::istep, ::jstep]
        y = self.sr.ycentergrid[::istep, ::jstep]
        u = u[::istep, ::jstep]
        v = v[::istep, ::jstep]
        # normalize
        if normalize:
            vmag = np.sqrt(u ** 2. + v ** 2.)
            idx = vmag > 0.
            u[idx] /= vmag[idx]
            v[idx] /= vmag[idx]

        if 'ax' in kwargs:
            ax = kwargs.pop('ax')
        else:
            ax = self.ax

        # mask discharge in inactive cells
        idx = (ib[self.layer, ::istep, ::jstep] == 0)
        u[idx] = np.nan
        v[idx] = np.nan

        # Rotate and plot
        urot, vrot = self.sr.rotate(u, v, self.sr.rotation)
        quiver = ax.quiver(x, y, urot, vrot, pivot=pivot, **kwargs)

        return quiver

    def plot_pathline(self, pl, travel_time=None, **kwargs):
        """
        Plot the MODPATH pathlines.

        Parameters
        ----------
        pl : list of rec arrays or a single rec array
            rec array or list of rec arrays is data returned from
            modpathfile PathlineFile get_data() or get_alldata()
            methods. Data in rec array is 'x', 'y', 'z', 'time',
            'k', and 'particleid'.
        travel_time: float or str
            travel_time is a travel time selection for the displayed
            pathlines. If a float is passed then pathlines with times
            less than or equal to the passed time are plotted. If a
            string is passed a variety logical constraints can be added
            in front of a time value to select pathlines for a select
            period of time. Valid logical constraints are <=, <, >=, and
            >. For example, to select all pathlines less than 10000 days
            travel_time='< 10000' would be passed to plot_pathline.
            (default is None)
        kwargs : layer, ax, colors.  The remaining kwargs are passed
            into the LineCollection constructor. If layer='all',
            pathlines are output for all layers

        Returns
        -------
        lc : matplotlib.collections.LineCollection

        """
        from matplotlib.collections import LineCollection
        # make sure pathlines is a list
        if not isinstance(pl, list):
            pl = [pl]

        if 'layer' in kwargs:
            kon = kwargs.pop('layer')
            if isinstance(kon, bytes):
                kon = kon.decode()
            if isinstance(kon, str):
                if kon.lower() == 'all':
                    kon = -1
                else:
                    kon = self.layer
        else:
            kon = self.layer

        if 'ax' in kwargs:
            ax = kwargs.pop('ax')
        else:
            ax = self.ax

        if 'colors' not in kwargs:
            kwargs['colors'] = '0.5'

        linecol = []
        for p in pl:
            if travel_time is None:
                tp = p.copy()
            else:
                if isinstance(travel_time, str):
                    if '<=' in travel_time:
                        time = float(travel_time.replace('<=', ''))
                        idx = (p['time'] <= time)
                    elif '<' in travel_time:
                        time = float(travel_time.replace('<', ''))
                        idx = (p['time'] < time)
                    elif '>=' in travel_time:
                        time = float(travel_time.replace('>=', ''))
                        idx = (p['time'] >= time)
                    elif '<' in travel_time:
                        time = float(travel_time.replace('>', ''))
                        idx = (p['time'] > time)
                    else:
                        try:
                            time = float(travel_time)
                            idx = (p['time'] <= time)
                        except:
                            errmsg = 'flopy.map.plot_pathline travel_time ' + \
                                     'variable cannot be parsed. ' + \
                                     'Acceptable logical variables are , ' + \
                                     '<=, <, >=, and >. ' + \
                                     'You passed {}'.format(travel_time)
                            raise Exception(errmsg)
                else:
                    time = float(travel_time)
                    idx = (p['time'] <= time)
                tp = p[idx]

            vlc = []
            # rotate data
            x0r, y0r = self.sr.rotate(tp['x'], tp['y'], self.sr.rotation, 0.,
                                      self.sr.yedge[0])
            x0r += self.sr.xul
            y0r += self.sr.yul - self.sr.yedge[0]
            # build polyline array
            arr = np.vstack((x0r, y0r)).T
            # select based on layer
            if kon >= 0:
                kk = p['k'].copy().reshape(p.shape[0], 1)
                kk = np.repeat(kk, 2, axis=1)
                arr = np.ma.masked_where((kk != kon), arr)
            else:
                arr = np.ma.asarray(arr)
            # append line to linecol if there is some unmasked segment
            if not arr.mask.all():
                linecol.append(arr)
        # create line collection
        lc = None
        if len(linecol) > 0:
            lc = LineCollection(linecol, **kwargs)
            ax.add_collection(lc)
        return lc

    def plot_endpoint(self, ep, direction='ending',
                      selection=None, selection_direction=None, **kwargs):
        """
        Plot the MODPATH endpoints.

        Parameters
        ----------
        ep : rec array
            A numpy recarray with the endpoint particle data from the
            MODPATH 6 endpoint file
        direction : str
            String defining if starting or ending particle locations should be
            considered. (default is 'ending')
        selection : tuple
            tuple that defines the zero-base layer, row, column location
            (l, r, c) to use to make a selection of particle endpoints.
            The selection could be a well location to determine capture zone
            for the well. If selection is None, all particle endpoints for
            the user-sepcified direction will be plotted. (default is None)
        selection_direction : str
            String defining is a selection should be made on starting or
            ending particle locations. If selection is not None and
            selection_direction is None, the selection direction will be set
            to the opposite of direction. (default is None)

        kwargs : ax, c, s or size, colorbar, colorbar_label, shrink. The
            remaining kwargs are passed into the matplotlib scatter
            method. If colorbar is True a colorbar will be added to the plot.
            If colorbar_label is passed in and colorbar is True then
            colorbar_label will be passed to the colorbar set_label()
            method. If shrink is passed in and colorbar is True then
            the colorbar size will be set using shrink.

        Returns
        -------
        sp : matplotlib.pyplot.scatter

        """
        if direction.lower() == 'ending':
            direction = 'ending'
        elif direction.lower() == 'starting':
            direction = 'starting'
        else:
            errmsg = 'flopy.map.plot_endpoint direction must be "ending" ' + \
                     'or "starting".'
            raise Exception(errmsg)

        if direction == 'starting':
            xp, yp = 'x0', 'y0'
        elif direction == 'ending':
            xp, yp = 'x', 'y'

        if selection_direction is not None:
            if selection_direction.lower() != 'starting' and \
                            selection_direction.lower() != 'ending':
                errmsg = 'flopy.map.plot_endpoint selection_direction ' + \
                         'must be "ending" or "starting".'
                raise Exception(errmsg)
        else:
            if direction.lower() == 'starting':
                selection_direction = 'ending'
            elif direction.lower() == 'ending':
                selection_direction = 'starting'

        if selection is not None:
            try:
                k, i, j = selection[0], selection[1], selection[2]
                if selection_direction.lower() == 'starting':
                    ksel, isel, jsel = 'k0', 'i0', 'j0'
                elif selection_direction.lower() == 'ending':
                    ksel, isel, jsel = 'k', 'i', 'j'
            except:
                errmsg = 'flopy.map.plot_endpoint selection must be a ' + \
                         'zero-based layer, row, column tuple (l, r, c) ' + \
                         'of the location to evaluate (i.e., well location).'
                raise Exception(errmsg)

        if selection is not None:
            idx = (ep[ksel] == k) & (ep[isel] == i) & (ep[jsel] == j)
            tep = ep[idx]
        else:
            tep = ep.copy()

        if 'ax' in kwargs:
            ax = kwargs.pop('ax')
        else:
            ax = self.ax

        # scatter kwargs that users may redefine
        if 'c' not in kwargs:
            c = tep['finaltime'] - tep['initialtime']
        else:
            c = np.empty((tep.shape[0]), dtype="S30")
            c.fill(kwargs.pop('c'))

        s = 50
        if 's' in kwargs:
            s = float(kwargs.pop('s')) ** 2.
        elif 'size' in kwargs:
            s = float(kwargs.pop('size')) ** 2.

        # colorbar kwargs
        createcb = False
        if 'colorbar' in kwargs:
            createcb = kwargs.pop('colorbar')

        colorbar_label = 'Endpoint Time'
        if 'colorbar_label' in kwargs:
            colorbar_label = kwargs.pop('colorbar_label')

        shrink = 1.
        if 'shrink' in kwargs:
            shrink = float(kwargs.pop('shrink'))

        # rotate data
        x0r, y0r = self.sr.rotate(tep[xp], tep[yp], self.sr.rotation, 0.,
                                  self.sr.yedge[0])
        x0r += self.sr.xul
        y0r += self.sr.yul - self.sr.yedge[0]
        # build array to plot
        arr = np.vstack((x0r, y0r)).T

        # plot the end point data
        sp = plt.scatter(arr[:, 0], arr[:, 1], c=c, s=s, **kwargs)

        # add a colorbar for travel times
        if createcb:
            cb = plt.colorbar(sp, shrink=shrink)
            cb.set_label(colorbar_label)
        return sp

    def get_grid_line_collection(self, **kwargs):
        """
        Get a LineCollection of the grid

        """
        from matplotlib.collections import LineCollection

        lc = LineCollection(self.sr.get_grid_lines(), **kwargs)
        return lc
コード例 #22
0
def test_get_destination_data():
    m = flopy.modflow.Modflow.load('EXAMPLE.nam', model_ws=path)

    mg1 = m.modelgrid
    mg1.set_coord_info(xoff=mg1._xul_to_xll(0.0, 30.0),
                       yoff=mg1._yul_to_yll(0.0, 30.0),
                       angrot=30.0)

    mg = StructuredGrid(delc=m.dis.delc.array, delr=m.dis.delr.array)
    mg.set_coord_info(xoff=mg._xul_to_xll(1000.0, 30.0),
                      yoff=mg._yul_to_yll(1000.0, 30.0),
                      angrot=30.0)

    # test deprecation
    sr2 = SpatialReference(xll=mg.xoffset, yll=mg.yoffset, rotation=-30)
    if shapefile:
        m.dis.export(path + '/dis.shp')

    pthld = PathlineFile(os.path.join(path, 'EXAMPLE-3.pathline'))
    epd = EndpointFile(os.path.join(path, 'EXAMPLE-3.endpoint'))

    well_epd = epd.get_destination_endpoint_data(dest_cells=[(4, 12, 12)])
    well_pthld = pthld.get_destination_pathline_data(dest_cells=[(4, 12, 12)],
                                                     to_recarray=True)

    # same particle IDs should be in both endpoint data and pathline data
    tval = len(set(well_epd.particleid).difference(set(well_pthld.particleid)))
    msg = 'same particle IDs should be in both endpoint data and pathline data'
    assert tval == 0, msg

    # check that all starting locations are included in the pathline data
    # (pathline data slice not just endpoints)
    starting_locs = ra_slice(well_epd, ['k0', 'i0', 'j0'])
    pathline_locs = np.array(np.array(well_pthld)[['k', 'i', 'j']].tolist(),
                             dtype=starting_locs.dtype)
    assert np.all(np.in1d(starting_locs, pathline_locs))

    if shapefile is None:
        return  # skip remainder

    # test writing a shapefile of endpoints
    epd.write_shapefile(well_epd,
                        direction='starting',
                        shpname=os.path.join(path, 'starting_locs.shp'),
                        mg=m.modelgrid)

    # test writing shapefile of pathlines
    fpth = os.path.join(path, 'pathlines_1per.shp')
    pthld.write_shapefile(well_pthld,
                          one_per_particle=True,
                          direction='starting',
                          mg=m.modelgrid,
                          shpname=fpth)
    fpth = os.path.join(path, 'pathlines_1per_end.shp')
    pthld.write_shapefile(well_pthld,
                          one_per_particle=True,
                          direction='ending',
                          mg=m.modelgrid,
                          shpname=fpth)
    # test writing shapefile of pathlines
    fpth = os.path.join(path, 'pathlines_1per2.shp')
    pthld.write_shapefile(well_pthld,
                          one_per_particle=True,
                          direction='starting',
                          mg=mg,
                          shpname=fpth)
    # test writing shapefile of pathlines
    fpth = os.path.join(path, 'pathlines_1per2_ll.shp')
    pthld.write_shapefile(well_pthld,
                          one_per_particle=True,
                          direction='starting',
                          mg=sr2,
                          shpname=fpth)
    fpth = os.path.join(path, 'pathlines.shp')
    pthld.write_shapefile(well_pthld,
                          one_per_particle=False,
                          mg=m.modelgrid,
                          shpname=fpth)

    # test that endpoints were rotated and written correctly
    from flopy.export.shapefile_utils import shp2recarray
    ra = shp2recarray(os.path.join(path, 'starting_locs.shp'))
    p3 = ra.geometry[ra.particleid == 4][0]
    xorig, yorig = m.modelgrid.get_coords(well_epd.x0[0], well_epd.y0[0])
    assert p3.x - xorig + p3.y - yorig < 1e-4
    xorig, yorig = mg1.xcellcenters[3, 4], mg1.ycellcenters[3, 4]
    assert np.abs(p3.x - xorig + p3.y -
                  yorig) < 1e-4  # this also checks for 1-based

    # test that particle attribute information is consistent with pathline file
    ra = shp2recarray(os.path.join(path, 'pathlines.shp'))
    inds = (ra.particleid == 8) & (ra.i == 12) & (ra.j == 12)
    assert ra.time[inds][0] - 20181.7 < .1
    assert ra.xloc[inds][0] - 0.933 < .01

    # test that k, i, j are correct for single geometry pathlines, forwards
    # and backwards
    ra = shp2recarray(os.path.join(path, 'pathlines_1per.shp'))
    assert ra.i[0] == 4, ra.j[0] == 5
    ra = shp2recarray(os.path.join(path, 'pathlines_1per_end.shp'))
    assert ra.i[0] == 13, ra.j[0] == 13

    # test use of arbitrary spatial reference and offset
    mg1.set_coord_info(xoff=mg.xoffset,
                       yoff=mg.yoffset,
                       angrot=mg.angrot,
                       epsg=mg.epsg,
                       proj4=mg.proj4)
    ra = shp2recarray(os.path.join(path, 'pathlines_1per2.shp'))
    p3_2 = ra.geometry[ra.particleid == 4][0]
    test1 = mg1.xcellcenters[3, 4]
    test2 = mg1.ycellcenters[3, 4]
    assert np.abs(p3_2.x[0] - mg1.xcellcenters[3, 4] + p3_2.y[0] -
                  mg1.ycellcenters[3, 4]) < 1e-4

    # arbitrary spatial reference with ll specified instead of ul
    ra = shp2recarray(os.path.join(path, 'pathlines_1per2_ll.shp'))
    p3_2 = ra.geometry[ra.particleid == 4][0]
    #sr3 = SpatialReference(xll=sr.xll, yll=sr.yll, rotation=-30,
    #                       delc=list(m.dis.delc))
    mg.set_coord_info(xoff=mg.xoffset, yoff=mg.yoffset, angrot=-30.0)
    assert np.abs(p3_2.x[0] - mg.xcellcenters[3, 4] + p3_2.y[0] -
                  mg.ycellcenters[3, 4]) < 1e-4

    xul = 3628793
    yul = 21940389

    m = flopy.modflow.Modflow.load('EXAMPLE.nam', model_ws=path)

    mg4 = m.modelgrid
    mg4.set_coord_info(xoff=mg4._xul_to_xll(xul, 0.0),
                       yoff=mg4._yul_to_yll(yul, 0.0),
                       angrot=0.0,
                       epsg=mg4.epsg,
                       proj4=mg4.proj4)

    fpth = os.path.join(path, 'dis2.shp')
    m.dis.export(fpth)
    pthobj = flopy.utils.PathlineFile(os.path.join(path, 'EXAMPLE-3.pathline'))
    fpth = os.path.join(path, 'pathlines_1per3.shp')
    pthobj.write_shapefile(shpname=fpth, direction='ending', mg=mg4)
コード例 #23
0
# make a shapefile!

circle = pd.DataFrame({'x':xcirc, 'y':ycirc})
# print(circle)


circle['cirque'] = circle.apply(lambda x: Point((float(x.x), float(x.y))), axis=1)

circle = geopandas.GeoDataFrame(circle, geometry = 'cirque')
circle.to_file('starting_circle.shp', driver='ESRI Shapefile')

# get the row/column!
delcl = np.ones(nrow)*(int(Lx/ncol))
delrl = delcl
sr = SpatialReference(delr=delrl, delc=delcl, xul=xul, yul=yul)

# the shapefile grid is wrong i think, because it's -1 on both sides
row_column=sr.get_rc(xcirc, ycirc)
row=row_column[0].tolist()
column=row_column[1].tolist()

# get the local x!
for i in column:
    for j in xcirc:
        print(j)
    # s1 = column[i]*delc
    # s2 = xul + s1
    # s3 = xcirc[i] - s2
    # s4 = delc - s3
    # s5 = 1 - (s4/delc)