root/PCL/trunk/PCL-GeoRSS/cartography/data/georss.py

Revision 786, 4.9 KB (checked in by dokai, 3 years ago)

Updated geometry accessors. Feedparser seems to give inconsistent results
across system. This needs to be investigated further!

Line 
1# =============================================================================
2# Python Cartographic Library. Copyright (C) 2007 Sean C. Gillies
3#
4# This program is free software; you can redistribute it and/or modify it
5# under the terms of the GNU General Public License as published by the Free
6# Software Foundation; either version 2 of the License, or (at your option)
7# any later version.
8#
9# This program is distributed in the hope that it will be useful, but WITHOUT
10# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12# details.
13#
14# You should have received a copy of the GNU General Public License along with
15# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16# Place, Suite 330, Boston, MA 02111-1307 USA
17#
18# Contact email: sgillies@frii.com
19# =============================================================================
20
21"""
22Read Georeferenced Atom/RSS entries (http://georss.org) as PCL features.
23Requires Mark Pilgrim's feedparser (http://www.feedparser.org/).
24
25See PCL-Core/tests/AtomFeatures.txt for usage examples.
26"""
27
28try:
29    import pkg_resources
30    pkg_resources.require('PCL-Core')
31    pkg_resources.require('PCL-GeoRSS')
32except:
33    pass
34
35import feedparser
36
37from cartography.styles import Layer
38from cartography.geometry import *
39from cartography.data.feature import *
40from cartography.proj import SpatialReference
41from cartography.data.interfaces import IFeature, IFeatureSource, IFeatureStore
42
43from zope.interface import implements
44
45
46# Factory for GeoRSS feature sources
47def georss_source(file):
48    """Return a feature source."""
49    # Python files, filenames, or strings
50    if hasattr(file, 'read'):
51        d = feedparser.parse(file.read())
52    else:
53        d = feedparser.parse(file)
54    try:
55        assert d.entries is not None
56    except:
57        import pdb; pdb.set_trace()
58    return GeoRSSFeatureSource(document=d)
59
60# Factory for features
61def georss_feature(entry):
62    # parse the geometry
63    if entry.has_key('point'):
64        y, x = [float(v) for v in entry['point'].split()]
65        the_geom = Point(x, y)
66    elif entry.has_key('line'):
67        vals = [float(v) for v in entry['line'].split()]
68        points = []
69        for i in range(len(vals)/2):
70            y, x = vals[2*i:2*i+2]
71            points.append(Point(x, y))
72        the_geom = LineString(points)
73    elif entry.has_key('polygon'):
74        vals = [float(v) for v in entry['polygon'].split()]
75        points = []
76        for i in range(len(vals)/2):
77            y, x = vals[2*i:2*i+2]
78            points.append(Point(x, y))
79        the_geom = Polygon(LinearRing(points))
80    elif entry.has_key('box'):
81        y0, x0, y1, x1 = [float(v) for v in entry['box'].split()]
82        the_geom = BoundingBox(x0, y0, x1, y1)
83    else:
84        the_geom = None
85
86    return GeoRSSFeature(
87        id=entry.id,
88        title=entry.title,
89        summary=entry.description,
90        updated=entry.date,
91        the_geom=the_geom
92        )
93
94def source_layer(source):
95    """Factory for a cartographic Layer."""
96    typename = source.document.feed.title
97    ds = GeoRSSFeatureStore(sources={typename: source})
98    return Layer(ds, typename)
99
100
101class GeoRSSFeature(Feature):
102
103    """A feature corresponds to an Atom/RSS entry.
104    """
105    implements(IFeature)
106
107    __typename__ = 'GeoRSSFeature'
108    __schema__ = PropertyTypeCollection([
109                    StringProperty('id'),
110                    StringProperty('title'),
111                    StringProperty('summary'),
112                    StringProperty('updated'),
113                    GeometryProperty('the_geom'),
114                    ])
115    __srs__ = SpatialReference(epsg=4326)
116
117
118class GeoRSSFeatureSource:
119
120    """Implements IFeatureSource.
121
122    A Source corresponds to a Atom/RSS feed.
123    """
124    implements(IFeatureSource)
125
126    def __init__(self, document):
127        """Initialize"""
128        self.document = document
129        self._featuretype = GeoRSSFeature
130        #self._bbox = None
131        #self._maxfeatures = -1
132
133    def schema(self):
134        return self._featuretype.schema()
135       
136    def iterfeatures(self):
137        for entry in self.document.entries:
138            yield georss_feature(entry)
139
140    __call__ = iterfeatures
141       
142
143class GeoRSSFeatureStore:
144
145    """Implements IFeatureStore.
146
147    A store corresponds to an Atom service document.
148    """
149    implements(IFeatureStore)
150
151    def __init__(self, sources):
152        self.sources = sources.copy()
153
154    def featuretype(self, typename):
155        return GeoRSSFeature
156
157    def source(self, typename, maxfeatures=-1):
158        return self.sources[typename]
159
160    def count(self, typename):
161        """Returns the feature count."""
162        return len(self.sources[typename].document.entries)
163
164    def typenames(self):
165        """Returns the typenames available in this store."""
166        return tuple(self.sources.keys())
167
168       
169
Note: See TracBrowser for help on using the browser.