-
Notifications
You must be signed in to change notification settings - Fork 14
Python API Use the Pixel Iterator
In IlwisObjects the PixelIterator is an important tool for accessing and modifying data from a RasterCoverage. There are several ways to use it and the more you know, the easier it will be for you to process your data.
Iterators can be thought of as pointers. They always point to one and only one specific member of a collection. That means, the iterator always has an exact position. This position is within the range of the size of the collection. If it gets to the end of the collection it will automatically stop. The PixelIterator in IlwisObjects has an own bounding box, which has to be in range of the collection but can be smaller, so that it just represents a part of the values.
Between the start and end it can move freely forwards or backwards. By default it always moves to the next member of the collection but it can as well skip members and jump straight to any member contained within its range.
IlwisObjects offers you multiple ways to get a new Pixeliterator. The only thing you will always need is an existing RasterCoverage, because else the iterator will have nothing to iterate over.
The probably simplest way to get an iterator is to just use the native python method iter() and pass your existing coverage to it. This will give you a PixelIterator that ranges over your whole coverage, including multiple bands and is set to the beginning (Pixel at 0,0,0).
rc = RasterCoverage("n000302.mpr")
# get a new PixelIterator
it = iter(rc)If you want to get an iterator that tells you where your coverage will end, you can call .end() on your RasterCoverage and you will get an iterator that points right to the end of your data. You can do the same for its beginning by calling .begin(). You can, e.g. use these function to create a loop over your whole coverage:
rc = ilwis.RasterCoverage("n000302.mpr")
itBegin = rc.begin()
itEnd = rc.end()
#the following loop will print all values of the iterator
while(itBegin != itEnd):
print(next(itBegin))In a lot of cases you will only want to access data in a certain part of your whole RasterCoverage. For example you have only a small area in a huge map that you want to analyze closer, but don't want to clip the raster to especially that area. For these cases the constructors of the PixelIterator give you two options:
You can create your own Box that defines the range of the PixelIterator. You can simply do it by giving the Box constructor two Pixels, the start (upper left corner) and the end (lower right corner).
rc = RasterCoverage("n000302.mpr")
# will create a box with the size (301, 301, 1)
box = Box(Pixel(200,0,1), Pixel(500, 300, 1))
it = PixelIterator(rc, bo)If you don't know the exact pixels but know the coordinates you can instead create a new envelope, which is the same as a box, but with coordinates and then turn this envelope into a box with the help of the coverage's georeference.
#get the georeference
gr = rc.geoReference()
#create an envelope
subenv = Envelope(Coordinate(-1e+06, -1e+06), Coordinate(1e+06, 1e+06))
#turn the envelope into a box
subbox = gr.envelope2Box(subenv)If the area you want to access is defined by a certain geometry, you can just pass it to the constructor as well. IlwisObjects will then create a box, which approximates the geometry best. You can get more information about geometries in this part of the wiki.
rc = RasterCoverage("n000302.mpr")
#create a geometry from WKT
geom = Geometry("Polygon((495209 80832,927209 -999367, 1887209 -1282307,2184809 311232,495209 80832))", rc.coordinateSystem())
it = PixelIterator(rc, geom)You can find an overview of the basic operations you can use in [this part of the wiki] (https://github.com/52North/IlwisCore/wiki/ILWIS-Python-API-Tutorial#basic-operations).
By default, the PixelIterator first iterates over all pixerls in x direction. Once it as reached the end of a line it goes a step further in the y direction. When it has reached the end of the iterators box like this it changes the z direction, if possible.
You can check for the switched columns, line or layers with the help of the functions .xChanged(), .yChanged() and .zChanged(), which will always return either true or false.
To make iterators more customizable IlwisObjects also offers you the possibility to switch the flow of the iterator. So instead of first going into the x direction you could go into the y or z direction. All possible flows are: XYZ, YXZ, ZXY. Theses are all available in an enumeration, so you have to put Flaw. in front of them.
You can simply change the iterator's flow by calling .setFlow() on it and then choosing from the available flows like:
rc = RasterCoverage("n000302.mpr")
it = iter(rc)
# change the flow
it.setFlow(Flow.fYXZ)