Coverage for shps/views.py: 78%

135 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-07-27 11:19 +0000

1import json 

2import geopandas as gp 

3import pandas as pd 

4from django.http import HttpResponse 

5from django.urls import reverse_lazy 

6from django.shortcuts import render, get_object_or_404 

7from django.views.generic.detail import DetailView 

8from django.views.generic.edit import DeleteView 

9from django.contrib.auth.decorators import login_required 

10from django.conf import settings 

11from django.contrib.gis.geos import Point 

12from django.utils.decorators import method_decorator 

13from django.views.generic.base import RedirectView 

14from django.views.generic.edit import FormView 

15 

16from shapely import wkt 

17from browsing.browsing_utils import GenericListView, BaseCreateView, BaseUpdateView 

18 

19from .models import TempSpatial, Source 

20from .tables import TempSpatialTable, SourceTable 

21from .filters import TempSpatialListFilter, SourceListFilter 

22from .forms import ( 

23 WhereWasForm, 

24 TempSpatialFilterFormHelper, 

25 TempSpatialForm, 

26 SourceFilterFormHelper, 

27 SourceForm, 

28) 

29 

30 

31class PermaLinkView(RedirectView): 

32 permanent = False 

33 query_string = True 

34 

35 def get_redirect_url(self, *args, **kwargs): 

36 shp = get_object_or_404(TempSpatial, unique=kwargs["unique"]) 

37 url = shp.get_absolute_url() 

38 return url 

39 

40 

41class WhereWas(FormView): 

42 template_name = "shps/where_was.html" 

43 form_class = WhereWasForm 

44 success_url = "." 

45 

46 def form_valid(self, form, **kwargs): 

47 context = super(WhereWas, self).get_context_data(**kwargs) 

48 cd = form.cleaned_data 

49 pnt = Point(cd["lng"], cd["lat"]) 

50 qs = TempSpatial.objects.filter(geom__contains=pnt) 

51 when = cd["when"] 

52 if when is not None: 

53 qs = qs.filter(temp_extent__contains=when) 

54 else: 

55 qs = qs 

56 if qs: 

57 context["answer"] = qs.order_by("spatial_extent") 

58 else: 

59 context["answer"] = ["No Match"] 

60 context["point"] = pnt 

61 return render(self.request, self.template_name, context) 

62 

63 

64class TempSpatialListView(GenericListView): 

65 model = TempSpatial 

66 table_class = TempSpatialTable 

67 filter_class = TempSpatialListFilter 

68 formhelper_class = TempSpatialFilterFormHelper 

69 paginate_by = 25 

70 init_columns = [ 

71 "id", 

72 "name", 

73 "administrative_unit", 

74 "start_date", 

75 "end_date", 

76 ] 

77 exclude_columns = [ 

78 "geom", 

79 ] 

80 

81 template_name = "shps/generic_list.html" 

82 

83 def get_context_data(self, **kwargs): 

84 context = super(TempSpatialListView, self).get_context_data() 

85 context["shapes"] = True 

86 return context 

87 

88 def render_to_response(self, context, **kwargs): 

89 if self.request.GET.get("dl-geojson", None): 

90 df = pd.DataFrame(list(self.get_queryset().values())) 

91 df["geometry"] = df.apply(lambda row: wkt.loads(row["geom"].wkt), axis=1) 

92 str_df = df.astype("str").drop(["geom"], axis=1) 

93 gdf = gp.GeoDataFrame(str_df) 

94 gdf["geometry"] = gdf.apply(lambda row: wkt.loads(row["geometry"]), axis=1) 

95 response = HttpResponse(gdf.to_json(), content_type="application/json") 

96 response["Content-Disposition"] = 'attachment; filename="out.geojson"' 

97 return response 

98 else: 

99 response = super(TempSpatialListView, self).render_to_response(context) 

100 return response 

101 

102 

103class TempSpatialDetailView(DetailView): 

104 model = TempSpatial 

105 template_name = "shps/shape_detail.html" 

106 

107 def get_context_data(self, **kwargs): 

108 context = super(TempSpatialDetailView, self).get_context_data() 

109 context["more"] = json.loads(self.object.additional_data) 

110 try: 

111 project_url = settings.BASE_URL 

112 except AttributeError: 

113 project_url = "https//provide/a/base-url" 

114 context["project_url"] = project_url 

115 return context 

116 

117 

118class TempSpatialCreate(BaseCreateView): 

119 model = TempSpatial 

120 form_class = TempSpatialForm 

121 template_name = "shps/generic_create.html" 

122 

123 @method_decorator(login_required) 

124 def dispatch(self, *args, **kwargs): 

125 return super(TempSpatialCreate, self).dispatch(*args, **kwargs) 

126 

127 

128class TempSpatialUpdate(BaseUpdateView): 

129 model = TempSpatial 

130 form_class = TempSpatialForm 

131 template_name = "shps/generic_create.html" 

132 

133 @method_decorator(login_required) 

134 def dispatch(self, *args, **kwargs): 

135 return super(TempSpatialUpdate, self).dispatch(*args, **kwargs) 

136 

137 

138class TempSpatialDelete(DeleteView): 

139 model = TempSpatial 

140 template_name = "webpage/confirm_delete.html" 

141 success_url = reverse_lazy("shapes:browse_shapes") 

142 

143 @method_decorator(login_required) 

144 def dispatch(self, *args, **kwargs): 

145 return super(TempSpatialDelete, self).dispatch(*args, **kwargs) 

146 

147 

148class SourceListView(GenericListView): 

149 model = Source 

150 table_class = SourceTable 

151 filter_class = SourceListFilter 

152 formhelper_class = SourceFilterFormHelper 

153 paginate_by = 25 

154 init_columns = [ 

155 "id", 

156 "name", 

157 ] 

158 template_name = "shps/generic_list.html" 

159 

160 

161class SourceDetailView(DetailView): 

162 model = Source 

163 template_name = "shps/source_detail.html" 

164 

165 

166class SourceCreate(BaseCreateView): 

167 model = Source 

168 form_class = SourceForm 

169 template_name = "shps/generic_create.html" 

170 

171 @method_decorator(login_required) 

172 def dispatch(self, *args, **kwargs): 

173 return super(SourceCreate, self).dispatch(*args, **kwargs) 

174 

175 

176class SourceUpdate(BaseUpdateView): 

177 model = Source 

178 form_class = SourceForm 

179 template_name = "shps/generic_create.html" 

180 

181 @method_decorator(login_required) 

182 def dispatch(self, *args, **kwargs): 

183 return super(SourceUpdate, self).dispatch(*args, **kwargs) 

184 

185 

186class SourceDelete(DeleteView): 

187 model = Source 

188 template_name = "webpage/confirm_delete.html" 

189 success_url = reverse_lazy("shapes:browse_sources") 

190 

191 @method_decorator(login_required) 

192 def dispatch(self, *args, **kwargs): 

193 return super(SourceDelete, self).dispatch(*args, **kwargs)