diff options
-rw-r--r-- | main/actions.py | 2 | ||||
-rw-r--r-- | main/models.py | 40 | ||||
-rw-r--r-- | main/views.py | 37 | ||||
-rw-r--r-- | settings.py | 14 | ||||
-rw-r--r-- | static/main_map.js | 56 | ||||
-rw-r--r-- | static/styles.css | 4 | ||||
-rw-r--r-- | templates/main_map.html | 2 | ||||
-rw-r--r-- | templates/submited.html | 1 | ||||
-rw-r--r-- | urls.py | 8 |
9 files changed, 113 insertions, 51 deletions
diff --git a/main/actions.py b/main/actions.py index a4bf06d..77f8a46 100644 --- a/main/actions.py +++ b/main/actions.py @@ -30,4 +30,4 @@ class Action: self.id, self.path, self.label = id, main_path + path, label actions = [Action('view', '', _('View')), Action('edit', 'edit', _('Add')), - Action('edit-route', 'edit-route', _('Add route'))] + Action('edit_route', 'edit_route', _('Add route'))] diff --git a/main/models.py b/main/models.py index ead8a85..ee44a84 100644 --- a/main/models.py +++ b/main/models.py @@ -24,6 +24,7 @@ from django.utils.translation import ugettext_lazy as _ from django.contrib.gis.db import models from django.contrib import admin +from django.db.models import Q from chimere import settings from chimere.main.widgets import PointField, RouteField @@ -72,20 +73,31 @@ class SubCategory(models.Model): name = models.CharField(_("Name"), max_length=150) available = models.BooleanField(_("Available")) icon = models.ForeignKey(Icon, verbose_name=_("Icon")) + color = models.CharField(max_length=10, blank=True, null=True) order = models.IntegerField(_("Order")) + TYPE = (('M', _('Marker')), + ('R', _('Route')), + ('B', _('Both')),) + item_type = models.CharField(_("Item type"), max_length=1, choices=TYPE) def __unicode__(self): return u"%s / %s" % (self.category.name, self.name) class Meta: ordering = ["category", "order"] verbose_name = _("Subcategory") - def getAvailable(): + def getAvailable(item_types=None): '''Get list of tuples with first the category and second the associated subcategories ''' sub_categories = {} - for sub_category in SubCategory.objects.filter(category__available=True, - available=True): + subcategories = None + if not item_types: + subcategories = SubCategory.objects.filter(category__available=True, + available=True) + else: + subcategories = SubCategory.objects.filter(category__available=True, + item_type__in=item_types) + for sub_category in subcategories: if sub_category.category not in sub_categories: sub_categories[sub_category.category] = [] sub_categories[sub_category.category].append(sub_category) @@ -153,13 +165,11 @@ class Marker(models.Model): def getGeoJSON(self): '''Return a GeoJSON string ''' - return """{"type":"Feature", "geometry":{"type":"Point", \ -"crs": "EPSG:%(epsg)d", "coordinates":[%(longitude)s, %(latitude)s]}, \ + return """{"type":"Feature", "geometry":%(geometry)s, \ "properties":{"pk": %(id)d, "name": "%(name)s", \ "icon_path":"%(icon_path)s", "icon_width":%(icon_width)d, \ "icon_height":%(icon_height)d}}""" % {'id':self.id, 'name':self.name, -'icon_path':self.subcategory.icon.image, 'latitude':self.getLatitude(), -'longitude':self.getLongitude(), 'epsg':settings.EPSG_PROJECTION, +'icon_path':self.subcategory.icon.image, 'geometry':self.point.geojson, 'icon_width':self.subcategory.icon.image.width, 'icon_height':self.subcategory.icon.image.height,} @@ -223,17 +233,13 @@ class Route(models.Model): def getGeoJSON(self): '''Return a GeoJSON string ''' - return """{"type":"Feature", "geometry":{"type":"Point", \ -"crs": "EPSG:%(epsg)d", "coordinates":[%(longitude)s, %(latitude)s]}, \ + color = '#000' + if self.subcategory.color: + color = self.subcategory.color + return """{"type":"Feature", "geometry":%(geometry)s, \ "properties":{"pk": %(id)d, "name": "%(name)s", \ -"icon_path":"%(icon_path)s", "icon_width":%(icon_width)d, \ -"icon_height":%(icon_height)d}}""" % {'id':self.id, 'name':self.name, -'icon_path':self.subcategory.icon.image, 'latitude':self.getLatitude(), -'longitude':self.getLongitude(), 'epsg':settings.EPSG_PROJECTION, -'icon_width':self.subcategory.icon.image.width, -'icon_height':self.subcategory.icon.image.height,} - - +"color":"%(color)s"}}""" % {'id':self.id, 'name':self.name, +'color':color, 'geometry':self.route.geojson,} class PropertyModel(models.Model): '''Model for a property diff --git a/main/views.py b/main/views.py index f0cc604..a7a4da7 100644 --- a/main/views.py +++ b/main/views.py @@ -77,7 +77,7 @@ def edit(request): # set the submited status marker.status = 'S' marker.save() - return HttpResponseRedirect('/chimere/submited') + return HttpResponseRedirect('/chimere/submited/edit') else: # An unbound form form = MarkerForm() @@ -88,7 +88,7 @@ def edit(request): 'media_path':settings.MEDIA_URL, 'form':form, 'extra_head':form.media, - 'sub_categories':SubCategory.getAvailable(), + 'sub_categories':SubCategory.getAvailable(['M', 'B']), 'point_widget':PointChooserWidget().render('point', None), 'properties':declared_fields } @@ -111,18 +111,18 @@ def editRoute(request): # set the submited status route.status = 'S' route.save() - return HttpResponseRedirect('/chimere/submited') + return HttpResponseRedirect('/chimere/submited/edit_route') else: # An unbound form form = RouteForm() # get the « manualy » declared_fields. Ie: properties declared_fields = form.declared_fields.keys() - response_dct = {'actions':actions, 'action_selected':'edit-route', + response_dct = {'actions':actions, 'action_selected':'edit_route', 'error_message':'', 'media_path':settings.MEDIA_URL, 'form':form, 'extra_head':form.media, - 'sub_categories':SubCategory.getAvailable(), + 'sub_categories':SubCategory.getAvailable(['R', 'B']), 'route_widget':RouteChooserWidget().render('route', None), 'properties':declared_fields } @@ -139,11 +139,12 @@ def welcome(request, display=None): response_dct['news_lst'] = News.objects.filter(available=True) return loader.render_to_string('welcome.html', response_dct) -def submited(request): +def submited(request, action): """ Successful submission page """ - response_dct = {'actions':actions, 'action_selected':'edit', + print action + response_dct = {'actions':actions, 'action_selected':action, 'media_path':settings.MEDIA_URL,} return render_to_response('submited.html', response_dct) @@ -174,3 +175,25 @@ def getMarkers(request, category_ids): data = '{"type": "FeatureCollection", "features":[%s]}' % \ ",".join([marker.getGeoJSON() for marker in markers]) return HttpResponse(data) + +def getGeoObjects(request, category_ids): + ''' + Get the JSON for a route + ''' + try: + query = Route.objects.filter(status='A', + subcategory__in=category_ids.split('_')) + except: + return HttpResponse('no results') + geo_objects = list(query) + try: + query = Marker.objects.filter(status='A', + subcategory__in=category_ids.split('_')) + except: + return HttpResponse('no results') + geo_objects += list(query) + if not geo_objects: + return HttpResponse('no results') + data = '{"type": "FeatureCollection", "features":[%s]}' % \ + ",".join([geo_object.getGeoJSON() for geo_object in geo_objects]) + return HttpResponse(data)
\ No newline at end of file diff --git a/settings.py b/settings.py index 88dbd7d..9fd47ba 100644 --- a/settings.py +++ b/settings.py @@ -1,9 +1,13 @@ # Django settings for chimere project. -# GDAL path for GeoDjango - ROOT_PATH = '/var/local/django/chimere/' +# chimere specific +MAP_BOUNDS = (-20037508.34, -20037508.34, 20037508.34, 20037508.34) +DEFAULT_CENTER = (-1.679444, 48.114722) +EPSG_PROJECTION = 900913 +EPSG_DISPLAY_PROJECTION = 4326 + DEBUG = True TEMPLATE_DEBUG = DEBUG @@ -85,9 +89,3 @@ INSTALLED_APPS = ( 'django.contrib.sites', 'chimere.main', ) - -# Wikimap specific -MAP_BOUNDS = (-20037508.34, -20037508.34, 20037508.34, 20037508.34) -DEFAULT_CENTER = (-1.679444, 48.114722) -EPSG_PROJECTION = 900913 -EPSG_DISPLAY_PROJECTION = 4326 diff --git a/static/main_map.js b/static/main_map.js index 4a9e684..3ccf2b0 100644 --- a/static/main_map.js +++ b/static/main_map.js @@ -44,6 +44,7 @@ var offset = new OpenLayers.Pixel(-(size.w/2), -size.h); /* define global variable */ var markers = new Array(); var layerMarkers; +var layerVectors; var currentPopup; var currentFeature; @@ -63,8 +64,8 @@ function showPop(feature) { currentPopup = feature.popup; } -/* load markers with an AJAX request */ -function loadMarkers(){ +/* load geo objects with an AJAX request */ +function loadGeoObjects(){ /* get checked categories */ inputs = window.document.forms["frm_categories"]; var categories = ''; @@ -79,28 +80,36 @@ function loadMarkers(){ } /* 0 stand for all categories */ if (!categories) categories = '0'; - var uri = "/chimere/getMarkers/" + categories; - OpenLayers.loadURL(uri, '', this, setMarkers); + var uri = "/chimere/getGeoObjects/" + categories; + OpenLayers.loadURL(uri, '', this, setGeoObjects); } -/* update the marker layers from an http response GeoJSON */ -function setMarkers(response){ +/* update the marker and vector layers from an http response GeoJSON */ +function setGeoObjects(response){ if(layerMarkers) layerMarkers.destroy(); + if(layerVectors) layerVectors.destroy(); if (response.responseText.indexOf('no results') == -1) { /* clean the marker layer */ if (currentPopup) { currentPopup.hide(); hide('detail'); } + layerVectors = new OpenLayers.Layer.Vector("Vector Layer"); + map.addLayer(layerVectors); + layerVectors.setOpacity(0.8); layerMarkers = new OpenLayers.Layer.Markers('POIs'); map.addLayer(layerMarkers); layerMarkers.setOpacity(0.8); var json = new OpenLayers.Format.JSON(); - var markers_pt = json.read(response.responseText); - /* load every marker */ - for (var i = 0; i < markers_pt.features.length; i++) { - putMarker(markers_pt.features[i]); + var geo_objects = json.read(response.responseText); + /* load every geo object */ + for (var i = 0; i < geo_objects.features.length; i++) { + var feature = geo_objects.features[i]; + if (feature.geometry.type == 'Point') putMarker(feature); + if (feature.geometry.type == 'LineString') { + putRoute(feature); + } } /* var geojson = new OpenLayers.Format.GeoJSON(); @@ -111,9 +120,32 @@ function setMarkers(response){ } } + +/* put a route on the map */ +function putRoute(route) { + var polyline = route.geometry; + var point_array = new Array(); + for (i=0; i<polyline.coordinates.length; i++){ + var point = new OpenLayers.Geometry.Point(polyline.coordinates[i][0], + polyline.coordinates[i][1]); + point_array.push(point); + } + var linestring = new OpenLayers.Geometry.LineString(point_array); + currentFeature = new OpenLayers.Feature.Vector(); + + var style = OpenLayers.Util.extend({}, + OpenLayers.Feature.Vector.style['default']); + style.strokeColor = route.properties.color; + style.strokeWidth = 3; + currentFeature.style = style; + currentFeature.geometry = linestring; + layerVectors.addFeatures([currentFeature]); +} + + /* put a marker on the map */ function putMarker(mark) { - /* initialise a new feature with appropriate attribute for setting a + /* initialise a new marker with appropriate attribute for setting a marker */ lat = mark.geometry.coordinates[1]; lon = mark.geometry.coordinates[0]; @@ -199,6 +231,6 @@ function init(){ /*projection: new OpenLayers.Projection('EPSG:900913'), displayProjection: new OpenLayers.Projection('EPSG:4326')*/ map.addLayers([layerMapnik, cyclemap]); - loadMarkers(); + loadGeoObjects(); map.setCenter(centerLonLat, 12); } diff --git a/static/styles.css b/static/styles.css index fda1fa9..6887dfb 100644 --- a/static/styles.css +++ b/static/styles.css @@ -44,6 +44,10 @@ border:None; visibility: hidden; } +fieldset{ +margin-top:4px; +} + .edit label{ display:block; } diff --git a/templates/main_map.html b/templates/main_map.html index 47a495a..6b2d9d5 100644 --- a/templates/main_map.html +++ b/templates/main_map.html @@ -6,7 +6,7 @@ <ul id='categories'>{% for category, lst_sub_categories in sub_categories %} <li>{% trans category.name %} <ul class='subcategories'>{% for sub_category in lst_sub_categories %} - <li><input type='checkbox' onclick='loadMarkers()' name='category_{{sub_category.id}}' id='{{sub_category.id}}'{% if sub_category.selected %} checked='checked'{% endif %}/> <label for='{{sub_category.id}}'><img alt='{{sub_category.name}}' src='{{media_path}}{{sub_category.icon.image}}'/> {% trans sub_category.name %}</label></li>{% endfor %} + <li><input type='checkbox' onclick='loadGeoObjects()' name='category_{{sub_category.id}}' id='{{sub_category.id}}'{% if sub_category.selected %} checked='checked'{% endif %}/> <label for='{{sub_category.id}}'><img alt='{{sub_category.name}}' src='{{media_path}}{{sub_category.icon.image}}'/> {% trans sub_category.name %}</label></li>{% endfor %} </ul> </li>{% endfor %} </ul> diff --git a/templates/submited.html b/templates/submited.html index 824bd7f..eae3623 100644 --- a/templates/submited.html +++ b/templates/submited.html @@ -2,7 +2,6 @@ {% load i18n %} {% block content %} <fieldset class='edit'> -<legend>{% trans "Add a new site" %}</legend> <p>{% trans "Your proposition has been submited. A moderator will treat your submission shortly. Thanks!" %}</p> </fieldset> {% endblock %} @@ -13,12 +13,12 @@ urlpatterns = patterns('', (r'^chimere/admin/(.*)', admin.site.root), (r'^chimere/$', 'chimere.main.views.index'), (r'^chimere/edit/$', 'chimere.main.views.edit'), - (r'^chimere/edit-route/$', 'chimere.main.views.editRoute'), - (r'^chimere/submited/$', 'chimere.main.views.submited'), + (r'^chimere/edit_route/$', 'chimere.main.views.editRoute'), + (r'^chimere/submited/(?P<action>\w+)/$$', 'chimere.main.views.submited'), (r'^chimere/getDetail/(?P<marker_id>\d+)/$', 'chimere.main.views.getDetail'), - (r'^chimere/getMarkers/(?P<category_ids>\w+)/$', - 'chimere.main.views.getMarkers'), + (r'^chimere/getGeoObjects/(?P<category_ids>\w+)/$', + 'chimere.main.views.getGeoObjects'), (r'^chimere/static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': ROOT_PATH + 'static/'}), (r'^chimere/media/(?P<path>.*)$', 'django.views.static.serve', |