RFC: ClassGroupPattern

Frank Koormann frank.koormann at intevation.de
Wed Jan 26 11:16:13 CET 2005


* Jan-Oliver Wagner <jan at intevation.de> [050126 07:11]:
> On Tue, Jan 25, 2005 at 06:45:48PM +0100, Frank Koormann wrote:
> > I just hacked in a new classification into Thuban I needed for a
> > specific task: Instead of a single value or a range (valid for numbers)
> > a regexp pattern can be applied (with re.match()). 
> 
> can you send the patches and the handcrafted file (I guess it is for
> iceland) ?

No, the Thuban iceland sample layers aren't the ones I usually work with ;)
However, I have prepared a sample based on iceland: Group the cultural
landmarks by CPTLABEL: A-M and N-Z. Search for "clpattern" in the file.

I attached the session file and the patch (now including also
Thuban/Model/save.py)

Regards,
        
        Frank

-- 
Frank Koormann                             <frank.koormann at intevation.de>
 Professional Service around Free Software       (http://intevation.net/)
 FreeGIS Project                                 (http://freegis.org/)
-------------- next part --------------
Index: Resources/XML/thuban-1.1.dtd
===================================================================
RCS file: /thubanrepository/thuban/Resources/XML/thuban-1.1.dtd,v
retrieving revision 1.2
diff -u -3 -p -r1.2 thuban-1.1.dtd
--- Resources/XML/thuban-1.1.dtd        3 Oct 2004 20:38:54 -0000       1.2
+++ Resources/XML/thuban-1.1.dtd        26 Jan 2005 09:14:01 -0000
@@ -173,7 +173,7 @@ identify the version of the file format.


 <!-- Classification data -->
-<!ELEMENT classification (clnull?, clpoint*, clrange*, clcont*)>
+<!ELEMENT classification (clnull?, clpoint*, clrange*, clcont*, clpattern*)>
 <!ATTLIST classification field CDATA #REQUIRED>
 <!ATTLIST classification field_type CDATA #REQUIRED>

@@ -181,6 +181,7 @@ identify the version of the file format.
 <!ELEMENT clpoint (cldata*)>
 <!ELEMENT clrange (cldata*)>
 <!ELEMENT clcont (cldata*)>
+<!ELEMENT clpattern (cldata*)>

 <!ATTLIST clnull label CDATA #IMPLIED>

@@ -196,6 +197,9 @@ identify the version of the file format.
 <!ATTLIST clcont rmax CDATA #REQUIRED>
 <!ATTLIST clcont dmin CDATA #REQUIRED>
 <!ATTLIST clcont dmax CDATA #REQUIRED>
+
+<!ATTLIST clpattern pattern CDATA #REQUIRED>
+<!ATTLIST clpattern label CDATA #IMPLIED>

 <!-- Visual appearance of the classification


Index: Thuban/Model/classification.py
===================================================================
RCS file: /thubanrepository/thuban/Thuban/Model/classification.py,v
retrieving revision 1.39
diff -u -3 -p -r1.39 classification.py
--- Thuban/Model/classification.py      3 Oct 2004 21:01:31 -0000       1.39
+++ Thuban/Model/classification.py      26 Jan 2005 09:14:02 -0000
@@ -21,6 +21,7 @@ on the mapping algorithm.
 """

 import copy, operator, types
+import re

 from Thuban import _

@@ -117,6 +118,9 @@ class Classification(Publisher):
                 if not compiled or compiled[-1][0] != "singletons":
                     compiled.append(("singletons", {}))
                 compiled[-1][1].setdefault(group.GetValue(), group)
+            elif isinstance(group, ClassGroupPattern):
+                pattern = re.compile(group.GetPattern())
+                compiled.append(("pattern", (pattern, group)))
             elif isinstance(group, ClassGroupRange):
                 left, min, max, right = group.GetRangeTuple()
                 if left == "[":
@@ -262,6 +266,10 @@ class Classification(Publisher):
                     group = params.get(value)
                     if group is not None:
                         return group
+                elif typ == "pattern":
+                    p, g = params
+                    if p.match(value):
+                        return g
                 elif typ == "range":
                     lfunc, min, max, rfunc, g = params
                     if lfunc(min, value) and rfunc(max, value):
@@ -738,6 +746,64 @@ class ClassGroupRange(ClassGroup):

     def __repr__(self):
         return "(" + str(self.__range) + ClassGroup.__repr__(self) + ")"
+
+class ClassGroupPattern(ClassGroup):
+    """A Group that is associated with a reg exp pattern."""
+
+    def __init__(self, pattern = "", props = None, label = "", group = None):
+        """Constructor.
+
+        pattern -- the associated pattern.
+
+        prop -- a ClassGroupProperites object. If prop is None a default
+                 set of properties is created.
+
+        label -- a label for this group.
+        """
+        ClassGroup.__init__(self, label, props, group)
+
+        self.SetPattern(pattern)
+
+    def __copy__(self):
+        return ClassGroupPattern(self.GetPattern(),
+                                   self.GetProperties(),
+                                   self.GetLabel())
+
+    def __deepcopy__(self, memo):
+        return ClassGroupPattern(self.GetPattern(), group = self)
+
+    def GetPattern(self):
+        """Return the associated pattern."""
+        return self.__pattern
+
+    def SetPattern(self, pattern):
+        """Associate this Group with the given pattern."""
+        self.__pattern = pattern
+
+    def Matches(self, pattern):
+        """Check if the given pattern matches the associated Group pattern."""
+
+        """Returns True if the value matches, False otherwise."""
+
+        if re.match(self.__pattern, pattern):
+            return True
+        else:
+            return False
+
+    def GetDisplayText(self):
+        label = self.GetLabel()
+
+        if label != "": return label
+
+        return str(self.GetPattern())
+
+    def __eq__(self, other):
+        return ClassGroup.__eq__(self, other) \
+            and isinstance(other, ClassGroupPattern) \
+            and self.__pattern == other.__pattern
+
+    def __repr__(self):
+        return "(" + repr(self.__pattern) + ", " + ClassGroup.__repr__(self) + ")"

 class ClassGroupMap(ClassGroup):
     """Currently, this class is not used."""
Index: Thuban/Model/load.py
===================================================================
RCS file: /thubanrepository/thuban/Thuban/Model/load.py,v
retrieving revision 1.52
diff -u -3 -p -r1.52 load.py
--- Thuban/Model/load.py        13 Dec 2004 17:51:11 -0000      1.52
+++ Thuban/Model/load.py        26 Jan 2005 09:14:02 -0000
@@ -33,7 +33,8 @@ from Thuban.Model.layer import Layer, Ra
 from Thuban.Model.proj import Projection
 from Thuban.Model.range import Range
 from Thuban.Model.classification import Classification, \
-    ClassGroupDefault, ClassGroupSingleton, ClassGroupRange, ClassGroupMap, \
+    ClassGroupDefault, ClassGroupSingleton, ClassGroupRange, \
+    ClassGroupPattern, ClassGroupMap, \
     ClassGroupProperties
 from Thuban.Model.data import DerivedShapeStore, ShapefileStore
 from Thuban.Model.table import DBFTable
@@ -136,6 +137,7 @@ class SessionLoader(XMLReader):
             'clnull'        : ("start_clnull",         "end_clnull"),
             'clpoint'       : ("start_clpoint",        "end_clpoint"),
             'clrange'       : ("start_clrange",        "end_clrange"),
+            'clpattern'     : ("start_clpattern",      "end_clpattern"),
             'cldata'        : ("start_cldata",         "end_cldata"),
             'table'         : ("start_table",          "end_table"),
             'labellayer'    : ("start_labellayer",     None),
@@ -596,6 +598,20 @@ class SessionLoader(XMLReader):
         self.cl_group.SetProperties(self.cl_prop)
         self.aLayer.GetClassification().AppendGroup(self.cl_group)
         del self.cl_group, self.cl_prop
+
+
+    def start_clpattern(self, name, qname, attrs):
+        pattern = attrs.get((None, 'pattern'), "")
+
+        self.cl_group = ClassGroupPattern(pattern)
+        self.cl_group.SetLabel(self.encode(attrs.get((None, 'label'), "")))
+        self.cl_prop = ClassGroupProperties()
+
+    def end_clpattern(self, name, qname):
+        self.cl_group.SetProperties(self.cl_prop)
+        self.aLayer.GetClassification().AppendGroup(self.cl_group)
+        del self.cl_group, self.cl_prop
+

     def start_cldata(self, name, qname, attrs):
         self.cl_prop.SetLineColor(
Index: Thuban/Model/save.py
===================================================================
RCS file: /thubanrepository/thuban/Thuban/Model/save.py,v
retrieving revision 1.41
diff -u -3 -p -r1.41 save.py
--- Thuban/Model/save.py        7 Oct 2004 14:24:24 -0000       1.41
+++ Thuban/Model/save.py        26 Jan 2005 09:14:02 -0000
@@ -18,12 +18,14 @@ __version__ = "$Revision: 1.41 $"

 import os

+from Thuban import _
+
 import Thuban.Lib.fileutil

 from Thuban.Model.layer import Layer, RasterLayer

-from Thuban.Model.classification import \
-    ClassGroupDefault, ClassGroupSingleton, ClassGroupRange, ClassGroupMap
+from Thuban.Model.classification import ClassGroupDefault, \
+    ClassGroupSingleton, ClassGroupRange, ClassGroupPattern, ClassGroupMap
 from Thuban.Model.transientdb import AutoTransientTable, TransientJoinedTable
 from Thuban.Model.table import DBFTable, FIELDTYPE_STRING
 from Thuban.Model.data import DerivedShapeStore, ShapefileStore, \
@@ -339,6 +341,11 @@ class SessionSaver(XMLWriter):
                 open_el  = 'clrange label="%s" range="%s"' \
                           % (self.encode(g.GetLabel()), str(g.GetRange()))
                 close_el = 'clrange'
+            elif isinstance(g, ClassGroupPattern):
+                open_el  = 'clpattern label="%s" pattern="%s"' \
+                          % (self.encode(g.GetLabel()), str(g.GetPattern()))
+                close_el = 'clpattern'
+
             else:
                 assert False, _("Unsupported group type in classification")
                 continue

-------------- next part --------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE session SYSTEM "thuban.dtd">
<session title="Thuban sample session">
    <map title="Iceland map">
        <projection>
            <parameter value="zone=26"/>
            <parameter value="proj=utm"/>
            <parameter value="ellps=clrk66"/>
        </projection>
        <layer stroke="#000000" filename="iceland/political.shp" fill="#c0c0c0" stroke_width="1" title="political"/>
        <layer stroke="#ffffff" filename="iceland/roads-line.shp" fill="None" stroke_width="1" title="roads-line">
            <classification field="RDLNTYPE" field_type="int">
                <clnull>
                    <cldata stroke="#ffffff" stroke_width="1" fill="None"/>
                </clnull>
                <clpoint value="1">
                    <cldata stroke="#ff0000" stroke_width="1" fill="None"/>
                </clpoint>
                <clpoint value="2">
                    <cldata stroke="#00aa00" stroke_width="1" fill="None"/>
                </clpoint>
                <clpoint value="3">
                    <cldata stroke="#0000ff" stroke_width="1" fill="None"/>
                </clpoint>
            </classification>
        </layer>
        <layer stroke="#000000" filename="iceland/cultural_landmark-point.shp" fill="#000000" stroke_width="1" title="cultural_landmark-point">
            <classification field="CLPTLABEL" field_type="string">
                <clnull>
                    <cldata stroke="#000000" stroke_width="1" fill="#000000"/>
                </clnull>
                <clpattern label="A-M" pattern="[A-M].*">
                    <cldata stroke="#000000" stroke_width="1" fill="#ffffff"/>
                </clpattern>
                <clpattern label="N-Z" pattern="[N-Z].*">
                    <cldata stroke="#000000" stroke_width="1" fill="#ffff00"/>
                </clpattern>
            </classification>
        </layer>
    </map>
</session>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://www.intevation.de/pipermail/thuban-devel/attachments/20050126/7620690e/attachment.bin


More information about the Thuban-devel mailing list

This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)