I'm trying to use Python to create a TextSymbolizer to display a trail
name above the trail LineSymbolizer. Below this layer is the OSM base
layer which contains its own data for that trail.
I can display the line but I cannot display any text. I've run out of
ideas, Google is proving fruitless so I'm looking for new ideas, if I
may be so bold.
I've compiled Mapnik with debug turned on only to find that there's no
logging near the text symbolizer code.
I had a go with gdb but I haven't spent enough time to workout how to
debug from python into the Mapnik shared library. If anybody has any
guidance for how to do this then I'd be grateful. I'm happy enough to
debug but I'm not familiar with gdb.
I also edited the osm.xml and took away the trails and trail names
which might be interfering with the TextSymbolizer but I didn't see
any difference.
Relevant code:
imgx = 400
imgy = 400
m = mapnik.Map(imgx,imgy)
m.buffer_size = 1000
workoutParams = dict(host='localhost',port='5432',user='postgres',password='password',dbname='postgis')
workoutParams['estimate_extent'] = False
workoutParams['extent']='-180,-89.99,180,89.99'
workoutTable = "(select id, geometry, 'really long trail name' as trail_name from pub_trail_segment where pub_trail_id = %s) as route" % idNumber
workoutParams['table']= workoutTable
workoutDatasource = PostGIS(**workoutParams)
workoutLayer = Layer('route','+proj=latlong +datum=WGS84')
workoutLayer.datasource = workoutDatasource
workoutStyle = mapnik.Style()
segmentStyleRule = mapnik.Rule()
segmentStyleRule.symbols.append(mapnik.LineSymbolizer(mapnik.Color('blue'),1)) #50 for print
segmentTextSymbolizer = mapnik.TextSymbolizer('trail_name', 'book-fonts', 20, mapnik.Color('blue'))
segmentTextSymbolizer.halo_radius = 1
segmentTextSymbolizer.label_placement = mapnik.label_placement.LINE_PLACEMENT
segmentTextSymbolizer.allow_overlap = True
segmentTextSymbolizer.avoid_edges = False
segmentStyleRule.symbols.append(segmentTextSymbolizer)
workoutStyle.rules.append(segmentStyleRule)
m.append_style('route',workoutStyle)
workoutLayer.styles.append('route')
m.layers.append(workoutLayer)
m.zoom_to_box(bbox)
im = mapnik.Image(imgx,imgy)
mapnik.render(m, im)
What am I doing wrong?
Many thanks for any ideas
Cros-posted to StackOverflow
Best Answer
Two options: Create a second style object and attach the text symbolizer to that style, then append that second style to the layer. Layers in Mapnik can accept any number of styles and will render them in the order attached, so if you attach the a second style with text rules, then they will be rendered second. However in the case of polygons with text most people go further and create a second layer with its own style containing text rules. This will ensure that all text is rendered after all other geometries are rendered.