Cascadenik icon indicating copy to clipboard operation
Cascadenik copied to clipboard

Handling of TextSymbolizer opacity and ratio, and Layer clear_label_cache attributes

Open numenor opened this issue 13 years ago • 0 comments

I needed transparency (opacity) of text labels, as well as the "clear_label_cache attribute" of layers and noticed, that so far it is not possible to do either using Cascadenik (and ratio was not handled completely, either, it seems). I modified it locally and can use it now. The following is the patch (output of git diff) wrt. branch "mapnik2" (I edited it by removing some changes, because I have other local changes not of general interest here; I hope, it still works with somewhat differing line numbers in the diff specifications):


diff --git a/cascadenik/compile.py b/cascadenik/compile.py                                                                                                                            
index f54d5f2..730d085 100644                                                                                                                                                         
--- a/cascadenik/compile.py                                                                                                                                                           
+++ b/cascadenik/compile.py                                                                                                                                                           
@@ -998,6 +998,7 @@ def get_text_rule_groups(declarations):                                                                                                                           
                     'text-dy': 'dy',                                                                                                                                                 
                     'text-face-name': 'face_name',                                                                                                                                   
                     'text-fill': 'fill',                                                                                                                                             
+                    'text-opacity': 'opacity',                                                                                                                                       
                     'text-fontset': 'fontset',                                                                                                                                       
                     'text-force-odd-labels': 'force_odd_labels',                                                                                                                     
                     'text-halo-fill': 'halo_fill',                                                                                                                                   
@@ -1049,7 +1050,7 @@ def get_text_rule_groups(declarations):
             fontset = values.has_key('text-fontset') and values['text-fontset'].value or None
             size = values.has_key('text-size') and values['text-size'].value
             color = values.has_key('text-fill') and values['text-fill'].value
-            
+            opacity = values.has_key('text-opacity') and values['text-opacity'].value or None
             ratio = values.has_key('text-ratio') and values['text-ratio'].value or None
             wrap_width = values.has_key('text-wrap-width') and values['text-wrap-width'].value or None
             label_spacing = values.has_key('text-spacing') and values['text-spacing'].value or None
@@ -1080,7 +1081,7 @@ def get_text_rule_groups(declarations):
                                               avoid_edges, minimum_distance, allow_overlap, label_placement, \
                                               line_spacing, character_spacing, text_transform, fontset,
                                               anchor_dx, anchor_dy,horizontal_alignment, \
-                                              vertical_alignment, justify_alignment, force_odd_labels)
+                                              vertical_alignment, justify_alignment, force_odd_labels, opacity, ratio)
             
                 rules.append(make_rule(filter, symbolizer))
         
@@ -1532,7 +1537,8 @@ def compile(src, dirs, verbose=False, srs=None, datasources_cfg=None):
                                  datasource, styles,
                                  layer_el.get('srs', None),
                                  layer_el.get('min_zoom', None) and int(layer_el.get('min_zoom')) or None,
-                                 layer_el.get('max_zoom', None) and int(layer_el.get('max_zoom')) or None)
+                                 layer_el.get('max_zoom', None) and int(layer_el.get('max_zoom')) or None,
+                                 layer_el.get('clear_label_cache', None))
     
             layers.append(layer)
     
diff --git a/cascadenik/output.py b/cascadenik/output.py
index ca07401..a8e19c1 100644
--- a/cascadenik/output.py
+++ b/cascadenik/output.py
@@ -62,7 +62,8 @@ class Map:
                 lay.srs = layer.srs or lay.srs
                 lay.minzoom = layer.minzoom or lay.minzoom
                 lay.maxzoom = layer.maxzoom or lay.maxzoom
-                
+                lay.clear_label_cache = layer.clear_label_cache if not(layer.clear_label_cache is None) else lay.clear_label_cache
+
                 for style in layer.styles:
                     lay.styles.append(style.name)
     
@@ -98,12 +99,13 @@ class Rule:
         return 'Rule(%s:%s, %s, %s)' % (repr(self.minscale), repr(self.maxscale), repr(self.filter), repr(self.symbolizers))
 
 class Layer:
