[GRASS-SVN] r70725 - grass/trunk/tools

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Mar 4 09:05:08 PST 2017


Author: wenzeslaus
Date: 2017-03-04 09:05:07 -0800 (Sat, 04 Mar 2017)
New Revision: 70725

Modified:
   grass/trunk/tools/thumbnails.py
Log:
replace g.ppmtopng and d.colortable by g.region, r.mapcalc and d.rast (see #3200)

PNG is now created directly correctly rotated. No flipping seems to be needed.
Same white-black border as from d.colortable done by d.graph but black just one pixel wide
resulting in images with lighter apparance.
No issue with missing black corner visible. All images have all borders (e.g. random, grey.log).
kelvin starts correctly with color (not white for nv), population correctly start with white,
gdd still starts with potentially too much white (0 white, 0.00001 grey) and is tricky to
satisfy by the same code as kelvin and grey1.0.
Alternative implementation could use frames and simpler r.mapcalc expressions. 
Border colors can be easilly changed, but widths would need some refactoring of constants.
Leaving the PPM manipulation code there.


Modified: grass/trunk/tools/thumbnails.py
===================================================================
--- grass/trunk/tools/thumbnails.py	2017-03-03 20:23:56 UTC (rev 70724)
+++ grass/trunk/tools/thumbnails.py	2017-03-04 17:05:07 UTC (rev 70725)
@@ -14,6 +14,7 @@
 
 import sys
 import os
+import shutil
 import atexit
 import string
 import array
@@ -23,8 +24,8 @@
 tmp_grad_abs = None
 tmp_grad_rel = None
 
-height = 85
-width = 15
+height = 15
+width = 85
 
 def cleanup():
     if tmp_img:
@@ -96,6 +97,8 @@
     else:
         grass.fatal(_("Cannot find g.ppmtopng, pnmtopng or convert"))
 
+# TODO: this code is not used and can be moved to some lib function or
+# separate module if useful
 def convert_and_rotate(src, dst, flip = False):
     ppm = read_ppm(src)
     if flip:
@@ -135,26 +138,52 @@
             maxval = 0.04
         else:
             minval = float(records[0][0])
+            # shift min up for floating point values so that
+            # first color in color table is visible
+            if '.' in records[0][0]:
+                # assumes that 1% of min does not go to the next value
+                # and is still represented as float and does not make
+                # too much difference in color
+                # works better than 1% of the difference to the next value
+                minval += abs(minval / 100)
             maxval = float(records[-1][0])
             maxval = min(maxval, 2500000)
         grad = tmp_grad_abs
-        grass.mapcalc("$grad = if(row()==1, float($min), float($max))",
+        # alternatively, only simpler expression would suffice if frames
+        # are used to render raster and then the borders
+        grass.mapcalc("$grad = if(col() > 2 && col() < ncols() - 1,"
+                      " float($min) + (col() - 3) * (float($max) - float($min)) / (ncols() - 2),"
+                      " null())",
         	      grad = tmp_grad_abs, min = minval, max = maxval, quiet = True)
     else:
         grad = tmp_grad_rel
 
     return grad
 
-def make_image(output_dir, table, grad, discrete = False):
-    if discrete:
-        lines, cols = height, 1
-    else:
-        lines, cols = None, None
+def make_image(output_dir, table, grad):
     grass.run_command("r.colors", map = grad, color = table, quiet = True)
-    grass.run_command("d.colortable", flags = 'n', map = grad,
-                      lines = lines, columns = cols, quiet = True)
+    grass.run_command("d.rast", map=grad, quiet=True)
+    if 1:
+        grass.write_command("d.graph", quiet=True, flags='m', stdin="""width 1
+        color {outcolor}
+        polyline
+        {x1} {y1}
+        {x2} {y1}
+        {x2} {y2}
+        {x1} {y2}
+        {x1} {y1}
+        color {incolor}
+        polyline
+        {x3} {y3}
+        {x4} {y3}
+        {x4} {y4}
+        {x3} {y4}
+        {x3} {y3}
+        """.format(x1=1, x2=width, y1=0, y2=height - 1,
+                   x3=2, x4=width - 1, y3=1, y4=height - 2,
+                   outcolor='white', incolor='black'))
     outfile = os.path.join(output_dir, "colortables", "%s.png" % table)
-    convert_and_rotate(tmp_img, outfile, discrete)
+    shutil.move(tmp_img, outfile)
 
 def main():
     global tmp_img, tmp_grad_abs, tmp_grad_rel
@@ -170,36 +199,43 @@
     pid = os.getpid()
     tmp_grad_abs = "tmp_grad_abs_%d" % pid
     tmp_grad_rel = "tmp_grad_rel_%d" % pid
-    tmp_img = grass.tempfile() + ".ppm"
+    tmp_img = grass.tempfile() + ".png"
 
     os.environ['GRASS_RENDER_WIDTH'] = '%d' % width
     os.environ['GRASS_RENDER_HEIGHT'] = '%d' % height
     os.environ['GRASS_RENDER_FRAME'] = '%f,%f,%f,%f' % (0,height,0,width)
     os.environ['GRASS_RENDER_FILE'] = tmp_img
     os.environ['GRASS_RENDER_TRUECOLOR'] = 'TRUE'
-    os.environ['GRASS_RENDER_FILE_READ'] = 'FALSE'
+    # for multiple d commands (requires to delete/move image each time)
+    os.environ['GRASS_RENDER_FILE_READ'] = 'TRUE'
     os.environ['GRASS_RENDER_FILE_MAPPED'] = 'FALSE'
     os.environ['GRASS_RENDER_TRANSPARENT'] = 'FALSE'
     os.environ['GRASS_RENDER_BACKGROUNDCOLOR'] = 'ffffff'
     os.environ['GRASS_RENDER_IMMEDIATE'] = 'cairo'
+    # for one pixel wide lines
+    os.environ['GRASS_RENDER_ANTIALIAS'] = 'none'
 
-    for var in ['GRASS_RENDER_LINE_WIDTH', 'GRASS_RENDER_ANTIALIAS']:
+    for var in ['GRASS_RENDER_LINE_WIDTH']:
         if var in os.environ:
             del os.environ[var]
 
     grass.use_temp_region()
-    grass.run_command('g.region', rows = 100, cols = 100)
+    grass.run_command('g.region', s=0, w=0, n=height, e=width,
+                      rows=height, cols=width, res=1, flags='a')
 
-    grass.mapcalc("$grad = row()/1.0", grad = tmp_grad_rel, quiet = True)
+    grass.mapcalc("$grad = if(col() > 2 && col() < ncols() - 1,"
+                  " float(col()), null())", grad=tmp_grad_rel, quiet=True)
     
     for table in os.listdir(color_dir):
         path = os.path.join(color_dir, table)
         grad = make_gradient(path)
         make_image(output_dir, table, grad)
-    
-    grass.mapcalc("$grad = row()", grad = tmp_grad_abs, quiet = True)
+
+    grass.mapcalc("$grad = if(col() > 2 && col() < ncols() - 1,"
+                  " col(), null())", grad=tmp_grad_abs, quiet=True)
     for table in ['grey.eq', 'grey.log', 'random']:
-        make_image(output_dir, table, tmp_grad_abs, True)
+        make_image(output_dir, table, tmp_grad_abs)
+
  
 if __name__ == "__main__":
     atexit.register(cleanup)



More information about the grass-commit mailing list