summaryrefslogtreecommitdiff
path: root/chimere/main
diff options
context:
space:
mode:
Diffstat (limited to 'chimere/main')
-rw-r--r--chimere/main/models.py90
-rw-r--r--chimere/main/views.py103
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)
+