QgsSingleBandPseudoColorRenderer 完整详解(QGIS 3.40.13 C++)

📅 2026/7/22 14:58:24 👁️ 阅读次数 📝 编程学习
QgsSingleBandPseudoColorRenderer 完整详解(QGIS 3.40.13 C++)

一、基础定位、头文件、继承关系

1. 引入头文件

#include<qgssinglebandpseudocolorrenderer.h>

2. 继承链

QgsRasterRenderer ↳ QgsSingleBandRenderer ↳ QgsSingleBandPseudoColorRenderer
  • QgsRasterRenderer:栅格渲染器顶层抽象基类,所有栅格渲染器统一父类,定义block()clone()、XML读写、透明度等通用接口;
  • QgsSingleBandRenderer:单波段渲染器公共父类,封装「渲染波段号」基础逻辑;
  • QgsSingleBandPseudoColorRenderer单波段伪彩色渲染器,专门实现单波段数值→渐变色/分级上色(DEM、NDVI、温度热力图底层渲染器)。

3. 完整渲染链路总览

QgsRasterLayer ↓ QgsSingleBandPseudoColorRenderer (当前讲解对象:控制渲染波段、透明度、持有QgsRasterShader) ↓ QgsRasterShader (scale/offset、拉伸min/max、Nodata透明、亮度对比度) ↓ QgsColorRampShader (分段色标、插值渐变/离散/精确匹配逻辑)

4. 核心职责

  1. 指定要渲染的目标波段(1起始);
  2. 持有唯一QgsRasterShader着色器实例,所有数值转颜色逻辑由shader提供;
  3. 实现栅格像素块渲染入口block(),从provider读取像素、调用shader上色、输出RGBA画布;
  4. 统一管理图层透明度、灰度转换、图层混合模式;
  5. 提供克隆、序列化XML(保存到qgs工程)。

二、构造函数

// 空构造,无数据源、无shader,仅用于反序列化加载工程QgsSingleBandPseudoColorRenderer();// 标准业务构造(最常用)// provider:栅格数据源;bandNo:渲染波段;shader:着色器(传入后renderer接管内存)QgsSingleBandPseudoColorRenderer(QgsRasterDataProvider*provider,intbandNo,QgsRasterShader*shader=nullptr);

三、核心属性读写API

1. 渲染波段(继承自 QgsSingleBandRenderer)

// 获取当前渲染波段intband()const;// 修改渲染波段,切换后需要重新统计极值、刷新shader拉伸区间voidsetBand(intbandNo);

注意:波段号从1开始,传0会渲染失效。

2. 着色器 QgsRasterShader 管理(核心)

// 获取内部着色器,可修改min/max、scale/offset、shaderFunctionQgsRasterShader*rasterShader()const;// 设置新着色器,renderer 获得 shader 所有权,自动释放旧shadervoidsetRasterShader(QgsRasterShader*shader);

内存规则:

  • setRasterShader()传入的shader由渲染器托管,外部禁止手动delete;
  • 替换shader时,旧着色器会自动销毁,无内存泄漏。

3. 图层全局透明度(继承 QgsRasterRenderer)

// 透明度 0~100,0完全不透明,100完全透明intopacity()const;voidsetOpacity(intopacity);

4. 图层混合模式(叠加、正片叠底等)

QPainter::CompositionModecompositionMode()const;voidsetCompositionMode(QPainter::CompositionMode mode);

5. Nodata全局透明开关(兼容层,实际优先走shader透明配置)

boolusesTransparentNodata()const;voidsetUsesTransparentNodata(booltransparent);

四、核心渲染入口函数 block()

函数签名(重写父类虚函数)

QgsRasterBlock*block(constQgsRectangle&extent,intwidth,intheight,QgsRasterBlockFeedback*feedback=nullptr)override;

功能:生成RGBA彩色像素块,供画布绘制

内部完整执行步骤
  1. 调用provider->readBlock(band(), extent, width, height)读取原始单波段浮点像素块;
  2. 创建RGBA 4通道输出像素块(Byte类型,0~255);
  3. 遍历每一行每一列像素:
    • 判断是否Nodata:若shader开启透明Nodata,直接填充Alpha=0;
    • 取出原始rawVal,交给rasterShader()->shade()计算RGBA;
    • 应用图层全局透明度opacity衰减Alpha通道;
  4. 返回彩色RGBA像素块,上层绘图组件渲染;
  5. 进度反馈feedback用于大影像渲染时进度条、取消渲染。

五、克隆、序列化(工程保存/加载必备)

1. 深度克隆 clone()

QgsRasterRenderer*clone()constoverride;
  • 完整复制:波段号、透明度、混合模式、内部完整QgsRasterShader(连带内部QgsColorRampShader色标列表深度拷贝);
  • 返回全新渲染器对象,使用完成必须手动delete。

2. XML读写 writeXml / readXml

voidwriteXml(QDomDocument&doc,QDomElement&parentElem)constoverride;voidreadXml(constQDomElement&rendererElem)override;

存储内容:

  • 渲染波段、透明度、混合模式;
  • 完整序列化QgsRasterShader(min/max、scale/offset、亮度对比度、transparentNodata);
  • 嵌套序列化QgsColorRampShader(全部色标、插值模式clip开关等)。
    QGIS工程保存、样式文件(.qml)读写底层依赖这两个接口。

六、自动生成拉伸区间工具函数(高频业务接口)

