__init__.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Fri May 25 12:56:33 2012
  4. @author: pietro
  5. """
  6. from __future__ import (nested_scopes, generators, division, absolute_import,
  7. with_statement, print_function, unicode_literals)
  8. import os
  9. import ctypes
  10. import numpy as np
  11. #
  12. # import GRASS modules
  13. #
  14. from grass.script import fatal, warning
  15. from grass.script import core as grasscore
  16. import grass.lib.gis as libgis
  17. import grass.lib.raster as libraster
  18. import grass.lib.rowio as librowio
  19. #
  20. # import pygrass modules
  21. #
  22. from grass.pygrass.errors import OpenError, must_be_open
  23. from grass.pygrass.gis.region import Region
  24. from grass.pygrass import functions
  25. #
  26. # import raster classes
  27. #
  28. from grass.pygrass.raster.abstract import RasterAbstractBase
  29. from grass.pygrass.raster.raster_type import TYPE as RTYPE, RTYPE_STR
  30. from grass.pygrass.raster.buffer import Buffer
  31. from grass.pygrass.raster.segment import Segment
  32. from grass.pygrass.raster.rowio import RowIO
  33. class RasterRow(RasterAbstractBase):
  34. """Raster_row_access": Inherits: "Raster_abstract_base" and implements
  35. the default row access of the Rast library.
  36. * Implements row access using row id
  37. * The get_row() method must accept a Row object as argument that will
  38. be used for value storage, so no new buffer will be allocated
  39. * Implements sequential writing of rows
  40. * Implements indexed value read only access using the [row][col]
  41. operator
  42. * Implements the [row] read method that returns a new Row object
  43. * Writing is limited using the put_row() method which accepts a
  44. Row as argument
  45. * No mathematical operation like __add__ and stuff for the Raster
  46. object (only for rows), since r.mapcalc is more sophisticated and
  47. faster
  48. Examples:
  49. >>> elev = RasterRow('elevation')
  50. >>> elev.exist()
  51. True
  52. >>> elev.is_open()
  53. False
  54. >>> elev.open()
  55. >>> elev.is_open()
  56. True
  57. >>> elev.has_cats()
  58. False
  59. >>> elev.mode
  60. u'r'
  61. >>> elev.mtype
  62. 'FCELL'
  63. >>> elev.num_cats()
  64. 0
  65. >>> elev.info.range
  66. (56, 156)
  67. >>> elev.info
  68. elevation@
  69. rows: 1350
  70. cols: 1500
  71. north: 228500.0 south: 215000.0 nsres:10.0
  72. east: 645000.0 west: 630000.0 ewres:10.0
  73. range: 56, 156
  74. proj: 99
  75. <BLANKLINE>
  76. Each Raster map have an attribute call ``cats`` that allow user
  77. to interact with the raster categories.
  78. >>> land = RasterRow('geology')
  79. >>> land.open()
  80. >>> land.cats # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
  81. [('Zml', 1, None),
  82. ...
  83. ('Tpyw', 1832, None)]
  84. Open a raster map using the *with statement*:
  85. >>> with RasterRow('elevation') as elev:
  86. ... for row in elev[:3]:
  87. ... row[:4]
  88. ...
  89. Buffer([ 141.99613953, 141.27848816, 141.37904358, 142.29821777], dtype=float32)
  90. Buffer([ 142.90461731, 142.39450073, 142.68611145, 143.59086609], dtype=float32)
  91. Buffer([ 143.81854248, 143.54707336, 143.83972168, 144.59527588], dtype=float32)
  92. >>> elev.is_open()
  93. False
  94. """
  95. def __init__(self, name, mapset='', *args, **kargs):
  96. super(RasterRow, self).__init__(name, mapset, *args, **kargs)
  97. # mode = "r", method = "row",
  98. @must_be_open
  99. def get_row(self, row, row_buffer=None):
  100. """Private method that return the row using the read mode
  101. call the `Rast_get_row` C function.
  102. :param row: the number of row to obtain
  103. :type row: int
  104. :param row_buffer: specify the Buffer object that will be instantiate
  105. :type row_buffer: bool
  106. >>> elev = RasterRow('elevation')
  107. >>> elev.open()
  108. >>> elev[0] # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
  109. Buffer([ 141.99613953, 141.27848816, 141.37904358, ..., 58.40825272,
  110. 58.30711365, 58.18310547], dtype=float32)
  111. >>> elev.get_row(0) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
  112. Buffer([ 141.99613953, 141.27848816, 141.37904358, ..., 58.40825272,
  113. 58.30711365, 58.18310547], dtype=float32)
  114. """
  115. if row_buffer is None:
  116. row_buffer = Buffer((self._cols,), self.mtype)
  117. libraster.Rast_get_row(self._fd, row_buffer.p, row, self._gtype)
  118. return row_buffer
  119. @must_be_open
  120. def put_row(self, row):
  121. """Private method to write the row sequentially.
  122. :param row: a Row object to insert into raster
  123. :type row: Buffer object
  124. """
  125. libraster.Rast_put_row(self._fd, row.p, self._gtype)
  126. def open(self, mode=None, mtype=None, overwrite=None):
  127. """Open the raster if exist or created a new one.
  128. :param str mode: Specify if the map will be open with read or write mode
  129. ('r', 'w')
  130. :param str type: If a new map is open, specify the type of the map(`CELL`,
  131. `FCELL`, `DCELL`)
  132. :param bool overwrite: Use this flag to set the overwrite mode of existing
  133. raster maps
  134. if the map already exist, automatically check the type and set:
  135. * self.mtype
  136. Set all the privite, attributes:
  137. * self._fd;
  138. * self._gtype
  139. * self._rows and self._cols
  140. """
  141. self.mode = mode if mode else self.mode
  142. self.mtype = mtype if mtype else self.mtype
  143. self.overwrite = overwrite if overwrite is not None else self.overwrite
  144. # check if exist and instantiate all the private attributes
  145. if self.exist():
  146. self.info.read()
  147. self.cats.mtype = self.mtype
  148. self.cats.read()
  149. self.hist.read()
  150. if self.mode == 'r':
  151. # the map exist, read mode
  152. self._fd = libraster.Rast_open_old(self.name, self.mapset)
  153. self._gtype = libraster.Rast_get_map_type(self._fd)
  154. self.mtype = RTYPE_STR[self._gtype]
  155. # try:
  156. # self.cats.read(self)
  157. # self.hist.read(self.name)
  158. # except:
  159. # import ipdb; ipdb.set_trace()
  160. elif self.overwrite:
  161. if self._gtype is None:
  162. raise OpenError(_("Raster type not defined"))
  163. self._fd = libraster.Rast_open_new(self.name, self._gtype)
  164. else:
  165. str_err = _("Raster map <{0}> already exists")
  166. raise OpenError(str_err.format(self))
  167. else:
  168. # Create a new map
  169. if self.mode == 'r':
  170. # check if we are in read mode
  171. str_err = _("The map does not exist, I can't open in 'r' mode")
  172. raise OpenError(str_err)
  173. self._fd = libraster.Rast_open_new(self.name, self._gtype)
  174. # read rows and cols from the active region
  175. self._rows = libraster.Rast_window_rows()
  176. self._cols = libraster.Rast_window_cols()
  177. class RasterRowIO(RasterRow):
  178. """Raster_row_cache_access": The same as "Raster_row_access" but uses
  179. the ROWIO library for cached row access
  180. """
  181. def __init__(self, name, *args, **kargs):
  182. self.rowio = RowIO()
  183. super(RasterRowIO, self).__init__(name, *args, **kargs)
  184. def open(self, mode=None, mtype=None, overwrite=False):
  185. """Open the raster if exist or created a new one.
  186. :param mode: specify if the map will be open with read or write mode
  187. ('r', 'w')
  188. :type mode: str
  189. :param type: if a new map is open, specify the type of the map(`CELL`,
  190. `FCELL`, `DCELL`)
  191. :type type: str
  192. :param overwrite: use this flag to set the overwrite mode of existing
  193. raster maps
  194. :type overwrite: bool
  195. """
  196. super(RasterRowIO, self).open(mode, mtype, overwrite)
  197. self.rowio.open(self._fd, self._rows, self._cols, self.mtype)
  198. @must_be_open
  199. def close(self):
  200. """Function to close the raster"""
  201. self.rowio.release()
  202. libraster.Rast_close(self._fd)
  203. # update rows and cols attributes
  204. self._rows = None
  205. self._cols = None
  206. self._fd = None
  207. @must_be_open
  208. def get_row(self, row, row_buffer=None):
  209. """This method returns the row using:
  210. * the read mode and
  211. * `rowcache` method
  212. :param row: the number of row to obtain
  213. :type row: int
  214. :param row_buffer: Specify the Buffer object that will be instantiate
  215. :type row_buffer: Buffer object
  216. """
  217. if row_buffer is None:
  218. row_buffer = Buffer((self._cols,), self.mtype)
  219. rowio_buf = librowio.Rowio_get(ctypes.byref(self.rowio.c_rowio), row)
  220. ctypes.memmove(row_buffer.p, rowio_buf, self.rowio.row_size)
  221. return row_buffer
  222. class RasterSegment(RasterAbstractBase):
  223. """Raster_segment_access": Inherits "Raster_abstract_base" and uses the
  224. segment library for cached randomly reading and writing access.
  225. * Implements the [row][col] operator for read and write access using
  226. segement_get() and segment_put() functions internally
  227. * Implements row read and write access with the [row] operator using
  228. segment_get_row() segment_put_row() internally
  229. * Implements the get_row() and put_row() method using
  230. segment_get_row() segment_put_row() internally
  231. * Implements the flush_segment() method
  232. * Implements the copying of raster maps to segments and vice verse
  233. * Overwrites the open and close methods
  234. * No mathematical operation like __add__ and stuff for the Raster
  235. object (only for rows), since r.mapcalc is more sophisticated and
  236. faster
  237. """
  238. def __init__(self, name, srows=64, scols=64, maxmem=100,
  239. *args, **kargs):
  240. self.segment = Segment(srows, scols, maxmem)
  241. super(RasterSegment, self).__init__(name, *args, **kargs)
  242. def _get_mode(self):
  243. return self._mode
  244. def _set_mode(self, mode):
  245. if mode and mode.lower() not in ('r', 'w', 'rw'):
  246. str_err = _("Mode type: {0} not supported ('r', 'w','rw')")
  247. raise ValueError(str_err.format(mode))
  248. self._mode = mode
  249. mode = property(fget=_get_mode, fset=_set_mode,
  250. doc="Set or obtain the opening mode of raster")
  251. def __setitem__(self, key, row):
  252. """Return the row of Raster object, slice allowed."""
  253. if isinstance(key, slice):
  254. #Get the start, stop, and step from the slice
  255. return [self.put_row(ii, row)
  256. for ii in range(*key.indices(len(self)))]
  257. elif isinstance(key, tuple):
  258. x, y = key
  259. return self.put(x, y, row)
  260. elif isinstance(key, int):
  261. if key < 0: # Handle negative indices
  262. key += self._rows
  263. if key >= self._rows:
  264. raise IndexError(_("Index out of range: %r.") % key)
  265. return self.put_row(key, row)
  266. else:
  267. raise TypeError("Invalid argument type.")
  268. @must_be_open
  269. def map2segment(self):
  270. """Transform an existing map to segment file.
  271. """
  272. row_buffer = Buffer((self._cols), self.mtype)
  273. for row in range(self._rows):
  274. libraster.Rast_get_row(
  275. self._fd, row_buffer.p, row, self._gtype)
  276. self.segment.put_row(row, row_buffer)
  277. @must_be_open
  278. def segment2map(self):
  279. """Transform the segment file to a map.
  280. """
  281. row_buffer = Buffer((self._cols), self.mtype)
  282. for row in range(self._rows):
  283. row_buffer = self.segment.get_row(row, row_buffer)
  284. libraster.Rast_put_row(self._fd, row_buffer.p, self._gtype)
  285. @must_be_open
  286. def get_row(self, row, row_buffer=None):
  287. """Return the row using the `segment.get_row` method
  288. :param row: specify the row number
  289. :type row: int
  290. :param row_buffer: specify the Buffer object that will be instantiate
  291. :type row_buffer: Buffer object
  292. """
  293. if row_buffer is None:
  294. row_buffer = Buffer((self._cols), self.mtype)
  295. return self.segment.get_row(row, row_buffer)
  296. @must_be_open
  297. def put_row(self, row, row_buffer):
  298. """Write the row using the `segment.put_row` method
  299. :param row: a Row object to insert into raster
  300. :type row: Buffer object
  301. """
  302. self.segment.put_row(row, row_buffer)
  303. @must_be_open
  304. def get(self, row, col):
  305. """Return the map value using the `segment.get` method
  306. :param row: Specify the row number
  307. :type row: int
  308. :param col: Specify the column number
  309. :type col: int
  310. """
  311. return self.segment.get(row, col)
  312. @must_be_open
  313. def put(self, row, col, val):
  314. """Write the value to the map using the `segment.put` method
  315. :param row: Specify the row number
  316. :type row: int
  317. :param col: Specify the column number
  318. :type col: int
  319. :param val: Specify the value that will be write to the map cell
  320. :type val: value
  321. """
  322. self.segment.val.value = val
  323. self.segment.put(row, col)
  324. def open(self, mode=None, mtype=None, overwrite=None):
  325. """Open the map, if the map already exist: determine the map type
  326. and copy the map to the segment files;
  327. else, open a new segment map.
  328. :param mode: specify if the map will be open with read, write or
  329. read/write mode ('r', 'w', 'rw')
  330. :type mode: str
  331. :param mtype: specify the map type, valid only for new maps: CELL,
  332. FCELL, DCELL
  333. :type mtype: str
  334. :param overwrite: use this flag to set the overwrite mode of existing
  335. raster maps
  336. :type overwrite: bool
  337. """
  338. # read rows and cols from the active region
  339. self._rows = libraster.Rast_window_rows()
  340. self._cols = libraster.Rast_window_cols()
  341. self.mode = mode if mode else self.mode
  342. self.mtype = mtype if mtype else self.mtype
  343. self.overwrite = overwrite if overwrite is not None else self.overwrite
  344. if self.exist():
  345. self.info.read()
  346. self.cats.mtype = self.mtype
  347. self.cats.read()
  348. self.hist.read()
  349. if ((self.mode == "w" or self.mode == "rw") and
  350. self.overwrite is False):
  351. str_err = _("Raster map <{0}> already exists. Use overwrite.")
  352. fatal(str_err.format(self))
  353. # We copy the raster map content into the segments
  354. if self.mode == "rw" or self.mode == "r":
  355. self._fd = libraster.Rast_open_old(self.name, self.mapset)
  356. self._gtype = libraster.Rast_get_map_type(self._fd)
  357. self.mtype = RTYPE_STR[self._gtype]
  358. # initialize the segment, I need to determine the mtype of the
  359. # map
  360. # before to open the segment
  361. self.segment.open(self)
  362. self.map2segment()
  363. self.segment.flush()
  364. self.cats.read(self)
  365. self.hist.read(self.name)
  366. if self.mode == "rw":
  367. warning(_(WARN_OVERWRITE.format(self)))
  368. # Close the file descriptor and open it as new again
  369. libraster.Rast_close(self._fd)
  370. self._fd = libraster.Rast_open_new(
  371. self.name, self._gtype)
  372. # Here we simply overwrite the existing map without content copying
  373. elif self.mode == "w":
  374. #warning(_(WARN_OVERWRITE.format(self)))
  375. self._gtype = RTYPE[self.mtype]['grass type']
  376. self.segment.open(self)
  377. self._fd = libraster.Rast_open_new(self.name, self._gtype)
  378. else:
  379. if self.mode == "r":
  380. str_err = _("Raster map <{0}> does not exists")
  381. raise OpenError(str_err.format(self.name))
  382. self._gtype = RTYPE[self.mtype]['grass type']
  383. self.segment.open(self)
  384. self._fd = libraster.Rast_open_new(self.name, self._gtype)
  385. @must_be_open
  386. def close(self, rm_temp_files=True):
  387. """Close the map, copy the segment files to the map.
  388. :param rm_temp_files: if True all the segments file will be removed
  389. :type rm_temp_files: bool
  390. """
  391. if self.mode == "w" or self.mode == "rw":
  392. self.segment.flush()
  393. self.segment2map()
  394. if rm_temp_files:
  395. self.segment.close()
  396. else:
  397. self.segment.release()
  398. libraster.Rast_close(self._fd)
  399. # update rows and cols attributes
  400. self._rows = None
  401. self._cols = None
  402. self._fd = None
  403. FLAGS = {1: {'b': 'i', 'i': 'i', 'u': 'i'},
  404. 2: {'b': 'i', 'i': 'i', 'u': 'i'},
  405. 4: {'f': 'f', 'i': 'i', 'b': 'i', 'u': 'i'},
  406. 8: {'f': 'd'}, }
  407. class RasterNumpy(np.memmap, RasterAbstractBase):
  408. """Raster_cached_narray": Inherits "Raster_abstract_base" and
  409. "numpy.memmap". Its purpose is to allow numpy narray like access to
  410. raster maps without loading the map into the main memory.
  411. * Behaves like a numpy array and supports all kind of mathematical
  412. operations: __add__, ...
  413. * Overrides the open and close methods
  414. * Be aware of the 2Gig file size limit
  415. >>> import grass.pygrass as pygrass
  416. >>> elev = pygrass.raster.RasterNumpy('elevation')
  417. >>> elev.open()
  418. >>> elev[:5, :3]
  419. RasterNumpy([[ 141.99613953, 141.27848816, 141.37904358],
  420. [ 142.90461731, 142.39450073, 142.68611145],
  421. [ 143.81854248, 143.54707336, 143.83972168],
  422. [ 144.56524658, 144.58493042, 144.86477661],
  423. [ 144.99488831, 145.22894287, 145.57142639]], dtype=float32)
  424. >>> el = elev < 144
  425. >>> el[:5, :3]
  426. RasterNumpy([[1, 1, 1],
  427. [1, 1, 1],
  428. [1, 1, 1],
  429. [0, 0, 0],
  430. [0, 0, 0]], dtype=int32)
  431. >>> el.exist()
  432. False
  433. >>> el.close('elev_bool', overwrite=True)
  434. >>> el.exist()
  435. True
  436. >>> el.remove()
  437. """
  438. def __new__(cls, name, mapset="", mtype='CELL', mode='r+',
  439. overwrite=False):
  440. reg = Region()
  441. shape = (reg.rows, reg.cols)
  442. mapset = libgis.G_find_raster(name, mapset)
  443. gtype = None
  444. if mapset:
  445. # map exist, set the map type
  446. gtype = libraster.Rast_map_type(name, mapset)
  447. mtype = RTYPE_STR[gtype]
  448. filename = grasscore.tempfile()
  449. obj = np.memmap.__new__(cls, filename=filename,
  450. dtype=RTYPE[mtype]['numpy'],
  451. mode=mode,
  452. shape=shape)
  453. obj.mtype = mtype.upper()
  454. obj.gtype = gtype if gtype else RTYPE[mtype]['grass type']
  455. obj._rows = reg.rows
  456. obj._cols = reg.cols
  457. obj.filename = filename
  458. obj._name = name
  459. obj.mapset = mapset
  460. obj.reg = reg
  461. obj.overwrite = overwrite
  462. return obj
  463. def __array_finalize__(self, obj):
  464. if hasattr(obj, '_mmap'):
  465. self._mmap = obj._mmap
  466. self.filename = grasscore.tempfile()
  467. self.offset = obj.offset
  468. self.mode = obj.mode
  469. self._rows = obj._rows
  470. self._cols = obj._cols
  471. self._name = None
  472. self.mapset = ''
  473. self.reg = obj.reg
  474. self.overwrite = obj.overwrite
  475. self.mtype = obj.mtype
  476. self._fd = obj._fd
  477. else:
  478. self._mmap = None
  479. def _get_mode(self):
  480. return self._mode
  481. def _set_mode(self, mode):
  482. if mode.lower() not in ('r', 'w+', 'r+', 'c'):
  483. raise ValueError(_("Mode type: {0} not supported.").format(mode))
  484. self._mode = mode
  485. mode = property(fget=_get_mode, fset=_set_mode,
  486. doc="Set or obtain the opening mode of raster")
  487. def __array_wrap__(self, out_arr, context=None):
  488. """See:
  489. http://docs.scipy.org/doc/numpy/user/
  490. basics.subclassing.html#array-wrap-for-ufuncs"""
  491. if out_arr.dtype.kind in 'bui':
  492. # there is not support for boolean maps, so convert into integer
  493. out_arr = out_arr.astype(np.int32)
  494. out_arr.mtype = 'CELL'
  495. #out_arr.p = out_arr.ctypes.data_as(out_arr.pointer_type)
  496. return np.ndarray.__array_wrap__(self, out_arr, context)
  497. def __init__(self, name, *args, **kargs):
  498. ## Private attribute `_fd` that return the file descriptor of the map
  499. self._fd = None
  500. rows, cols = self._rows, self._cols
  501. RasterAbstractBase.__init__(self, name)
  502. self._rows, self._cols = rows, cols
  503. def __unicode__(self):
  504. return RasterAbstractBase.__unicode__(self)
  505. def __str__(self):
  506. return self.__unicode__()
  507. def _get_flags(self, size, kind):
  508. if size in FLAGS:
  509. if kind in FLAGS[size]:
  510. return size, FLAGS[size][kind]
  511. else:
  512. raise ValueError(_('Invalid type {0}'.format(kind)))
  513. else:
  514. raise ValueError(_('Invalid size {0}'.format(size)))
  515. def _read(self):
  516. """!Read raster map into array
  517. :return: 0 on success
  518. :return: non-zero code on failure
  519. """
  520. with RasterRow(self.name, self.mapset, mode='r') as rst:
  521. buff = rst[0]
  522. for i in range(len(rst)):
  523. self[i] = rst.get_row(i, buff)
  524. def _write(self, name, overwrite):
  525. """Write the numpy array into map
  526. """
  527. if not self.exist() or self.mode != 'r':
  528. self.flush()
  529. buff = Buffer(self[0].shape, mtype=self.mtype)
  530. with RasterRow(name, self.mapset, mode='w',
  531. mtype=self.mtype, overwrite=overwrite) as rst:
  532. for i in range(len(rst)):
  533. buff[:] = self[i][:]
  534. rst.put_row(buff[:])
  535. self.name = name
  536. def open(self, mtype='', null=None, overwrite=None):
  537. """Open the map, if the map already exist: determine the map type
  538. and copy the map to the segment files;
  539. else, open a new segment map.
  540. :param mtype: specify the map type, valid only for new maps: CELL,
  541. FCELL, DCELL;
  542. :type mtype: str
  543. :param null:
  544. :type null:
  545. :param overwrite: use this flag to set the overwrite mode of existing
  546. raster maps
  547. :type overwrite: bool
  548. """
  549. if overwrite is not None:
  550. self.overwrite = overwrite
  551. self.null = null
  552. # rows and cols already set in __new__
  553. if self.exist():
  554. self.info.read()
  555. self.cats.mtype = self.mtype
  556. self.cats.read()
  557. self.hist.read()
  558. self._read()
  559. else:
  560. if mtype:
  561. self.mtype = mtype
  562. self._gtype = RTYPE[self.mtype]['grass type']
  563. # set _fd, because this attribute is used to check
  564. # if the map is open or not
  565. self._fd = 1
  566. def close(self, name='', overwrite=False):
  567. """Function to close the map
  568. :param name: the name of raster
  569. :type name: str
  570. """
  571. if self.is_open():
  572. name = name if name else self.name
  573. if not name:
  574. raise RuntimeError('Raster name not set neither '
  575. 'given as parameter.')
  576. self._write(name, overwrite)
  577. os.remove(self.filename)
  578. self._fd = None
  579. def get_value(self, point, region=None):
  580. """This method returns the pixel value of a given pair of coordinates:
  581. :param point: pair of coordinates in tuple object
  582. :type point: tuple
  583. :param region: the region to crop the request
  584. :type region: Region object
  585. """
  586. if not region:
  587. region = Region()
  588. x, y = functions.coor2pixel(point.coords(), region)
  589. return self[x][y]
  590. def random_map_only_columns(mapname, mtype, overwrite=True, factor=100):
  591. region = Region()
  592. random_map = RasterRow(mapname)
  593. row_buf = Buffer((region.cols, ), mtype,
  594. buffer=(np.random.random(region.cols,) * factor).data)
  595. random_map.open('w', mtype, overwrite)
  596. for _ in range(region.rows):
  597. random_map.put_row(row_buf)
  598. random_map.close()
  599. return random_map
  600. def random_map(mapname, mtype, overwrite=True, factor=100):
  601. region = Region()
  602. random_map = RasterRow(mapname)
  603. random_map.open('w', mtype, overwrite)
  604. for _ in range(region.rows):
  605. row_buf = Buffer((region.cols, ), mtype,
  606. buffer=(np.random.random(region.cols,) * factor).data)
  607. random_map.put_row(row_buf)
  608. random_map.close()
  609. return random_map