render_cmd.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #!/usr/bin/env python3
  2. import os
  3. import sys
  4. import tempfile
  5. from grass.script import core as grass
  6. from grass.script import task as gtask
  7. from grass.exceptions import CalledModuleError
  8. # read environment variables from file
  9. def read_env_file(env_file):
  10. width = height = legfile = None
  11. fd = open(env_file, "r")
  12. if fd is None:
  13. grass.fatal("Unable to open file '{0}'".format(env_file))
  14. lines = fd.readlines()
  15. for line in lines:
  16. if line.startswith("#"):
  17. continue
  18. k, v = line.rstrip("\n").split("#", 1)[0].strip().split("=", 1)
  19. os.environ[k] = v
  20. if width is None and k == "GRASS_RENDER_WIDTH":
  21. width = int(v)
  22. if height is None and k == "GRASS_RENDER_HEIGHT":
  23. height = int(v)
  24. if legfile is None and k == "GRASS_LEGEND_FILE":
  25. legfile = v
  26. fd.close()
  27. if width is None or height is None:
  28. grass.fatal("Unknown monitor size")
  29. return width, height, legfile
  30. # run display command
  31. def render(cmd, mapfile):
  32. env = os.environ.copy()
  33. if mapfile:
  34. env["GRASS_RENDER_FILE"] = mapfile
  35. try:
  36. grass.run_command(cmd[0], env=env, **cmd[1])
  37. except CalledModuleError as e:
  38. grass.debug("Unable to render: {0}".format(e), 1)
  39. # update cmd file
  40. def update_cmd_file(cmd_file, cmd, mapfile):
  41. if cmd[0] in (
  42. "d.colorlist",
  43. "d.font",
  44. "d.fontlist",
  45. "d.frame",
  46. "d.info",
  47. "d.mon",
  48. "d.out.file",
  49. "d.redraw",
  50. "d.to.rast",
  51. "d.what.rast",
  52. "d.what.vect",
  53. "d.where",
  54. ):
  55. return
  56. mode = "w" if cmd[0] == "d.erase" else "a"
  57. # update cmd file
  58. fd = open(cmd_file, mode)
  59. if fd is None:
  60. grass.fatal("Unable to open file '{0}'".format(cmd_file))
  61. if mode == "a":
  62. frame = os.getenv("GRASS_RENDER_FRAME", None)
  63. if frame:
  64. fd.write("# GRASS_RENDER_FRAME={0}\n".format(frame))
  65. if mapfile:
  66. fd.write("# GRASS_RENDER_FILE={0}\n".format(mapfile))
  67. fd.write(" ".join(gtask.cmdtuple_to_list(cmd)))
  68. fd.write("\n")
  69. else:
  70. fd.write("")
  71. fd.close()
  72. # adjust region
  73. def adjust_region(width, height):
  74. region = grass.region()
  75. mapwidth = abs(region["e"] - region["w"])
  76. mapheight = abs(region["n"] - region["s"])
  77. region["nsres"] = mapheight / height
  78. region["ewres"] = mapwidth / width
  79. region["rows"] = int(round(mapheight / region["nsres"]))
  80. region["cols"] = int(round(mapwidth / region["ewres"]))
  81. region["cells"] = region["rows"] * region["cols"]
  82. kwdata = [
  83. ("proj", "projection"),
  84. ("zone", "zone"),
  85. ("north", "n"),
  86. ("south", "s"),
  87. ("east", "e"),
  88. ("west", "w"),
  89. ("cols", "cols"),
  90. ("rows", "rows"),
  91. ("e-w resol", "ewres"),
  92. ("n-s resol", "nsres"),
  93. ]
  94. grass_region = ""
  95. for wkey, rkey in kwdata:
  96. grass_region += "%s: %s;" % (wkey, region[rkey])
  97. os.environ["GRASS_REGION"] = grass_region
  98. # read any input from stdin and create a temporary file
  99. def read_stdin(cmd):
  100. opt = None
  101. if (
  102. cmd[0] == "d.text"
  103. and "text" not in cmd[1]
  104. and ("input" not in cmd[1] or cmd[1]["input"] == "-")
  105. ):
  106. if sys.stdin.isatty():
  107. sys.stderr.write(
  108. "\nPlease enter text instructions."
  109. " Enter EOF (ctrl-d) on last line to quit.\n"
  110. )
  111. opt = "input"
  112. if opt:
  113. tmpfile = tempfile.NamedTemporaryFile(dir=path).name + ".txt"
  114. fd = open(tmpfile, "w")
  115. while 1:
  116. line = sys.stdin.readline()
  117. if not line:
  118. break
  119. fd.write(line)
  120. fd.close()
  121. cmd[1][opt] = tmpfile
  122. if __name__ == "__main__":
  123. cmd = gtask.cmdstring_to_tuple(sys.argv[1])
  124. if not cmd[0] or cmd[0] == "d.mon":
  125. sys.exit(0)
  126. path = os.path.dirname(os.path.abspath(__file__))
  127. mon = os.path.split(path)[-1]
  128. width, height, legfile = read_env_file(os.path.join(path, "env"))
  129. if mon.startswith("wx"):
  130. mapfile = tempfile.NamedTemporaryFile(dir=path).name
  131. if cmd[0] in ("d.barscale", "d.legend", "d.northarrow", "d.legend.vect"):
  132. mapfile += ".png"
  133. else:
  134. mapfile += ".ppm"
  135. else:
  136. mapfile = None
  137. adjust_region(width, height)
  138. read_stdin(cmd)
  139. render(cmd, mapfile)
  140. update_cmd_file(os.path.join(path, "cmd"), cmd, mapfile)
  141. if cmd[0] == "d.erase" and os.path.exists(legfile):
  142. os.remove(legfile)
  143. sys.exit(0)