>>> from env_helper import info; info()
页面更新时间: 2024-04-10 15:21:42
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-18-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

9.5. 绘制线

Mapnik提供了两种绘制线状要素的方法: LineSymbolizer 和LinePatternSymbolizer。让我们依次来看一看:

9.5.1. LineSymbolizer

LinesSymbolizer可以绘制线状要素,也可以用来表征多边形轮廓。

LinesSymbolizer是Mapnik中最有用的symbolizers之一。这里是用于创建绘制虚线的LinesSymbolizer的Python的代码,例如:

>>> import mapnik
>>>
>>> symbolizer = mapnik.LineSymbolizer()
>>> symbolizer.stroke = mapnik.Color("#008000")
>>> symbolizer.stroke_width = 1.0

LineSymbolizer使用Mapnik的 Stroke 对象来定义绘制线。 为了使用LineSymbolizer,首先你需要创建stroke对象和绘制线形的各种选项。 然后,可以创建 LineSymbolizer,传递 stroke 对象到 LineSymbolizer 的构造器中。

让我们来更仔细的看一下由stroke对象提供的绘制线型的各种选项。

默认情况下,线将会被绘制成黑色。你可以通过设置 strokecolor 属性到Mapnik的颜色对象中来改变颜色。

stroke.color = mapnik.Color("red")

在默认情况下,LineSymbolizer绘制的线有一个像元的宽。 你可以设置stroke的width属性改变线的宽度;你也可以通过设置stroke的opacity属性改变线的透明程度:

stroke.width = 1.5
stroke.opacity = 0.8

注意:你可以通过改变微小的线的宽度来对你的线的宽度进行细粒度的控制。

透明度的范围是从0.0(完全透明)到1.0(完全不透明)。如果没有定义透明度,则线将会完全不透明。

line_cap定义的是绘制线的结尾。Mapnik支持三种水平的line_cap的设置。

默认情况下,线会使用BUTT_CAP格式,但是你可以通过设置strokeline_cap属性来改变这种状况,例如:

stroke1.line_cap = mapnik.line_cap.BUTT_CAP
stroke2.line_cap = mapnik.line_cap.ROUND_CAP
stroke3.line_cap = mapnik.line_cap.SQUARE_CAP

下面看一下实例:

>>> roadEdgeSymbolizer = mapnik.LineSymbolizer()
>>> roadEdgeSymbolizer.stroke = mapnik.Color("#bf7a3a")
>>> roadEdgeSymbolizer.stroke_width = 7
>>>
>>> roadInteriorSymbolizer = mapnik.LineSymbolizer()
>>> roadInteriorSymbolizer.stroke = mapnik.Color("#ffd3a9")
>>> roadInteriorSymbolizer.stroke_width = 6
>>>
>>> m = mapnik.Map(600, 300, "+proj=latlong +datum=WGS84")
>>> # m.background = mapnik.Color('steelblue')
>>> s = mapnik.Style()
>>> r = mapnik.Rule()
>>>
>>> r.symbols.append(roadEdgeSymbolizer)
>>> s.rules.append(r)
>>> m.append_style('My Style', s)
>>> lyr = mapnik.Layer('world', "+proj=latlong +datum=WGS84")
>>> lyr.datasource = mapnik.Shapefile(file='/gdata/GSHHS_c.shp')
>>> lyr.styles.append('My Style')
>>> m.layers.append(lyr)
>>>
>>>
>>> m.zoom_all()
>>>
>>>
>>> mapnik.render_to_file(m, 'xx_line_kz.png', 'png')

上面生成的结果为:

>>> from IPython.display import Image
>>> Image('./xx_line_kz.png')
_images/sec5_mapnik-line_9_0.png

9.5.2. 使用XML文件

线的顶端样式

>>>
>>> stylesheet = 'test_fig_line_cap.xml'
>>>
>>> # image = 'xx_world_style_from_xml.png'
>>> m = mapnik.Map(600, 300)
>>> mapnik.load_map(m, stylesheet)
>>> m.zoom_all()
>>> # m.background = mapnik.Color('steelblue')
>>>
>>> # bbox = mapnik.Box2d(118, 36.6, 124.6, 40.7)
>>> bbox = mapnik.Box2d(-1, -1, 25, 1)
>>> m.zoom_to_box(bbox)
>>> mapnik.render_to_file(m, 'xx_outfile.png')

以下为结果:

线的顶端样式

图 9.4 线的顶端样式

线状要素样式

下面来看一下如何绘制虚线和点线:

你可以添加“breaks”使其出现虚线和点线。

你可以通过调用 strokeadd_dash() 的方法在线上添加少许线段:

  • all text stuff

  • dash arrays

    stroke.add_dash(5, 5)

这将会给线一个 5 像元的短划线,接下来是 5 像元的间隔: 你不能被限制到只有一个虚线片段: 如果调用 add_dash() 多次,你将创建一个拥有更多片段的线。 这些虚线片段也会被依次处理,并允许你创建更多虚线和点的模式。例如:

>>>
>>> stylesheet = 'test_fig_line_dash.xml'
>>>
>>> # image = 'xx_world_style_from_xml.png'
>>> m = mapnik.Map(600, 300)
>>> mapnik.load_map(m, stylesheet)
>>> m.zoom_all()
>>> # m.background = mapnik.Color('steelblue')
>>>
>>> # bbox = mapnik.Box2d(118, 36.6, 124.6, 40.7)
>>> bbox = mapnik.Box2d(-1, -1, 25, 1)
>>> m.zoom_to_box(bbox)
>>> mapnik.render_to_file(m, 'xx_fig_line_dash.png')
>>>
线状要素样式

图 9.5 线状要素样式

另一个实例:

>>> stylesheet = '/gdata/world_map_dash.xml'
>>>
>>> m = mapnik.Map(600, 300)
>>> mapnik.load_map(m, stylesheet)
>>> m.zoom_all()
>>>
>>>
>>> bbox = mapnik.Box2d(118, 36.6, 124.6, 40.7)
>>>
>>> m.zoom_to_box(bbox)
>>>
>>> mapnik.render_to_file(m, 'xx_line_jv.png', 'png')
线状要素样式

图 9.6 线状要素样式

线的连接

改变一条线的方向,可以通过三种标准的方式之一来绘制它的转折端:

默认的行为就是使用MITER_JOIN, 你可以通过设置stroke为一个不同的值的line_join,来得到不同的效果。

>>>
>>> stylesheet = 'test_fig_line_join.xml'
>>>
>>> # image = 'xx_world_style_from_xml.png'
>>> m = mapnik.Map(600, 300)
>>> mapnik.load_map(m, stylesheet)
>>> m.zoom_all()
>>> # m.background = mapnik.Color('steelblue')
>>>
>>> # bbox = mapnik.Box2d(118, 36.6, 124.6, 40.7)
>>> bbox = mapnik.Box2d(-1, -1, 25, 1)
>>> m.zoom_to_box(bbox)
>>> mapnik.render_to_file(m, 'xx_fig_line_join.png')
>>>
>>>
线的连接样式

图 9.7 线的连接样式