[GRASS-dev] [GRASS GIS] #3845: pygrass + mapset resolution

GRASS GIS trac at osgeo.org
Tue May 14 03:33:41 PDT 2019


#3845: pygrass + mapset resolution
-------------------------+-------------------------
 Reporter:  pmav99       |      Owner:  grass-dev@…
     Type:  defect       |     Status:  new
 Priority:  normal       |  Milestone:
Component:  PyGRASS      |    Version:  svn-trunk
 Keywords:               |        CPU:  Unspecified
 Platform:  Unspecified  |
-------------------------+-------------------------
 I am not sure if this is a bug or just lack of understanding from my part.

 The following function:

 1. Creates a new (temporary) mapset (e.g. named A)
 2. Makes A the current mapset
 3. Creates a map inside A
 4. Confirms that the map exists
 5. Tries to open the map using RasterRow
 6. On exit, restores PERMANENT as the current mapset and **deletes** A

 You may call this function as many times as you want and it will work as
 long as you use the same mapset name. As soon as you change the mapset
 name though it will fail with the rather confusing exception:

 {{{
 grass.exceptions.OpenError: The map does not exist, I can't open in 'r'
 mode
 }}}

 Note: The function has confirmed that the map exists before the exception

 This is the code:

 {{{
 import grass.script as gscript
 import grass.pygrass as pygrass
 import grass.pygrass.raster
 import grass.pygrass.gis

 # import grass.lib.gis as libgis
 # libgis.G_gisinit("asdf")

 gscript.run_command("g.region", n=10, s=0, e=10, w=0, res=1)

 def test(mapset_name, map_name):
     # create a new mapset and make it the current one
     pygrass.gis.make_mapset(mapset_name)
     pygrass.gis.set_current_mapset(mapset_name)

     # Create a map inside the new mapset and try to open it using pygrass
 methods
     try:
         mapset = pygrass.gis.Mapset(mapset_name)
         assert mapset.glist("raster") == []
         gscript.run_command("r.mapcalc", expression=f"{map_name}=1",
 quiet=True)
         assert mapset.glist("raster") == [map_name]
         # OK we've proved that the map exists and that the mapset object
 can see it
         # Let's now try to open the map though. As we will see, opening
 the map will fail
         r = pygrass.raster.RasterRow(map_name)
         r.open()                                        # you will get an
 exception here
         assert r.is_open()
     finally:
         # cleanup
         pygrass.gis.set_current_mapset("PERMANENT")
         mapset.delete()


 # (Re-)create and delete the "aaa" mapset as many times as you want.
 # Everything will be working just fine.
 test("aaa", "m1")
 test("aaa", "m1")
 test("aaa", "m1")
 test("aaa", "m2")
 test("aaa", "m2")
 test("aaa", "m1")

 # But as soon as you try to create a mapset with a different name
 # pygrass will no longer be able to resolve map names.
 test("bbb", "m1")       # this will fail
 }}}

 As soon as you figure out what the problem is, it is not difficult to work
 around it. In this case You just need to specify the mapset name when you
 create the {{{RasterRow}}} instance. I.e. if you apply the following
 patch, the function will no longer raise an Exception:

 {{{
 -        r = pygrass.raster.RasterRow(map_name)
 +        r = pygrass.raster.RasterRow(map_name, mapset_name)
 }}}

 I guess that the same is true for {{{pygrass.utils.get_mapset_raster()}}}
 and possible other similar function and classes.

 If I have understood this correctly, the problem seems to be in the
 {{{G_find_raster*()}}} functions which for some reason seem to "get stuck"
 to the initial mapset name.

 1. Is this documented and I somehow completely missed that?
 2. When creating a new mapset, do we need to call some function from e.g.
 {{{grass.lib.gis}}} in order to get name resolution working?
 3. If not, should we make {{{get_mapset_raster}}} and friends explicitly
 pass the current mapset to {{{G_find_raster*()}}} if a mapset has not been
 specified?

-- 
Ticket URL: <https://trac.osgeo.org/grass/ticket/3845>
GRASS GIS <https://grass.osgeo.org>



More information about the grass-dev mailing list