').attr('name', feature.name).append(
+ $('').text(feature.title).append(' ').append(
+ $('').text(feature.name)
+ )
+ )
+ );
}
$('.start-drawing').show();
$('#mapeditcontrols').addClass('list');
editor.set_current_level(editor._level);
});
-
},
_get_feature_style: function (feature) {
return editor.feature_types[feature.properties.feature_type];
},
+ _click_start_drawing: function (e) {
+ editor.start_creating($(this).closest('fieldset').attr('name'));
+ },
+ _hover_feature_detail: function (e) {
+ editor._highlight_layer.clearLayers();
+ L.geoJSON(editor.features[$(this).attr('name')].geometry, {
+ style: function() {
+ return {
+ color: '#FFFFEE',
+ opacity: 0.5,
+ fillOpacity: 0.5,
+ className: 'c3nav-highlight'
+ };
+ }
+ }).addTo(editor._highlight_layer);
+ },
+ _unhover_feature_detail: function () {
+ editor._highlight_layer.clearLayers();
+ },
+ _click_feature_detail: function() {
+ editor.start_editing($(this).attr('name'));
+ },
+
+ _hover_feature_layer: function (e) {
+ editor._unhover_feature_layer();
+ if (editor._editing === null && editor._creating === null) {
+ editor._highlight_layer.clearLayers();
+ L.geoJSON(e.layer.toGeoJSON(), {
+ style: function() {
+ return {
+ color: '#FFFFEE',
+ opacity: 0.5,
+ fillOpacity: 0.5,
+ className: 'c3nav-highlight'
+ };
+ }
+ }).addTo(editor._highlight_layer);
+ }
+ $('.feature_list li[name='+e.layer.feature.properties.name+']').addClass('hover');
+ },
+ _unhover_feature_layer: function (e) {
+ editor._highlight_layer.clearLayers();
+ $('.feature_list .hover').removeClass('hover');
+ },
+ _click_feature_layer: function(e) {
+ editor.start_editing(e.layer.feature.properties.name);
+ if ((e.originalEvent.ctrlKey || e.originalEvent.metaKey) && this.editEnabled()) {
+ if (e.layer.feature.properties.geomtype == 'polygon') {
+ this.editor.newHole(e.latlng);
+ }
+ }
+ },
+
start_creating: function (feature_type) {
if (editor._creating !== null || editor._editing !== null) return;
+ editor._highlight_layer.clearLayers();
editor._creating = feature_type;
var options = editor.feature_types[feature_type];
if (options.geomtype == 'polygon') {
@@ -230,8 +313,13 @@ editor = {
}
},
- start_editing: function () {
- // todo
+ start_editing: function (name) {
+ if (editor._creating !== null || editor._editing !== null) return;
+ editor._highlight_layer.clearLayers();
+ editor._editing = editor.features[name].layer;
+ var path = '/editor/features/edit/' + name + '/';
+ $('#mapeditcontrols').removeClass('list');
+ $('#mapeditdetail').load(path, editor.edit_form_loaded);
},
edit_form_loaded: function() {
$('#mapeditcontrols').addClass('detail');
@@ -263,9 +351,18 @@ editor = {
editor.get_features();
}
},
- submit_editing: function(e) {
+ submit_editing_btn_click: function(e) {
+ e.preventDefault();
+ $(this).closest('form').trigger('submit', $(this));
+ },
+ submit_editing: function(e, btn) {
e.preventDefault();
var data = $(this).serialize();
+ console.log($(btn));
+ console.log($(btn).is('[name]'));
+ if (btn !== undefined && $(btn).is('[name]')) {
+ data += '&'+$('').attr('name', $(btn).attr('name')).val($(btn).val()).serialize();
+ }
var action = $(this).attr('action');
$('#mapeditcontrols').removeClass('detail');
$('#mapeditdetail').html('');
diff --git a/src/c3nav/editor/templates/editor/feature.html b/src/c3nav/editor/templates/editor/feature.html
index 75fca294..0ed4cafb 100644
--- a/src/c3nav/editor/templates/editor/feature.html
+++ b/src/c3nav/editor/templates/editor/feature.html
@@ -5,11 +5,16 @@
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
-
+ {% if not new %}
+
+ {% endif %}
+
{% endbuttons %}
diff --git a/src/c3nav/editor/templates/editor/feature_delete.html b/src/c3nav/editor/templates/editor/feature_delete.html
new file mode 100644
index 00000000..9eb8343d
--- /dev/null
+++ b/src/c3nav/editor/templates/editor/feature_delete.html
@@ -0,0 +1,17 @@
+{% load bootstrap3 %}
+
+Delete {{ feature_type.title }}
+
diff --git a/src/c3nav/editor/urls.py b/src/c3nav/editor/urls.py
index 51ce70a4..7b80e5df 100644
--- a/src/c3nav/editor/urls.py
+++ b/src/c3nav/editor/urls.py
@@ -1,9 +1,10 @@
from django.conf.urls import url
from django.views.generic import TemplateView
-from c3nav.editor.views import add_feature
+from c3nav.editor.views import add_feature, edit_feature
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='editor/map.html'), name='editor.index'),
- url(r'^features/(?P[^/]+)/add/$', add_feature, name='editor.feature.add')
+ url(r'^features/(?P[^/]+)/add/$', add_feature, name='editor.feature.add'),
+ url(r'^features/edit/(?P[^/]+)/$', edit_feature, name='editor.feature.edit')
]
diff --git a/src/c3nav/editor/views.py b/src/c3nav/editor/views.py
index f7bd64af..c4031940 100644
--- a/src/c3nav/editor/views.py
+++ b/src/c3nav/editor/views.py
@@ -1,10 +1,12 @@
from django.conf import settings
+from django.core.exceptions import PermissionDenied
from django.db import transaction
from django.http.response import Http404
-from django.shortcuts import render
+from django.shortcuts import get_object_or_404, render
from c3nav.editor.forms import FeatureForm
-from c3nav.mapdata.models.feature import FEATURE_TYPES
+from c3nav.mapdata.models.feature import FEATURE_TYPES, Feature
+from c3nav.mapdata.permissions import can_access_package
def add_feature(request, feature_type):
@@ -37,3 +39,47 @@ def add_feature(request, feature_type):
'path': request.path,
'new': True
})
+
+
+def edit_feature(request, name):
+ feature = get_object_or_404(Feature, name=name)
+ if not can_access_package(feature.package):
+ raise PermissionDenied
+ feature_type = FEATURE_TYPES.get(feature.feature_type)
+
+ if request.method == 'POST':
+ if request.POST.get('delete') == '1':
+ if request.POST.get('delete_confirm') == '1':
+ feature.delete()
+ return render(request, 'editor/feature_success.html', {})
+
+ return render(request, 'editor/feature_delete.html', {
+ 'name': feature.name,
+ 'feature_type': feature_type,
+ 'path': request.path
+ })
+
+ form = FeatureForm(instance=feature, data=request.POST, feature_type=feature_type)
+ if form.is_valid():
+ if not settings.DIRECT_EDITING:
+ return render(request, 'editor/feature_success.html', {})
+
+ with transaction.atomic():
+ feature = form.instance
+ feature.feature_type = feature_type.name
+ feature.titles = {}
+ for language, title in form.titles.items():
+ if title:
+ feature.titles[language] = title
+ feature.save()
+
+ return render(request, 'editor/feature_success.html', {})
+ else:
+ form = FeatureForm(instance=feature, feature_type=feature_type)
+
+ return render(request, 'editor/feature.html', {
+ 'form': form,
+ 'feature_type': feature_type,
+ 'path': request.path,
+ 'new': False
+ })
diff --git a/src/c3nav/mapdata/api.py b/src/c3nav/mapdata/api.py
index 0bec0253..b6cc486e 100644
--- a/src/c3nav/mapdata/api.py
+++ b/src/c3nav/mapdata/api.py
@@ -4,7 +4,6 @@ import os
from django.conf import settings
from django.core.files import File
from django.http import Http404, HttpResponse
-
from rest_framework.decorators import detail_route
from rest_framework.response import Response
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
diff --git a/src/c3nav/mapdata/models/feature.py b/src/c3nav/mapdata/models/feature.py
index 77668afb..20ae3690 100644
--- a/src/c3nav/mapdata/models/feature.py
+++ b/src/c3nav/mapdata/models/feature.py
@@ -7,6 +7,7 @@ from django.utils.translation import get_language
from shapely.geometry import mapping, shape
from c3nav.mapdata.utils import sort_geojson
+
from ..fields import GeometryField, JSONField
@@ -35,7 +36,7 @@ class Feature(models.Model):
"""
TYPES = tuple((name, t.title) for name, t in FEATURE_TYPES.items())
- name = models.SlugField(_('feature identifier'), primary_key=True, max_length=50, help_text=_('e.g. noc'))
+ name = models.SlugField(_('feature identifier'), primary_key=True, max_length=50)
package = models.ForeignKey('mapdata.Package', on_delete=models.CASCADE, related_name='features',
verbose_name=_('map package'))
feature_type = models.CharField(max_length=50, choices=TYPES)
diff --git a/src/c3nav/mapdata/packageio/const.py b/src/c3nav/mapdata/packageio/const.py
index 05c6ad4f..098ffbd0 100644
--- a/src/c3nav/mapdata/packageio/const.py
+++ b/src/c3nav/mapdata/packageio/const.py
@@ -1,4 +1,3 @@
from ..models import Feature, Level, Package, Source
-
ordered_models = (Package, Level, Source, Feature)
diff --git a/src/c3nav/mapdata/permissions.py b/src/c3nav/mapdata/permissions.py
index 651ea9b4..2fa1c6c0 100644
--- a/src/c3nav/mapdata/permissions.py
+++ b/src/c3nav/mapdata/permissions.py
@@ -1,6 +1,5 @@
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
-
from rest_framework.exceptions import PermissionDenied
from rest_framework.permissions import BasePermission