>>> from env_helper import info; info()
页面更新时间: 2022-12-28 08:26:47
运行环境:
Linux发行版本: Debian GNU/Linux 11 (bullseye)
操作系统内核: Linux-5.10.0-20-amd64-x86_64-with-glibc2.31
Python版本: 3.9.2
8.8. 绘制点状要素¶
最后来了解一下点状要素的绘制。
点是最简单的要素,为什么要放到最后来说呢。 主要是因为点的显示除了样式之外,文本标记的配合显示也比较独特。 关于点要素及其显示方式,只能用简约而不简单来形容了。
使用Mapnik绘制点有两种方式:
PointSymbolizer
允许你在给定的点上绘制图像,
ShieldSymbolizer
将图像和文本标记结合起来产生一个“盾”。
现在分别来看一下是如何使用的。
8.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()
>>> # line_sym.stroke_linecap = mapnik.stroke_linecap.ROUND_CAP
>>> # line_sym.stroke_linejoin = mapnik.stroke_linejoin.ROUND_JOIN
>>> # line_sym.stroke_dasharray = [(3,4)]
>>> # line_sym.stroke_linecap = mapnik.stroke_linecap.SQUARE_CAP
>>>
>>> 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将使用这些特征绘制每个点。

图 8.6 result¶
需要知道的是PointSymbolizer绘制影像会覆盖到你所想要的点上。 可能需要在影片的周围留白(或者透明) [1], 这样影像中你想要的部分就会出现在你想要的点上。 例如,如果你希望在一个确切的位置绘制一根针脚,你可能需要设置格式。
额外的(透明的)空白确保针脚的点位于图像的中央,使影像正好在地图所需的位置上。
无论你是否提供影像,PointSymbolizer都有两个用来修正行为的属性:
symbolizer.allow_overlap = True
:如果你将这个属性设置成True,即使影像重叠,所有的点都将会被绘制。缺省情况下不会重叠。symbolizer.opacity = 0.75
:透明或者不透明怎样来绘制影像。值为0.0,则绘制的影像是完全透明的,而值为1.0(默认情况下),则绘制的影像是完全不透明的。
8.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()
方法来正确的定位文本,
若在默认情况下文本直接出现在点上,即图像的中央。
8.8.3. 使用TextSymbolizer来绘制点符号¶
这里要介绍一种变通的技巧,直接使用TextSymbolizer来绘制点符号。
在前面两节中,我们介绍了使用PointSymbolizer
与
ShieldSymbolizer
两种方式对点状要素进行绘制的方法,
除了默认的情况,都要求使用图片来绘制点状符号。除去分辨率的因素,由于需要指定图片的大小,
在更换图片或是需要更换出图的大小时,都有一个重新设置的问题。
考虑一下前面提到过的标注,使用字体的时候,只需要指定字体大小(按一定的规范), 则会自动计算产生精美的结果。也可以使用标注的方式来绘制点符号。
前提是要有相应的字库。这里我选择使用的是ESRI公司在ArcGIS软件中携带的字体 [2]。
使用SpatiaLite数据库文件,对表进行更新:
alter table dxt25w_E49C001001_respt_point add sty char(1);
-- 村
update dxt25w_E49C001001_respt_point set sty='(' where gb=31091;
-- 乡
update dxt25w_E49C001001_respt_point set sty='5' where gb=31090;
-- 镇
update dxt25w_E49C001001_respt_point set sty='R' where gb=31080;
-- 区县
update dxt25w_E49C001001_respt_point set sty='H' where gb=31060 or gb=31061;
-- 县
update dxt25w_E49C001001_respt_point set sty='P' where gb=31050;
-- 市
update dxt25w_E49C001001_respt_point set sty='Q' where gb=31030;
-- 地区盟
update dxt25w_E49C001001_respt_point set sty='O' where gb=31040;
将字体设置为ESRI Default Marker Regular
,即可产生相应的效果。
[1] 使用图像处理软件可以做到这一点,如开源图像处理软件 GIMP
[2] 这个涉及到版权问题,使用时请慎重