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)