diff options
author | etienne <etienne@9215b0d5-fb2c-4bbd-8d3e-bd2e9090e864> | 2010-03-14 18:35:23 +0000 |
---|---|---|
committer | etienne <etienne@9215b0d5-fb2c-4bbd-8d3e-bd2e9090e864> | 2010-03-14 18:35:23 +0000 |
commit | 64acbb356f5a177dc5bd80e7ad493ee554ca0e09 (patch) | |
tree | 8d3708eb5a235581d598cdbe672524f1d453df35 | |
parent | 63a9537e7deeb473145512fe8a080c62ea62c2c7 (diff) | |
download | Chimè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.py | 42 | ||||
-rw-r--r-- | chimere/main/forms.py | 17 | ||||
-rw-r--r-- | chimere/main/models.py | 38 | ||||
-rw-r--r-- | chimere/main/widgets.py | 9 | ||||
-rw-r--r-- | chimere/settings.py | 7 | ||||
-rw-r--r-- | chimere/static/base.js | 5 | ||||
-rw-r--r-- | chimere/static/edit_area.js | 3 | ||||
-rw-r--r-- | chimere/static/edit_map.js | 4 | ||||
-rw-r--r-- | chimere/static/edit_route_map.js | 7 | ||||
-rw-r--r-- | chimere/static/main_map.js | 1 |
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({}, |