// 根据栅格波段统计,自动填充shader的min/max(原始像素值,scale=offset=0场景)voidsetShaderMinMaxToNone();voidsetShaderMinMaxToFullExtent();voidsetShaderMinMaxToCurrentExtent(constQgsRectangle&currentExtent);

常用场景

// 自动用整幅栅格的波段极值填充shader拉伸窗口renderer->setShaderMinMaxToFullExtent();

内部逻辑:调用provider->bandStatistics()获取min/max,赋值给shader的minimumValue/maximumValue。

七、完整分层协作示例代码(DEM伪彩色渲染)

#include<qgsrasterdataprovider.h>#include<qgsrasterbandstats.h>#include<qgsrastershader.h>#include<qgsrastercolorrampshader.h>#include<qgssinglebandpseudocolorrenderer.h>#include<qgsrasterlayer.h>// DEM单波段伪彩色渲染封装函数voidsetupDemPseudoColorRender(QgsRasterLayer*demLayer){QgsRasterDataProvider*prov=demLayer->dataProvider();if(!prov||!prov->isValid())return;intrenderBand=1;// 1. 统计波段原始极值QgsRasterBandStats stats=prov->bandStatistics(renderBand,QgsRasterBandStats::Min|QgsRasterBandStats::Max);if(!stats.isValid())return;// 2. 构建色标(无scale/offset,displayVal=rawVal)QList<QgsColorRampItem>items;items.append(QgsColorRampItem(stats.minVal,QColor(10,40,200),"低海拔"));items.append(QgsColorRampItem((stats.minVal+stats.maxVal)/2,QColor(30,190,50),"中海拔"));items.append(QgsColorRampItem(stats.maxVal,QColor(210,20,20),"高海拔"));// 3. 色带着色函数QgsColorRampShader*rampFunc=newQgsColorRampShader(items,QgsColorRampShader::Interpolated);rampFunc->setClipBelow(true);rampFunc->setClipAbove(true);// 4. 外层ShaderQgsRasterShader*shader=newQgsRasterShader();shader->setMinimumValue(stats.minVal);shader->setMaximumValue(stats.maxVal);shader->setTransparentNodata(true);shader->setRasterShaderFunction(rampFunc);// 5. 创建伪彩色渲染器(核心类)QgsSingleBandPseudoColorRenderer*render=newQgsSingleBandPseudoColorRenderer(prov,renderBand,shader);render->setOpacity(90);// 图层透明度90%render->setCompositionMode(QPainter::CompositionMode_SourceOver);// 6. 绑定到栅格图层demLayer->setRenderer(render);demLayer->triggerRepaint();// 刷新画布}

八、与其他栅格渲染器对比区分

渲染器类用途是否依赖 QgsRasterShader
QgsSingleBandPseudoColorRenderer单波段渐变/分级伪彩色(DEM、NDVI、热力图)✅ 必须依赖
QgsSingleBandGrayRenderer单波段黑白灰度拉伸✅ 依赖灰度shader
QgsMultiBandColorRendererRGB三波段真彩色遥感影像❌ 无shader,直接合成三色
QgsPalettedRasterRenderer索引色栅格(自带色表)

关键区分

QgsSingleBandGrayRendererQgsSingleBandPseudoColorRenderer同属单波段渲染器,都持有QgsRasterShader

  • 灰度渲染器内部shaderFunction是灰度映射;
  • 伪彩色渲染器搭配QgsColorRampShader实现多色渐变分级。

九、开发高频踩坑点

1. 内存所有权问题

// 正确:renderer接管shader,无需手动delete shaderQgsRasterShader*shader=newQgsRasterShader();QgsSingleBandPseudoColorRenderer*render=newQgsSingleBandPseudoColorRenderer(prov,1,shader);// 错误:外部手动delete shader,渲染器析构时二次释放崩溃deleteshader;

2. scale/offset 存在时,shader min/max 不能填原始波段极值

QgsSingleBandPseudoColorRenderer只负责持有shader,不会自动换算scale/offset后的区间;
需要手动计算displayMin = (rawMin-offset)*scale赋值给shader。

3. 切换波段后极值不刷新

调用setBand(2)切换渲染波段后,旧shader的min/max仍是波段1的区间,必须重新统计并更新shader拉伸窗口。

4. 浮点栅格使用 Exact 模式匹配失败

Exact精确匹配仅适合整型分类栅格,浮点存在精度误差,渲染器会大面积透明。

5. 渲染器替换后图层不刷新

修改完renderer必须调用layer->triggerRepaint()触发画布重绘。

6. 多线程渲染限制

block()内部会读取provider,GDAL驱动非线程安全,多线程并行渲染同一图层需要加互斥锁。

十、典型业务使用场景

  1. DEM数字高程模型渐变伪彩色渲染;
  2. NDVI、NDWI植被指数热力分级;
  3. 气温、降雨量、污染物浓度热力图;
  4. 坡度、地形起伏度离散分级设色;
  5. 单波段灰度数据自定义渐变色展示。

十一、类层级结构精简总结

QgsRasterRenderer (顶层栅格渲染器) └── QgsSingleBandRenderer (单波段公共父类:管理波段号) └── QgsSingleBandPseudoColorRenderer ├─ 成员:QgsRasterShader* mShader ├─ 核心方法:block() 输出RGBA彩色像素块 ├─ 辅助:setShaderMinMaxToFullExtent() 自动拉伸 ├─ 生命周期:clone()、writeXml/readXml 序列化 └─ 配置:透明度、图层混合模式