raster.rst 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. .. _raster-label:
  2. Introduction to Raster classes
  3. ==============================
  4. Details about the architecture can be found in the `GRASS GIS 7 Programmer's Manual: GRASS Raster Library <http://grass.osgeo.org/programming7/rasterlib.html>`_
  5. PyGRASS uses 4 different Raster classes, that respect the 4 different approaches
  6. of GRASS-C API.
  7. The read access is row wise for :ref:`RasterRow-label` and
  8. :ref:`RasterRowIO-label` and additionally
  9. cached in the RowIO class. Both classes write sequentially.
  10. RowIO is row cached, :ref:`RasterSegment-label` and :ref:`RasterNumpy-label`
  11. are tile cached for reading and writing therefore a randomly access is possible.
  12. Hence RasterRow and RasterRowIO should be used in case for fast (cached)
  13. row read access and RasterRow for fast sequential writing.
  14. Segment and Numpy should be used for random access, but Numpy only for files
  15. not larger than 2GB.
  16. ========================== ======================= ======== ============
  17. Class Name C library Read Write
  18. ========================== ======================= ======== ============
  19. :ref:`RasterRow-label` `Raster library`_ randomly sequentially
  20. :ref:`RasterRowIO-label` `RowIO library`_ cached no
  21. :ref:`RasterSegment-label` `Segmentation library`_ cached randomly
  22. :ref:`RasterNumpy-label` `numpy.memmap`_ cached randomly
  23. ========================== ======================= ======== ============
  24. All these classes share common methods and attributes, necessary to address
  25. common tasks as rename, remove, open, close, exist, is_open.
  26. In the next examples we instantiate a RasterRow object. ::
  27. >>> from pygrass import raster
  28. >>> elev = raster.RasterRow('elevation')
  29. >>> elev.name
  30. 'elevation'
  31. >>> print(elev)
  32. elevation@PERMANENT
  33. >>> elev.exist()
  34. True
  35. >>> elev.is_open()
  36. False
  37. >>> new = raster.RasterRow('new')
  38. >>> new.exist()
  39. False
  40. >>> new.is_open()
  41. False
  42. We can rename the map: ::
  43. >>> # setting the attribute
  44. >>> new.name = 'new_map'
  45. >>> print(new)
  46. new_map
  47. >>> # or using the rename methods
  48. >>> new.rename('new')
  49. >>> print(new)
  50. new
  51. .. _RasterRow-label:
  52. RastRow
  53. -------
  54. PyGrass allow user to open the maps, in read and write mode,
  55. row by row using the `Raster library`_, there is not support to read and write
  56. to the same map at the same time, for this functionality, please see the
  57. :ref:`RasterSegment-label` and :ref:`RasterNumpy-label` classes.
  58. The RasterRow class allow to read in a randomly order the row from a map, but
  59. it is only possible to write the map using only a sequence order, therefore every
  60. time you are writing a new map, the row is add to the file as the last row. ::
  61. >>> raster = reload(raster)
  62. >>> elev = raster.RasterRow('elevation')
  63. >>> # the cols attribute is set from the current region only when the map is open
  64. >>> elev.cols
  65. >>> elev.open()
  66. >>> elev.is_open()
  67. True
  68. >>> elev.cols
  69. 1500
  70. >>> # we can read the elevation map, row by row
  71. >>> for row in elev[:5]: print(row[:3])
  72. [ 141.99613953 141.27848816 141.37904358]
  73. [ 142.90461731 142.39450073 142.68611145]
  74. [ 143.81854248 143.54707336 143.83972168]
  75. [ 144.56524658 144.58493042 144.86477661]
  76. [ 144.99488831 145.22894287 145.57142639]
  77. >>> # we can open a new map in write mode
  78. >>> new = raster.RasterRow('new')
  79. >>> new.open('w', 'CELL')
  80. >>> # for each elev row we can perform computation, and write the result into
  81. >>> # the new map
  82. >>> for row in elev:
  83. ... new.put_row(row < 144)
  84. ...
  85. >>> # close the maps
  86. >>> new.close()
  87. >>> elev.close()
  88. >>> # check if the map exist
  89. >>> new.exist()
  90. True
  91. >>> # we can open the map in read mode
  92. >>> new.open('r')
  93. >>> for row in new[:5]: print(row[:3])
  94. [1 1 1]
  95. [1 1 1]
  96. [1 1 1]
  97. [0 0 0]
  98. [0 0 0]
  99. >>> new.close()
  100. >>> new.remove()
  101. >>> new.exist()
  102. False
  103. .. autoclass:: pygrass.raster.RasterRow
  104. :members:
  105. .. _RasterRowIO-label:
  106. RasterRowIO
  107. -----------
  108. The RasterRowIO class use the grass `RowIO library`_, and implement a row
  109. cache. The RasterRowIO class support only reading the raster, because the
  110. raster rows can only be written in sequential order, writing by row id is not
  111. supported by design. Hence, we should use the rowio lib only for caching rows
  112. for reading and use the default row write access as in the RasterRow class. ::
  113. >>> raster = reload(raster)
  114. >>> elev = raster.RasterRowIO('elevation')
  115. >>> elev.open('r')
  116. >>> for row in elev[:5]: print(row[:3])
  117. [ 141.99613953 141.27848816 141.37904358]
  118. [ 142.90461731 142.39450073 142.68611145]
  119. [ 143.81854248 143.54707336 143.83972168]
  120. [ 144.56524658 144.58493042 144.86477661]
  121. [ 144.99488831 145.22894287 145.57142639]
  122. >>> elev.close()
  123. .. autoclass:: pygrass.raster.RasterRowIO
  124. :members:
  125. .. _RasterSegment-label:
  126. RastSegment
  127. -----------
  128. The RasterSegment class use the grass `Segmentation library`_, it work dividing
  129. the raster map into small different files, that grass read load into the memory
  130. and write to the hardisk.
  131. The segment library allow to open a map in a read-write mode. ::
  132. >>> raster = reload(raster)
  133. >>> elev = raster.RasterSegment('elevation')
  134. >>> elev.open()
  135. >>> for row in elev[:5]: print(row[:3])
  136. [ 141.99613953 141.27848816 141.37904358]
  137. [ 142.90461731 142.39450073 142.68611145]
  138. [ 143.81854248 143.54707336 143.83972168]
  139. [ 144.56524658 144.58493042 144.86477661]
  140. [ 144.99488831 145.22894287 145.57142639]
  141. >>> new = raster.RasterSegment('new')
  142. >>> new.open('w', 'CELL')
  143. >>> for irow in xrange(elev.rows):
  144. ... new[irow] = elev[irow] < 144
  145. ...
  146. >>> for row in new[:5]: print(row[:3])
  147. [1 1 1]
  148. [1 1 1]
  149. [1 1 1]
  150. [0 0 0]
  151. [0 0 0]
  152. The RasterSegment class define two methods to read and write the map:
  153. * ``get_row`` that return the buffer object with the row that call the
  154. C function ``segment_get_row``. ::
  155. >>> # call explicity the method
  156. >>> elev_row0 = elev.get_row(0)
  157. >>> # call implicity the method
  158. >>> elev_row0 = elev[0]
  159. * ``get`` that return the value of the call map that call the
  160. C function ``segment_get``. ::
  161. >>> # call explicity the method
  162. >>> elev_val_0_0 = elev.get(0, 0)
  163. >>> # call implicity the method
  164. >>> elev_val_0_0 = elev[0, 0]
  165. Similarly to write the map, with ``put_row``, to write a row and with ``put``
  166. to write a single value to the map. ::
  167. >>> # compare the cell value get using the ``get`` method, and take the first
  168. >>> # value of the row with the ``get_row`` method
  169. >>> elev[0, 0] == elev[0][0]
  170. True
  171. >>> # write a new value to a cell,
  172. >>> new[0, 0] = 10
  173. >>> new[0, 0]
  174. 10
  175. >>> new.close()
  176. >>> new.exist()
  177. True
  178. >>> new.remove()
  179. >>> elev.close()
  180. >>> elev.remove()
  181. .. autoclass:: pygrass.raster.RasterSegment
  182. :members:
  183. .. _RasterNumpy-label:
  184. RasterNumpy
  185. -----------
  186. The RasterNumpy class, is based on the `numpy.memmap`_ class If you open an
  187. existing map, the map will be copied on a binary format, and read to avoid
  188. to load all the map in memory. ::
  189. >>> raster = reload(raster)
  190. >>> elev = raster.RasterNumpy('elevation', 'PERMANENT')
  191. >>> elev.open('r')
  192. >>> # in this case RasterNumpy is an extention of the numpy class
  193. >>> # therefore you may use all the fancy things of numpy.
  194. >>> elev[:5, :3]
  195. RasterNumpy([[ 141.99613953, 141.27848816, 141.37904358],
  196. [ 142.90461731, 142.39450073, 142.68611145],
  197. [ 143.81854248, 143.54707336, 143.83972168],
  198. [ 144.56524658, 144.58493042, 144.86477661],
  199. [ 144.99488831, 145.22894287, 145.57142639]], dtype=float32)
  200. >>> el = elev < 144
  201. >>> el[:5, :3]
  202. RasterNumpy([[1, 1, 1],
  203. [1, 1, 1],
  204. [1, 1, 1],
  205. [0, 0, 0],
  206. [0, 0, 0]], dtype=int32)
  207. >>> el.name == None
  208. True
  209. >>> # give a name to the new map
  210. >>> el.name = 'new'
  211. >>> el.exist()
  212. False
  213. >>> el.close()
  214. >>> el.exist()
  215. True
  216. >>> el.remove()
  217. .. autoclass:: pygrass.raster.RasterNumpy
  218. :members:
  219. .. _Raster library: http://grass.osgeo.org/programming7/rasterlib.html
  220. .. _RowIO library: http://grass.osgeo.org/programming7/rowiolib.html
  221. .. _Segmentation library: http://grass.osgeo.org/programming7/segmentlib.html
  222. .. _numpy.memmap: http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html