Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…
Cannot retrieve contributors at this time
331 lines (283 sloc) 11.9 KB
from geonode.maps.models import Map
from geonode.maps.models import Layer
from geonode.maps.models import MapLayer
from geonode.maps.models import Thumbnail
from geonode.maps.utils import forward_mercator
from geonode.maps.views import json_response
from mapstory import models
from mapstory.util import lazy_context
from mapstory.util import render_manual
from mapstory.forms import CheckRegistrationForm
import account.views
from django.contrib.auth.models import User
from django.core.cache import cache
from django.core.exceptions import PermissionDenied
from django.conf import settings
from django.db.models import signals
from django.shortcuts import get_object_or_404
from django.views.decorators.http import require_POST
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.template import loader
from django.contrib.contenttypes.models import ContentType
from django.views.decorators.cache import cache_page
import math
import os
import random
def alerts(req):
return render_to_response('mapstory/alerts.html', RequestContext(req))
def lazy_tiles():
return ''.join( [ _render_map_tile(m) for m in get_map_carousel_maps()] )
def index(req):
# resolve video to use
# two modes of operation here
# 1) don't specify publish and one will randomly be chosen
# 2) specify one or more publish links and one will be chosen
#users = User.objects.exclude(username__in=settings.USERS_TO_EXCLUDE_IN_LISTINGS)
users = []
return render_to_response('index.html', RequestContext(req,{
"video" : models.VideoLink.objects.front_page_video(),
"tiles" : lazy_tiles(),
"users" : users
def how_to(req):
return render_to_response('mapstory/how_to.html', RequestContext(req,{
'videos' : models.VideoLink.objects.how_to_videos()
def manual(req):
html = render_manual('manual.rst')
if 'test' in req.GET:
return HttpResponse(html)
return render_to_response('mapstory/manual.html', RequestContext(req,{
'content' : html
def section_detail(req, section):
sec = get_object_or_404(models.Section, slug=section)
return render_to_response('mapstory/section_detail.html', RequestContext(req,{
'section' : sec
def resource_detail(req, resource):
res = get_object_or_404(models.Resource, slug=resource)
return render_to_response('mapstory/resource.html', RequestContext(req,{
'resource' : res
def get_map_carousel_maps():
'''Get the carousel ids/thumbnail dict either
1. as specified (model does not exist yet...)
2. by some rating/view ranking (not implemented)
3. any map that has a thumbnail (current)
favorites = models.Favorite.objects.favorite_maps_for_user(User.objects.get(username='admin'))
if favorites.count() > 3:
favorites = random.sample(favorites, min(10,favorites.count()))
return [ f.content_object for f in favorites ]
# get all Map thumbnails
thumb_type = ContentType.objects.get_for_model(Map)
thumbs = Thumbnail.objects.filter(
thumbs = thumbs.filter(object_id__in = Map.objects.filter(publish__status='Public'))
# trim this down to a smaller set
thumbs = random.sample(thumbs, min(10,len(thumbs)))
# and make sure they have a valid file path
return [ t.content_object for t in thumbs if os.path.exists(t.get_thumbnail_path())]
def map_tiles(req):
maps = get_map_carousel_maps()
return HttpResponse(''.join( [ _render_map_tile(m) for m in maps] ))
def _render_map_tile(obj,req=None):
template = 'mapstory/_story_tile.html'
ctx = {'map':obj,'when':obj.last_modified}
if req:
return render_to_response(template, RequestContext(req,ctx))
return loader.render_to_string(template,ctx)
def map_tile(req, mapid):
obj = get_object_or_404(Map,pk=mapid)
return _render_map_tile(obj,req=req)
def favoriteslinks(req):
ident = req.GET['ident']
layer_or_map, id = ident.split('-')
if layer_or_map == 'map':
obj = get_object_or_404(Map, pk = id)
maps = models.PublishingStatus.objects.get_in_progress(req.user,Map)
elif layer_or_map == 'layer':
obj = get_object_or_404(Layer, pk = id)
maps = None
return HttpResponse('')
return render_to_response("simplesearch/_widget_search_favorites.html",{
layer_or_map : obj,
"maps" : maps,
"user" : req.user
def favoriteslist(req):
ctx = {
"favorites" : models.Favorite.objects.favorites_for_user(req.user),
"in_progress_maps" : Map.objects.filter(owner=req.user).exclude(publish__status='Public'),
"in_progress_layers" : Layer.objects.filtered().filter(owner=req.user).exclude(publish__status='Public')
return render_to_response("mapstory/_widget_favorites.html",ctx)
def layer_metadata(request, layername):
'''ugh, override the default'''
from geonode.maps.views import LayerDescriptionForm
layer = get_object_or_404(Layer, typename=layername)
if not request.user.has_perm('maps.change_layer', obj=layer):
return HttpResponse(loader.render_to_string('401.html',
RequestContext(request, {'error_message':
"You are not permitted to modify this layer's metadata"})), status=401)
if request.method == "POST":
form = LayerDescriptionForm(request.POST, prefix="layer")
if form.is_valid():
layer.title = form.cleaned_data['title']
layer.abstract = form.cleaned_data['abstract']
return HttpResponse('OK')
errors = "<div class='errorlist'><p class='alert alert-error'>There were errors in the data provided:</p>%s</div>" % form.errors.as_ul()
return HttpResponse(errors, status=400)
def favorite(req, layer_or_map, id):
if layer_or_map == 'map':
obj = get_object_or_404(Map, pk = id)
obj = get_object_or_404(Layer, pk = id)
models.Favorite.objects.create_favorite(obj, req.user)
return HttpResponse('OK', status=200)
def delete_favorite(req, id):
models.Favorite.objects.get(user=req.user, pk=id).delete()
return HttpResponse('OK', status=200)
def publish_status(req, layer_or_map, layer_or_map_id):
if req.method != 'POST':
return HttpResponse('POST required',status=400)
model = Map if layer_or_map == 'map' else Layer
obj = _resolve_object(req, model, 'mapstory.change_publishingstatus',
allow_owner=True, id=layer_or_map_id)
models.PublishingStatus.objects.set_status(obj, req.POST['status'])
related = obj.publish.check_related()
if related:
return HttpResponse('WARN', status=200)
return HttpResponse('OK', status=200)
def add_to_map(req,id,typename):
if req.method != 'POST':
return HttpResponse('POST required',status=400)
mapobj = get_object_or_404(Map, id=id)
if mapobj.owner != req.user and not req.user.has_perm('maps.change_map', mapobj):
return HttpResponse('Not sufficient permissions',status=401)
layer = get_object_or_404(Layer, typename=typename)
existing = MapLayer.objects.filter(map = mapobj)
vs_url = settings.GEOSERVER_BASE_URL + '%s/%s/wms' % tuple(layer.typename.split(':'))
stack_order = max([l.stack_order for l in existing]) + 1
# have to use local name, not full typename when using ows_url
maplayer = MapLayer(name =, ows_url=vs_url, map=mapobj, stack_order=stack_order)
# if bounding box is equivalent to default, compute and save
ints = lambda t: map(int,t)
if ints( == ints(forward_mercator(settings.DEFAULT_MAP_CENTER)):
bbox = layer.resource.latlon_bbox[0:4]
# @todo copy-paste from geonode.maps.views - extract this for reuse
minx, maxx, miny, maxy = [float(c) for c in bbox]
x = (minx + maxx) / 2
y = (miny + maxy) / 2
center = forward_mercator((x, y))
if center[1] == float('-inf'):
center = (center[0], 0)
if maxx == minx:
width_zoom = 15
width_zoom = math.log(360 / (maxx - minx), 2)
if maxy == miny:
height_zoom = 15
height_zoom = math.log(360 / (maxy - miny), 2)
mapobj.center_x = center[0]
mapobj.center_y = center[1]
mapobj.zoom = math.ceil(min(width_zoom, height_zoom))
return HttpResponse('OK', status=200)
def about_storyteller(req, username):
user = get_object_or_404(User, username=username)
return render_to_response('mapstory/about_storyteller.html', RequestContext(req,{
"storyteller" : user,
def delete_story_comment(req, layer_or_map, layer_or_map_id):
'''allow a user to delete comments attached to their layer or map'''
def topics_api(req, layer_or_map, layer_or_map_id):
if layer_or_map == 'map':
obj = get_object_or_404(Map, pk = layer_or_map_id)
perm = 'maps.change_map'
obj = get_object_or_404(Layer, pk = layer_or_map_id)
perm = 'maps.change_layer'
if obj.owner != req.user and not req.user.has_perm(perm, obj):
return HttpResponse('Not sufficient permissions',status=401)
if req.method == 'GET':
elif req.method == 'POST':
topics = req.POST['topics']
if req.method != 'POST':
return HttpResponse(status=400)
return HttpResponse('OK', status=200)
class SignupView(account.views.SignupView):
form_class = CheckRegistrationForm
def create_annotations_layer(req, mapid):
'''Create an annotations layer with the predefined schema.
@todo ugly hack - using existing view to allow this
from geonode.maps.views import _create_layer
mapobj = get_object_or_404(Map,pk=mapid)
if req.method != 'POST':
return HttpResponse('POST required',status=400)
if mapobj.owner != req.user:
return HttpResponse('Not owner of map',status=401)
atts = [
#name, type, nillable
# @todo remove this when hack is resolved. build our spec string
atts = ','.join([ ':'.join(map(str,a)) for a in atts])
return _create_layer(
name = "_map_%s_annotations" % mapid,
srs = 'EPSG:4326', # @todo how to obtain this in a nicer way...
attributes = atts,
skip_style = True
def _resolve_object(req, model, perm, perm_required=False,
allow_owner=False, **kw):
obj = get_object_or_404(model,**kw)
allowed = True
if perm:
if perm_required or req.method != 'GET':
if allow_owner:
allowed = req.user == obj.owner
if not allowed:
allowed = req.user.has_perm(perm, obj=obj)
if not allowed:
raise PermissionDenied("You do not have adequate permissions")
return obj
def _remove_annotation_layer(sender, instance, **kw):
Layer.objects.get(name='_map_%s_annotations' %
except Layer.DoesNotExist:
signals.pre_delete.connect(_remove_annotation_layer, sender=Map)
Jump to Line
Something went wrong with that request. Please try again.