>>> from env_helper import info; info()
页面更新时间: 2024-04-10 15:24:47
运行环境:
Linux发行版本: Debian GNU/Linux 12 (bookworm)
操作系统内核: Linux-6.1.0-18-amd64-x86_64-with-glibc2.36
Python版本: 3.11.2
9.8. 绘制点状要素¶
最后来了解一下点状要素的绘制。
点是最简单的要素,为什么要放到最后来说呢。 主要是因为点的显示除了样式之外,文本标记的配合显示也比较独特。 关于点要素及其显示方式,只能用简约而不简单来形容了。
使用Mapnik绘制点有两种方式:
PointSymbolizer
允许你在给定的点上绘制图像,
ShieldSymbolizer
将图像和文本标记结合起来产生一个“盾”。
现在分别来看一下是如何使用的。
9.8.1. PointSymbolizer¶
PointSymbolizer能在点上绘制图片,默认的构造函数没有提供参数,并显示每一个点作为一个 4 × 4 像元的黑色方点:
>>> def renderit(line_sym=None, poly_sym=None, point_sym=None, shpfile=None, fig_index=0):
>>> m = mapnik.Map(600, 300, "+proj=latlong +datum=WGS84")
>>> s = mapnik.Style()
>>> r = mapnik.Rule()
>>>
>>>
>>> if poly_sym:
>>> r.symbols.append(poly_sym)
>>> if point_sym:
>>> r.symbols.append(point_sym)
>>> if line_sym:
>>> r.symbols.append(line_sym)
>>> s.rules.append(r)
>>> m.append_style('My Style', s)
>>> lyr = mapnik.Layer('world', "+proj=latlong +datum=WGS84")
>>> # lyr.datasource = mapnik.Shapefile(file='/gdata/world_borders.shp')
>>> if shpfile:
>>> lyr.datasource = mapnik.Shapefile(file=shpfile)
>>> else:
>>> lyr.datasource = mapnik.Shapefile(file=os.path.join(BASE_PATH, 'fig_data_line.shp'))
>>> lyr.styles.append('My Style')
>>> m.layers.append(lyr)
>>> # bbox = mapnik.Box2d(118, 36.6, 124.6, 40.7)
>>> # m.zoom_to_box(bbox)
>>> m.zoom_all()
>>> return m
>>>
>>> import os, mapnik
>>>
>>> shpfile='/gdata/fig_data/fig_data_poly.shp'
>>> ply_sym = mapnik.PolygonSymbolizer()
>>> ply_sym.fill = mapnik.Color('#f2eff9')
>>> li_sym = mapnik.LineSymbolizer()
>>> pt_sym = mapnik.PointSymbolizer()
>>> m = renderit(point_sym=pt_sym, line_sym=li_sym,
>>> poly_sym=ply_sym,shpfile=shpfile)
>>> m.zoom_all()
>>> mapnik.render_to_file(m, 'xx_sym.png')
可以为图片文件提供名称、类型、尺寸,PointSymbolizer将使用这些特征绘制每个点。
需要知道的是PointSymbolizer绘制影像会覆盖到你所想要的点上。 可能需要在影片的周围留白(或者透明) ,这样影像中你想要的部分就会出现在你想要的点上。 例如,如果你希望在一个确切的位置绘制一根针脚,你可能需要设置格式。
额外的(透明的)空白确保针脚的点位于图像的中央,使影像正好在地图所需的位置上。
无论你是否提供影像,PointSymbolizer都有两个用来修正行为的属性:
symbolizer.allow_overlap = True
:如果你将这个属性设置成True
,即使影像重叠,所有的点都将会被绘制。缺省情况下不会重叠。symbolizer.opacity = 0.75
:透明或者不透明怎样来绘制影像。值为0.0
,则绘制的影像是完全透明的,而值为1.0
(默认情况下),则绘制的影像是完全不透明的。
9.8.2. ShieldSymbolizer¶
ShieldSymbolizer允许你绘制标记,并将文本与图片结合。 在本章节中,我们将会着眼于ShieldSymbolizer绘制点。 ShieldSymbolize绘制的是一个和文本标记相关的影像:
ShieldSymbolizer
与 TextSymbolizer
和 PointSymbolizer
在呈现相同的数据时具有相同的工作方式。 仅有的不同就是
ShieldSymbolizer
确保文本和影像呈现在一起;
你永远也得不到一个没有文本的影像,或者反之亦然。 当你创建一个
ShieldSymbolizer
,你需要提供较多的参数。
symbolizer = mapnik.ShieldSymbolizer( fieldName, font, fontSize, color,
imageFile, imageFormat, imageWidth, imageHeight)
其中:
fieldName
是作为文本字段所要显示的字段或者属性的名称。font
是绘制文本所使用的字型名称。fontSize
是文本的尺寸的,以点数为单位。color
是Mapnik颜色对象定义用来绘制文本的颜色。imageFile
是掌握显示影像的文件的名字(和可选的路径)imageFormat
是定义图像文件格式的字符串(PNG or TIFF)imageWidth
是该影像文件的宽度,以像元为单位。imageHeight
是影像文件的高度,以像元为单位。
因为ShieldSymbolizer
是TextSymbolizer
的一个子类,
所有TextSymbolizer
可以利用的定位和格式的选项同样对ShieldSymbolizer
也有用。
由于,他也绘制一个影像,一个ShieldSymbolizer
同样拥有PointSymbolize
的allow_overlap
和opacity属性。
请注意你可能需要调用ShieldSymbolizer
的displacement()
方法来正确的定位文本,
若在默认情况下文本直接出现在点上,即图像的中央。
>>> import mapnik
>>> import os
>>>
>>> stylesheet = 'test_fig_poly_shield.xml'
>>>
>>> m = mapnik.Map(600, 200)
>>> mapnik.load_map(m, stylesheet)
>>>
>>> m.zoom_all()
>>> # env = m.envelope()
>>> # print(env)
>>> # box = mapnik.Box2d(env.minx - .1, env.miny - .3, env.maxx + .3, env.maxy + .3)
>>> # m.zoom_to_box(box)
>>>
>>> mapnik.render_to_file(m, 'xx_test_fig_poly_shield.png')
>>>
9.8.3. 使用TextSymbolizer来绘制点符号¶
这里要介绍一种变通的技巧,直接使用TextSymbolizer来绘制点符号。
在前面两节中,我们介绍了使用 PointSymbolizer
与 ShieldSymbolizer
两种方式对点状要素进行绘制的方法,
除了默认的情况,都要求使用图片来绘制点状符号。
除去分辨率的因素,由于需要指定图片的大小,
在更换图片或是需要更换出图的大小时,都有一个重新设置的问题。
考虑一下前面提到过的标注,使用字体的时候,只需要指定字体大小(按一定的规范), 则会自动计算产生精美的结果。也可以使用标注的方式来绘制点符号。
前提是要有相应的字库。