diff options
Diffstat (limited to 'chimere/main')
| -rw-r--r-- | chimere/main/models.py | 90 | ||||
| -rw-r--r-- | chimere/main/views.py | 103 |
2 files changed, 148 insertions, 45 deletions
diff --git a/chimere/main/models.py b/chimere/main/models.py index 60a5837..c977446 100644 --- a/chimere/main/models.py +++ b/chimere/main/models.py @@ -126,6 +126,9 @@ class SubCategory(models.Model): for sub_category in subcategories: if sub_category.category not in sub_categories: sub_categories[sub_category.category] = [] + if sub_category.id in settings.DEFAULT_CATEGORIES: + sub_category.selected = True + sub_category.category.selected = True sub_categories[sub_category.category].append(sub_category) return [(category, sub_cats) for category, sub_cats \ in sub_categories.items()] @@ -222,16 +225,6 @@ class Route(models.Model): ordering = ('subcategory__category', 'subcategory', 'status', 'name') verbose_name = _("Route") - def getLatitude(self): - '''Return the latitude - ''' - return self.point.y - - def getLongitude(self): - '''Return the longitude - ''' - return self.point.x - def getProperty(self, propertymodel, safe=None): """Get the property of an associated property model. If safe set to True, verify if the property is available @@ -265,7 +258,82 @@ class Route(models.Model): "color":"%(color)s"}}""" % {'id':self.id, 'name':self.name, 'color':color, 'geometry':self.route.geojson,} -class Area(models.Model): +class SimplePoint: + """ + Point in the map (not in the database) + """ + def __init__(self, x, y): + self.x, self.y = x, y + +class SimpleArea: + """ + Rectangular area of a map (not in the database) + """ + def __init__(self, area): + """ + Defining upper left corner ans lower right corner from a tuple + """ + assert len(area) == 4 + x1, y1, x2, y2 = area + self.upper_left_corner = SimplePoint(x1, y1) + self.lower_right_corner = SimplePoint(x2, y2) + + def isIn(self, area): + """ + Verify if the current area is in the designated area + """ + if self.upper_left_corner.x >= area.upper_left_corner.x and \ + self.upper_left_corner.y <= area.upper_left_corner.x and \ + self.lower_right_corner.x <= area.lower_right_corner.x and \ + self.lower_right_corner.y >= area.lower_right_corner.y: + return True + return False + + def getCategories(self, status='A'): + """ + Get categories for this area + """ + equal_status = '' + if len(status) == 1: + equal_status = "='%s'" % status[0] + else: + equal_status = " in ('%s')" % "','".join(status) + area = "ST_GeometryFromText('POLYGON((%f %f,%f %f,%f %f,%f %f, %f %f))'\ +, %d)" % (self.upper_left_corner.x, self.upper_left_corner.y, + self.lower_right_corner.x, self.upper_left_corner.y, + self.lower_right_corner.x, self.lower_right_corner.y, + self.upper_left_corner.x, self.lower_right_corner.y, + self.upper_left_corner.x, self.upper_left_corner.y, + settings.EPSG_DISPLAY_PROJECTION + ) + sql_main = '''select subcat.id as id, subcat.category_id as category_id, +subcat.name as name, subcat.available as available, subcat.icon_id as icon_id, +subcat.color_theme_id as color_theme_id, subcat.order as order, +subcat.item_type as item_type from main_subcategory subcat''' + sql = sql_main + ''' +inner join main_marker mark on mark.subcategory_id=subcat.id and mark.status%s +and ST_Contains(%s, mark.point) where subcat.available = TRUE''' % ( + equal_status, area) + # django > 1.1 + #subcats = SubCategory.objects.raw(sql) + from django.db import connection, transaction + cursor = connection.cursor() + cursor.execute(sql, []) + subcats = set() + for r in cursor.fetchall(): + subcats.add(SubCategory.objects.get(id=r[0])) + sql = sql_main + ''' +inner join main_route rt on rt.subcategory_id=subcat.id and rt.status%s +and (ST_Intersects(%s, rt.route) or ST_Contains(%s, rt.route)) +where subcat.available = TRUE''' % (equal_status, area, area) + # django > 1.1 + #subcats += SubCategory.objects.raw(sql) + cursor.execute(sql, []) + for r in cursor.fetchall(): + subcats.add(SubCategory.objects.get(id=r[0])) + return subcats + +class Area(models.Model, SimpleArea): """Rectangular area of the map """ name = models.CharField(_("Name"), max_length=150) diff --git a/chimere/main/views.py b/chimere/main/views.py index 9de8f4b..f584702 100644 --- a/chimere/main/views.py +++ b/chimere/main/views.py @@ -22,6 +22,7 @@ Views of the project """ import datetime +from itertools import groupby from django.utils.translation import ugettext as _ from django.shortcuts import render_to_response @@ -32,23 +33,20 @@ from django.core import serializers from chimere import settings from chimere.main.actions import actions from chimere.main.models import Category, SubCategory, PropertyModel, Marker, \ - Route, News, Area, Color + Route, News, SimpleArea, Area, Color from chimere.main.widgets import getMapJS, PointChooserWidget, \ RouteChooserWidget, URL_OSM_JS, URL_OSM_CSS from chimere.main.forms import MarkerForm, RouteForm, ContactForm, \ notifySubmission, notifyStaff +base_response_dct = {'media_path':settings.MEDIA_URL, + 'extra_url':settings.EXTRA_URL,} + def index(request): """ Main page """ - subcategories = SubCategory.getAvailable() - for cat, sub_cats in subcategories: - for sub_category in sub_cats: - if sub_category.id in settings.DEFAULT_CATEGORIES: - sub_category.selected = True - cat.selected= True extra = "" tab = " "*4 for url in URL_OSM_CSS: @@ -64,16 +62,14 @@ def index(request): request.session['last_visit'] != today: request.session['last_visit'] = today display_welcome = True - response_dct = {'actions':actions, 'action_selected':('view',), - 'error_message':'', - 'sub_categories':subcategories, - 'extra_head':extra + getMapJS(), - 'media_path':settings.MEDIA_URL, - 'extra_url':settings.EXTRA_URL, - 'welcome':welcome(request, display_welcome), - 'areas':Area.getAvailable(), - 'map_layer':settings.MAP_LAYER - } + response_dct = base_response_dct + response_dct.update({'actions':actions, 'action_selected':('view',), + 'error_message':'', + 'extra_head':extra + getMapJS(), + 'welcome':welcome(request, display_welcome), + 'areas':Area.getAvailable(), + 'map_layer':settings.MAP_LAYER, + }) # manage permalink if request.GET: for key in ('zoom', 'lon', 'lat', 'display_submited'): @@ -109,17 +105,17 @@ def edit(request): form = MarkerForm() # get the « manualy » declared_fields. Ie: properties declared_fields = form.declared_fields.keys() - response_dct = {'actions':actions, 'action_selected':('contribute', 'edit'), + response_dct = base_response_dct + response_dct.update({'actions':actions, + 'action_selected':('contribute', 'edit'), 'error_message':'', - 'media_path':settings.MEDIA_URL, - 'extra_url':settings.EXTRA_URL, 'map_layer':settings.MAP_LAYER, 'form':form, 'extra_head':form.media, 'sub_categories':SubCategory.getAvailable(['M', 'B']), 'point_widget':PointChooserWidget().render('point', None), 'properties':declared_fields - } + }) # manualy populate the custom widget if 'subcategory' in form.data and form.data['subcategory']: response_dct['current_category'] = int(form.data['subcategory']) @@ -146,18 +142,17 @@ def editRoute(request): form = RouteForm() # get the « manualy » declared_fields. Ie: properties declared_fields = form.declared_fields.keys() - response_dct = {'actions':actions, - 'action_selected':('contribute', 'edit_route'), + response_dct = base_response_dct + response_dct.update({'actions':actions, + 'action_selected':('contribute', 'edit_route'), 'error_message':'', - 'media_path':settings.MEDIA_URL, 'map_layer':settings.MAP_LAYER, 'form':form, 'extra_head':form.media, - 'extra_url':settings.EXTRA_URL, 'sub_categories':SubCategory.getAvailable(['R', 'B']), 'route_widget':RouteChooserWidget().render('route', None), 'properties':declared_fields - } + }) # manualy populate the custom widget if 'subcategory' in form.data and form.data['subcategory']: response_dct['current_category'] = int(form.data['subcategory']) @@ -175,8 +170,8 @@ def submited(request, action): """ Successful submission page """ - response_dct = {'actions':actions, 'action_selected':action, - 'media_path':settings.MEDIA_URL,} + response_dct = base_response_dct + response_dct.update({'actions':actions, 'action_selected':action,}) return render_to_response('submited.html', response_dct) def contactus(request): @@ -200,8 +195,9 @@ details.") msg = _(u"Temporary error. Renew your message later.") else: form = ContactForm() - response_dct = {'actions':actions, 'action_selected':('contact',), - 'media_path':settings.MEDIA_URL,'contact_form':form, 'message':msg} + response_dct = base_response_dct + response_dct = ({'actions':actions, 'action_selected':('contact',), + 'contact_form':form, 'message':msg}) return render_to_response('contactus.html', response_dct) def getDetail(request, marker_id): @@ -212,7 +208,8 @@ def getDetail(request, marker_id): marker = Marker.objects.filter(id=int(marker_id), status='A')[0] except (ValueError, IndexError): return HttpResponse('no results') - response_dct= {'media_path':settings.MEDIA_URL, 'marker':marker} + response_dct = base_response_dct + response_dct['marker'] = marker return render_to_response('detail.html', response_dct) def getDescriptionDetail(request, category_id): @@ -223,13 +220,16 @@ def getDescriptionDetail(request, category_id): category = Category.objects.filter(id=int(category_id))[0] except (ValueError, IndexError): return HttpResponse('no results') - response_dct= {'media_path':settings.MEDIA_URL, 'category':category} + response_dct = base_response_dct + response_dct['category'] = category return render_to_response('category_detail.html', response_dct) -def getGeoObjects(request, category_ids, status='A'): +def getGeoObjects(request, category_ids, status): ''' - Get the JSON for a route + Get the JSON for markers and routes ''' + if not status: + status = 'A' status = status.split('_') try: query = Route.objects.filter(status__in=status, @@ -258,3 +258,38 @@ def getGeoObjects(request, category_ids, status='A'): return HttpResponse('no results') data = '{"type": "FeatureCollection", "features":[%s]}' % ",".join(jsons) return HttpResponse(data) + +def getAvailableCategories(request, area=None, status='A', force=None): + ''' + Get categories for a designed area + ''' + if settings.DYNAMIC_CATEGORIES and not area: + return "" + response_dct = base_response_dct + if not settings.DYNAMIC_CATEGORIES: + subcategories = SubCategory.getAvailable() + response_dct['sub_categories'] = subcategories + return render_to_response('categories.html', response_dct) + default_message = "<p>%s</p>" % _("No category available in this area.") + if not status: # there must be a status + status = 'A' + try: + status = status.split('_') + area = area.replace('M', '-').replace('D', '.') + area = SimpleArea([float(pt) for pt in area.split('_')]) + except: + # bad area format + return HttpResponse(default_message) + # if not force and area.isIn(SimpleArea(cookie.AREA):return + categories = area.getCategories(status) + if not categories: + return HttpResponse(default_message) + get_cat = lambda subcat: subcat.category + get_cat_order = lambda subcat: (subcat.category.order, subcat.category, + subcat.order) + categories = sorted(categories, key=get_cat_order) + subcategories = [(cat, list(subcats)) \ + for cat, subcats in groupby(categories, get_cat)] + response_dct['sub_categories'] = subcategories + return render_to_response('categories.html', response_dct) + |
