views.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. from django.conf import settings
  4. from django.core.urlresolvers import reverse_lazy
  5. from django.http import HttpResponse, JsonResponse
  6. from django.shortcuts import render, get_object_or_404
  7. from django.views.generic import CreateView, DetailView, RedirectView, ListView, TemplateView
  8. from .models import Point, Panorama, ReferencePoint
  9. from .forms import SelectReferencePointForm, CustomPointForm
  10. class PanoramaUpload(CreateView):
  11. model = Panorama
  12. fields = ('name', 'image', 'loop', 'latitude', 'longitude', 'altitude')
  13. template_name = "panorama/new.html"
  14. def get_success_url(self):
  15. return reverse_lazy("panorama:gen_tiles", kwargs={"pk": self.object.id})
  16. class PanoramaView(DetailView):
  17. model = Panorama
  18. template_name = "panorama/view.html"
  19. context_object_name = "panorama"
  20. class PanoramaGenTiles(RedirectView):
  21. permanent = False
  22. pattern_name = "panorama:view_pano"
  23. def get_redirect_url(self, *args, **kwargs):
  24. pano = get_object_or_404(Panorama, pk=kwargs['pk'])
  25. pano.generate_tiles()
  26. return super(PanoramaGenTiles, self).get_redirect_url(*args, **kwargs)
  27. class PanoramaList(ListView):
  28. model = Panorama
  29. template_name = "panorama/list.html"
  30. context_object_name = "panoramas"
  31. class LocatePointView(TemplateView):
  32. """View to choose a point to locate (either an existing reference point,
  33. or from GPS coordinates)"""
  34. template_name = 'panorama/locate_point.html'
  35. def get_context_data(self, **kwargs):
  36. context = super(LocatePointView, self).get_context_data(**kwargs)
  37. context['refpoints_form'] = SelectReferencePointForm
  38. context['custom_point_form'] = CustomPointForm
  39. return context
  40. def compute_interesting_panoramas(self, point):
  41. """Compute all panoramas that see the given point, along with the distance
  42. and direction from each panorama towards the point. Returns a
  43. list of (panorama, distance, bearing, elevation) triples.
  44. """
  45. if isinstance(point, ReferencePoint):
  46. queryset = Panorama.objects.exclude(id=point.id)
  47. else:
  48. queryset = Panorama.objects
  49. l = [(pano, pano.line_distance(point), pano.bearing(point), pano.elevation(point))
  50. for pano in queryset.all() if pano.is_visible(point)]
  51. # Sort by increasing distance
  52. return sorted(l, key=lambda x: x[1])
  53. class LocateReferencePointView(LocatePointView):
  54. """Subclass that handles locating a reference point"""
  55. def post(self, request, *args, **kwargs):
  56. context = self.get_context_data()
  57. form = SelectReferencePointForm(request.POST)
  58. context['refpoints_form'] = form
  59. if form.is_valid():
  60. point = form.cleaned_data['reference_point']
  61. context['panoramas'] = self.compute_interesting_panoramas(point)
  62. context['point_name'] = point.name
  63. return super(LocateReferencePointView, self).render_to_response(context)
  64. class LocateCustomPointView(LocatePointView):
  65. """Subclass that handles locating a custom point"""
  66. def post(self, request, *args, **kwargs):
  67. context = self.get_context_data()
  68. form = CustomPointForm(request.POST)
  69. context['custom_point_form'] = form
  70. if form.is_valid():
  71. point = Point(**form.cleaned_data)
  72. context['panoramas'] = self.compute_interesting_panoramas(point)
  73. context['point_lat'] = point.latitude
  74. context['point_lon'] = point.longitude
  75. return super(LocateCustomPointView, self).render_to_response(context)