summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoretienne <etienne@9215b0d5-fb2c-4bbd-8d3e-bd2e9090e864>2010-03-14 18:35:23 +0000
committeretienne <etienne@9215b0d5-fb2c-4bbd-8d3e-bd2e9090e864>2010-03-14 18:35:23 +0000
commit64acbb356f5a177dc5bd80e7ad493ee554ca0e09 (patch)
tree8d3708eb5a235581d598cdbe672524f1d453df35
parent63a9537e7deeb473145512fe8a080c62ea62c2c7 (diff)
downloadChimère-64acbb356f5a177dc5bd80e7ad493ee554ca0e09.tar.bz2
Chimère-64acbb356f5a177dc5bd80e7ad493ee554ca0e09.zip
Correct projection problems on database #87 - Filter categories for moderator by area #88
git-svn-id: http://www.peacefrogs.net/svn/chimere/trunk@72 9215b0d5-fb2c-4bbd-8d3e-bd2e9090e864
-rw-r--r--chimere/main/admin.py42
-rw-r--r--chimere/main/forms.py17
-rw-r--r--chimere/main/models.py38
-rw-r--r--chimere/main/widgets.py9
-rw-r--r--chimere/settings.py7
-rw-r--r--chimere/static/base.js5
-rw-r--r--chimere/static/edit_area.js3
-rw-r--r--chimere/static/edit_map.js4
-rw-r--r--chimere/static/edit_route_map.js7
-rw-r--r--chimere/static/main_map.js1
10 files changed, 111 insertions, 22 deletions
diff --git a/chimere/main/admin.py b/chimere/main/admin.py
index 195e7c4..31c9d5c 100644
--- a/chimere/main/admin.py
+++ b/chimere/main/admin.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2008 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2008-2010 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
@@ -29,6 +29,19 @@ from chimere.main.widgets import TextareaWidget
from django.contrib import admin
+def get_areas_for_user(user):
+ """
+ Getting subcats for a specific user
+ """
+ perms = user.get_all_permissions()
+ areas = set()
+ prefix = 'main.change_area_'
+ for perm in perms:
+ if perm.startswith(prefix):
+ area = Area.objects.get(urn=perm[len(prefix):])
+ areas.add(area)
+ return areas
+
class MarkerAdmin(admin.ModelAdmin):
"""
Specialized the Point field.
@@ -38,6 +51,19 @@ class MarkerAdmin(admin.ModelAdmin):
list_filter = ('status', 'subcategory')
form = MarkerAdminForm
+ def queryset(self, request):
+ qs = self.model._default_manager.get_query_set()
+ if not request.user.is_superuser:
+ areas = get_areas_for_user(request.user)
+ if not areas:
+ return self.model.objects.extra(where=['1=0'])
+ in_areas = " or ".join([area.getIncludeSql() for area in areas])
+ qs = qs.extra(where=[in_areas])
+ ordering = self.ordering or ()
+ if ordering:
+ qs = qs.order_by(*ordering)
+ return qs
+
class RouteAdmin(admin.ModelAdmin):
"""
Specialized the Route field.
@@ -47,6 +73,20 @@ class RouteAdmin(admin.ModelAdmin):
list_filter = ('status', 'subcategory')
form = RouteAdminForm
+ def queryset(self, request):
+ qs = self.model._default_manager.get_query_set()
+ if not request.user.is_superuser:
+ areas = get_areas_for_user(request.user)
+ if not areas:
+ return self.model.objects.extra(where=['1=0'])
+ in_areas = " or ".join([area.getIncludeSql(
+ geometry='"main_route".route') for area in areas])
+ qs = qs.extra(where=[in_areas])
+ ordering = self.ordering or ()
+ if ordering:
+ qs = qs.order_by(*ordering)
+ return qs
+
class AreaAdmin(admin.ModelAdmin):
"""
Specialized the area field.
diff --git a/chimere/main/forms.py b/chimere/main/forms.py
index 74577d1..4618321 100644
--- a/chimere/main/forms.py
+++ b/chimere/main/forms.py
@@ -23,7 +23,7 @@ Forms
from django import forms
from django.contrib.gis.db import models
from django.utils.translation import ugettext as _
-from django.contrib.auth.models import User
+from django.contrib.auth.models import User, Permission, ContentType
from django.core.mail import EmailMessage, BadHeaderError
from chimere import settings
@@ -250,4 +250,19 @@ class AreaAdminForm(forms.ModelForm):
new_area.upper_left_corner = 'POINT(%s %s)' % (area[0][0], area[0][1])
new_area.lower_right_corner = 'POINT(%s %s)' % (area[1][0],
area[1][1])
+ content_type = ContentType.objects.get(app_label="main",
+ model="area")
+ if new_area.urn:
+ mnemo = 'change_area_' + new_area.urn
+ perm = Permission.objects.filter(codename=mnemo)
+ if not perm:
+ perm = Permission(name='Can change ' + new_area.name,
+ content_type_id=content_type.id, codename=mnemo)
+ perm.save()
+ else:
+ if 'urn' in self.initial:
+ mnemo = 'change_area_' + self.initial['urn']
+ perm = Permission.objects.filter(codename=mnemo)
+ if perm:
+ perm[0].delete()
return new_area
diff --git a/chimere/main/models.py b/chimere/main/models.py
index 710623c..4197a23 100644
--- a/chimere/main/models.py
+++ b/chimere/main/models.py
@@ -23,6 +23,7 @@ Models description
from django.utils.translation import ugettext_lazy as _
from django.contrib.gis.db import models
+from django.contrib.gis.gdal import SpatialReference
from django.contrib import admin
from chimere import settings
@@ -292,14 +293,14 @@ class SimpleArea:
return True
return False
- def getCategories(self, status='A'):
+ def getCategories(self, status='A', filter_available=True):
"""
Get categories for this area
"""
equal_status = ''
if len(status) == 1:
equal_status = "='%s'" % status[0]
- else:
+ elif status:
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,
@@ -314,9 +315,12 @@ 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)
+inner join main_marker mark on mark.subcategory_id=subcat.id
+ and ST_Contains(%s, mark.point)''' % area
+ if equal_status:
+ sql += ' and mark.status' + equal_status
+ if filter_available:
+ sql += ' where subcat.available = TRUE'
# django > 1.1
#subcats = SubCategory.objects.raw(sql)
from django.db import connection, transaction
@@ -326,9 +330,12 @@ and ST_Contains(%s, mark.point) where subcat.available = TRUE''' % (
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)
+inner join main_route rt on rt.subcategory_id=subcat.id
+and (ST_Intersects(%s, rt.route) or ST_Contains(%s, rt.route))''' % (area, area)
+ if equal_status:
+ sql += ' and rt.status' + equal_status
+ if filter_available:
+ sql += ' where subcat.available = TRUE'
# django > 1.1
#subcats += SubCategory.objects.raw(sql)
cursor.execute(sql, [])
@@ -366,6 +373,21 @@ class Area(models.Model, SimpleArea):
'''
return cls.objects.filter(available=True)
+ def getIncludeSql(self, geometry='"main_marker".point'):
+ """
+ Get the sql statement for the test if the point is included in the area
+ """
+ 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 = "ST_Contains(" + area + ", " + geometry + ")"
+ return sql
+
class PropertyModel(models.Model):
'''Model for a property
'''
diff --git a/chimere/main/widgets.py b/chimere/main/widgets.py
index 2653c19..4ad6475 100644
--- a/chimere/main/widgets.py
+++ b/chimere/main/widgets.py
@@ -265,8 +265,9 @@ class AreaWidget(forms.TextInput):
init();"""
if value:
tpl += """var extent = new OpenLayers.Bounds(%f, %f, %f, %f);
-map.zoomToExtent(extent, true);""" % (upper_left_lat, upper_left_lon, lower_right_lat,
- lower_right_lon)
+extent.transform(epsg_display_projection, epsg_projection);
+map.zoomToExtent(extent, true);""" % (upper_left_lon, upper_left_lat,
+ lower_right_lon, lower_right_lat)
tpl += """// --></script>
<hr class='spacer'/>
"""
@@ -277,8 +278,8 @@ map.zoomToExtent(extent, true);""" % (upper_left_lat, upper_left_lon, lower_righ
Return the appropriate values
"""
values = []
- for keys in (('upper_left_lat', 'upper_left_lon',),
- ('lower_right_lat', 'lower_right_lon')):
+ for keys in (('upper_left_lon', 'upper_left_lat',),
+ ('lower_right_lon', 'lower_right_lat')):
value = []
for key in keys:
val = data.get(key, None)
diff --git a/chimere/settings.py b/chimere/settings.py
index 503d681..3281277 100644
--- a/chimere/settings.py
+++ b/chimere/settings.py
@@ -13,9 +13,14 @@ EMAIL_HOST = 'localhost'
TINYMCE_URL = SERVER_URL + 'tinymce/'
-# chimere specific
+## chimere specific ##
+# center of the map
DEFAULT_CENTER = (-1.679444, 48.114722)
+# projection used by the main map
+# most public map providers use spherical mercator : 900913
EPSG_PROJECTION = 900913
+# projection displayed to the end user by openlayers
+# chimere use the same projection to save its data in the database
EPSG_DISPLAY_PROJECTION = 4326
# to restrict the map to a defined bounding box set it here
RESTRICTED_EXTENT = None
diff --git a/chimere/static/base.js b/chimere/static/base.js
index 449cc0f..70b8742 100644
--- a/chimere/static/base.js
+++ b/chimere/static/base.js
@@ -64,8 +64,9 @@ function zoomToCurrentExtent(map){
current_extent[2], current_extent[3]);
}
else if (OpenLayers && default_area && default_area.length == 4){
- extent = new OpenLayers.Bounds(default_area[1], default_area[0],
- default_area[3], default_area[2]);
+ extent = new OpenLayers.Bounds(default_area[0], default_area[1],
+ default_area[2], default_area[3]);
+ extent.transform(epsg_display_projection, epsg_projection);
}
else{
return;
diff --git a/chimere/static/edit_area.js b/chimere/static/edit_area.js
index 4daccf3..7695e6b 100644
--- a/chimere/static/edit_area.js
+++ b/chimere/static/edit_area.js
@@ -22,7 +22,8 @@ var map;
/* update form fields on zoom action */
function updateForm(){
- var bounds = map.getExtent();
+ var bounds = map.getExtent().transform(epsg_projection,
+ epsg_display_projection);
document.getElementById('upper_left_lat').value = bounds.top;
document.getElementById('upper_left_lon').value = bounds.left;
document.getElementById('lower_right_lat').value = bounds.bottom;
diff --git a/chimere/static/edit_map.js b/chimere/static/edit_map.js
index 8f37f6b..88237a4 100644
--- a/chimere/static/edit_map.js
+++ b/chimere/static/edit_map.js
@@ -47,8 +47,8 @@ var putMarker = function (lonlat, zoom){
epsg_display_projection);
document.getElementById('id_point').value = 'POINT(' + lonlat.lon +
' ' + lonlat.lat + ')';
- document.getElementById('live_latitude').value = lonlat.lon;
- document.getElementById('live_longitude').value = lonlat.lat;
+ document.getElementById('live_latitude').value = lonlat.lat;
+ document.getElementById('live_longitude').value = lonlat.lon;
/*zoom to the point*/
if (zoom){
var bounds = layerMarkers.getDataExtent();
diff --git a/chimere/static/edit_route_map.js b/chimere/static/edit_route_map.js
index dcf7c84..28a0498 100644
--- a/chimere/static/edit_route_map.js
+++ b/chimere/static/edit_route_map.js
@@ -39,7 +39,6 @@ function featureCreated(event) {
help_route_create.style.display = 'None';
}
document.getElementById('help-route-modify').style.display = 'block';
-
pathModify.activate();
updateForm(event);
pathModify.selectControl.select(event.feature);
@@ -56,6 +55,7 @@ function initFeature(json_geometry){
point_array.push(point);
}
var linestring = new OpenLayers.Geometry.LineString(point_array);
+ linestring.transform(epsg_display_projection, map.getProjectionObject());
currentFeature = new OpenLayers.Feature.Vector();
currentFeature.geometry = linestring;
vectors.addFeatures([currentFeature]);
@@ -68,7 +68,10 @@ function initFeature(json_geometry){
function updateForm(event) {
/* update the form */
currentFeature = event.feature;
- document.getElementById('id_route').value = currentFeature.geometry;
+ var current_geo = currentFeature.geometry.clone();
+ current_geo.transform(map.getProjectionObject(),
+ epsg_display_projection);
+ document.getElementById('id_route').value = current_geo;
}
diff --git a/chimere/static/main_map.js b/chimere/static/main_map.js
index 8137b03..5c698c1 100644
--- a/chimere/static/main_map.js
+++ b/chimere/static/main_map.js
@@ -287,6 +287,7 @@ function putRoute(layer, route) {
point_array.push(point);
}
var linestring = new OpenLayers.Geometry.LineString(point_array);
+ linestring.transform(epsg_display_projection, map.getProjectionObject());
currentFeature = new OpenLayers.Feature.Vector();
var style = OpenLayers.Util.extend({},