__init__.py 25 KB

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