Explorar o código

d.frame: copy from addons (waiting for upgrade to the new d.mon architecture)

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@64416 15284696-431f-4ddb-bdfa-cd5b030d7da7
Martin Landa %!s(int64=10) %!d(string=hai) anos
pai
achega
e78d6d37ed
Modificáronse 4 ficheiros con 360 adicións e 0 borrados
  1. 7 0
      scripts/d.frame/Makefile
  2. 95 0
      scripts/d.frame/d.frame.html
  3. 258 0
      scripts/d.frame/d.frame.py
  4. BIN=BIN
      scripts/d.frame/d_frame.png

+ 7 - 0
scripts/d.frame/Makefile

@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../..
+
+PGM = d.frame
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script

+ 95 - 0
scripts/d.frame/d.frame.html

@@ -0,0 +1,95 @@
+<h2>DESCRIPTION</h2>
+
+<em>d.frame</em> manages display frames on the current user's graphics
+monitor. Graphics are displayed in rectangular frames on whatever
+graphics monitor the user is currently directing GRASS display output
+to (defined by <em><a href="d.mon.html">d.mon</a></em> module). These
+frames are created and managed with this module.
+
+<p>
+Note that GRASS frame contents <em>are not</em> retained when one
+frame covers another. You cannot shuffle frames from top to bottom and
+then back again. They simply define rectangular areas on the screen
+where subsequent drawing will occur.
+
+<h2>NOTES</h2>
+
+The coordinates for the <b>at</b> option are stated in the form
+<em>top,bottom,left,right</em> values are in percent. The upper-left
+corner of the graphics monitor always is at location 0,0 while the
+monitor's lower-right corner is always at 100,100.
+
+<p>
+If the user has created multiple display frames that overlap one another, 
+whatever the user displays in the active frame will overwrite 
+those portions of the underlying frame where these frames overlap. 
+
+<h2>EXAMPLE</h2>
+
+<div class="code"><pre>
+# start a new graphics monitor, the data will be rendered to
+# /tmp/map.png image output file of size 600x540px
+d.mon cairo out=/tmp/map.png width=600 height=540 --o
+
+# set up region
+g.region raster=elevation
+
+# remove all frames and erase the current graphics monitor
+d.frame -e
+
+# create a first frame and display 'landuse96_28m' raster map including text label
+d.frame -c frame=first at=0,50,0,50
+d.rast landuse96_28m
+d.text text='Landuse' bgcolor=220:220:220 color=black size=6
+
+# create a second frame and display 'streams' vector map
+d.frame -c frame=second at=0,50,50,100
+d.vect streams color=blue
+d.text text='Streams' bgcolor=220:220:220 color=black size=6
+
+# create a third frame and display 'elevation' raster map including text label and scale
+d.frame -c frame=third at=50,100,0,50
+d.rast elevation
+d.text text='Elevation' bgcolor=220:220:220 color=black size=6
+d.barscale at=0,10 style=line bgcolor=none
+
+# create a fourth frame and display RGB composition map including text label
+d.frame -c frame=fourth at=50,100,50,100
+d.rgb red=lsat7_2002_30 green=lsat7_2002_20 blue=lsat7_2002_10
+d.text text='RGB true colors' bgcolor=220:220:220 color=black size=6
+
+# release the current graphics monitor
+d.mon -r
+</pre></div>
+
+<center>
+  <img src="d_frame.png" alt="d.frame example"><br>
+  <em>Figure: d.frame example</em>
+</center>
+
+<h2>SEE ALSO</h2>
+
+<em>
+  <a href="d.erase.html">d.erase</a>,
+  <a href="d.info.html">d.info</a>,
+  <a href="d.mon.html">d.mon</a>,
+  <a href="d.redraw.html">d.redraw</a>
+</em>
+
+<p>
+  <a href="variables.html#rendering">GRASS environment variables for
+  rendering</a> (GRASS_RENDER_FRAME)
+  
+<h2>AUTHOR</h2>
+
+Martin Landa, Czech Technical University in Prague, Czech Republic
+
+<p>
+Based on <em>d.frame</em> from GRASS 6:<br>
+James Westervelt, U.S. Army Construction Engineering Research
+Laboratory<br>
+Michael Shapiro, U.S. Army Construction Engineering 
+Research Laboratory
+
+<p>
+<i>Last changed: $Date$</i>

