django.contrib.gis.feeds のソースコード

from __future__ import unicode_literals

from django.contrib.syndication.views import Feed as BaseFeed
from django.utils.feedgenerator import Atom1Feed, Rss201rev2Feed

class GeoFeedMixin(object):
    This mixin provides the necessary routines for SyndicationFeed subclasses
    to produce simple GeoRSS or W3C Geo elements.

    def georss_coords(self, coords):
        In GeoRSS coordinate pairs are ordered by lat/lon and separated by
        a single white space.  Given a tuple of coordinates, this will return
        a unicode GeoRSS representation.
        return ' '.join('%f %f' % (coord[1], coord[0]) for coord in coords)

    def add_georss_point(self, handler, coords, w3c_geo=False):
        Adds a GeoRSS point with the given coords using the given handler.
        Handles the differences between simple GeoRSS and the more popular
        W3C Geo specification.
        if w3c_geo:
            lon, lat = coords[:2]
            handler.addQuickElement('geo:lat', '%f' % lat)
            handler.addQuickElement('geo:lon', '%f' % lon)
            handler.addQuickElement('georss:point', self.georss_coords((coords,)))

    def add_georss_element(self, handler, item, w3c_geo=False):
        This routine adds a GeoRSS XML element using the given item and handler.
        # Getting the Geometry object.
        geom = item.get('geometry')
        if geom is not None:
            if isinstance(geom, (list, tuple)):
                # Special case if a tuple/list was passed in.  The tuple may be
                # a point or a box
                box_coords = None
                if isinstance(geom[0], (list, tuple)):
                    # Box: ( (X0, Y0), (X1, Y1) )
                    if len(geom) == 2:
                        box_coords = geom
                        raise ValueError('Only should be two sets of coordinates.')
                    if len(geom) == 2:
                        # Point: (X, Y)
                        self.add_georss_point(handler, geom, w3c_geo=w3c_geo)
                    elif len(geom) == 4:
                        # Box: (X0, Y0, X1, Y1)
                        box_coords = (geom[:2], geom[2:])
                        raise ValueError('Only should be 2 or 4 numeric elements.')
                # If a GeoRSS box was given via tuple.
                if box_coords is not None:
                    if w3c_geo:
                        raise ValueError('Cannot use simple GeoRSS box in W3C Geo feeds.')
                    handler.addQuickElement('georss:box', self.georss_coords(box_coords))
                # Getting the lower-case geometry type.
                gtype = str(geom.geom_type).lower()
                if gtype == 'point':
                    self.add_georss_point(handler, geom.coords, w3c_geo=w3c_geo)
                    if w3c_geo:
                        raise ValueError('W3C Geo only supports Point geometries.')
                    # For formatting consistent w/the GeoRSS simple standard:
                    if gtype in ('linestring', 'linearring'):
                        handler.addQuickElement('georss:line', self.georss_coords(geom.coords))
                    elif gtype in ('polygon',):
                        # Only support the exterior ring.
                        handler.addQuickElement('georss:polygon', self.georss_coords(geom[0].coords))
                        raise ValueError('Geometry type "%s" not supported.' % geom.geom_type)

# ### SyndicationFeed subclasses ###
[ドキュメント]class GeoRSSFeed(Rss201rev2Feed, GeoFeedMixin): def rss_attributes(self): attrs = super(GeoRSSFeed, self).rss_attributes() attrs['xmlns:georss'] = '' return attrs def add_item_elements(self, handler, item): super(GeoRSSFeed, self).add_item_elements(handler, item) self.add_georss_element(handler, item) def add_root_elements(self, handler): super(GeoRSSFeed, self).add_root_elements(handler) self.add_georss_element(handler, self.feed)
[ドキュメント]class GeoAtom1Feed(Atom1Feed, GeoFeedMixin): def root_attributes(self): attrs = super(GeoAtom1Feed, self).root_attributes() attrs['xmlns:georss'] = '' return attrs def add_item_elements(self, handler, item): super(GeoAtom1Feed, self).add_item_elements(handler, item) self.add_georss_element(handler, item) def add_root_elements(self, handler): super(GeoAtom1Feed, self).add_root_elements(handler) self.add_georss_element(handler, self.feed)
[ドキュメント]class W3CGeoFeed(Rss201rev2Feed, GeoFeedMixin): def rss_attributes(self): attrs = super(W3CGeoFeed, self).rss_attributes() attrs['xmlns:geo'] = '' return attrs def add_item_elements(self, handler, item): super(W3CGeoFeed, self).add_item_elements(handler, item) self.add_georss_element(handler, item, w3c_geo=True) def add_root_elements(self, handler): super(W3CGeoFeed, self).add_root_elements(handler) self.add_georss_element(handler, self.feed, w3c_geo=True)
# ### Feed subclass ###
[ドキュメント]class Feed(BaseFeed): """ This is a subclass of the `Feed` from `django.contrib.syndication`. This allows users to define a `geometry(obj)` and/or `item_geometry(item)` methods on their own subclasses so that geo-referenced information may placed in the feed. """ feed_type = GeoRSSFeed def feed_extra_kwargs(self, obj): return {'geometry': self._get_dynamic_attr('geometry', obj)} def item_extra_kwargs(self, item): return {'geometry': self._get_dynamic_attr('item_geometry', item)}
Back to Top