Этот раздел описывает различные действия, которые можно выполнять с растровыми слоями.
Растровый слой состоит из одного или нескольких каналов и, соответственно, является одноканальным или многоканальным растром. Канал можно представить в виде матрицы значений. Обычно, цветные изображения (например, аэрофотоснимок) это растр состоящий из красного, зеленого и синего каналов. Одноканальные слои, как правило, представляют непрерывную (например, высота) или дискретную величину (например, использование земли). В некоторых случаях растровые слои поставляются с палитрой, и значения ячеек растра соответствуют цветам в палитре.
>>> rlayer.width(), rlayer.height()
(812, 301)
>>> rlayer.extent()
u'12.095833,48.552777 : 18.863888,51.056944'
>>> rlayer.rasterType()
2 # 0 = GrayOrUndefined (single band), 1 = Palette (single band), 2 = Multiband
>>> rlayer.bandCount()
3
>>> rlayer.metadata()
u'<p class="glossy">Driver:</p>...'
>>> rlayer.hasPyramids()
False
Сразу после загрузки растровый слой отображается стилем, основанным на его типе. Стиль отображения может быть изменён в диалоге свойств растрового слоя или программным путем. Существуют следующие стили отображения:
Индекс |
Константа: QgsRasterLater.X |
Комментарий |
---|---|---|
1 | SingleBandGray | Одноканальное изображение отображается в оттенках серого цвета |
2 | SingleBandPseudoColor | Одноканальное изображение отображается с использованием псевдоцвета |
3 | PalettedColor | Одноканальное изображение отображается с использованием псевдоцвета |
4 | PalettedSingleBandGray | Слой с “палитрой”, отрисовка в оттенках серого |
5 | PalettedSingleBandPseudoColor | Слой с “палитрой”, отрисовка в псевдоцвете |
7 | MultiBandSingleBandGray | Слой состоит из 2 и более каналов, но отображается только один канал в оттенках серого |
8 | MultiBandSingleBandPseudoColor | Слой состоит из 2 и более каналов, но отображается только один канал с использованием псевдоцвета |
9 | MultiBandColor | Слой состоит из 2 и более каналов, установлено соответствие с цветами пространства RGB |
Узнать текущий стиль отображения можно так:
>>> rlayer.drawingStyle()
9
Одноканальные растровые слои могут отображаться либо в оттенках серого (малые значения = черный, большие значения = белый) или с использованием псевдоцвета, когда одинаковым значениям присваивается свой цвет. Кроме того, одноканальные растры могут отображаться с использованием палитры. При отображении многоканальных слоёв обычно устанавливается соответствие между каналами и цветами пространства RGB. Ещё один способ — использование одного канала для отрисовки в оттенках серого или в псевдоцвете.
В следующих разделах описано как узнать и изменить стиль отображения слоя. После того, как изменения внесены, потребуется обновить карту, см. Обновление слоёв.
TODO: contrast enhancements, transparency (no data), user defined min/max, band statistics
По умолчанию отрисовка идет в оттенках серого. Чтобы изменить стиль отрисовки на псевдоцвет:
>>> rlayer.setDrawingStyle(QgsRasterLayer.SingleBandPseudoColor)
>>> rlayer.setColorShadingAlgorithm(QgsRasterLayer.PseudoColorShader)
The PseudoColorShader is a basic shader that highlighs low values in blue and high values in red. Another, FreakOutShader uses more fancy colors and according to the documentation, it will frighten your granny and make your dogs howl.
There is also ColorRampShader which maps the colors as specified by its color map. It has three modes of interpolation of values:
точный (EXACT): цвета не интерполируются, отображаются только пиксели со значениями, равными значениям цветовой карты
Установка градиента от зеленого к желтому цвету (для значений от 0 до 255) выглядит так:
>>> rlayer.setColorShadingAlgorithm(QgsRasterLayer.ColorRampShader)
>>> lst = [ QgsColorRampShader.ColorRampItem(0, QColor(0,255,0)), \
QgsColorRampShader.ColorRampItem(255, QColor(255,255,0)) ]
>>> fcn = rlayer.rasterShader().rasterShaderFunction()
>>> fcn.setColorRampType(QgsColorRampShader.INTERPOLATED)
>>> fcn.setColorRampItemList(lst)
Вернуться к стандартному отображению в оттенках серого можно так:
>>> rlayer.setDrawingStyle(QgsRasterLayer.SingleBandGray)
По умолчанию, чтобы получить цветное изображение, QGIS ставит в соответствие трём первым каналам значения красного, зеленого и синего (это соответствует стилю отображения MultiBandColor). В некоторых случаях требуется переопределить эти настройки. Следующий код показывает как поменять местами красный (1) и зелёный (2) каналы:
>>> rlayer.setGreenBandName(rlayer.bandName(1))
>>> rlayer.setRedBandName(rlayer.bandName(2))
Когда для визуализации слоя достаточно одного канала, можно выбрать отрисовку с использованием только одного канала — в оттенках серого или в псевдоцвете, см. предыдущий раздел:
>>> rlayer.setDrawingStyle(QgsRasterLayer.MultiBandSingleBandPseudoColor)
>>> rlayer.setGrayBandName(rlayer.bandName(1))
>>> rlayer.setColorShadingAlgorithm(QgsRasterLayer.PseudoColorShader)
>>> # now set the shader
Если символика слоя была изменена и необходимо сделать изменения видимыми пользователю, вызовите следующие методы:
if hasattr(layer, "setCacheImage"): layer.setCacheImage(None)
layer.triggerRepaint()
Первая конструкция нужна для того, чтобы убедиться, что при использовании кеша отрисовки кешированные изображения обновляемого слоя удалены. Этот функционал доступен начиная с QGIS 1.4, в более ранних версиях такой функции нет — поэтому, в начале, чтобы быть уверенными в работоспособности кода во всех версиях QGIS, выполняется проверка на существование метода.
Вторая конструкция вызывает сигнал, который заставляет все карты, содержащие слой, выполнить перерисовку.
With WMS raster layers, these commands do not work. In this case, you have to do it explicitily:
layer.dataProvider().reloadData()
layer.triggerRepaint()
После изменения символики слоя (о том, как это сделать рассказано в разделах, посвящённых растровым и векторным слоям), может потребоваться обновить символику слоя в виджете списка слоёв (легенде). Ниже показано как это делается (iface это экземпляр QgisInterface):
iface.legendInterface().refreshLayerSymbology(layer)
Чтобы узнать значение каналов растрового слоя в определенной точке выполните:
ident = rlayer.dataProvider().identify(QgsPoint(15.30,40.98), \
QgsRaster.IdentifyFormatValue)
if ident.isValid():
print ident.results()
The results method in this case returs a dictionary, with band indices as keys, and band values as values.
{1: 17, 2: 220}