+ 258 - 0
scripts/d.frame/d.frame.py

@@ -0,0 +1,258 @@
+#!/usr/bin/env python
+
+############################################################################
+#
+# MODULE:       d.frame
+# AUTHOR(S):    Martin Landa <landa.martin gmail.com>
+#               Based on d.frame from GRASS 6
+# PURPOSE:      Manages display frames on the user's graphics monitor
+# COPYRIGHT:    (C) 2014 by Martin Landa, and the GRASS Development Team
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+############################################################################
+#%module
+#% description: Manages display frames on the user's graphics monitor.
+#% keyword: display
+#% keyword: graphics
+#% keyword: monitors
+#% keyword: frame
+#% overwrite: yes
+#%end
+#%flag
+#% key: c
+#% description: Create a new frame if doesn't exist and select
+#%end
+#%flag
+#% key: e
+#% description: Remove all frames, erase the screen and exit
+#% suppress_required: yes
+#%end
+#%flag
+#% key: p
+#% description: Print name of current frame and exit
+#% suppress_required: yes
+#%end
+#%flag
+#% key: a
+#% description: Print names of all frames including 'at' position and exit
+#% suppress_required: yes
+#%end
+#%option
+#% key: frame
+#% type: string
+#% required: yes
+#% multiple: no
+#% key_desc: name
+#% description: Frame to be selected or created (if -c flag is given)
+#%end
+#%option
+#% key: at
+#% type: double
+#% required: no
+#% multiple: no
+#% key_desc: bottom,top,left,right
+#% label: Screen coordinates in percent where to place the frame (0,0 is lower-left)
+#% options: 0-100
+#% description: Implies only when -c or --overwrite flag is given
+#%end
+
+import os
+import sys
+
+from grass.script.core import parser, read_command, fatal, debug, run_command, gisenv, warning
+
+# check if monitor is running
+def check_monitor():
+    return read_command('d.mon', flags='p', quiet=True).strip()
+
+# read monitor file and return list of lines
+def read_monitor_file(monitor, ftype='env'):
+    mfile = check_monitor_file(monitor, ftype)
+    try:
+        fd = open(mfile, 'r')
+    except IOError as e:
+        fatal(_("Unable to get monitor info. %s"), e)
+
+    lines = []
+    for line in fd.readlines():
+        lines.append(line)
+
+    fd.close()
+    
+    return lines
+
+# check if monitor file exists
+def check_monitor_file(monitor, ftype='env'):
+    var = 'MONITOR_%s_%sFILE' % (monitor.upper(), ftype.upper())
+    mfile = gisenv().get(var, None)
+    if mfile is None or not os.path.isfile(mfile):
+        fatal(_("Unable to get monitor info (no %s found)") % var)
+    
+    return mfile
+
+# write new monitor file
+def write_monitor_file(monitor, lines, ftype='env'):
+    mfile = check_monitor_file(monitor, ftype)
+
+    try:
+        fd = open(mfile, 'w')
+    except IOError as e:
+        fatal(_("Unable to get monitor info. %s"), e)
+
+    fd.writelines(lines)
+    fd.close()
+
+# remove all frames and erase screen
+def erase(monitor):
+    # remove frames
+    lines = []
+    for line in read_monitor_file(monitor):
+        if 'FRAME' not in line:
+            lines.append(line)
+            
+    write_monitor_file(monitor, lines)
+    
+    # erase screen
+    run_command('d.erase')
+
+# find frame for given monitor
+def find_frame(monitor, frame):
+    for line in read_monitor_file(monitor):
+        if 'FRAME' in line:
+            if get_frame_name(line) == frame:
+                return True
+
+    return False
+
+# print frames name(s) to stdout
+def print_frames(monitor, current_only=False, full=False):
+    for line in read_monitor_file(monitor):
+        if 'FRAME' not in line:
+            continue
+        if current_only and line.startswith('#'):
+            continue
+        sys.stdout.write(get_frame_name(line))
+        if full:
+            sys.stdout.write(':' + line.split('=', 1)[1].rsplit('#', 1)[0])
+        sys.stdout.write('\n')
+
+# get frame name from line
+def get_frame_name(line):
+    return line.rstrip('\n').rsplit('#', 1)[1].strip(' ')
+
+# calculate position of the frame in percent
+def calculate_frame(frame, at, width, height):
+    try:
+        b, t, l, r = map(float, at.split(','))
+    except:
+        fatal(_("Invalid frame position: %s") % at)
+
+    top = height - (t / 100. * height)
+    bottom = height - (b / 100. * height)
+    left = l / 100. * width
+    right = r / 100. * width
+    
+    return 'GRASS_RENDER_FRAME=%d,%d,%d,%d # %s%s' % \
+        (top, bottom, left, right, frame, '\n')
+    
+# create new frame
+def create_frame(monitor, frame, at, overwrite=False):
+    lines = read_monitor_file(monitor)
+    # get width and height of the monitor
+    width = height = -1
+    for line in lines:
+        try:
+            if 'WIDTH' in line:
+                width = int(line.split('=', 1)[1].rsplit(' ', 1)[0])
+            elif 'HEIGHT' in line:
+                height = int(line.split('=', 1)[1].rsplit(' ', 1)[0])
+        except:
+            pass
+
+    if width < 0 or height < 0:
+        fatal(_("Invalid monitor size: %dx%d") % (width, height))
+    
+    if not overwrite:
+        lines.append(calculate_frame(frame, at, width, height))
+    else:
+        for idx in range(len(lines)):
+            line = lines[idx]
+            if 'FRAME' not in line:
+                continue
+            if get_frame_name(line) == frame:
+                lines[idx] = calculate_frame(frame, at, width, height)
+    
+    write_monitor_file(monitor, lines)
+
+# select existing frame
+def select_frame(monitor, frame):
+    lines = read_monitor_file(monitor)
+    for idx in range(len(lines)):
+        line = lines[idx]
+        if 'FRAME' not in line:
+            continue
+        if get_frame_name(line) == frame:
+            if line.startswith('#'):
+                lines[idx] = line.lstrip('# ') # un-comment line
+        elif not line.startswith('#'):
+            lines[idx] = '# ' + line # comment-line
+    
+    write_monitor_file(monitor, lines)
+    
+def main():
+    # get currently selected monitor
+    monitor = check_monitor()
+    if not monitor:
+        fatal(_("No graphics device selected. Use d.mon to select graphics device."))
+    if monitor not in ('png', 'cairo'):
+        fatal(_("Only Cairo or PNG monitors are currently supported"))
+    
+    if flags['e']:
+        # remove frames and erase monitor and exit
+        erase(monitor)
+        return
+    
+    if flags['p']:
+        # print current frame and exit
+        print_frames(monitor, current_only=True)
+        return
+        
+    if flags['a']:
+        # print all frames including their position and exit
+        print_frames(monitor, current_only=False, full=True)
+        return
+
+    found = find_frame(monitor, options['frame'])
+    if not found:
+        if not flags['c']:
+            fatal(_("Frame <%s> doesn't exist, exiting. "
+                    "To create a new frame use '-c' flag.") % options['frame'])
+        else:
+            if not options['at']:
+                fatal(_("Required parameter <%s> not set") % "at")
+            # create new frame if not exists
+            create_frame(monitor, options['frame'], options['at'])
+    else:
+        if os.getenv('GRASS_OVERWRITE', '0') == '1':
+            warning(_("Frame <%s> already exists and will be overwritten") % options['frame'])
+            create_frame(monitor, options['frame'], options['at'], overwrite=True)
+        else:
+            if options['at']:
+                warning(_("Frame <%s> already found. An existing frame can be overwritten by '%s' flag.") % \
+                        (options['frame'], "--overwrite"))
+    
+    # select givenframe 
+    select_frame(monitor, options['frame'])
+            
+if __name__ == "__main__":
+    options, flags = parser()
+    sys.exit(main())

BIN=BIN
scripts/d.frame/d_frame.png