In [1]:
using RasterIO
In [2]:
raster = RasterIO.openraster("pyrasterio/RGB.byte.tif")
Out[2]:
In addition to the file-like attributes shown above, a dataset has a number of other read-only attributes that help explain its role in spatial information systems. The height
and width
are the number of rows and columns of the raster dataset. The nband
attribute tells you the number of bands in the dataset.
In [3]:
raster.height, raster.width, raster.nband
Out[3]:
You can also query for the name of the GDAL format driver used.
In [4]:
RasterIO.drivershortname(RasterIO._getdatasetdriver(raster.dataset))
Out[4]:
What makes geospatial raster datasets different from other raster files is that their pixels map to regions of the Earth. A dataset has a coordinate reference system and an affine transformation matrix that maps pixel coordinates to coordinates in that reference system.
In [5]:
RasterIO.getprojection(raster.dataset)
Out[5]:
In [6]:
RasterIO.getgeotransform(raster.dataset)
Out[6]:
In [7]:
RasterIO.fetch(raster, 1)
Out[7]:
The returned object is a 2-dimensional Array. The GeoTIFF file that Rasterio uses for testing has 0 values in the corners, but has nonzero values elsewhere.
You can also fetch multiple bands by passing in a vector of indices corresponding to the bands, and get a 3-dimensional Array as the result.
In [8]:
RasterIO.fetch(raster, [1,3])
Out[8]:
If you omit the indices to fetch, RasterIO.jl will fetch all of the indices
In [9]:
RasterIO.fetch(raster)
Out[9]:
In [10]:
band = RasterIO._getrasterband(raster.dataset, 1)
Out[10]:
In [11]:
band_color = RasterIO._getrastercolorinterpretation(band)
Out[11]:
In [12]:
RasterIO.colorinterpname(band_color)
Out[12]:
In [13]:
using Images
In [14]:
Images.RGB(1,0,0)
Out[14]:
For more details, see https://github.com/timholy/Images.jl/blob/master/doc/overlays.md
In [15]:
Images.Overlay((RasterIO.fetch(raster, 1),),
(Images.RGB(1,0,0),),
((0, 255),))
Out[15]:
In [16]:
Images.Image(ans)
Out[16]:
Compare to the original:
In [17]:
Images.imread("pyrasterio/RGB.byte.tif")
Out[17]:
We can also overlay all 3 channels of the RGB dataset, to recover the original image.
In [18]:
o = Images.Overlay((RasterIO.fetch(raster, 1),
RasterIO.fetch(raster, 2),
RasterIO.fetch(raster, 3)),
(Images.RGB(1,0,0),
Images.RGB(0,1,0),
Images.RGB(0,0,1)),
((0, 255),(0, 255),(0, 255)))
Images.Image(o)
Out[18]:
In [19]:
RasterIO.closeraster(raster)
Out[19]:
After it's closed, data can no longer be read.
In [20]:
RasterIO.fetch(raster, 1)
A window is a view onto a rectangular subset of a raster dataset and is described in rasterio by a pair of range tuples.
((row_start, row_stop), (col_start, col_stop))
The first pair contains the indexes of the raster rows at which the window starts and stops. The second contains the indexes of the raster columns at which the window starts and stops. For example,
((0, 4), (0, 4))
Specifies a 4 x 4 window at the upper left corner of a raster dataset and
((10, 20), (10, 20))
specifies a 10 x 10 window with origin at row 10 and column 10. Use of None for a range value indicates either 0 (in the start position) or the full raster height or width (in the stop position). The window tuple
((None, 4), (None, 4))
also specifies a 4 x 4 window at the upper left corner of the raster and
((4, None), (4, None))
specifies a rectangular subset with upper left at row 4, column 4 and extending to the lower right corner of the raster dataset.
Using window tuples should feel like using Python's range() and slice() functions. Range() selects a range of numbers from the sequence of all integers and slice() produces a object that can be used in slicing expressions.
In [21]:
raster = RasterIO.openraster("pyrasterio/RGB.byte.tif")
w = RasterIO.fetch(raster, 1, 1:100, 1:100)
RasterIO.closeraster(raster)
w
Out[21]:
In [22]:
image = fill(UInt8(127), (150, 250))
raster = RasterIO.createraster("pyrasterio/example.tif",
500, # width
300, # height
1, # number of bands
UInt8, # DataType
"GTiff") # Drivername
Out[22]:
In [23]:
RasterIO.update!(raster,
image, # image to "burn" into the raster
1, # update band 1
30:180, # along (window) xcoords 30 to 180
50:300) # along (window) ycoords 30 to 180
Out[23]:
In [24]:
RasterIO.closeraster(raster)
Out[24]:
The result:
In [25]:
Images.imread("pyrasterio/example.tif")
Out[25]:
In [26]:
src = RasterIO.openraster("pyrasterio/RGB.byte.tif")
Out[26]:
In [27]:
dst = RasterIO.createraster("pyrasterio/example2.tif",
500, # width
300, # height
3, # number of bands
UInt8, # DataType
"GTiff")
In [28]:
rgb = RasterIO.fetch(src, [1,2,3]) # fetch bands 1 - 3
# You can update all 3 bands simultaneously
RasterIO.update!(dst,
rgb, # image to "burn" into destination dataset
[1,2,3], # indices of the bands to be updated
30:269, # along (window) xcoords 30 to 269
50:313) # along (window) xcoords 50 to 313
Out[28]:
In [29]:
RasterIO.closeraster(dst)
Out[29]:
In [30]:
RasterIO.closeraster(src)
Out[30]:
And the result:
In [31]:
Images.imread("pyrasterio/example2.tif")
Out[31]:
Below is an example of reading a raster subset and then writing it into a larger subset that is defined relative to the upper left corner of the destination dataset.
In [32]:
src = RasterIO.openraster("pyrasterio/RGB.byte.tif")
Out[32]:
In [33]:
dst = RasterIO.createraster("pyrasterio/example3.tif",
500, # width
300, # height
3, # number of bands
eltype(rgb), # DataType
"GTiff")
Out[33]:
In [34]:
rgb = RasterIO.fetch(src, [1,2,3],
350:410,
350:450)
Out[34]:
In [35]:
RasterIO.update!(dst, rgb, [1,2,3],
1:240,
1:400)
Out[35]:
In [36]:
RasterIO.closeraster(dst)
Out[36]:
In [37]:
RasterIO.closeraster(src)
Out[37]:
This example clearly demonstrates decimation.
In [38]:
Images.imread("pyrasterio/example3.tif")
Out[38]:
Remove all working/temporary examples
In [39]:
; rm pyrasterio/example*.tif
In [ ]: