source: TI02-CSML/trunk/services/3rdParty/GeoTypes-0.6.0/GeoTypes/_Path.py @ 2194

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI02-CSML/trunk/services/3rdParty/GeoTypes-0.6.0/GeoTypes/_Path.py@2194
Revision 2194, 5.8 KB checked in by lawrence, 13 years ago (diff)

Adding various specs and 3rd party code of interest for the CSML
services development.

Line 
1
2################################################################################
3# Copyright (c) QinetiQ Plc 2003
4#
5# Licensed under the LGPL. For full license details see the LICENSE file.
6################################################################################
7
8"""
9Implementation of Path.
10"""
11
12import types, string
13
14from _Point import Point, pointFromSequence
15
16class Path:
17    """
18    Path provides and implementation of a sequence of connected Points in 2d space.
19
20    It implements most of the methods of a container class and should be usable as if
21    it were a list of Points.
22
23    Both 'open' and 'closed' paths are supported and a path can be toggled between
24    open and closed using the setOpen() and setClosed() methods.
25    """
26   
27    def __init__(self,s=None):
28        """
29        Constructor. Optional (arg s) is a string as returned by postgres.
30
31        Its form is a bit of a pain because postgres does not have seperate types for
32        open and closed paths. See http://www.postgresql.org/docs/7.3/static/datatype-geometric.html
33        for a description of its represenation.
34
35        If (arg s) is None or omitted the Path is initialised to have no Points.
36
37
38        """
39        if s:
40            self.fromString(s)
41        else:
42            self.emptyPointList()
43
44    def emptyPointList(self):
45        """
46        Reset the Path to have no Points.
47        """
48        self._points = []
49        self.setClosed()
50
51    def getPoints(self):
52        """
53        Return a list of all the points on the Path.
54        """
55        return self._points
56
57    def setClosed(self):
58        """
59        Make the Path an closed Path.
60        """
61        self._closed = 1
62       
63    def setOpen(self):
64        """
65        Make the Path an open Path.
66        """
67
68        self._closed = 0
69
70
71    def isClosed(self):
72        return self._closed
73
74    def isOpen(self):
75        return not self._closed
76       
77    def fromString(self,s):
78        """
79        Initialse the Path from a string.
80
81        (arg s) is of the form described in
82        http://www.postgresql.org/docs/7.3/static/datatype-geometric.html
83       
84        """
85        seq = eval(s,{},{})
86        self.emptyPointList()
87
88        # If it is a tuple PG defines it as closed
89        # If it is a list PG defines it as open
90        # not nice but what can you do ?
91        if type(seq) == types.TupleType:
92            self.setClosed()
93        elif type(seq) == types.ListType:
94            self.setOpen()
95        else:
96            raise TypeError, 'Bad initalise string must be a Tuple or a List'
97        for p in seq:
98            self.append(pointFromSequence(p))
99
100    def append(self, p):
101        self.getPoints().append(p)
102       
103    def count(self, p):
104        return self.getPoints().count(p)
105       
106    def index(self, p):
107        return self.getPoints().index(p)
108       
109    def extend(self, path):
110        self.getPoints().extend(path._points)
111       
112    def insert(self,pos,p):
113        self.getPoints().insert(pos,p)
114       
115    def pop(self):
116        return self.getPoints().pop()
117   
118    def remove(self,p):
119        self.getPoints().remove(p)
120
121    def __len__(self):
122        return len(self.getPoints())
123   
124    def __getitem__(self, key):
125        return self.getPoints()[key]
126   
127    def __setitem__(self, key, value):
128        # check that value is a Point!       
129        self.getPoints()[key] = value
130       
131    def __delitem__(self, key):
132        del self.getPoints()[key]
133   
134    def __iter__(self):
135
136        class __iter__:
137            def __init__(self,points):
138                self._points = points
139                self.pos = 0
140
141            def __iter__(self): return self
142
143            def next(self):
144                if self.pos == len(self._points):
145                    raise StopIteration
146               
147                point = self._points[self.pos]
148                self.pos = self.pos + 1
149                return point
150
151        return __iter__(self.getPoints())
152       
153    def __contains__(self, p):
154        return p in self.getPoints()
155   
156    def __str__(self):
157        if self.isClosed(): envolope = "'(%s)'"
158        else: envolope = "'[%s]'"
159
160        s = string.join([ point.__repr__() for point in self.getPoints() ],',')
161           
162        return envolope % (s,)
163   
164    def __repr__(self):
165        if self.isClosed(): envolope = "(%s)"
166        else: envolope = "[%s]"
167
168        s = string.join([ point.__repr__() for point in self.getPoints() ],',')
169           
170        return envolope % (s,)
171
172    def __eq__(self,other):
173        """
174        Equality for paths means that:
175             both paths are either open or closed.
176             both paths have the same number of points
177             all points are equal
178       
179        """
180        if (type(self) != type(other)):
181            return False
182       
183        if not ((self.isClosed() and other.isClosed() ) or \
184                (self.isOpen() and other.isOpen())):
185            return False
186
187        if not len(self) == len(other):
188            return False
189
190        count = 0
191        while count < len(self):
192            if self[count] != other[count]: return False
193            count = count + 1
194
195        return True
196           
197    def __ne__(self,other):
198        return not self.__eq__(other)
199
200
201# factory methods
202
203def pathFromPoints(*points):
204    """
205    Return a Path.
206
207    (arg *points) any number of Points that make up the Path.
208
209    NOTE: The Path will be closed by default.
210    """
211    path = Path()
212    for point in points:
213        path.append(point)
214       
215    return path
216
217def pathFromSequence(seq):
218    """
219    Return a Path.
220
221    (arg *seq) a sequence of the form ((x,y),...,(x,y)) that make up the Path,
222    where x and y are floats.
223
224    NOTE: The Path will be closed by default.
225    """
226
227    path = Path()
228    for point in seq:
229        path.append(pointFromSequence(point))
230       
231    return path
232               
Note: See TracBrowser for help on using the repository browser.