-    def __init__(self, name, datasource, styles=None, srs=None, minzoom=None, maxzoom=None):
+    def __init__(self, name, datasource, styles=None, srs=None, minzoom=None, maxzoom=None, clearlabelcache=None):
         assert isinstance(name, basestring)
         assert styles is None or type(styles) in (list, tuple)
         assert srs is None or isinstance(srs, basestring)
         assert minzoom is None or type(minzoom) in (int, float)
         assert maxzoom is None or type(maxzoom) in (int, float)
+        assert clearlabelcache is None or isinstance(clearlabelcache, basestring)
         
         self.name = safe_str(name)
         self.datasource = datasource
@@ -111,6 +113,7 @@ class Layer:
         self.srs = safe_str(srs)
         self.minzoom = minzoom
         self.maxzoom = maxzoom
+        self.clear_label_cache = True if (clearlabelcache and (clearlabelcache in ["on", "true", "On", "True", "ON", "TRUE", "1"])) else False
 
     def __repr__(self):
         return 'Layer(%s: %s)' % (self.name, repr(self.styles))
@@ -236,8 +239,8 @@ class TextSymbolizer:
         halo_color=None, halo_radius=None, dx=None, dy=None, avoid_edges=None, \
         minimum_distance=None, allow_overlap=None, label_placement=None, \
         character_spacing=None, line_spacing=None, text_transform=None, fontset=None, \
-        anchor_dx=None, anchor_dy=None,horizontal_alignment=None,vertical_alignment=None,
-        justify_alignment=None, force_odd_labels=None):
+        anchor_dx=None, anchor_dy=None,horizontal_alignment=None,vertical_alignment=None, \
+        justify_alignment=None, force_odd_labels=None, opacity=None, ratio=None):
 
         assert isinstance(name, basestring)
         assert face_name is None or isinstance(face_name, basestring)
@@ -250,6 +253,8 @@ class TextSymbolizer:
         assert max_char_angle_delta is None or type(max_char_angle_delta) is int
         assert halo_color is None or halo_color.__class__ is style.color
         assert halo_radius is None or type(halo_radius) is int
+        assert opacity is None or type(opacity) is float
+        assert ratio is None or type(ratio) is int
         assert dx is None or type(dx) is int
         assert dy is None or type(dy) is int
         assert character_spacing is None or type(character_spacing) is int
@@ -274,6 +279,8 @@ class TextSymbolizer:
         self.max_char_angle_delta = max_char_angle_delta
         self.halo_color = halo_color
         self.halo_radius = halo_radius
+        self.opacity = opacity
+        self.ratio = ratio
         self.dx = dx
         self.dy = dy
         self.character_spacing = character_spacing
@@ -309,6 +316,8 @@ class TextSymbolizer:
         sym.max_char_angle_delta = self.max_char_angle_delta or sym.max_char_angle_delta
         sym.halo_fill = mapnik.Color(str(self.halo_color)) if self.halo_color else sym.halo_fill
         sym.halo_radius = self.halo_radius or sym.halo_radius
+        sym.opacity = self.opacity or sym.opacity
+        sym.text_ratio = self.ratio or sym.text_ratio
         sym.character_spacing = self.character_spacing or sym.character_spacing
         sym.line_spacing = self.line_spacing or sym.line_spacing
         sym.avoid_edges = self.avoid_edges.value if self.avoid_edges else sym.avoid_edges
diff --git a/cascadenik/style.py b/cascadenik/style.py
index b2d5885..11dc019 100644
--- a/cascadenik/style.py
+++ b/cascadenik/style.py
@@ -182,8 +186,8 @@ properties = {
     # Font size
     'text-size': int,
 
-    # ?
-    'text-ratio': None, # ?
+    # target ratio for text bounding box in pixels
+    'text-ratio': int,
 
     # length before wrapping long names
     'text-wrap-width': int,
@@ -206,6 +210,9 @@ properties = {
     # Color of the fill ie #FFFFFF
     'text-fill': color,
 
+    # 0.0 - 1.0 (default 1.0)
+    'text-opacity': float,
+
     # Color of the halo
     'text-halo-fill': color,
 

Btw.: point opacity (image/icons), shield avoid-edges, and shield placement attributes do not seem to be supported yet, either; but I do not have a tested patch for these yet.

numenor avatar Jan 08 '11 17:01 numenor