本章主要简介Qgis 的矢量图层的符号化。Qgis的符号化具体作用于每个图层,图层通过具体的方法设置符号化样式。
1、QgsFeatureRenderer
Qgs的符号化类主要是QgsFeatureRenderer,这是一个抽象类,它派生出了许多类,如下所示。常用的有三个 QgsSingleSymbolRenderer(单一符号化),QgisCategorizedSymbolRenderer(分类符号化),QgsGraduatedSymbolRenderer(分级符号化),分级符号化是连续的。符号化派生类是需要Symbol 才能实例化的。
2、Symbol
符号化的本质是符号。QgsSymbol 也是一个抽象类,针对点,线,面 三种情况,派生如下三个类。Symbol 通常要配合QgsSymbolLayer 来使用。
用Render 和Symbol 可以直接符号化矢量图层,以下是一个简单的示例。
QgsCategoryList cats = QgsCategoryList();QgsRendererCategory qrc = QgsRendererCategory();qrc.setLabel(item->entName()); //字段名字
qrc.setValue(item->code()); //值
qrc.setRenderState(true);
QgsSymbol* symbol= QgsSymbol::defaultSymbol(vecLayer->geometryType());
QColor startColor;
color.setRgb(200,0, 0);
symbol->setColor(color);qrc.setSymbol(symbol);
cats.push_back(qrc);//这里可以循环遍历多加几个值//构建Render
std::unique_ptr< QgsCategorizedSymbolRenderer > r = std::make_unique< QgsCategorizedSymbolRenderer >(ysdm, cats);
//渲染图层
vecLayer->setRenderer(r->clone());
如下是一个db 中GeometryGenerator 类型的 SymbolLayer。
<symbol type="marker" alpha="1" force_rhr="0" frame_rate="10" name="DMWZ" clip_to_extent="1" is_animated="0">
<data_defined_properties>
<Option type="Map">
<Option value="" type="QString" name="name" /><Option name="properties" /><Option value="collection" type="QString" name="type" /></Option>
</data_defined_properties><layer pass="0" class="GeometryGenerator" locked="0" enabled="1"><Option type="Map">
<Option value="Line" type="QString" name="SymbolType" />
<Option value="make_line(make_point(x($geometry)+0.5000, y($geometry)), make_point(x($geometry)+0.4924, y($geometry)+0.0868), make_point(x($geometry)+0.4698, y($geometry)+0.1710), make_point(x($geometry)+0.4330,
y($geometry)+0.2500), make_point(x($geometry)+0.3830, y($geometry)+0.3214), make_point(x($geometry)+0.3214, y($geometry)+0.3830), make_point(x($geometry)+0.2500,
y($geometry)+0.4330), make_point(x($geometry)+0.1710, y($geometry)+0.4698), make_point(x($geometry)+0.0868, y($geometry)+0.4924), make_point(x($geometry),
y($geometry)+0.5000), make_point(x($geometry)-0.0868, y($geometry)+0.4924), make_point(x($geometry)-0.1710, y($geometry)+0.4698),
make_point(x($geometry)-0.2500, y($geometry)+0.4330), make_point(x($geometry)-0.3214, y($geometry)+0.3830), make_point(x($geometry)-0.3830,
y($geometry)+0.3214), make_point(x($geometry)-0.4330, y($geometry)+0.2500), make_point(x($geometry)-0.4698, y($geometry)+0.1710),
make_point(x($geometry)-0.4924, y($geometry)+0.0868), make_point(x($geometry)-0.5000, y($geometry)), make_point(x($geometry)-0.4924,
y($geometry)-0.0868), make_point(x($geometry)-0.4698, y($geometry)-0.1710), make_point(x($geometry)-0.4330, y($geometry)-0.2500),make_point(x($geometry)-0.3830, y($geometry)-0.3214), make_point(x($geometry)-0.3214, y($geometry)-0.3830), make_point(x($geometry)-0.2500, y($geometry)-0.4330), make_point(x($geometry)-0.1710, y($geometry)-0.4698), make_point(x($geometry)-0.0868, y($geometry)-0.4924), make_point(x($geometry), y($geometry)-0.5000), make_point(x($geometry)+0.0868, y($geometry)-0.4924), make_point(x($geometry)+0.1710, y($geometry)-0.4698), make_point(x($geometry)+0.2500, y($geometry)-0.4330), make_point(x($geometry)+0.3214, y($geometry)-0.3830), make_point(x($geometry)+0.3830, y($geometry)-0.3214), make_point(x($geometry)+0.4330, y($geometry)-0.2500), make_point(x($geometry)+0.4698, y($geometry)-0.1710), make_point(x($geometry)+0.4924, y($geometry)-0.0868), make_point(x($geometry)+0.5000, y($geometry)))" type="QString" name="geometryModifier" /><Option value="MapUnit" type="QString" name="units" /></Option><data_defined_properties><Option type="Map"><Option value="" type="QString" name="name" /><Option name="properties" /><Option value="collection" type="QString" name="type" /></Option></data_defined_properties><symbol type="line" alpha="1" force_rhr="0" frame_rate="10" name="@DMWZ@0" clip_to_extent="1" is_animated="0"><data_defined_properties><Option type="Map"><Option value="" type="QString" name="name" /><Option name="properties" /><Option value="collection" type="QString" name="type" /></Option></data_defined_properties><layer pass="0" class="SimpleLine" locked="0" enabled="1"><Option type="Map"><Option value="0" type="QString" name="align_dash_pattern" /><Option value="square" type="QString" name="capstyle" /><Option value="5;2" type="QString" name="customdash" /><Option value="3x:0,0,0,0,0,0" type="QString" name="customdash_map_unit_scale" /><Option value="MM" type="QString" name="customdash_unit" /><Option value="0" type="QString" name="dash_pattern_offset" /><Option value="3x:0,0,0,0,0,0" type="QString" name="dash_pattern_offset_map_unit_scale" /><Option value="MM" type="QString" name="dash_pattern_offset_unit" /><Option value="0" type="QString" name="draw_inside_polygon" /><Option value="bevel" type="QString" name="joinstyle" /><Option value="35,35,35,255" type="QString" name="line_color" /><Option value="solid" type="QString" name="line_style" /><Option value="0.26" type="QString" name="line_width" /><Option value="MM" type="QString" name="line_width_unit" /><Option value="0" type="QString" name="offset" /><Option value="3x:0,0,0,0,0,0" type="QString" name="offset_map_unit_scale" /><Option value="MM" type="QString" name="offset_unit" /><Option value="0" type="QString" name="ring_filter" /><Option value="0" type="QString" name="trim_distance_end" /><Option value="3x:0,0,0,0,0,0" type="QString" name="trim_distance_end_map_unit_scale" /><Option value="MM" type="QString" name="trim_distance_end_unit" /><Option value="0" type="QString" name="trim_distance_start" /><Option value="3x:0,0,0,0,0,0" type="QString" name="trim_distance_start_map_unit_scale" /><Option value="MM" type="QString" name="trim_distance_start_unit" /><Option value="0" type="QString" name="tweak_dash_pattern_on_corners" /><Option value="0" type="QString" name="use_custom_dash" /><Option value="3x:0,0,0,0,0,0" type="QString" name="width_map_unit_scale" /></Option><data_defined_properties><Option type="Map"><Option value="" type="QString" name="name" /><Option name="properties" /><Option value="collection" type="QString" name="type" /></Option></data_defined_properties></layer></symbol></layer></symbol>
这里可以看到这个符号是用Option里面的代码画出来的。
3、SymbolLayer
如下是SymbolLayer 类,该类大部分来说是枚举值,但是它有一个强大的功能可以用QgsGeometryGeneratorSymbolLayer类代码画出矢量符号。QgsGeometryGeneratorSymbolLayer 相当于自定义符号。
4、Style 管理器
Qgis 可以 用db文件存储它的Style的文件。Style 文件通过Style的管理器可以将db的每行实例成Symbol。具体的使用如下,这里是判断 styleSettings 里面是否有 syle.db 文件,如果没有则添加该文件。
QString styleName ="syle.db";QList<QgsStyle*> stylelist = QgsProject::instance()->styleSettings()->styles();QgsStyle* style = nullptr;for (auto& item : stylelist) {if (item->name() + ".db" == styleName) {style = item;}}if (style == nullptr) {QgsProject::instance()->styleSettings()->addStyleDatabasePath(stylePath);style = QgsProject::instance()->styleSettings()->styles().last();}
5、Label 显示
Qgis 也有arcgis 的类似的Label 的功能。它可以显示某个具体属性里面的内容。在qgis 软件里面是下面的功能:Labels。它也是通过Symbol 来实现的。
如下代码封装是Labels 的实现,它实际只显示了文字,透明了符号本身。
bool symbolLayer(QgsVectorLayer* annotationLayer, const QString& noteTblName, const QString& esriGeoType, CAnnoUtils* annoUtil) {
#pragma region 文字符号化//将原来的点设置为透明QgsSymbol* symbol = QgsSymbol::defaultSymbol(Qgis::GeometryType::Point);symbol->setColor(QColor(0, 0, 0, 0));symbol->symbolLayers().at(0)->setStrokeColor(QColor(0, 0, 0, 0));QgsSingleSymbolRenderer* renderer = new QgsSingleSymbolRenderer(symbol);annotationLayer->setRenderer(renderer);//设置文字符号化QgsPalLayerSettings settings;QgsPropertyCollection settingsProperties;settings.drawLabels = true;settings.fieldName = CSystemFieldDZ::GetZJNRField(noteTblName);settings.obstacleSettings().setIsObstacle(false);//文字设置QgsTextFormat textFormat;//textFormat.setSize(annoUtil->m_noteSet.fontSize);textFormat.setSizeUnit(Qgis::RenderUnit::Points /*QgsUnitTypes::RenderPoints*/);// 设置字体颜色CUserLayerInfo* userInfo = CCommGISDB::GetUserLayerInfo(annotationLayer->name());QStringList rgbList = userInfo->layerColor().split(",");if (rgbList.size() == 3) {int r = rgbList[0].toInt(); // R 值int g = rgbList[1].toInt(); // G 值int b = rgbList[2].toInt(); // B 值textFormat.setColor(QColor(r,g,b));}else {textFormat.setColor(Qt::black);}QFont font(annoUtil->m_noteSet.trueTypeName);font.setBold(true);textFormat.setFont(font);settings.setFormat(textFormat);//设置位置settings.placement = Qgis::LabelPlacement::OverPoint;//对齐方式由备注字段或对齐方式控制QString BZField = CSystemFieldDZ::GetBZField(noteTblName);QString note_ZJDZField = CSystemFieldDZ::GetZJDZField(noteTblName);QString dqField = BZField;//如果有对齐方式的话:if (annotationLayer->fields().indexOf(note_ZJDZField) != -1) {dqField = note_ZJDZField;}const QVariantMap conversionMap{{ QStringLiteral("center"), 4 },{ QStringLiteral("left"), 5 },{ QStringLiteral("right"), 3 },{ QStringLiteral("top"), 7 },{ QStringLiteral("bottom"), 1 },{ QStringLiteral("top-left"), 8 },{ QStringLiteral("top-right"), 6 },{ QStringLiteral("bottom-left"), 2 },{ QStringLiteral("bottom-right"), 0 },};QString caseString = QStringLiteral("CASE ""WHEN '左对齐'= regexp_substr(%1,'[^;]+') THEN %2 ""WHEN '右对齐'= regexp_substr(%1,'[^;]+') THEN %3 ""WHEN '居中对齐'= regexp_substr(%1,'[^;]+') THEN %4 ""ELSE %4 END").arg(dqField,QgsExpression::quotedValue(conversionMap.value("left", "left")),QgsExpression::quotedValue(conversionMap.value("right", "right")),QgsExpression::quotedValue(conversionMap.value("center", "center")));settingsProperties.setProperty(QgsPalLayerSettings::OffsetQuad, QgsProperty::fromExpression(caseString));偏移也由备注中的内容做控制//QString offsetString = QStringLiteral("array(to_real(regexp_substr(%1,'[^;]+;([^;]+);')),-1*to_real(regexp_substr(%1,'[^;]+$')))").arg(BZField);//settingsProperties.setProperty(QgsPalLayerSettings::OffsetXY, QgsProperty::fromExpression(offsetString));settings.placementSettings().setAllowDegradedPlacement(true);settings.placementSettings().setOverlapHandling(Qgis::LabelOverlapHandling::AllowOverlapIfRequired);settings.setRotationUnit(Qgis::AngleUnit::Radians /*AngleRadians*/);//设置旋转角度settingsProperties.setProperty(QgsPalLayerSettings::LabelRotation, QgsProperty::fromField(CSystemFieldDZ::GetZJXZJField(noteTblName))); //注记旋转角 字段控制旋转角度//设置字体大小QString fontSizeField = CSystemFieldDZ::GetZJZGField(noteTblName);QString fontString = QStringLiteral("%1 * 1000 / @map_scale").arg(fontSizeField);settingsProperties.setProperty(QgsPalLayerSettings::Size, QgsProperty::fromExpression(fontString));settings.setDataDefinedProperties(settingsProperties);QgsVectorLayerSimpleLabeling* simpleLabeling = new QgsVectorLayerSimpleLabeling(settings);annotationLayer->setLabelsEnabled(true);annotationLayer->setLabeling(simpleLabeling);return true;
#pragma endregion
}
6、小节
本章就先介绍到这里,有些细节需要读者自己去摸索试用。本章主要介绍了Api的使用和类之间的逻辑关系。