web/lib/django/contrib/gis/sitemaps/views.py
changeset 38 77b6da96e6f1
equal deleted inserted replaced
37:8d941af65caf 38:77b6da96e6f1
       
     1 from django.http import HttpResponse, Http404
       
     2 from django.template import loader
       
     3 from django.contrib.sites.models import Site
       
     4 from django.core import urlresolvers
       
     5 from django.core.paginator import EmptyPage, PageNotAnInteger
       
     6 from django.contrib.gis.db.models.fields import GeometryField
       
     7 from django.db import connections, DEFAULT_DB_ALIAS
       
     8 from django.db.models import get_model
       
     9 from django.utils.encoding import smart_str
       
    10 
       
    11 from django.contrib.gis.shortcuts import render_to_kml, render_to_kmz
       
    12 
       
    13 def index(request, sitemaps):
       
    14     """
       
    15     This view generates a sitemap index that uses the proper view
       
    16     for resolving geographic section sitemap URLs.
       
    17     """
       
    18     current_site = Site.objects.get_current()
       
    19     sites = []
       
    20     protocol = request.is_secure() and 'https' or 'http'
       
    21     for section, site in sitemaps.items():
       
    22         if callable(site):
       
    23             pages = site().paginator.num_pages
       
    24         else:
       
    25             pages = site.paginator.num_pages
       
    26         sitemap_url = urlresolvers.reverse('django.contrib.gis.sitemaps.views.sitemap', kwargs={'section': section})
       
    27         sites.append('%s://%s%s' % (protocol, current_site.domain, sitemap_url))
       
    28 
       
    29         if pages > 1:
       
    30             for page in range(2, pages+1):
       
    31                 sites.append('%s://%s%s?p=%s' % (protocol, current_site.domain, sitemap_url, page))
       
    32     xml = loader.render_to_string('sitemap_index.xml', {'sitemaps': sites})
       
    33     return HttpResponse(xml, mimetype='application/xml')
       
    34 
       
    35 def sitemap(request, sitemaps, section=None):
       
    36     """
       
    37     This view generates a sitemap with additional geographic
       
    38     elements defined by Google.
       
    39     """
       
    40     maps, urls = [], []
       
    41     if section is not None:
       
    42         if section not in sitemaps:
       
    43             raise Http404("No sitemap available for section: %r" % section)
       
    44         maps.append(sitemaps[section])
       
    45     else:
       
    46         maps = sitemaps.values()
       
    47 
       
    48     page = request.GET.get("p", 1)
       
    49     for site in maps:
       
    50         try:
       
    51             if callable(site):
       
    52                 urls.extend(site().get_urls(page))
       
    53             else:
       
    54                 urls.extend(site.get_urls(page))
       
    55         except EmptyPage:
       
    56             raise Http404("Page %s empty" % page)
       
    57         except PageNotAnInteger:
       
    58             raise Http404("No page '%s'" % page)
       
    59     xml = smart_str(loader.render_to_string('gis/sitemaps/geo_sitemap.xml', {'urlset': urls}))
       
    60     return HttpResponse(xml, mimetype='application/xml')
       
    61 
       
    62 def kml(request, label, model, field_name=None, compress=False, using=DEFAULT_DB_ALIAS):
       
    63     """
       
    64     This view generates KML for the given app label, model, and field name.
       
    65 
       
    66     The model's default manager must be GeoManager, and the field name
       
    67     must be that of a geographic field.
       
    68     """
       
    69     placemarks = []
       
    70     klass = get_model(label, model)
       
    71     if not klass:
       
    72         raise Http404('You must supply a valid app label and module name.  Got "%s.%s"' % (label, model))
       
    73 
       
    74     if field_name:
       
    75         try:
       
    76             info = klass._meta.get_field_by_name(field_name)
       
    77             if not isinstance(info[0], GeometryField):
       
    78                 raise Exception
       
    79         except:
       
    80             raise Http404('Invalid geometry field.')
       
    81 
       
    82     connection = connections[using]
       
    83 
       
    84     if connection.ops.postgis:
       
    85         # PostGIS will take care of transformation.
       
    86         placemarks = klass._default_manager.using(using).kml(field_name=field_name)
       
    87     else:
       
    88         # There's no KML method on Oracle or MySQL, so we use the `kml`
       
    89         # attribute of the lazy geometry instead.
       
    90         placemarks = []
       
    91         if connection.ops.oracle:
       
    92             qs = klass._default_manager.using(using).transform(4326, field_name=field_name)
       
    93         else:
       
    94             qs = klass._default_manager.using(using).all()
       
    95         for mod in qs:
       
    96             setattr(mod, 'kml', getattr(mod, field_name).kml)
       
    97             placemarks.append(mod)
       
    98 
       
    99     # Getting the render function and rendering to the correct.
       
   100     if compress:
       
   101         render = render_to_kmz
       
   102     else:
       
   103         render = render_to_kml
       
   104     return render('gis/kml/placemarks.kml', {'places' : placemarks})
       
   105 
       
   106 def kmz(request, label, model, field_name=None, using=DEFAULT_DB_ALIAS):
       
   107     """
       
   108     This view returns KMZ for the given app label, model, and field name.
       
   109     """
       
   110     return kml(request, label, model, field_name, compress=True, using=using)