地图样式与符号化
第九章 地图样式与符号化
9.1 符号化概述
9.1.1 什么是符号化
符号化是将地理数据以可视化方式呈现的过程,包括:
- 颜色设置
- 符号形状
- 大小比例
- 透明度
- 标注样式
9.1.2 QGIS符号系统架构
QgsSymbol (符号基类)
├── QgsMarkerSymbol (点符号)
├── QgsLineSymbol (线符号)
└── QgsFillSymbol (面符号)
每种符号可包含多个符号图层(SymbolLayer)
实现复杂的叠加效果
9.1.3 渲染器类型
| 渲染器 | 适用场景 | 说明 |
|---|---|---|
| 单一符号 | 统一样式 | 所有要素相同 |
| 分类 | 分类数据 | 按类别区分 |
| 分级 | 数值数据 | 按数值范围 |
| 规则 | 复杂条件 | 基于表达式 |
| 点位移 | 重叠点 | 分散显示 |
| 聚类 | 密集点 | 聚合显示 |
| 热力图 | 密度分析 | 热度渲染 |
| 2.5D | 立体效果 | 伪3D |
9.2 点符号
9.2.1 简单标记
from qgis.core import (
QgsMarkerSymbol,
QgsSimpleMarkerSymbolLayer,
QgsSingleSymbolRenderer
)
from qgis.PyQt.QtGui import QColor
# 创建简单标记
symbol = QgsMarkerSymbol.createSimple({
'name': 'circle', # 形状
'color': '255,0,0,255', # RGBA
'size': '5', # 大小
'outline_color': 'black',
'outline_width': '0.5'
})
# 应用到图层
renderer = QgsSingleSymbolRenderer(symbol)
layer.setRenderer(renderer)
layer.triggerRepaint()
可用形状:
- circle(圆形)
- square(方形)
- diamond(菱形)
- pentagon(五边形)
- hexagon(六边形)
- triangle(三角形)
- star(星形)
- cross(十字)
- cross2(X形)
- arrow(箭头)
9.2.2 SVG标记
from qgis.core import QgsSvgMarkerSymbolLayer
# 使用SVG符号
symbol = QgsMarkerSymbol()
svg_layer = QgsSvgMarkerSymbolLayer('/path/to/icon.svg')
svg_layer.setSize(10)
svg_layer.setFillColor(QColor(255, 0, 0))
symbol.changeSymbolLayer(0, svg_layer)
9.2.3 字体标记
from qgis.core import QgsFontMarkerSymbolLayer
# 使用字体符号(如图标字体)
symbol = QgsMarkerSymbol()
font_layer = QgsFontMarkerSymbolLayer('Arial', 'A')
font_layer.setSize(10)
font_layer.setColor(QColor(255, 0, 0))
symbol.changeSymbolLayer(0, font_layer)
9.2.4 组合点符号
# 创建多层符号
symbol = QgsMarkerSymbol()
# 底层:大圆
base = QgsSimpleMarkerSymbolLayer()
base.setShape(QgsSimpleMarkerSymbolLayer.Circle)
base.setSize(10)
base.setColor(QColor(255, 255, 255))
base.setStrokeColor(QColor(0, 0, 0))
# 上层:小圆
top = QgsSimpleMarkerSymbolLayer()
top.setShape(QgsSimpleMarkerSymbolLayer.Circle)
top.setSize(5)
top.setColor(QColor(255, 0, 0))
symbol.changeSymbolLayer(0, base)
symbol.appendSymbolLayer(top)
9.3 线符号
9.3.1 简单线
from qgis.core import QgsLineSymbol, QgsSimpleLineSymbolLayer
symbol = QgsLineSymbol.createSimple({
'color': '0,0,255',
'width': '1',
'line_style': 'solid' # solid, dash, dot, dash_dot等
})
# 或使用符号图层
line_layer = QgsSimpleLineSymbolLayer()
line_layer.setColor(QColor(0, 0, 255))
line_layer.setWidth(1)
line_layer.setPenStyle(Qt.DashLine)
线型样式:
- solid(实线)
- dash(虚线)
- dot(点线)
- dash_dot(点划线)
- dash_dot_dot(双点划线)
9.3.2 标记线
from qgis.core import QgsMarkerLineSymbolLayer
# 沿线放置标记
marker_line = QgsMarkerLineSymbolLayer()
marker_line.setInterval(10) # 间隔
marker_line.setPlacement(QgsMarkerLineSymbolLayer.Interval)
# 设置标记符号
marker = QgsMarkerSymbol.createSimple({'name': 'arrow'})
marker_line.setSubSymbol(marker)
9.3.3 渐变线
from qgis.core import QgsLineSymbol
# 线宽渐变
symbol = QgsLineSymbol()
line_layer = symbol.symbolLayer(0)
# 使用数据定义的宽度
from qgis.core import QgsProperty
line_layer.setDataDefinedProperty(
QgsSymbolLayer.PropertyStrokeWidth,
QgsProperty.fromExpression('"width_field"')
)
9.3.4 箭头线
from qgis.core import QgsArrowSymbolLayer
arrow = QgsArrowSymbolLayer()
arrow.setArrowWidth(2)
arrow.setArrowStartWidth(0.5)
arrow.setHeadLength(3)
arrow.setHeadThickness(2)
arrow.setIsCurved(False)
symbol = QgsLineSymbol()
symbol.changeSymbolLayer(0, arrow)
9.4 面符号
9.4.1 简单填充
from qgis.core import QgsFillSymbol, QgsSimpleFillSymbolLayer
symbol = QgsFillSymbol.createSimple({
'color': '200,200,200',
'outline_color': '0,0,0',
'outline_width': '0.5',
'style': 'solid' # solid, horizontal, vertical, cross等
})
填充样式:
- solid(实心)
- horizontal(水平线)
- vertical(垂直线)
- cross(交叉线)
- b_diagonal(反斜线)
- f_diagonal(斜线)
- diagonal_x(X形)
- dense1-7(不同密度点)
9.4.2 渐变填充
from qgis.core import QgsGradientFillSymbolLayer
gradient = QgsGradientFillSymbolLayer()
gradient.setColor(QColor(255, 255, 255))
gradient.setColor2(QColor(0, 0, 255))
gradient.setGradientType(QgsGradientFillSymbolLayer.Linear)
gradient.setCoordinateMode(QgsGradientFillSymbolLayer.Feature)
gradient.setGradientSpread(QgsGradientFillSymbolLayer.Pad)
9.4.3 图案填充
from qgis.core import QgsSVGFillSymbolLayer
svg_fill = QgsSVGFillSymbolLayer('/path/to/pattern.svg')
svg_fill.setPatternWidth(10)
svg_fill.setSvgFillColor(QColor(255, 0, 0))
9.4.4 质心填充
from qgis.core import QgsCentroidFillSymbolLayer
centroid = QgsCentroidFillSymbolLayer()
# 在多边形质心处放置点符号
marker = QgsMarkerSymbol.createSimple({'name': 'circle', 'size': '5'})
centroid.setSubSymbol(marker)
9.5 分类渲染
9.5.1 分类符号渲染器
from qgis.core import (
QgsCategorizedSymbolRenderer,
QgsRendererCategory,
QgsMarkerSymbol
)
# 创建分类
categories = []
# 类别1
symbol1 = QgsMarkerSymbol.createSimple({'color': 'red'})
cat1 = QgsRendererCategory('类型A', symbol1, '类型A')
categories.append(cat1)
# 类别2
symbol2 = QgsMarkerSymbol.createSimple({'color': 'blue'})
cat2 = QgsRendererCategory('类型B', symbol2, '类型B')
categories.append(cat2)
# 创建渲染器
renderer = QgsCategorizedSymbolRenderer('type_field', categories)
layer.setRenderer(renderer)
9.5.2 自动分类
from qgis.core import QgsStyle
# 使用颜色渐变自动分类
style = QgsStyle.defaultStyle()
ramp = style.colorRamp('Spectral')
renderer = QgsCategorizedSymbolRenderer.createRenderer(
layer,
'category_field',
QgsFillSymbol.createSimple({}),
ramp
)
layer.setRenderer(renderer)
9.6 分级渲染
9.6.1 分级符号渲染器
from qgis.core import (
QgsGraduatedSymbolRenderer,
QgsRendererRange,
QgsFillSymbol
)
# 创建分级
ranges = []
# 范围1: 0-100
symbol1 = QgsFillSymbol.createSimple({'color': '#ffffcc'})
range1 = QgsRendererRange(0, 100, symbol1, '0-100')
ranges.append(range1)
# 范围2: 100-500
symbol2 = QgsFillSymbol.createSimple({'color': '#fed976'})
range2 = QgsRendererRange(100, 500, symbol2, '100-500')
ranges.append(range2)
# 范围3: 500-1000
symbol3 = QgsFillSymbol.createSimple({'color': '#fd8d3c'})
range3 = QgsRendererRange(500, 1000, symbol3, '500-1000')
ranges.append(range3)
renderer = QgsGraduatedSymbolRenderer('value_field', ranges)
layer.setRenderer(renderer)
9.6.2 分级方法
# 使用分级方法
renderer = QgsGraduatedSymbolRenderer('population')
# 设置分类方法
# 0=等间距, 1=等计数, 2=自然断点, 3=标准差, 4=Pretty Breaks
renderer.setClassificationMethod(QgsClassificationJenks())
# 设置分类数
renderer.updateClasses(layer, 5)
layer.setRenderer(renderer)
9.6.3 分级颜色渐变
from qgis.core import QgsStyle, QgsGraduatedSymbolRenderer
style = QgsStyle.defaultStyle()
ramp = style.colorRamp('YlOrRd')
renderer = QgsGraduatedSymbolRenderer.createRenderer(
layer,
'value_field',
5, # 分类数
QgsGraduatedSymbolRenderer.Jenks, # 分类方法
QgsFillSymbol.createSimple({}),
ramp
)
layer.setRenderer(renderer)
9.7 规则渲染
9.7.1 规则渲染器
from qgis.core import QgsRuleBasedRenderer
# 创建根规则
root = QgsRuleBasedRenderer.Rule(None)
# 规则1: 大城市
symbol1 = QgsMarkerSymbol.createSimple({'color': 'red', 'size': '8'})
rule1 = QgsRuleBasedRenderer.Rule(symbol1)
rule1.setLabel('大城市')
rule1.setFilterExpression('"population" > 10000000')
# 规则2: 中等城市
symbol2 = QgsMarkerSymbol.createSimple({'color': 'orange', 'size': '5'})
rule2 = QgsRuleBasedRenderer.Rule(symbol2)
rule2.setLabel('中等城市')
rule2.setFilterExpression('"population" > 1000000 AND "population" <= 10000000')
# 规则3: 小城市
symbol3 = QgsMarkerSymbol.createSimple({'color': 'yellow', 'size': '3'})
rule3 = QgsRuleBasedRenderer.Rule(symbol3)
rule3.setLabel('小城市')
rule3.setFilterExpression('"population" <= 1000000')
root.appendChild(rule1)
root.appendChild(rule2)
root.appendChild(rule3)
renderer = QgsRuleBasedRenderer(root)
layer.setRenderer(renderer)
9.7.2 嵌套规则
# 创建嵌套规则结构
root = QgsRuleBasedRenderer.Rule(None)
# 父规则
parent = QgsRuleBasedRenderer.Rule(None)
parent.setLabel('已开发地区')
parent.setFilterExpression('"developed" = true')
# 子规则
child1 = QgsRuleBasedRenderer.Rule(QgsFillSymbol.createSimple({'color': 'red'}))
child1.setLabel('商业区')
child1.setFilterExpression('"type" = \'commercial\'')
child2 = QgsRuleBasedRenderer.Rule(QgsFillSymbol.createSimple({'color': 'yellow'}))
child2.setLabel('住宅区')
child2.setFilterExpression('"type" = \'residential\'')
parent.appendChild(child1)
parent.appendChild(child2)
root.appendChild(parent)
9.8 数据驱动样式
9.8.1 属性驱动大小
from qgis.core import QgsProperty, QgsSymbolLayer
symbol = QgsMarkerSymbol.createSimple({'name': 'circle'})
symbol_layer = symbol.symbolLayer(0)
# 根据字段值设置大小
symbol_layer.setDataDefinedProperty(
QgsSymbolLayer.PropertySize,
QgsProperty.fromExpression('sqrt("population") / 100')
)
9.8.2 属性驱动颜色
# 根据字段值设置颜色
symbol_layer.setDataDefinedProperty(
QgsSymbolLayer.PropertyFillColor,
QgsProperty.fromExpression('''
CASE
WHEN "value" > 100 THEN 'red'
WHEN "value" > 50 THEN 'yellow'
ELSE 'green'
END
''')
)
9.8.3 属性驱动旋转
# 根据字段值设置角度
symbol_layer.setDataDefinedProperty(
QgsSymbolLayer.PropertyAngle,
QgsProperty.fromField('rotation_angle')
)
9.9 标注
9.9.1 基本标注
from qgis.core import QgsPalLayerSettings, QgsVectorLayerSimpleLabeling
settings = QgsPalLayerSettings()
settings.fieldName = 'name' # 标注字段
settings.enabled = True
# 文字格式
text_format = QgsTextFormat()
text_format.setFont(QFont('Arial', 12))
text_format.setSize(12)
text_format.setColor(QColor(0, 0, 0))
settings.setFormat(text_format)
# 应用标注
labeling = QgsVectorLayerSimpleLabeling(settings)
layer.setLabeling(labeling)
layer.setLabelsEnabled(True)
9.9.2 标注样式
# 背景
background = QgsTextBackgroundSettings()
background.setEnabled(True)
background.setType(QgsTextBackgroundSettings.ShapeRectangle)
background.setFillColor(QColor(255, 255, 255, 200))
text_format.setBackground(background)
# 缓冲区(描边)
buffer = QgsTextBufferSettings()
buffer.setEnabled(True)
buffer.setSize(1)
buffer.setColor(QColor(255, 255, 255))
text_format.setBuffer(buffer)
# 阴影
shadow = QgsTextShadowSettings()
shadow.setEnabled(True)
shadow.setOffsetDistance(2)
shadow.setOffsetUnit(QgsUnitTypes.RenderMillimeters)
shadow.setBlurRadius(3)
text_format.setShadow(shadow)
9.9.3 标注位置
# 点图层标注位置
settings.placement = QgsPalLayerSettings.OverPoint # 在点上方
# 可选位置:
# OverPoint - 在点上
# AroundPoint - 围绕点
# Line - 沿线
# Curved - 弯曲沿线
# Horizontal - 水平
# Free - 自由
# OrderedPositionsAroundPoint - 优先位置
# 线图层
settings.placement = QgsPalLayerSettings.Line
settings.placementFlags = QgsPalLayerSettings.OnLine
# 面图层
settings.placement = QgsPalLayerSettings.OverPoint # 质心
9.9.4 标注表达式
# 使用表达式作为标注
settings.isExpression = True
settings.fieldName = '''
"name" || '\\n' ||
format_number("population", 0) || ' 人'
'''
9.10 样式管理
9.10.1 保存和加载样式
# 保存样式到QML
layer.saveNamedStyle('/path/to/style.qml')
# 加载样式
layer.loadNamedStyle('/path/to/style.qml')
# 保存样式到SLD
layer.saveSldStyle('/path/to/style.sld')
9.10.2 样式管理器
设置 > 样式管理器
功能:
- 管理符号库
- 导入/导出符号
- 创建符号收藏夹
- 管理颜色渐变
9.10.3 复制粘贴样式
# 复制样式
from qgis.core import QgsMapLayerStyle
style = QgsMapLayerStyle()
style.readFromLayer(source_layer)
# 粘贴到其他图层
style.writeToLayer(target_layer)
9.11 小结
本章详细介绍了QGIS中地图样式与符号化的各种方法:
关键要点:
- 理解QGIS符号系统架构
- 掌握点、线、面符号的创建和配置
- 熟练使用分类和分级渲染
- 了解规则渲染的强大功能
- 掌握数据驱动样式的使用
- 能够配置专业的标注效果
良好的符号化是制作专业地图的关键。
上一章:第08章 坐标参考系统与投影
下一章:第10章 空间分析工具

浙公网安备 33010602011771号