|
1 from django.http import HttpResponse, Http404 |
|
2 from django.template import loader |
|
3 from django.contrib.gis.db.backend import SpatialBackend |
|
4 from django.contrib.sites.models import Site |
|
5 from django.core import urlresolvers |
|
6 from django.core.paginator import EmptyPage, PageNotAnInteger |
|
7 from django.db.models import get_model |
|
8 from django.contrib.gis.db.models.fields import GeometryField |
|
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): |
|
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 if SpatialBackend.postgis: |
|
83 # PostGIS will take care of transformation. |
|
84 placemarks = klass._default_manager.kml(field_name=field_name) |
|
85 else: |
|
86 # There's no KML method on Oracle or MySQL, so we use the `kml` |
|
87 # attribute of the lazy geometry instead. |
|
88 placemarks = [] |
|
89 if SpatialBackend.oracle: |
|
90 qs = klass._default_manager.transform(4326, field_name=field_name) |
|
91 else: |
|
92 qs = klass._default_manager.all() |
|
93 for mod in qs: |
|
94 setattr(mod, 'kml', getattr(mod, field_name).kml) |
|
95 placemarks.append(mod) |
|
96 |
|
97 # Getting the render function and rendering to the correct. |
|
98 if compress: |
|
99 render = render_to_kmz |
|
100 else: |
|
101 render = render_to_kml |
|
102 return render('gis/kml/placemarks.kml', {'places' : placemarks}) |
|
103 |
|
104 def kmz(request, label, model, field_name=None): |
|
105 """ |
|
106 This view returns KMZ for the given app label, model, and field name. |
|
107 """ |
|
108 return kml(request, label, model, field_name, True) |