[GRASS-SVN] r66071 - in grass/trunk/lib/python/pygrass/raster: . testsuite

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Aug 30 13:52:19 PDT 2015


Author: huhabla
Date: 2015-08-30 13:52:19 -0700 (Sun, 30 Aug 2015)
New Revision: 66071

Added:
   grass/trunk/lib/python/pygrass/raster/testsuite/test_raster_img.py
Modified:
   grass/trunk/lib/python/pygrass/raster/__init__.py
Log:
pygrass raster: Implemented the generation of numpy arrays out of raster map layers that 
represent 32bit ARGB or 8bit gray scale images. To be used in PyQt or Wx based map 
canvas that support pan, zoom or time series animations.


Modified: grass/trunk/lib/python/pygrass/raster/__init__.py
===================================================================
--- grass/trunk/lib/python/pygrass/raster/__init__.py	2015-08-30 20:49:14 UTC (rev 66070)
+++ grass/trunk/lib/python/pygrass/raster/__init__.py	2015-08-30 20:52:19 UTC (rev 66071)
@@ -614,6 +614,67 @@
         return np.array(rast)
 
 
+def raster2numpy_img(rastname, region, color="ARGB", array=None):
+    """Convert a raster map layer into a string with
+       32Bit ARGB or 8Bit Gray little endian encoding.
+    
+        Return a numpy array from a raster map of type uint8
+        that contains the colored map data as 32 bit ARGB or 8 bit image
+
+       :param rastname: The name of raster map
+       :type rastname: string
+       
+       :param region: The region to be used for raster map reading
+       :type region: grass.pygrass.gis.region.Region
+       
+       :param color: "ARGB", "GRAY1", "GRAY2"
+                     ARGB  -> 32Bit RGB with alpha channel
+                     GRAY1 -> grey scale formular: .33R+ .5G+ .17B
+                     GRAY2 -> grey scale formular: .30R+ .59G+ .11B
+       :type color: String
+
+       :param array: A numpy array (optional) to store the image, 
+                     the array needs to setup as follows:
+                     
+                     array = np.ndarray((region.rows*region.cols*scale), np.uint8)
+                     
+                     scale is 4 in case of ARGB or 1 in case of Gray scale
+       :type array: numpy.ndarray
+       
+       :return: A numpy array of size rows*cols*4 in case of ARGB and
+                rows*cols*1 in case of gray scale
+    
+       Attention: This function will change the computational raster region
+       of the current process while running.
+    """
+    from copy import deepcopy
+    region_orig = deepcopy(region)
+    # Set the raster region
+    region.set_raster_region()
+    
+    scale = 1
+    color_mode = 1
+    if color.upper() == "ARGB":
+        scale = 4
+        color_mode = 1
+    elif color.upper() == "GRAY1":
+        scale = 1
+        color_mode = 2
+    elif color.upper() == "GRAY2":
+        scale = 1
+        color_mode = 3
+        
+    if array is None:
+        array = np.ndarray((region.rows*region.cols*scale), np.uint8)
+
+    libraster.Rast_map_to_img_str(rastname, color_mode, 
+                                  array.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8)))
+    # Restore the raster region
+    region_orig.set_raster_region()
+    
+    return array
+
+
 def numpy2raster(array, mtype, rastname, overwrite=False):
     """Save a numpy array to a raster map
 

Added: grass/trunk/lib/python/pygrass/raster/testsuite/test_raster_img.py
===================================================================
--- grass/trunk/lib/python/pygrass/raster/testsuite/test_raster_img.py	                        (rev 0)
+++ grass/trunk/lib/python/pygrass/raster/testsuite/test_raster_img.py	2015-08-30 20:52:19 UTC (rev 66071)
@@ -0,0 +1,156 @@
+# -*- coding: utf-8
+import numpy as np
+import unittest
+import ctypes
+from unittest import skip
+
+from grass.gunittest.case import TestCase
+from grass.gunittest.main import test
+
+from grass.pygrass.raster import RasterRow
+from grass.pygrass.raster import raster2numpy_img
+from grass.pygrass.gis.region import Region
+from grass.script.core import tempfile
+
+has_PyQt4=False
+try:
+    from PyQt4.QtCore import *
+    from PyQt4.QtGui import *
+    has_PyQt4=True
+except:
+    pass
+
+class RasterRowImgTestCase(TestCase):
+
+    name = "RasterRowImgTestCase_map"
+
+    @classmethod
+    def setUpClass(cls):
+        """Create test raster map and region"""
+        cls.use_temp_region()
+        cls.runModule("g.region", n=60, s=0, e=40, w=0, res=0.1)
+        cls.runModule("r.mapcalc", expression="%s = if(row() >= 10 && row() <= 60, null(), row()  + (10.0 * col()))"%(cls.name),
+                                   overwrite=True)
+        cls.runModule("r.colors", map=cls.name, color="elevation")
+
+    @classmethod
+    def tearDownClass(cls):
+        """Remove the generated vector map, if exist"""
+        cls.runModule("g.remove", flags='f', type='raster', 
+                      name=cls.name)
+        cls.del_temp_region()
+
+    @unittest.skipIf(has_PyQt4 is False, "Require PyQt4")
+    def test_resampling_to_QImg_1(self):
+        
+        region = Region()
+        region.from_rast(self.name)
+        region.cols = 320
+        region.rows = 240
+        region.adjust()
+        
+        tmpfile = tempfile(False)
+        tmpfile = tmpfile + ".png"
+
+        a = raster2numpy_img(self.name, region)
+        
+        image = QImage(a.data, region.cols, region.rows, 
+                       QImage.Format_ARGB32)
+        #image.save("data/a.png")
+        image.save(tmpfile)
+        self.assertFilesEqualMd5(tmpfile, "data/a.png")
+        
+    @unittest.skipIf(has_PyQt4 is False, "Require PyQt4")
+    def test_resampling_to_QImg_2(self):
+        
+        region = Region()
+        region.from_rast(self.name)
+        region.cols = 640
+        region.rows = 480
+        region.adjust()
+        
+        tmpfile = tempfile(False)
+        tmpfile = tmpfile + ".png"
+
+        # With array as argument
+        array = np.ndarray((region.rows*region.cols*4), np.uint8)
+
+        raster2numpy_img(rastname=self.name, region=region, 
+                         color="ARGB", array=array)
+        
+        image = QImage(array.data, 
+                       region.cols, region.rows, QImage.Format_ARGB32)
+        #image.save("data/b.png")
+        image.save(tmpfile)
+        self.assertFilesEqualMd5(tmpfile, "data/b.png")
+        
+    @unittest.skipIf(has_PyQt4 is False, "Require PyQt4")
+    def test_resampling_to_QImg_large(self):
+        
+        region = Region()
+        region.from_rast(self.name)
+        region.cols = 4000
+        region.rows = 3000
+        region.adjust()
+        
+        tmpfile = tempfile(False)
+        tmpfile = tmpfile + ".png"
+
+        # With array as argument
+        array = np.ndarray((region.rows*region.cols*4), np.uint8)
+
+        raster2numpy_img(rastname=self.name, region=region, 
+                         color="ARGB", array=array)
+        
+        image = QImage(array.data, 
+                       region.cols, region.rows, QImage.Format_ARGB32)
+        #image.save("data/c.png")
+        image.save(tmpfile)
+        self.assertFilesEqualMd5(tmpfile, "data/c.png")
+        
+    def test_resampling_to_numpy_img_1(self):
+                
+        region = Region()
+        region.ewres = 10
+        region.nsres = 10
+        region.adjust(rows=True, cols=True)
+        
+        a = raster2numpy_img(self.name, region)
+        
+        self.assertEqual(len(a), region.rows * region.cols*4)
+
+    def test_resampling_to_numpy_img_2(self):
+                
+        region = Region()
+        region.ewres = 1
+        region.nsres = 1
+        region.adjust(rows=True, cols=True)
+        
+        a = raster2numpy_img(self.name, region)
+        
+        self.assertEqual(len(a), region.rows * region.cols*4)
+
+    def test_resampling_to_numpy_img_3(self):
+                
+        region = Region()
+        region.ewres = 0.4
+        region.nsres = 0.4
+        region.adjust(rows=True, cols=True)
+        
+        a = raster2numpy_img(self.name, region, color="GRAY1")
+        
+        self.assertEqual(len(a), region.rows * region.cols*1)
+
+    def test_resampling_to_numpy_img_4(self):
+                
+        region = Region()
+        region.ewres = 0.1
+        region.nsres = 0.1
+        region.adjust(rows=True, cols=True)
+        
+        a = raster2numpy_img(self.name, region, color="GRAY2")
+        
+        self.assertEqual(len(a), region.rows * region.cols*1)
+
+if __name__ == '__main__':
+    test()



More information about the grass-commit mailing list