示例#1
0
def layer_append(request, layername, template='upload/layer_append.html'):
    print 'layer append'
    context = {}
    layer_destination = _resolve_layer(
        request,
        layername,
        'base.change_resourcebase_metadata',
        _PERMISSION_MSG_METADATA)

    def parse_layers(get_capabilities_xml_str):
        xml = etree.XML(get_capabilities_xml_str)
        tree = etree.ElementTree(xml)
        root = tree.getroot()
        # BUG with lxml? When elements do not have a prefix, even if None:'{http://www.opengis.net/wms}' is set as a namespace,
        # namespace elements are not resolved. xpath doesn't work and findXXX needs the namespace for wms to work: {http://www.opengis.net/wms}Layer
        # no luck getting tree.xpath('//WMS_Capabilities/Capability/Layer/Layer') or variation to work
        layer_elements = root.findall('.//{http://www.opengis.net/wms}Layer')
        layers = {}
        for layer in layer_elements:
            name_element = layer.find('{http://www.opengis.net/wms}Name')
            if name_element is not None and name_element.text:
                layers[name_element.text] = name_element.text
        return layers

    return render_to_response(template, context, context_instance=RequestContext(request),)
示例#2
0
def ediproxy_importmd(request, layername):
    layer = _resolve_layer(request, layername, 'base.change_resourcebase', _PERMISSION_MSG_METADATA)
    isoml = request.POST.get('generatedXml').encode('utf8')
    ediml = request.POST.get('ediml').encode('utf8')
    edimlid = request.POST.get('edimlid')
    try:
        _savelayermd(layer, isoml, ediml, version='2')
    except Exception as e:
        return json_response(exception=e, status=500)
    return json_response(body={'success':True})

# fare una class base view
# e spostare in una nuova funzione rest
# def load_isoedimlid(request, layername):

# def load_isoediml(request, layername):
#     layer = _resolve_layer(request, layername, 'base.change_layer', _PERMISSION_MSG_METADATA)
#     ediml = request.raw_post_data

#         _savelayermd(layer, rndt, ediml)
#     except Exception as e:
#         return json_response(exception=e, status=500)

#     return json_response(body={'success':True,'redirect': reverse('layer_detail', args=(layer.typename,))})
#     # return HttpResponseRedirect()

# # def load_
示例#3
0
文件: views.py 项目: lhcramer/geonode
def feature_edit_check(request, layername):
    """
    If the layer is not a raster and the user has edit permission, return a status of 200 (OK).
    Otherwise, return a status of 401 (unauthorized).
    """
    try:
        layer = _resolve_layer(request, layername)
    except:
        # Intercept and handle correctly resource not found exception
        return HttpResponse(
            json.dumps({'authorized': False}), content_type="application/json")
    datastore = ogc_server_settings.DATASTORE
    feature_edit = getattr(settings, "GEOGIG_DATASTORE", None) or datastore
    is_admin = False
    is_staff = False
    is_owner = False
    is_manager = False
    if request.user:
        is_admin = request.user.is_superuser if request.user else False
        is_staff = request.user.is_staff if request.user else False
        is_owner = (str(request.user) == str(layer.owner))
        try:
            is_manager = request.user.groupmember_set.all().filter(role='manager').exists()
        except:
            is_manager = False
    if is_admin or is_staff or is_owner or is_manager or request.user.has_perm(
            'change_layer_data',
            obj=layer) and layer.storeType == 'dataStore' and feature_edit:
        return HttpResponse(
            json.dumps({'authorized': True}), content_type="application/json")
    else:
        return HttpResponse(
            json.dumps({'authorized': False}), content_type="application/json")
示例#4
0
def crowd_layer_detail(request, layername, template='features/crowd_layer_detail.html'):
    layer = _resolve_layer(request, layername, 'layers.view_layer', _PERMISSION_MSG_VIEW)
    layer.json_url = layer.link_set.get(name='GeoJSON').url
    return render_to_response(template, RequestContext(request, {
        "layer": layer,
        "features": layer.feature_set.all(),  
    }))
示例#5
0
文件: views.py 项目: GavinDu/geonode
def layer_style(request, layername):
    layer = _resolve_layer(
        request,
        layername,
        'base.change_resourcebase',
        _PERMISSION_MSG_MODIFY)

    style_name = request.POST.get('defaultStyle')

    # would be nice to implement
    # better handling of default style switching
    # in layer model or deeper (gsconfig.py, REST API)

    old_default = layer.default_style
    if old_default.name == style_name:
        return HttpResponse(
            "Default style for %s remains %s" %
            (layer.name, style_name), status=200)

    # This code assumes without checking
    # that the new default style name is included
    # in the list of possible styles.

    new_style = (
        style for style in layer.styles if style.name == style_name).next()

    # Does this change this in geoserver??
    layer.default_style = new_style
    layer.styles = [
        s for s in layer.styles if s.name != style_name] + [old_default]
    layer.save()

    return HttpResponse(
        "Default style for %s changed to %s" %
        (layer.name, style_name), status=200)
示例#6
0
def layer_remove(request, layername, template='layers/layer_remove.html'):
    layer = _resolve_layer(
        request,
        layername,
        'base.delete_resourcebase',
        _PERMISSION_MSG_DELETE)

    if (request.method == 'GET'):
        return render_to_response(template, RequestContext(request, {
            "layer": layer
        }))
    if (request.method == 'POST'):
        try:
            delete_layer.delay(object_id=layer.id)
        except Exception as e:
            message = '{0}: {1}.'.format(_('Unable to delete layer'), layer.typename)

            if 'referenced by layer group' in getattr(e, 'message', ''):
                message = _('This layer is a member of a layer group, you must remove the layer from the group '
                            'before deleting.')

            messages.error(request, message)
            return render_to_response(template, RequestContext(request, {"layer": layer}))
        return HttpResponseRedirect(reverse("index_view"))
    else:
        return HttpResponse("Not allowed", status=403)
示例#7
0
def rndtproxy(request, layername):
    layer = _resolve_layer(request, layername, 'base.change_layer', _PERMISSION_MSG_METADATA)
    ediml = request.body
    try:
        rndt = _ediml2rndt(ediml)
    except UnregisteredSKException, e:
        return json_response(errors=e.message,
                             status=500)
示例#8
0
def layer_metadata_detail(request, layername,
                          template='layers/metadata_detail.html'):

    layer = _resolve_layer(request, layername, 'view_resourcebase',
                           _PERMISSION_MSG_METADATA)

    return render_to_response(template, RequestContext(request, {
        "layer": layer,
        'SITEURL': settings.SITEURL[:-1]
    }))
示例#9
0
def layer_publish(request, layername):
    layer = _resolve_layer(request, layername, 'view_resourcebase',
                           _PERMISSION_MSG_METADATA)
    layer.is_published = True
    layer.save()

    return HttpResponseRedirect(reverse(
                                'layer_detail',
                                args=([layer.service_typename])
                                ))
示例#10
0
def rndteditor(request, layername):
    layer = _resolve_layer(request, layername, 'layers.change_layer', _PERMISSION_MSG_METADATA)

    queryStringValues = {
        'template': 'RNDT',
        'version': '2.00',
        'parameters': "{}"
        }

    fileid = layer.mdextension.fileid
    pars = {}
    if fileid is not None:
        queryStringValues['edit'] = fileid
        pars = {
            'uid': layer.uuid,
            'westlon': layer.bbox_x0,
            'eastlon': layer.bbox_x1,
            'southlat': layer.bbox_y0,
            'northlat': layer.bbox_y1,
            'referencesystem': layer.srid.split(':')[1],
        }

    else:
        pars = {
            'uid': layer.uuid,
            # inserire data_md
            'title': layer.title,
            # 'data_md': layer.date.date().isoformat(), # layer.mdextension.md_date.date().isoformat(),
            'date': datetime.date.today().isoformat(), # layer.date.date().isoformat(),
            # 'tipo_di_data': layer.date_type,
            'abstract': layer.abstract,
            'spatialrepresentationtype': (EDI_MAP_SPATIALREPRESENTATIONTYPE).get(layer.storeType),
            'westlon': layer.bbox_x0,
            'eastlon': layer.bbox_x1,
            'southlat': layer.bbox_y0,
            'northlat': layer.bbox_y1,
            'resource': '%s%s' % (settings.SITEURL[:-1], layer.get_absolute_url()),
            'referencesystem': layer.srid.split(':')[1],
            }


    js_pars = json.dumps(pars, cls=DjangoJSONEncoder)

    queryStringValues['parameters'] = json.dumps(pars, cls=DjangoJSONEncoder)

    js_queryStringValues = json.dumps(queryStringValues)
    return render_to_response(
        'mdtools/rndt.html',
        RequestContext(request, {
                'layername': layername,
                'queryStringValues': mark_safe(js_queryStringValues)
                })
        )
示例#11
0
def feature_edit_check(request, layername):
    """
    If the layer is not a raster and the user has edit permission, return a status of 200 (OK).
    Otherwise, return a status of 401 (unauthorized).
    """
    layer = _resolve_layer(request, layername)
    datastore = ogc_server_settings.DATASTORE
    feature_edit = getattr(settings, "GEOGIG_DATASTORE", None) or datastore
    if request.user.has_perm("change_layer_data", obj=layer) and layer.storeType == "dataStore" and feature_edit:
        return HttpResponse(json.dumps({"authorized": True}), content_type="application/json")
    else:
        return HttpResponse(json.dumps({"authorized": False}), content_type="application/json")
示例#12
0
文件: views.py 项目: GeoNode/geonode
def site_layer_detail(request, layername, template='layers/layer_detail.html'):
    # BETTER WAY INSTEAD OF DO TWO _RESOLVE_LAYER PER CALL?
    layer = _resolve_layer(
        request,
        layername,
        'base.view_resourcebase',
        _PERMISSION_MSG_VIEW)
    site = get_current_site(request)
    if not SiteResources.objects.get(site=site).resources.filter(pk=layer.pk).exists():
        raise Http404
    else:
        return layer_detail(request, layername, template='layers/layer_detail.html')
示例#13
0
文件: views.py 项目: GavinDu/geonode
def layer_style_upload(request, layername):
    def respond(*args, **kw):
        kw['content_type'] = 'text/html'
        return json_response(*args, **kw)
    form = LayerStyleUploadForm(request.POST, request.FILES)
    if not form.is_valid():
        return respond(errors="Please provide an SLD file.")

    data = form.cleaned_data
    layer = _resolve_layer(
        request,
        layername,
        'base.change_resourcebase',
        _PERMISSION_MSG_MODIFY)

    sld = request.FILES['sld'].read()

    try:
        dom = etree.XML(sld)
    except Exception:
        return respond(errors="The uploaded SLD file is not valid XML")

    el = dom.findall(
        "{http://www.opengis.net/sld}NamedLayer/{http://www.opengis.net/sld}Name")
    if len(el) == 0 and not data.get('name'):
        return respond(
            errors="Please provide a name, unable to extract one from the SLD.")
    name = data.get('name') or el[0].text
    if data['update']:
        match = None
        styles = list(layer.styles) + [layer.default_style]
        for style in styles:
            if style.sld_name == name:
                match = style
                break
        if match is None:
            return respond(errors="Cannot locate style : " + name)
        match.update_body(sld)
    else:
        try:
            cat = gs_catalog
            cat.create_style(name, sld)
            layer.styles = layer.styles + \
                [type('style', (object,), {'name': name})]
            cat.save(layer.publishing)
        except ConflictingDataError:
            return respond(errors="""A layer with this name exists. Select
                                     the update option if you want to update.""")
    return respond(
        body={
            'success': True,
            'style': name,
            'updated': data['update']})
示例#14
0
def _change_published_status(request, layername, published):
    layer = _resolve_layer(
        request,
        layername,
        'base.change_resourcebase_metadata',
        _PERMISSION_MSG_METADATA)

    # let's restrict auth to superuser only
    if not request.user.is_superuser:
        return HttpResponse("Not allowed", status=403)

    Layer.objects.filter(id=layer.id).update(is_published=published)

    return layer_detail(request, layername)
示例#15
0
def get_remote_url(request, layername):
    layer = _resolve_layer(
        request,
        layername,
        'base.view_resourcebase',
        _PERMISSION_MSG_DELETE)

    url = None

    if layer.remote_service is not None:
        service = layer.remote_service
        url = service.online_resource

    return HttpResponse(url)
示例#16
0
def feature_edit_check(request, layername):
    """
    If the layer is not a raster and the user has edit permission, return a status of 200 (OK).
    Otherwise, return a status of 401 (unauthorized).
    """
    layer = _resolve_layer(request, layername)
    datastore = ogc_server_settings.DATASTORE
    feature_edit = getattr(settings, "GEOGIT_DATASTORE", None) or datastore
    if request.user.has_perm(
            'base.change_resourcebase',
            obj=layer.resourcebase_ptr) and layer.storeType == 'dataStore' and feature_edit:
        return HttpResponse(
            json.dumps({'authorized': True}), mimetype="application/json")
    else:
        return HttpResponse(
            json.dumps({'authorized': False}), mimetype="application/json")
示例#17
0
def layer_remove(request, layername, template='layers/layer_remove.html'):
    layer = _resolve_layer(
        request,
        layername,
        'base.delete_resourcebase',
        _PERMISSION_MSG_DELETE)

    if (request.method == 'GET'):
        return render(request, template, context={
            "layer": layer
        })
    if (request.method == 'POST'):
        try:
            with transaction.atomic():
                # Using Tastypie
                # from geonode.api.resourcebase_api import LayerResource
                # res = LayerResource()
                # request_bundle = res.build_bundle(request=request)
                # layer_bundle = res.build_bundle(request=request, obj=layer)
                # layer_json = res.serialize(None,
                #                            res.full_dehydrate(layer_bundle),
                #                            "application/json")
                # delete_layer.delay(instance=layer_json)
                result = delete_layer.delay(layer_id=layer.id)
                result.wait(10)
        except TimeoutError:
            # traceback.print_exc()
            pass
        except Exception as e:
            traceback.print_exc()
            message = '{0}: {1}.'.format(
                _('Unable to delete layer'), layer.alternate)

            if 'referenced by layer group' in getattr(e, 'message', ''):
                message = _(
                    'This layer is a member of a layer group, you must remove the layer from the group '
                    'before deleting.')

            messages.error(request, message)
            return render(
                request, template, context={"layer": layer})
        # MapStory Specific Change
        return HttpResponseRedirect(reverse("profile_detail", kwargs={'slug': layer.owner}))
        # End MapStory Specific Change
    else:
        return HttpResponse("Not allowed", status=403)
示例#18
0
def layer_style_upload(req, layername):
    def respond(*args,**kw):
        kw['content_type'] = 'text/html'
        return json_response(*args, **kw)
    form = LayerStyleUploadForm(req.POST, req.FILES)
    if not form.is_valid():
        return respond(errors="Please provide an SLD file.")
    
    data = form.cleaned_data
    layer = _resolve_layer(req, layername, 'base.change_resourcebase', _PERMISSION_MSG_MODIFY)
    
    sld = req.FILES['sld'].read()

    try:
        dom = etree.XML(sld)
    except Exception, ex:
        return respond(errors="The uploaded SLD file is not valid XML")
示例#19
0
def importrndt(request, template='mdtools/upload_metadata.html'):
    if request.method == 'POST':
        form = UploadMetadataFileForm(request.POST, request.FILES)
        if form.is_valid():
            layername = Layer.objects.get(pk=form.cleaned_data['layer']).typename
            layer = _resolve_layer(request, layername, 'base.change_layer', _PERMISSION_MSG_METADATA)
            rndt = request.FILES['file'].read()
            try:
                _savelayermd(layer, rndt, None)
                messages.add_message(request, messages.SUCCESS, 'Metadata Uploaded')
            except Exception as e:
                messages.add_message(request, messages.ERROR, e)

    else:
        form = UploadMetadataFileForm()
    return render_to_response(template,
                              RequestContext(request, {'form': form}))
示例#20
0
def importediml(request, template='mdtools/upload_metadata.html'):
    if request.method == 'POST':
        form = UploadMetadataFileForm(request.POST, request.FILES)
        if form.is_valid():
            layername = Layer.objects.get(pk=form.cleaned_data['layer']).typename
            layer = _resolve_layer(request, layername, 'base.change_layer', _PERMISSION_MSG_METADATA)
            ediml = request.FILES['file'].read()
            try:
                rndt = _ediml2rndt(ediml)
            except UnregisteredSKException, e:
                messages.add_message(request, messages.ERROR, e)
            if not rndt:
                messages.add_message(request, messages.ERROR, 'Cannot get RNDT.')
            try:
                _savelayermd(layer, rndt, ediml)
                messages.add_message(request, messages.SUCCESS, 'Metadata Uploaded')
            except Exception as e:
                messages.add_message(request, messages.ERROR, e)
示例#21
0
def layer_metadata_detail(request, layername,
                          template='layers/metadata_detail.html'):

    layer = _resolve_layer(request, layername, 'view_resourcebase',
                           _PERMISSION_MSG_METADATA)

    thumbnail_dir = os.path.join(settings.MEDIA_ROOT, 'thumbs')
    default_thumbnail_array = layer.get_thumbnail_url().split('/')
    default_thumbnail_name = default_thumbnail_array[
        len(default_thumbnail_array) - 1
    ]
    default_thumbnail = os.path.join(thumbnail_dir, default_thumbnail_name)

    if request.method == 'POST':
        thumb_form = ThumbnailImageForm(request.POST, request.FILES)
        if thumb_form.is_valid():
            new_img = ThumbnailImage(
                thumbnail_image=request.FILES['thumbnail_image']
            )
            new_img.save()
            user_upload_thumbnail = ThumbnailImage.objects.all()[0]
            user_upload_thumbnail_filepath = str(
                user_upload_thumbnail.thumbnail_image
            )

            # only create backup for original thumbnail
            if os.path.isfile(default_thumbnail + '.bak') is False:
                os.rename(default_thumbnail, default_thumbnail + '.bak')

            os.rename(user_upload_thumbnail_filepath, default_thumbnail)

            return HttpResponseRedirect(
                reverse('layer_metadata_detail', args=[layername])
            )
    else:
        thumb_form = ThumbnailImageForm()

    thumbnail = layer.get_thumbnail_url
    return render_to_response(template, RequestContext(request, {
        "layer": layer,
        'SITEURL': settings.SITEURL[:-1],
        "thumbnail": thumbnail,
        "thumb_form": thumb_form
    }))
示例#22
0
文件: api.py 项目: ABasoni/starterkit
def rndtproxy(request, layername):
    layer = _resolve_layer(request, layername, 'layers.change_layer', _PERMISSION_MSG_METADATA)

    service = settings.RITMARE['MDSERVICE'] + 'postMetadata'

    headers = {'api_key': get_key(),
               'Content-Type': 'application/xml',
               }

    r = requests.post(service, data=request.raw_post_data,  headers=headers, verify=False)
    if r.status_code == 200:
        rndt = r.text.encode('utf8')
        # extract fileid
        ediml = etree.fromstring(request.raw_post_data)
        fileid = ediml.find('fileId').text

        # new fileid must be equal to the old one
        if layer.mdextension.fileid is not None:
            if int(layer.mdextension.fileid) != int(fileid):
                return json_response(errors='New fileid (%s) is different from the old one (%s)' % (fileid, layer.mdextension.fileid), 
                                     status=500)
        else:
            layer.mdextension.fileid = fileid
    else:
        return json_response(errors='Cannot create RNDT', 
                             status=500)

    try:
        vals, keywords = rndt2dict(etree.fromstring(rndt))
        errors = _post_validate(vals)
        if len(errors) > 0:
            return json_response(exception=errors, status=500)
        _mdimport(layer, vals, keywords, rndt)
    except Exception as e:
        return json_response(exception=e, status=500)
        
    # save rndt & edi xml
    layer.mdextension.md_date = vals['md_language']
    layer.mdextension.md_date = vals['md_date']
    layer.mdextension.rndt_xml = rndt
    layer.mdextension.elements_xml = request.raw_post_data
    layer.mdextension.save()
    return json_response(body={'success':True,'redirect': reverse('layer_detail', args=(layer.typename,))})
示例#23
0
def get_project_definitions(request):
    """
    Given a layer name, read the corresponding project definitions from
    the layer's metadata and return them as a json

    :param request:
        A "GET" :class:`django.http.HttpRequest` object containing
        the following parameter:
            * 'layer_name': the layer identifier

    :return:
        A JSON containing the layer's project definitions
    """
    layer_name = request.GET.get('layer_name')
    if not layer_name:
        return HttpResponseBadRequest(
            'Please provide the layer_name parameter')
    try:
        layer = _resolve_layer(
            request, layer_name, 'layers.view_layer', _PERMISSION_MSG_VIEW)
    except PermissionDenied:
        return HttpResponse(
            'You are not allowed to view this layer',
            mimetype='text/plain',
            status=401)
    supplemental_information_str = layer.supplemental_information
    try:
        supplemental_information = json.loads(supplemental_information_str)
    except Exception as e:
        return HttpResponseBadRequest(
            "The layer's supplemental information is not in a valid"
            "json format: %s", str(e))
    if 'project_definitions' in supplemental_information:
        project_definitions = supplemental_information['project_definitions']
    else:
        # if this is an old project, the project definitions are not nested
        # into the 'project_definitions' key
        project_definitions = supplemental_information
    return HttpResponse(json.dumps(project_definitions,
                                   sort_keys=False,
                                   indent=2,
                                   separators=(',', ': ')),
                        content_type="application/json")
示例#24
0
def layer_style_upload(request, layername):
    def respond(*args, **kw):
        kw['content_type'] = 'text/html'
        return json_response(*args, **kw)
    form = LayerStyleUploadForm(request.POST, request.FILES)
    if not form.is_valid():
        return respond(errors="Please provide an SLD file.")

    data = form.cleaned_data
    layer = _resolve_layer(
        request,
        layername,
        'base.change_resourcebase',
        _PERMISSION_MSG_MODIFY)

    sld = request.FILES['sld'].read()
    sld_name = None
    try:
        # Check SLD is valid
        try:
            if sld:
                if isfile(sld):
                    sld = open(sld, "r").read()
                etree.XML(sld)
        except Exception:
            logger.exception("The uploaded SLD file is not valid XML")
            raise Exception(
                "The uploaded SLD file is not valid XML")

        sld_name = extract_name_from_sld(
            gs_catalog, sld, sld_file=request.FILES['sld'])
    except Exception as e:
        respond(errors="The uploaded SLD file is not valid XML: {}".format(e))

    name = data.get('name') or sld_name

    set_layer_style(layer, data.get('title') or name, sld)

    return respond(
        body={
            'success': True,
            'style': data.get('title') or name,
            'updated': data['update']})
示例#25
0
文件: views.py 项目: giohappy/geonode
def layer_searchable_fields(
        request,
        layername):
    """
    Manage the layer in the gazetteer.
    """

    layer = _resolve_layer(
        request,
        layername,
        'base.change_resourcebase_metadata',
        'permissions message from searchable layers')

    status_message = None
    if request.method == 'POST':
        attributes_list = request.POST.getlist('attributes')
        status_message = ''
        for attribute in layer.attributes:
            ext_att, created = ExtLayerAttribute.objects.get_or_create(attribute=attribute)
            ext_att.searchable = False
            if attribute.attribute in attributes_list and attribute.attribute_type == 'xsd:string':
                ext_att.searchable = True
                status_message += ' %s' % attribute.attribute
            ext_att.save()

    searchable_attributes = []
    for attribute in layer.attributes:
        if attribute.attribute_type == 'xsd:string':
            if hasattr(attribute, 'extlayerattribute'):
                attribute.searchable = attribute.extlayerattribute.searchable
            else:
                attribute.searchable = False
            searchable_attributes.append(attribute)

    template = 'wm_extra/layers/edit_searchable_fields.html'

    return render(request, template, {
        "layer": layer,
        "searchable_attributes": searchable_attributes,
        "status_message": status_message,
    })
示例#26
0
文件: views.py 项目: lhcramer/geonode
def layer_style_upload(request, layername):
    def respond(*args, **kw):
        kw['content_type'] = 'text/html'
        return json_response(*args, **kw)
    form = LayerStyleUploadForm(request.POST, request.FILES)
    if not form.is_valid():
        return respond(errors="Please provide an SLD file.")

    data = form.cleaned_data
    layer = _resolve_layer(
        request,
        layername,
        'base.change_resourcebase',
        _PERMISSION_MSG_MODIFY)

    sld = request.FILES['sld'].read()
    sld_name = None
    try:
        # Check SLD is valid
        sld_name = extract_name_from_sld(gs_catalog, sld, sld_file=request.FILES['sld'])
    except Exception, e:
        respond(errors="The uploaded SLD file is not valid XML: {}".format(e))
示例#27
0
文件: views.py 项目: GavinDu/geonode
def layer_style_manage(request, layername):

    layer = _resolve_layer(
        request,
        layername,
        'layers.change_layer_style',
        _PERMISSION_MSG_MODIFY)

    if request.method == 'GET':
        try:
            cat = gs_catalog

            # First update the layer style info from GS to GeoNode's DB
            # The try/except is
            try:
                set_styles(layer, cat)
            except AttributeError:
                logger.warn(
                    'Unable to set the default style.  Ensure Geoserver is running and that this layer exists.')

            all_available_gs_styles = cat.get_styles()
            gs_styles = []
            for style in all_available_gs_styles:
                gs_styles.append((style.name, style.sld_title))

            current_layer_styles = layer.styles.all()
            layer_styles = []
            for style in current_layer_styles:
                layer_styles.append((style.name, style.sld_title))

            # Render the form
            return render_to_response(
                'layers/layer_style_manage.html',
                RequestContext(request, {
                    "layer": layer,
                    "gs_styles": gs_styles,
                    "layer_styles": layer_styles,
                    "default_style": (layer.default_style.name, layer.default_style.sld_title)
                }
                )
            )
        except (FailedRequestError, EnvironmentError) as e:
            msg = ('Could not connect to geoserver at "%s"'
                   'to manage style information for layer "%s"' % (
                       ogc_server_settings.LOCATION, layer.name)
                   )
            logger.warn(msg, e)
            # If geoserver is not online, return an error
            return render_to_response(
                'layers/layer_style_manage.html',
                RequestContext(request, {
                    "layer": layer,
                    "error": msg
                }
                )
            )
    elif request.method == 'POST':
        try:
            selected_styles = request.POST.getlist('style-select')
            default_style = request.POST['default_style']
            # Save to GeoServer
            cat = gs_catalog
            gs_layer = cat.get_layer(layer.name)
            gs_layer.default_style = default_style
            styles = []
            for style in selected_styles:
                styles.append(style)
            gs_layer.styles = styles
            cat.save(gs_layer)

            # Save to Django
            layer = set_styles(layer, cat)
            layer.save()
            return HttpResponseRedirect(
                reverse(
                    'layer_detail',
                    args=(
                        layer.service_typename,
                    )))
        except (FailedRequestError, EnvironmentError, MultiValueDictKeyError) as e:
            msg = ('Error Saving Styles for Layer "%s"' % (layer.name)
                   )
            logger.warn(msg, e)
            return render_to_response(
                'layers/layer_style_manage.html',
                RequestContext(request, {
                    "layer": layer,
                    "error": msg
                }
                )
            )
示例#28
0
def layer_metadata(request,
                   layername,
                   template='upload/layer_upload_metadata.html'):
    layer = _resolve_layer(request, layername,
                           'base.change_resourcebase_metadata',
                           _PERMISSION_MSG_METADATA)
    topic_category = layer.category

    poc = layer.poc or layer.owner
    metadata_author = layer.metadata_author

    if request.method == "POST":
        layer_form = UploadLayerForm(request.POST,
                                     instance=layer,
                                     prefix="resource")
        category_form = CategoryForm(
            request.POST,
            prefix="category_choice_field",
            initial=int(request.POST["category_choice_field"])
            if "category_choice_field" in request.POST else None)
    else:
        layer_form = UploadLayerForm(instance=layer, prefix="resource")
        category_form = CategoryForm(
            prefix="category_choice_field",
            initial=topic_category.id if topic_category else None)

    if request.method == "POST" and layer_form.is_valid(
    ) and category_form.is_valid():
        new_poc = layer_form.cleaned_data['poc']
        new_author = layer_form.cleaned_data['metadata_author']
        new_keywords = layer_form.cleaned_data['keywords']

        if new_poc is None:
            if poc is None:
                poc_form = ProfileForm(request.POST,
                                       prefix="poc",
                                       instance=poc)
            else:
                poc_form = ProfileForm(request.POST, prefix="poc")
            if poc_form.has_changed and poc_form.is_valid():
                new_poc = poc_form.save()

        else:
            if not isinstance(new_poc, Profile):
                new_poc = Profile.objects.get(id=new_poc)

        if new_author is None:
            if metadata_author is None:
                author_form = ProfileForm(request.POST,
                                          prefix="author",
                                          instance=metadata_author)
            else:
                author_form = ProfileForm(request.POST, prefix="author")
            if author_form.has_changed and author_form.is_valid():
                new_author = author_form.save()

        else:
            if not isinstance(new_author, Profile):
                new_author = Profile.objects.get(id=new_author)

        new_category = TopicCategory.objects.get(
            id=category_form.cleaned_data['category_choice_field'])

        if new_poc is not None and new_author is not None:
            new_keywords = layer_form.cleaned_data['keywords']
            layer.keywords.clear()
            layer.keywords.add(*new_keywords)
            the_layer = layer_form.save()
            the_layer.poc = new_poc
            the_layer.metadata_author = new_author
            Layer.objects.filter(id=the_layer.id).update(category=new_category)

            return HttpResponseRedirect(
                reverse('layer_detail', args=(layer.service_typename, )))

    if poc is None:
        poc_form = ProfileForm(instance=poc, prefix="poc")
    else:
        layer_form.fields['poc'].initial = poc.id
        poc_form = ProfileForm(prefix="poc")
        poc_form.hidden = True

    if metadata_author is None:
        author_form = ProfileForm(instance=metadata_author, prefix="author")
    else:
        layer_form.fields['metadata_author'].initial = metadata_author.id
        author_form = ProfileForm(prefix="author")
        author_form.hidden = True

    return render_to_response(
        template,
        RequestContext(
            request, {
                "layer": layer,
                "layer_form": layer_form,
                "poc_form": poc_form,
                "author_form": author_form,
                "category_form": category_form,
            }))
示例#29
0
文件: views.py 项目: rbs-pli/geonode
def new_map_config(request):
    '''
    View that creates a new map.

    If the query argument 'copy' is given, the initial map is
    a copy of the map with the id specified, otherwise the
    default map configuration is used.  If copy is specified
    and the map specified does not exist a 404 is returned.
    '''
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config()

    if request.method == 'GET' and 'copy' in request.GET:
        mapid = request.GET['copy']
        if not mapid.isdigit():
            map_obj = _resolve_map_custom(request, mapid, 'urlsuffix',
                                          'base.view_resourcebase')
        else:
            map_obj = _resolve_map(request, mapid, 'base.view_resourcebase')

        map_obj.abstract = DEFAULT_ABSTRACT
        map_obj.title = DEFAULT_TITLE
        if request.user.is_authenticated(): map_obj.owner = request.user
        config = map_obj.viewer_json(request.user)
        del config['id']
    else:
        if request.method == 'GET':
            params = request.GET
        elif request.method == 'POST':
            params = request.POST
        else:
            return HttpResponse(status=405)

        if 'layer' in params:
            bbox = None
            map_obj = Map(projection="EPSG:900913")
            layers = []
            for layer_name in params.getlist('layer'):
                try:
                    layer = _resolve_layer(request, layer_name)
                except ObjectDoesNotExist:
                    # bad layer, skip
                    continue

                if not request.user.has_perm('view_resourcebase',
                                             obj=layer.get_self_resource()):
                    # invisible layer, skip inclusion
                    continue

                layer_bbox = layer.bbox
                # assert False, str(layer_bbox)
                if bbox is None:
                    bbox = list(layer_bbox[0:4])
                else:
                    bbox[0] = min(bbox[0], layer_bbox[0])
                    bbox[1] = max(bbox[1], layer_bbox[1])
                    bbox[2] = min(bbox[2], layer_bbox[2])
                    bbox[3] = max(bbox[3], layer_bbox[3])

                config = layer.attribute_config()

                #Add required parameters for GXP lazy-loading
                config["srs"] = layer.srid
                config["title"] = layer.title
                config["bbox"] =  [float(coord) for coord in bbox] \
                    if layer.srid == "EPSG:4326" else llbbox_to_mercator([float(coord) for coord in bbox])
                config["queryable"] = True

                if layer.storeType == "remoteStore":
                    service = layer.service
                    maplayer = MapLayer(map=map_obj,
                                        name=layer.typename,
                                        ows_url=layer.ows_url,
                                        layer_params=json.dumps(config),
                                        visibility=True,
                                        source_params=json.dumps({
                                            "ptype":
                                            service.ptype,
                                            "remote":
                                            True,
                                            "url":
                                            service.base_url,
                                            "name":
                                            service.name
                                        }))
                else:
                    maplayer = MapLayer(map=map_obj,
                                        name=layer.typename,
                                        ows_url=layer.ows_url,
                                        layer_params=json.dumps(config),
                                        visibility=True)

                layers.append(maplayer)

            if bbox is not None:
                minx, miny, maxx, maxy = [float(c) for c in bbox]
                x = (minx + maxx) / 2
                y = (miny + maxy) / 2

                center = list(forward_mercator((x, y)))
                if center[1] == float('-inf'):
                    center[1] = 0

                BBOX_DIFFERENCE_THRESHOLD = 1e-5

                #Check if the bbox is invalid
                valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD
                valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD

                if valid_x:
                    width_zoom = math.log(360 / abs(maxx - minx), 2)
                else:
                    width_zoom = 15

                if valid_y:
                    height_zoom = math.log(360 / abs(maxy - miny), 2)
                else:
                    height_zoom = 15

                map_obj.center_x = center[0]
                map_obj.center_y = center[1]
                map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

            config = map_obj.viewer_json(request.user,
                                         *(DEFAULT_BASE_LAYERS + layers))
            config['fromLayer'] = True
        else:
            config = DEFAULT_MAP_CONFIG
    return json.dumps(config)
示例#30
0
def layer_metadata(request,
                   layername,
                   template='layers/site_layers_metadata.html'):
    """
    Override original layer's metadata view for adding translations
    """

    layer = _resolve_layer(request, layername,
                           'base.change_resourcebase_metadata',
                           _PERMISSION_MSG_METADATA)
    layer_attribute_set = inlineformset_factory(
        Layer,
        Attribute,
        extra=0,
        form=LayerAttributeForm,
    )
    topic_category = layer.category

    poc = layer.poc
    metadata_author = layer.metadata_author

    internationalize_fields()
    change_abstract(layer)

    if request.method == "POST":
        if layer.metadata_uploaded_preserve:  # layer metadata cannot be edited
            out = {
                'success': False,
                'errors': METADATA_UPLOADED_PRESERVE_ERROR
            }
            return HttpResponse(json.dumps(out),
                                content_type='application/json',
                                status=400)

        layer_form = LayerForm(request.POST, instance=layer, prefix="resource")

        attribute_form = layer_attribute_set(
            request.POST,
            instance=layer,
            prefix="layer_attribute_set",
            queryset=Attribute.objects.order_by('display_order'))
        category_form = CategoryForm(
            request.POST,
            prefix="category_choice_field",
            initial=int(request.POST["category_choice_field"])
            if "category_choice_field" in request.POST else None)

    else:
        layer_form = LayerForm(instance=layer, prefix="resource")
        attribute_form = layer_attribute_set(
            instance=layer,
            prefix="layer_attribute_set",
            queryset=Attribute.objects.order_by('display_order'))
        category_form = CategoryForm(
            prefix="category_choice_field",
            initial=topic_category.id if topic_category else None)

    if request.method == "POST" and layer_form.is_valid(
    ) and attribute_form.is_valid() and category_form.is_valid():
        new_poc = layer_form.cleaned_data['poc']
        new_author = layer_form.cleaned_data['metadata_author']

        if new_poc is None:
            if poc is None:
                poc_form = ProfileForm(request.POST,
                                       prefix="poc",
                                       instance=poc)
            else:
                poc_form = ProfileForm(request.POST, prefix="poc")
            if poc_form.is_valid():
                if len(poc_form.cleaned_data['profile']) == 0:
                    # FIXME use form.add_error in django > 1.7
                    errors = poc_form._errors.setdefault(
                        'profile', ErrorList())
                    errors.append(
                        _('You must set a point of contact for this resource'))
                    poc = None
            if poc_form.has_changed and poc_form.is_valid():
                new_poc = poc_form.save()

        if new_author is None:
            if metadata_author is None:
                author_form = ProfileForm(request.POST,
                                          prefix="author",
                                          instance=metadata_author)
            else:
                author_form = ProfileForm(request.POST, prefix="author")
            if author_form.is_valid():
                if len(author_form.cleaned_data['profile']) == 0:
                    # FIXME use form.add_error in django > 1.7
                    errors = author_form._errors.setdefault(
                        'profile', ErrorList())
                    errors.append(
                        _('You must set an author for this resource'))
                    metadata_author = None
            if author_form.has_changed and author_form.is_valid():
                new_author = author_form.save()

        new_category = TopicCategory.objects.get(
            id=category_form.cleaned_data['category_choice_field'])

        for form in attribute_form.cleaned_data:
            la = Attribute.objects.get(id=int(form['id'].id))
            la.description = form["description"]
            la.attribute_label = form["attribute_label"]
            la.visible = form["visible"]
            la.display_order = form["display_order"]
            la.save()

        if new_poc is not None and new_author is not None:
            new_keywords = [
                x.strip() for x in layer_form.cleaned_data['keywords']
            ]
            layer.keywords.clear()
            layer.keywords.add(*new_keywords)
            the_layer = layer_form.save()
            up_sessions = UploadSession.objects.filter(layer=the_layer.id)
            if up_sessions.count(
            ) > 0 and up_sessions[0].user != the_layer.owner:
                up_sessions.update(user=the_layer.owner)
            the_layer.poc = new_poc
            the_layer.metadata_author = new_author
            Layer.objects.filter(id=the_layer.id).update(category=new_category)

            if getattr(settings, 'SLACK_ENABLED', False):
                try:
                    from geonode.contrib.slack.utils import build_slack_message_layer, send_slack_messages
                    send_slack_messages(
                        build_slack_message_layer("layer_edit", the_layer))
                except:
                    print "Could not send slack message."

            return HttpResponseRedirect(
                reverse('layer_detail', args=(layer.service_typename, )))

    if poc is not None:
        layer_form.fields['poc'].initial = poc.id
        poc_form = ProfileForm(prefix="poc")
        poc_form.hidden = True
    else:
        poc_form = ProfileForm(prefix="poc")
        poc_form.hidden = False

    if metadata_author is not None:
        layer_form.fields['metadata_author'].initial = metadata_author.id
        author_form = ProfileForm(prefix="author")
        author_form.hidden = True
    else:
        author_form = ProfileForm(prefix="author")
        author_form.hidden = False

    return render_to_response(
        template,
        RequestContext(
            request, {
                "layer": layer,
                "layer_form": layer_form,
                "poc_form": poc_form,
                "author_form": author_form,
                "attribute_form": attribute_form,
                "category_form": category_form,
            }))
示例#31
0
def layer_detail(request, layername, template='layers/layer_detail.html'):
    layer = _resolve_layer(request, layername, 'base.view_resourcebase',
                           _("You are not permitted to view this layer"))

    # assert False, str(layer_bbox)
    config = layer.attribute_config()

    # Add required parameters for GXP lazy-loading
    layer_bbox = layer.bbox
    bbox = [float(coord) for coord in list(layer_bbox[0:4])]
    config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')
    config["bbox"] = bbox if config["srs"] != 'EPSG:900913' \
        else llbbox_to_mercator([float(coord) for coord in bbox])
    config["title"] = layer.title
    config["queryable"] = True
    if layer.default_style:
        config["styles"] = layer.default_style.name

    if layer.storeType == "remoteStore":
        source_srid = None
        # Only grab the service proj/bbox if it is valid
        if None not in layer.service.bbox[0:4]:
            bbox = [float(coord) for coord in list(layer.service.bbox[0:4])]
            source_srid = layer.service.srid
        # Otherwise try the service directly
        # This is needed since previous services registered
        # did not store the bbox/srid in the model
        else:
            try:
                service_handler = get_service_handler(
                    base_url=layer.service.base_url,
                    service_type=layer.service.type)
                if getattr(service_handler.parsed_service, 'initialExtent',
                           None):
                    bbox[0] = service_handler.parsed_service.initialExtent[
                        'xmin']
                    bbox[1] = service_handler.parsed_service.initialExtent[
                        'ymin']
                    bbox[2] = service_handler.parsed_service.initialExtent[
                        'xmax']
                    bbox[3] = service_handler.parsed_service.initialExtent[
                        'ymax']
                else:
                    logger.info(
                        'Could not retrieve extent from service: {0}'.format(
                            layer.service))
                if getattr(service_handler.parsed_service, 'spatialReference',
                           None):
                    source_srid = \
                        service_handler.parsed_service.spatialReference[
                            'latestWkid']
                else:
                    logger.info(
                        'Could not retrieve srid from service: {0}'.format(
                            layer.service))
            except Exception as e:
                logger.info('Failed to access service endpoint: {0}'.format(
                    layer.service.base_url))
                logger.info('Caught error: {0}'.format(e))
        if source_srid is None:
            source_srid = layer.srid
        target_srid = 3857 if config["srs"] == 'EPSG:900913' else config["srs"]
        reprojected_bbox = bbox_to_projection(bbox,
                                              source_srid=source_srid,
                                              target_srid=target_srid)
        bbox = reprojected_bbox[:4]
        config['bbox'] = [float(coord) for coord in bbox]
        service = layer.service
        source_url = service.base_url
        use_proxy = (callable(uses_proxy_route)
                     and uses_proxy_route(service.base_url))
        components = urlsplit(service.base_url)
        query_params = None
        if components.query:
            query_params = OrderedDict(
                parse_qsl(components.query, keep_blank_values=True))
            removed_query = [
                components.scheme, components.netloc, components.path, None,
                components.fragment
            ]
            source_url = urlunsplit(removed_query)
        source_params = {
            "ptype": service.ptype,
            "remote": True,
            "url": source_url,
            "name": service.name,
            "use_proxy": use_proxy
        }
        if query_params is not None:
            source_params["params"] = query_params
        if layer.alternate is not None:
            config["layerid"] = layer.alternate
        maplayer = GXPLayer(name=layer.typename,
                            ows_url=layer.ows_url,
                            layer_params=json.dumps(config),
                            source_params=json.dumps(source_params))
    else:
        maplayer = GXPLayer(name=layer.typename,
                            ows_url=layer.ows_url,
                            layer_params=json.dumps(config))

    # Update count for popularity ranking,
    # but do not includes admins or resource owners
    if request.user != layer.owner and not request.user.is_superuser:
        Layer.objects.filter(id=layer.id).update(
            popular_count=F('popular_count') + 1)

    # center/zoom don't matter; the viewer will center on the layer bounds
    map_obj = GXPMap(
        projection=getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913'))

    metadata = layer.link_set.metadata().filter(
        name__in=settings.DOWNLOAD_FORMATS_METADATA)

    granules = None
    all_granules = None
    filter = None
    if layer.is_mosaic:
        try:
            cat = gs_catalog
            cat._cache.clear()
            store = cat.get_store(layer.name)
            coverages = cat.mosaic_coverages(store)

            filter = None
            try:
                if request.GET["filter"]:
                    filter = request.GET["filter"]
            except:
                pass

            offset = 10 * (request.page - 1)
            granules = cat.mosaic_granules(
                coverages['coverages']['coverage'][0]['name'],
                store,
                limit=10,
                offset=offset,
                filter=filter)
            all_granules = cat.mosaic_granules(
                coverages['coverages']['coverage'][0]['name'],
                store,
                filter=filter)
        except:
            granules = {"features": []}
            all_granules = {"features": []}

    context_dict = {
        "resource": layer,
        'perms_list': get_perms(request.user, layer.get_self_resource()),
        "permissions_json": _perms_info_json(layer),
        "documents": get_related_documents(layer),
        "metadata": metadata,
        "is_layer": True,
        "wps_enabled": settings.OGC_SERVER['default']['WPS_ENABLED'],
        "granules": granules,
        "all_granules": all_granules,
        "filter": filter,
    }

    if 'access_token' in request.session:
        access_token = request.session['access_token']
    else:
        u = uuid.uuid1()
        access_token = u.hex

    if bbox is not None:
        minx, miny, maxx, maxy = [float(coord) for coord in bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2

        if layer.is_remote or getattr(settings, 'DEFAULT_MAP_CRS',
                                      'EPSG:900913') == "EPSG:4326":
            center = list((x, y))
        else:
            center = list(forward_mercator((x, y)))

        if center[1] == float('-inf'):
            center[1] = 0

        BBOX_DIFFERENCE_THRESHOLD = 1e-5

        # Check if the bbox is invalid
        valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD
        valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD

        if valid_x:
            width_zoom = math.log(360 / abs(maxx - minx), 2)
        else:
            width_zoom = 15

        if valid_y:
            height_zoom = math.log(360 / abs(maxy - miny), 2)
        else:
            height_zoom = 15

        map_obj.center_x = center[0]
        map_obj.center_y = center[1]
        map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

    context_dict["viewer"] = json.dumps(
        map_obj.viewer_json(request.user, access_token,
                            *(default_map_config(request)[1] + [maplayer])))

    context_dict["preview"] = getattr(settings, 'LAYER_PREVIEW_LIBRARY',
                                      'leaflet')
    context_dict["crs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')

    if layer.storeType == 'dataStore':
        links = layer.link_set.download().filter(
            name__in=settings.DOWNLOAD_FORMATS_VECTOR)
    else:
        links = layer.link_set.download().filter(
            name__in=settings.DOWNLOAD_FORMATS_RASTER)
    links_view = [
        item for idx, item in enumerate(links)
        if item.url and 'wms' in item.url or 'gwc' in item.url
    ]
    links_download = [
        item for idx, item in enumerate(links)
        if item.url and 'wms' not in item.url and 'gwc' not in item.url
    ]
    for item in links_view:
        if item.url and access_token:
            item.url = "%s&access_token=%s&time=%s" % \
                       (item.url, access_token, "0/9999")
    for item in links_download:
        if item.url and access_token:
            item.url = "%s&access_token=%s" % (item.url, access_token)

    if request.user.has_perm('view_resourcebase', layer.get_self_resource()):
        context_dict["links"] = links_view
    if request.user.has_perm('download_resourcebase',
                             layer.get_self_resource()):
        if layer.storeType == 'dataStore':
            links = layer.link_set.download().filter(
                name__in=settings.DOWNLOAD_FORMATS_VECTOR)
        else:
            links = layer.link_set.download().filter(
                name__in=settings.DOWNLOAD_FORMATS_RASTER)
        context_dict["links_download"] = links_download

    if settings.SOCIAL_ORIGINS:
        context_dict["social_links"] = build_social_links(request, layer)

    return render_to_response(template, RequestContext(request, context_dict))
示例#32
0
def rndt(request, layername):
    layer = _resolve_layer(request, layername, 'layers.view_layer',
                           _PERMISSION_MSG_METADATA)
    rndt = layer.mdextension.rndt_xml
    return HttpResponse(rndt, mimetype="text/xml")
示例#33
0
def ediml(request, layername):
    layer = _resolve_layer(request, layername, 'layers.view_layer',
                           _PERMISSION_MSG_METADATA)
    ediml = layer.mdextension.elements_xml
    return HttpResponse(ediml, mimetype="text/xml")
示例#34
0
def clip_layer(request, layername):
    """Clipping raster layer and save to temp folder.
    Clipping layer by bbox or by geojson.
    :param layername: The layer name in Geonode.
    :type layername: basestring
    :return: file size
    """
    # PREPARATION
    try:
        layer = _resolve_layer(request, layername, 'base.view_resourcebase',
                               _PERMISSION_MSG_VIEW)
    except Http404 as e:
        response = JsonResponse({
            'error':
            '%s. '
            'Please do '
            '<i>python manage.py updatelayers</i> '
            'to retrieve it from geoserver.' % e
        })
        response.status_code = 404
        return response

    download_from_wcs = False

    query = request.GET or request.POST
    params = {param.upper(): value for param, value in query.iteritems()}
    bbox_string = params.get('BBOX', '')
    geojson = params.get('GEOJSON', '')
    current_date = datetime.datetime.today().strftime('%Y-%m-%d_%H-%M-%S')

    # create temp folder
    temporary_folder = os.path.join(tempfile.gettempdir(), 'clipped')
    try:
        os.mkdir(temporary_folder)
    except OSError as e:
        pass

    # get file for raster
    raster_filepath = None
    extention = ''

    # get file for raster
    try:
        if not raster_filepath:
            file_names = []
            for layerfile in layer.upload_session.layerfile_set.all():
                file_names.append(layerfile.file.path)

            for target_file in file_names:
                if '.tif' in target_file:
                    raster_filepath = target_file
                    extention = 'tif'
                    break
        bbox_array = bbox_string.split(',')
        southwest_lat = bbox_array[1]
        bbox_array[1] = bbox_array[3]
        bbox_array[3] = southwest_lat
        bbox_string = ','.join(bbox_array)
    except AttributeError:
        # Call wcs command
        bbox_array = bbox_string.split(',')
        offset = 50
        x = float(bbox_array[2]) - float(bbox_array[0])
        width = int(x * 43260) + offset

        y = float(bbox_array[3]) - float(bbox_array[1])
        height = int(y * 43260) + offset

        width = int(width * settings.WCS_DOWNLOADED_RATIO_SIZE)
        height = int(height * settings.WCS_DOWNLOADED_RATIO_SIZE)

        extention = 'tif'

        # checking file size of wcs download
        # it is done by assumption by getting sample
        # 1. getting part 10x10 through wcs
        # 2. get the filesize
        # 3. times filesize by width/10 * height/10, as assumption for actual filesize
        # -------------------------------------------------
        number_tile_in_width = int(width / TILE_SAMPLE_SIZE)
        number_tile_in_height = int(height / TILE_SAMPLE_SIZE)

        sample_filepath = os.path.join(temporary_folder,
                                       layer.title + '.sample.' + extention)
        download_wcs(layername, bbox_string, TILE_SAMPLE_SIZE,
                     TILE_SAMPLE_SIZE, sample_filepath)

        expected_clip_size = os.path.getsize(sample_filepath)
        # size of 10x10 times width_sample * height_sample
        expected_clip_size = expected_clip_size * (number_tile_in_width *
                                                   number_tile_in_height)

        if not check_file_size(expected_clip_size):
            response = JsonResponse({
                'error':
                'Clipped file size is '
                'bigger than %s mb' % (int(MAX_CLIP_SIZE) / 1000000)
            })
            response.status_code = 403
            return response

        # -------------------------------------------------

        # download actual wcs clipped
        raster_filepath = os.path.join(temporary_folder,
                                       layer.title + '.' + extention)
        x1, x2 = bbox_array[0], bbox_array[2]
        y1, y2 = bbox_array[1], bbox_array[3]
        inProj = Proj(init='epsg:4326')
        outProj = Proj(init='epsg:32618')

        x1, y1 = transform(inProj, outProj, x1, y1)
        x2, y2 = transform(inProj, outProj, x2, y2)

        download_wcs_v2(layername, x1, x2, y1, y2, raster_filepath)

        if not geojson:
            response = JsonResponse({
                'success':
                'Successfully clipping layer',
                'clip_filename':
                os.path.basename(raster_filepath)
            })
            response.status_code = 200
            return response

        download_from_wcs = True

    # get temp filename for output
    filename = os.path.basename(raster_filepath)
    if len(filename.split('.')) >= 3:
        filename = filename.split('.')[0]
    clip_filename = filename + '.' + current_date + '.' + extention

    if bbox_string and not download_from_wcs and not geojson:
        output = os.path.join(temporary_folder, clip_filename)
        clipping = ('gdal_translate -projwin ' +
                    '%(CLIP)s %(PROJECT)s %(OUTPUT)s')
        request_process = clipping % {
            'CLIP': bbox_string.replace(',', ' '),
            'PROJECT': raster_filepath,
            'OUTPUT': output,
        }
    elif geojson:
        output = os.path.join(temporary_folder, clip_filename)
        mask_file = os.path.join(temporary_folder,
                                 filename + '.' + current_date + '.geojson')
        _file = open(mask_file, 'w+')
        _file.write(geojson)
        _file.close()

        masking = ("gdalwarp -dstnodata 0 -q -cutline '%(MASK)s' " +
                   "-crop_to_cutline " + "-dstalpha -of " +
                   "GTiff '%(PROJECT)s' '%(OUTPUT)s'")
        request_process = masking % {
            'MASK': mask_file,
            'PROJECT': raster_filepath,
            'OUTPUT': output,
        }
    else:
        raise Http404('No bbox or geojson in parameters.')

    # generate if output is not created
    if not os.path.exists(output):
        if raster_filepath:
            subprocess.call(request_process, shell=True)

    if os.path.exists(output):
        # Check size
        clipped_size = os.path.getsize(output)

        if not check_file_size(clipped_size):
            response = JsonResponse({
                'error':
                'Clipped file size is '
                'bigger than %s mb' % (int(MAX_CLIP_SIZE) / 1000000)
            })
            response.status_code = 403
            return response

        response = JsonResponse({
            'success': 'Successfully clipping layer',
            'clip_filename': clip_filename
        })
        response.status_code = 200
        return response
    else:
        raise Http404('Project can not be clipped or masked.')
示例#35
0
def new_map_config(request):
    '''
    View that creates a new map.

    If the query argument 'copy' is given, the initial map is
    a copy of the map with the id specified, otherwise the
    default map configuration is used.  If copy is specified
    and the map specified does not exist a 404 is returned.
    '''
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request)

    if 'access_token' in request.session:
        access_token = request.session['access_token']
    else:
        access_token = None

    if request.method == 'GET' and 'copy' in request.GET:
        mapid = request.GET['copy']
        map_obj = _resolve_map(request, mapid, 'base.view_resourcebase')

        map_obj.abstract = DEFAULT_ABSTRACT
        map_obj.title = DEFAULT_TITLE
        if request.user.is_authenticated():
            map_obj.owner = request.user

        config = map_obj.viewer_json(request.user, access_token)
        del config['id']
    else:
        if request.method == 'GET':
            params = request.GET
        elif request.method == 'POST':
            params = request.POST
        else:
            return HttpResponse(status=405)

        if 'layer' in params:
            bbox = None
            map_obj = Map(projection=getattr(settings, 'DEFAULT_MAP_CRS',
                          'EPSG:900913'))
            layers = []
            for layer_name in params.getlist('layer'):
                try:
                    layer = _resolve_layer(request, layer_name)
                except ObjectDoesNotExist:
                    # bad layer, skip
                    continue

                if not request.user.has_perm(
                        'view_resourcebase',
                        obj=layer.get_self_resource()):
                    # invisible layer, skip inclusion
                    continue

                layer_bbox = layer.bbox
                # assert False, str(layer_bbox)
                if bbox is None:
                    bbox = list(layer_bbox[0:4])
                else:
                    bbox[0] = min(bbox[0], layer_bbox[0])
                    bbox[1] = max(bbox[1], layer_bbox[1])
                    bbox[2] = min(bbox[2], layer_bbox[2])
                    bbox[3] = max(bbox[3], layer_bbox[3])

                config = layer.attribute_config()

                # Add required parameters for GXP lazy-loading
                config["title"] = layer.title
                config["queryable"] = True

                config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')
                config["bbox"] = bbox if config["srs"] != 'EPSG:900913' \
                    else llbbox_to_mercator([float(coord) for coord in bbox])

                if layer.storeType == "remoteStore":
                    service = layer.service
                    # Probably not a good idea to send the access token to every remote service.
                    # This should never match, so no access token should be sent to remote services.
                    ogc_server_url = urlparse.urlsplit(ogc_server_settings.PUBLIC_LOCATION).netloc
                    service_url = urlparse.urlsplit(service.base_url).netloc

                    if access_token and ogc_server_url == service_url and 'access_token' not in service.base_url:
                        url = service.base_url+'?access_token='+access_token
                    else:
                        url = service.base_url
                    maplayer = MapLayer(map=map_obj,
                                        name=layer.typename,
                                        ows_url=layer.ows_url,
                                        layer_params=json.dumps(config),
                                        visibility=True,
                                        source_params=json.dumps({
                                            "ptype": service.ptype,
                                            "remote": True,
                                            "url": url,
                                            "name": service.name}))
                else:
                    ogc_server_url = urlparse.urlsplit(ogc_server_settings.PUBLIC_LOCATION).netloc
                    layer_url = urlparse.urlsplit(layer.ows_url).netloc

                    if access_token and ogc_server_url == layer_url and 'access_token' not in layer.ows_url:
                        url = layer.ows_url+'?access_token='+access_token
                    else:
                        url = layer.ows_url
                    maplayer = MapLayer(
                        map=map_obj,
                        name=layer.typename,
                        ows_url=url,
                        # use DjangoJSONEncoder to handle Decimal values
                        layer_params=json.dumps(config, cls=DjangoJSONEncoder),
                        visibility=True
                    )

                layers.append(maplayer)

            if bbox is not None:
                minx, miny, maxx, maxy = [float(c) for c in bbox]
                x = (minx + maxx) / 2
                y = (miny + maxy) / 2

                if getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913') == "EPSG:4326":
                    center = list((x, y))
                else:
                    center = list(forward_mercator((x, y)))

                if center[1] == float('-inf'):
                    center[1] = 0

                BBOX_DIFFERENCE_THRESHOLD = 1e-5

                # Check if the bbox is invalid
                valid_x = (maxx - minx) ** 2 > BBOX_DIFFERENCE_THRESHOLD
                valid_y = (maxy - miny) ** 2 > BBOX_DIFFERENCE_THRESHOLD

                if valid_x:
                    width_zoom = math.log(360 / abs(maxx - minx), 2)
                else:
                    width_zoom = 15

                if valid_y:
                    height_zoom = math.log(360 / abs(maxy - miny), 2)
                else:
                    height_zoom = 15

                map_obj.center_x = center[0]
                map_obj.center_y = center[1]
                map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

            config = map_obj.viewer_json(
                request.user, access_token, *(DEFAULT_BASE_LAYERS + layers))
            config['fromLayer'] = True
        else:
            config = DEFAULT_MAP_CONFIG
    return json.dumps(config)
示例#36
0
def layer_detail(request, layername, template='layers/layer_detail.html'):
    layer = _resolve_layer(request, layername, 'base.view_resourcebase',
                           _PERMISSION_MSG_VIEW)
    # assert False, str(layer_bbox)
    config = layer.attribute_config()

    # only owners and admins can view unpublished layers
    if not layer.is_published:
        if request.user != layer.owner and not request.user.is_superuser:
            return HttpResponse(_PERMISSION_MSG_VIEW,
                                status=403,
                                content_type="text/plain")

    # TODO (Mapstory): This has been commented out to force the client to make a getCapabilities request in order
    # to pull in the time dimension data.  Ideally we would cache time data just like the srs and bbox data to prevent
    # making the getCapabilities request.

    # Add required parameters for GXP lazy-loading
    #layer_bbox = layer.bbox
    #bbox = [float(coord) for coord in list(layer_bbox[0:4])]
    #srid = layer.srid

    # Transform WGS84 to Mercator.
    #config["srs"] = srid if srid != "EPSG:4326" else "EPSG:900913"
    #config["bbox"] = llbbox_to_mercator([float(coord) for coord in bbox])

    #config["title"] = layer.title
    #config["queryable"] = True

    if layer.storeType == "remoteStore":
        service = layer.service
        source_params = {
            "ptype": service.ptype,
            "remote": True,
            "url": service.base_url,
            "name": service.name
        }
        maplayer = GXPLayer(name=layer.typename,
                            ows_url=layer.ows_url,
                            layer_params=json.dumps(config),
                            source_params=json.dumps(source_params))
    else:
        maplayer = GXPLayer(name=layer.name,
                            ows_url=layer.ows_url,
                            layer_params=json.dumps(config))

    # Update count for popularity ranking,
    # but do not includes admins or resource owners
    if request.user != layer.owner and not request.user.is_superuser:
        Layer.objects.filter(id=layer.id).update(
            popular_count=F('popular_count') + 1)

    # center/zoom don't matter; the viewer will center on the layer bounds
    map_obj = GXPMap(projection="EPSG:900913")
    NON_WMS_BASE_LAYERS = [
        la for la in default_map_config()[1] if la.ows_url is None
    ]

    metadata = layer.link_set.metadata().filter(
        name__in=settings.DOWNLOAD_FORMATS_METADATA)

    keywords = json.dumps([tag.name for tag in layer.keywords.all()])

    if request.method == "POST":
        keywords_form = KeywordsForm(request.POST, instance=layer)
        metadata_form = MetadataForm(instance=layer)
        if 'keywords' in request.POST:
            if keywords_form.is_valid():
                keywords_form.save()
                new_keywords = keywords_form.cleaned_data['keywords']
                layer.keywords.set(*new_keywords)
                layer.save()
            metadata_form = MetadataForm(instance=layer)
            published_form = PublishStatusForm(instance=layer)
        elif 'title' in request.POST:
            metadata_form = MetadataForm(request.POST, instance=layer)
            if metadata_form.is_valid():
                metadata_form.save()
                # update all the metadata
                if metadata_form.cleaned_data['category'] is not None:
                    new_category = TopicCategory.objects.get(
                        id=metadata_form.cleaned_data['category'].id)
                    Layer.objects.filter(id=layer.id).update(
                        category=new_category)
                layer.title = metadata_form.cleaned_data['title']
                layer.language = metadata_form.cleaned_data['language']
                layer.distribution_url = metadata_form.cleaned_data[
                    'distribution_url']
                layer.data_quality_statement = metadata_form.cleaned_data[
                    'data_quality_statement']
                layer.purpose = metadata_form.cleaned_data['purpose']
                layer.is_published = metadata_form.cleaned_data['is_published']
                layer.save()
            keywords_form = KeywordsForm(instance=layer)
        elif 'add_keyword' in request.POST:
            layer.keywords.add(request.POST['add_keyword'])
            layer.save()
        elif 'remove_keyword' in request.POST:
            layer.keywords.remove(request.POST['remove_keyword'])
            layer.save()
    else:
        keywords_form = KeywordsForm(instance=layer)
        metadata_form = MetadataForm(instance=layer)

    content_moderators = Group.objects.filter(name='content_moderator').first()

    thumbnail_dir = os.path.join(settings.MEDIA_ROOT, 'thumbs')
    default_thumbnail_array = layer.get_thumbnail_url().split('/')
    default_thumbnail_name = default_thumbnail_array[
        len(default_thumbnail_array) - 1]
    default_thumbnail = os.path.join(thumbnail_dir, default_thumbnail_name)

    if request.method == 'POST':
        thumb_form = ThumbnailImageForm(request.POST, request.FILES)
        if thumb_form.is_valid():
            new_img = ThumbnailImage(
                thumbnail_image=request.FILES['thumbnail_image'])
            new_img.save()
            user_upload_thumbnail = ThumbnailImage.objects.all()[0]
            user_upload_thumbnail_filepath = str(
                user_upload_thumbnail.thumbnail_image)

            # only create backup for original thumbnail
            if os.path.isfile(default_thumbnail + '.bak') is False:
                os.rename(default_thumbnail, default_thumbnail + '.bak')

            os.rename(user_upload_thumbnail_filepath, default_thumbnail)

    else:
        thumb_form = ThumbnailImageForm()

    thumbnail = layer.get_thumbnail_url

    context_dict = {
        "resource": layer,
        "permissions_json": _perms_info_json(layer),
        "documents": get_related_documents(layer),
        "metadata": metadata,
        "keywords": keywords,
        "is_layer": True,
        "wps_enabled": settings.OGC_SERVER['default']['WPS_ENABLED'],
        "keywords_form": keywords_form,
        "metadata_form": metadata_form,
        "content_moderators": content_moderators,
        "thumbnail": thumbnail,
        "thumb_form": thumb_form
    }

    context_dict["viewer"] = json.dumps(
        map_obj.viewer_json(request.user, *(NON_WMS_BASE_LAYERS + [maplayer])))
    context_dict["preview"] = getattr(settings, 'LAYER_PREVIEW_LIBRARY')

    if request.user.has_perm('download_resourcebase',
                             layer.get_self_resource()):
        if layer.storeType == 'dataStore':
            links = layer.link_set.download().filter(
                name__in=settings.DOWNLOAD_FORMATS_VECTOR)
        else:
            links = layer.link_set.download().filter(
                name__in=settings.DOWNLOAD_FORMATS_RASTER)
        context_dict["links"] = links

    layer_property_names = []
    for attrib in layer.attributes:
        if attrib.attribute not in settings.SCHEMA_DOWNLOAD_EXCLUDE and not (
                attrib.attribute.endswith('_xd')
                or attrib.attribute.endswith('_parsed')):
            layer_property_names.append(attrib.attribute)
    layer_attrib_string = ','.join(layer_property_names)

    shapefile_link = layer.link_set.download().filter(mime='SHAPE-ZIP').first()
    if shapefile_link is not None:
        shapefile_link = shapefile_link.url + '&featureID=fakeID' + '&propertyName=' + layer_attrib_string
        context_dict["shapefile_link"] = shapefile_link

    csv_link = layer.link_set.download().filter(mime='csv').first()
    if csv_link is not None:
        csv_link = csv_link.url + '&featureID=fakeID' + '&propertyName=' + layer_attrib_string
        context_dict["csv_link"] = csv_link

    if settings.SOCIAL_ORIGINS:
        context_dict["social_links"] = build_social_links(request, layer)

    return render_to_response(template, RequestContext(request, context_dict))
示例#37
0
def ediml(request, layername):
    layer = _resolve_layer(request, layername, 'base.view_layer', _PERMISSION_MSG_METADATA)
    ediml = layer.mdextension.elements_xml
    return HttpResponse(ediml, content_type="text/xml")
示例#38
0
def layer_style_manage(request, layername):
    layer = _resolve_layer(request, layername, 'layers.change_layer_style',
                           _PERMISSION_MSG_MODIFY)

    if request.method == 'GET':
        try:
            cat = gs_catalog

            # First update the layer style info from GS to GeoNode's DB
            # The try/except is
            try:
                set_styles(layer, cat)
            except AttributeError:
                logger.warn(
                    'Unable to set the default style.  Ensure Geoserver is running and that this layer exists.'
                )

            # Ahmed Nour:
            # Get public styles also
            all_available_gs_styles = cat.get_styles(
                settings.DEFAULT_WORKSPACE)
            all_available_gs_styles += cat.get_styles()
            gs_styles = []
            for style in all_available_gs_styles:
                sld_title = style.name
                try:
                    if style.sld_title:
                        sld_title = style.sld_title
                except BaseException:
                    pass
                gs_styles.append((style.name, sld_title))

            current_layer_styles = layer.styles.all()
            layer_styles = []
            for style in current_layer_styles:
                sld_title = style.name
                try:
                    if style.sld_title:
                        sld_title = style.sld_title
                except BaseException:
                    pass
                layer_styles.append((style.name, sld_title))

            # Render the form
            sld_title = layer.default_style.name
            try:
                if layer.default_style.sld_title:
                    sld_title = layer.default_style.sld_title
            except BaseException:
                pass
            default_style = (layer.default_style.name, sld_title)
            return render(request,
                          'layers/layer_style_manage.html',
                          context={
                              "layer": layer,
                              "gs_styles": gs_styles,
                              "layer_styles": layer_styles,
                              "default_style": default_style
                          })
        except (FailedRequestError, EnvironmentError):
            tb = traceback.format_exc()
            logger.debug(tb)
            msg = ('Could not connect to geoserver at "%s"'
                   'to manage style information for layer "%s"' %
                   (ogc_server_settings.LOCATION, layer.name))
            logger.warn(msg)
            # If geoserver is not online, return an error
            return render(request,
                          'layers/layer_style_manage.html',
                          context={
                              "layer": layer,
                              "error": msg
                          })
    elif request.method == 'POST':
        try:
            selected_styles = request.POST.getlist('style-select')
            default_style = request.POST['default_style']
            # Save to GeoServer
            cat = gs_catalog
            gs_layer = cat.get_layer(layer.name)
            if gs_layer:
                gs_layer.default_style = cat.get_style(default_style, workspace=settings.DEFAULT_WORKSPACE) or \
                    cat.get_style(default_style)
                styles = []
                for style in selected_styles:
                    styles.append(
                        cat.get_style(style,
                                      workspace=settings.DEFAULT_WORKSPACE)
                        or cat.get_style(style))
                gs_layer.styles = styles
                cat.save(gs_layer)

            # Save to Django
            layer = set_styles(layer, cat)
            layer.save()

            # Invalidate GeoWebCache for the updated resource
            _invalidate_geowebcache_layer(layer.alternate)

            return HttpResponseRedirect(
                reverse('layer_detail', args=(layer.service_typename, )))
        except (FailedRequestError, EnvironmentError, MultiValueDictKeyError):
            tb = traceback.format_exc()
            logger.debug(tb)
            msg = ('Error Saving Styles for Layer "%s"' % (layer.name))
            logger.warn(msg)
            return render(request,
                          'layers/layer_style_manage.html',
                          context={
                              "layer": layer,
                              "error": msg
                          })
示例#39
0
def layer_style_upload(request, layername):
    def respond(*args, **kw):
        kw['content_type'] = 'text/html'
        return json_response(*args, **kw)

    form = LayerStyleUploadForm(request.POST, request.FILES)
    if not form.is_valid():
        return respond(errors="Please provide an SLD file.")

    data = form.cleaned_data
    layer = _resolve_layer(request, layername, 'base.change_resourcebase',
                           _PERMISSION_MSG_MODIFY)

    sld = request.FILES['sld'].read()
    sld_name = None
    try:
        # Check SLD is valid
        try:
            if sld:
                if isfile(sld):
                    sld = open(sld, "r").read()
                etree.XML(sld)
        except Exception:
            logger.exception("The uploaded SLD file is not valid XML")
            raise Exception("The uploaded SLD file is not valid XML")

        sld_name = extract_name_from_sld(gs_catalog,
                                         sld,
                                         sld_file=request.FILES['sld'])
    except Exception as e:
        respond(errors="The uploaded SLD file is not valid XML: {}".format(e))

    name = data.get('name') or sld_name
    if data['update']:
        match = None
        styles = list(layer.styles) + [layer.default_style]
        for style in styles:
            if style.sld_name == name:
                match = style
                break
        if match is None:
            return respond(errors="Cannot locate style : " + name)
        match.update_body(sld)
    else:
        try:
            cat = gs_catalog
            cat.create_style(name,
                             sld,
                             raw=True,
                             workspace=settings.DEFAULT_WORKSPACE)
            layer.styles = layer.styles + \
                [type('style', (object,), {'name': name})]
            cat.save(layer.publishing)
        except ConflictingDataError:
            return respond(errors="""A layer with this name exists. Select
                                     the update option if you want to update."""
                           )
    # Invalidate GeoWebCache for the updated resource
    _invalidate_geowebcache_layer(layer.alternate)
    return respond(body={
        'success': True,
        'style': name,
        'updated': data['update']
    })
示例#40
0
def add_layers_to_map_config(request,
                             map_obj,
                             layer_names,
                             add_base_layers=True):
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request)
    if 'access_token' in request.session:
        access_token = request.session['access_token']
    else:
        access_token = None

    bbox = None

    layers = []
    for layer_name in layer_names:
        try:
            layer = _resolve_layer(request, layer_name)
        except ObjectDoesNotExist:
            # bad layer, skip
            continue

        if not layer.is_published:
            # invisible layer, skip inclusion
            continue

        if not request.user.has_perm('view_resourcebase',
                                     obj=layer.get_self_resource()):
            # invisible layer, skip inclusion
            continue

        layer_bbox = layer.bbox
        # assert False, str(layer_bbox)
        if bbox is None:
            bbox = list(layer_bbox[0:4])
        else:
            bbox[0] = min(bbox[0], layer_bbox[0])
            bbox[1] = max(bbox[1], layer_bbox[1])
            bbox[2] = min(bbox[2], layer_bbox[2])
            bbox[3] = max(bbox[3], layer_bbox[3])

        config = layer.attribute_config()
        if hasattr(layer, 'srid'):
            config['crs'] = {'type': 'name', 'properties': layer.srid}
        # Add required parameters for GXP lazy-loading
        config["title"] = layer.title
        config["queryable"] = True
        config["wrapDateLine"] = True
        config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')
        config["bbox"] = bbox if config["srs"] != 'EPSG:900913' \
            else llbbox_to_mercator([float(coord) for coord in bbox])

        if layer.storeType == "remoteStore":
            service = layer.service
            # Probably not a good idea to send the access token to every remote service.
            # This should never match, so no access token should be
            # sent to remote services.
            ogc_server_url = urlparse.urlsplit(
                ogc_server_settings.PUBLIC_LOCATION).netloc
            service_url = urlparse.urlsplit(service.base_url).netloc

            if access_token and ogc_server_url == service_url and 'access_token' not in service.base_url:
                url = service.base_url + '?access_token=' + access_token
            else:
                url = service.base_url
            maplayer = MapLayer(map=map_obj,
                                name=layer.alternate,
                                ows_url=layer.ows_url,
                                layer_params=json.dumps(config),
                                visibility=True,
                                source_params=json.dumps({
                                    "ptype": service.ptype,
                                    "remote": True,
                                    "url": url,
                                    "name": service.name
                                }))
        else:
            ogc_server_url = urlparse.urlsplit(
                ogc_server_settings.PUBLIC_LOCATION).netloc
            layer_url = urlparse.urlsplit(layer.ows_url).netloc

            if access_token and ogc_server_url == layer_url and 'access_token' not in layer.ows_url:
                url = layer.ows_url + '?access_token=' + access_token
            else:
                url = layer.ows_url
            maplayer = MapLayer(
                map=map_obj,
                name=layer.alternate,
                ows_url=url,
                # use DjangoJSONEncoder to handle Decimal values
                layer_params=json.dumps(config, cls=DjangoJSONEncoder),
                visibility=True)

        layers.append(maplayer)

    if bbox is not None:
        minx, maxx, miny, maxy = [float(coord) for coord in bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2

        if getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913') == "EPSG:4326":
            center = list((x, y))
        else:
            center = list(forward_mercator((x, y)))

        if center[1] == float('-inf'):
            center[1] = 0

        BBOX_DIFFERENCE_THRESHOLD = 1e-5

        # Check if the bbox is invalid
        valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD
        valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD

        if valid_x:
            width_zoom = math.log(360 / abs(maxx - minx), 2)
        else:
            width_zoom = 15

        if valid_y:
            height_zoom = math.log(360 / abs(maxy - miny), 2)
        else:
            height_zoom = 15

        map_obj.center_x = center[0]
        map_obj.center_y = center[1]
        map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

    map_obj.handle_moderated_uploads()

    if add_base_layers:
        layers_to_add = DEFAULT_BASE_LAYERS + layers
    else:
        layers_to_add = layers
    config = map_obj.viewer_json(request.user, access_token, *layers_to_add)

    config['fromLayer'] = True

    return config
示例#41
0
文件: views.py 项目: jsiochi/geonode
def layer_style_manage(req, layername):
    layer = _resolve_layer(req, layername, 'layers.change_layer', _PERMISSION_MSG_MODIFY)
    if req.method == 'GET':
        try:
            cat = gs_catalog

            # First update the layer style info from GS to GeoNode's DB
            # The try/except is
            try:
                set_styles(layer, cat)
            except AttributeError:
                logger.warn('Unable to set the default style.  Ensure Geoserver is running and that this layer exists.')

            all_available_gs_styles = cat.get_styles()
            gs_styles = []
            for style in all_available_gs_styles:
                gs_styles.append(style.name)

            current_layer_styles = layer.styles.all()
            layer_styles = []
            for style in current_layer_styles:
                layer_styles.append(style.name)

            # Render the form
            return render_to_response(
                'layers/layer_style_manage.html',
                RequestContext(req, {
                    "layer": layer,
                    "gs_styles": gs_styles,
                    "layer_styles": layer_styles,
                    "default_style": layer.default_style.name
                    }
                )
            )
        except (FailedRequestError, EnvironmentError) as e:
            msg = ('Could not connect to geoserver at "%s"'
               'to manage style information for layer "%s"' % (
                ogc_server_settings.LOCATION, layer.name)
            )
            logger.warn(msg, e)
            # If geoserver is not online, return an error
            return render_to_response(
                'layers/layer_style_manage.html',
                RequestContext(req, {
                    "layer": layer,
                    "error": msg
                    }
                )
            )
    elif req.method == 'POST':
        try:
            selected_styles = req.POST.getlist('style-select')
            default_style = req.POST['default_style']
            # Save to GeoServer
            cat = gs_catalog
            gs_layer = cat.get_layer(layer.name)
            gs_layer.default_style = default_style
            styles = []
            for style in selected_styles:
                styles.append(style)
            gs_layer.styles = styles
            cat.save(gs_layer)

            # Save to Django
            layer = set_styles(layer, cat)
            layer.save()
            return HttpResponseRedirect(reverse('layer_detail', args=(layer.typename,)))
        except (FailedRequestError, EnvironmentError, MultiValueDictKeyError) as e:
            msg = ('Error Saving Styles for Layer "%s"' % (layer.name)
            )
            logger.warn(msg, e)
            return render_to_response(
                'layers/layer_style_manage.html',
                RequestContext(req, {
                    "layer": layer,
                    "error": msg
                    }
                )
            )
示例#42
0
    def convert(self, viewer, request):
        """
            input: GeoNode JSON Gxp Config
            output: MapStore2 compliant str(config)
        """
        # Initialization
        viewer_obj = json.loads(viewer)

        map_id = None
        if 'id' in viewer_obj and viewer_obj['id']:
            try:
                map_id = int(viewer_obj['id'])
            except Exception:
                pass

        data = {}
        data['version'] = 2

        # Map Definition
        try:
            # Map Definition
            ms2_map = {}
            ms2_map['projection'] = viewer_obj['map']['projection']
            ms2_map['units'] = viewer_obj['map']['units']
            ms2_map['zoom'] = viewer_obj['map'][
                'zoom'] if viewer_obj['map']['zoom'] > 0 else 2
            ms2_map['maxExtent'] = viewer_obj['map']['maxExtent']
            ms2_map['maxResolution'] = viewer_obj['map']['maxResolution']

            # Backgrouns
            backgrounds = self.getBackgrounds(viewer, MAP_BASELAYERS)
            if backgrounds:
                ms2_map['layers'] = backgrounds
            else:
                ms2_map['layers'] = MAP_BASELAYERS + [
                    # TODO: covnert Viewer Background Layers
                    # Add here more backgrounds e.g.:
                    # {
                    # 	"type": "wms",
                    # 	"url": "https://demo.geo-solutions.it/geoserver/wms",
                    # 	"visibility": True,
                    # 	"opacity": 0.5,
                    # 	"title": "Weather data",
                    # 	"name": "nurc:Arc_Sample",
                    # 	"group": "Meteo",
                    # 	"format": "image/png",
                    # 	"bbox": {
                    # 		"bounds": {
                    # 			"minx": -25.6640625,
                    # 			"miny": 26.194876675795218,
                    # 			"maxx": 48.1640625,
                    # 			"maxy": 56.80087831233043
                    # 		},
                    # 		"crs": "EPSG:4326"
                    # 	}
                    # }, ...
                ]

            if settings.BING_API_KEY:
                ms2_map['bingApiKey'] = settings.BING_API_KEY

            # Security Info
            info = {}
            info['canDelete'] = False
            info['canEdit'] = False
            info['description'] = viewer_obj['about']['abstract']
            info['id'] = map_id
            info['name'] = viewer_obj['about']['title']
            ms2_map['info'] = info

            # Overlays
            overlays, selected = self.get_overlays(viewer, request=request)
            if selected and 'name' in selected and selected[
                    'name'] and not map_id:
                # We are generating a Layer Details View
                center, zoom = self.get_center_and_zoom(
                    viewer_obj['map'], selected)
                ms2_map['center'] = center
                ms2_map['zoom'] = zoom

                try:
                    # - extract from GeoNode guardian
                    from geonode.layers.views import (_resolve_layer,
                                                      _PERMISSION_MSG_MODIFY,
                                                      _PERMISSION_MSG_DELETE)
                    if _resolve_layer(request, selected['name'],
                                      'base.change_resourcebase',
                                      _PERMISSION_MSG_MODIFY):
                        info['canEdit'] = True

                    if _resolve_layer(request, selected['name'],
                                      'base.delete_resourcebase',
                                      _PERMISSION_MSG_DELETE):
                        info['canDelete'] = True
                except Exception:
                    tb = traceback.format_exc()
                    logger.debug(tb)
            else:
                # We are getting the configuration of a Map
                # On GeoNode model the Map Center is always saved in 4326
                _x = get_valid_number(viewer_obj['map']['center'][0])
                _y = get_valid_number(viewer_obj['map']['center'][1])
                _crs = 'EPSG:4326'
                if _x > 360.0 or _x < -360.0:
                    _crs = viewer_obj['map']['projection']
                ms2_map['center'] = {'x': _x, 'y': _y, 'crs': _crs}
                try:
                    # - extract from GeoNode guardian
                    from geonode.maps.views import (_resolve_map,
                                                    _PERMISSION_MSG_SAVE,
                                                    _PERMISSION_MSG_DELETE)
                    if _resolve_map(request, str(map_id),
                                    'base.change_resourcebase',
                                    _PERMISSION_MSG_SAVE):
                        info['canEdit'] = True

                    if _resolve_map(request, str(map_id),
                                    'base.delete_resourcebase',
                                    _PERMISSION_MSG_DELETE):
                        info['canDelete'] = True
                except Exception:
                    tb = traceback.format_exc()
                    logger.debug(tb)

            for overlay in overlays:
                if 'name' in overlay and overlay['name']:
                    ms2_map['layers'].append(overlay)

            data['map'] = ms2_map
        except Exception:
            # traceback.print_exc()
            tb = traceback.format_exc()
            logger.debug(tb)

        # Additional Configurations
        if map_id:
            from mapstore2_adapter import fixup_map
            from mapstore2_adapter.api.models import MapStoreResource
            try:
                fixup_map(map_id)
                ms2_resource = MapStoreResource.objects.get(id=map_id)
                ms2_map_data = ms2_resource.data.blob
                if isinstance(ms2_map_data, string_types):
                    ms2_map_data = json.loads(ms2_map_data)
                if 'map' in ms2_map_data:
                    for _k, _v in ms2_map_data['map'].items():
                        if _k not in data['map']:
                            data['map'][_k] = ms2_map_data['map'][_k]
                    del ms2_map_data['map']
                data.update(ms2_map_data)
            except Exception:
                # traceback.print_exc()
                tb = traceback.format_exc()
                logger.debug(tb)

        # Default Catalogue Services Definition
        try:
            ms2_catalogue = {}
            ms2_catalogue['selectedService'] = CATALOGUE_SELECTED_SERVICE
            ms2_catalogue['services'] = CATALOGUE_SERVICES
            data['catalogServices'] = ms2_catalogue
        except Exception:
            # traceback.print_exc()
            tb = traceback.format_exc()
            logger.debug(tb)

        json_str = json.dumps(data, cls=DjangoJSONEncoder, sort_keys=True)
        for (c, d) in unsafe_chars.items():
            json_str = json_str.replace(c, d)

        return json_str
示例#43
0
def download_clip(request, layername, clip_filename):
    """Download clipped file.
    Clipping layer by bbox or by geojson.
    :param layername: The layer name in Geonode.
    :type layername: basestring
    :param clip_filename: clipped filename
    :type clip_filename: basestring
    :return: The HTTPResponse with a file.
    """
    # PREPARATION
    layer = _resolve_layer(request, layername, 'base.view_resourcebase',
                           _PERMISSION_MSG_VIEW)

    query = request.GET or request.POST
    params = {param.upper(): value for param, value in query.iteritems()}
    current_date = datetime.datetime.today().strftime('%Y-%m-%d_%H-%M-%S')

    # create temp folder
    temporary_folder = os.path.join(tempfile.gettempdir(), 'clipped')
    try:
        os.mkdir(temporary_folder)
    except OSError as e:
        pass

    # get file for raster
    raster_filepath = None
    extention = ''

    file_names = []
    try:
        for layerfile in layer.upload_session.layerfile_set.all():
            file_names.append(layerfile.file.path)

        for target_file in file_names:
            if '.tif' in target_file:
                raster_filepath = target_file
                target_filename, extention = os.path.splitext(target_file)
                break
    except AttributeError:
        raster_filepath = layername
        pass

    # get temp filename for output
    filename = os.path.basename(clip_filename)

    output = os.path.join(temporary_folder, clip_filename)

    if os.path.exists(output):
        # Create zip file
        s = StringIO.StringIO()
        zf = zipfile.ZipFile(s, "w")

        zip_subdir = layer.name + '_clipped'
        zip_filename = "%s.zip" % zip_subdir

        files_to_zipped = []
        for filename in file_names:
            if not filename.endswith('.qgs') and \
                    not filename.endswith(extention):
                files_to_zipped.append(filename)

        for fpath in files_to_zipped:
            # Calculate path for file in zip
            fdir, fname = os.path.split(fpath)
            fnames = fname.split('.')
            fname = fnames[0] + '.' + current_date + '.' + fnames[1]
            zip_path = os.path.join(zip_subdir, fname)
            zf.write(fpath, zip_path)

        # Add clipped raster
        opath, oname = os.path.split(output)
        zip_path = os.path.join(zip_subdir, oname)
        zf.write(output, zip_path)

        # Must close zip for all contents to be written
        zf.close()
        resp = HttpResponse(s.getvalue(),
                            content_type="application/x-zip-compressed")
        resp['Content-Disposition'] = 'attachment; filename=%s' % zip_filename
        return resp
    else:
        raise Http404('Project can not be clipped or masked.')
示例#44
0
def layer_detail(request, layername, template='layers/layer_detail.html'):

    #if template:
    #logger.warning('Template param not expected: %s', template)

    layer = _resolve_layer(request, layername, 'base.view_resourcebase',
                           _PERMISSION_MSG_VIEW)

    # assert False, str(layer_bbox)
    config = layer.attribute_config()

    # Add required parameters for GXP lazy-loading
    layer_bbox = layer.bbox
    bbox = [float(coord) for coord in list(layer_bbox[0:4])]
    srid = layer.srid

    # Transform WGS84 to Mercator.
    config["srs"] = srid if srid != "EPSG:4326" else "EPSG:900913"
    config["bbox"] = llbbox_to_mercator([float(coord) for coord in bbox])

    config["title"] = layer.title
    config["queryable"] = True

    if layer.storeType == "remoteStore":
        service = layer.service
        source_params = {
            "ptype": service.ptype,
            "remote": True,
            "url": service.base_url,
            "name": service.name
        }
        maplayer = GXPLayer(name=layer.typename,
                            ows_url=layer.ows_url,
                            layer_params=json.dumps(config),
                            source_params=json.dumps(source_params))
    else:
        maplayer = GXPLayer(name=layer.typename,
                            ows_url=layer.ows_url,
                            layer_params=json.dumps(config))

    # Update count for popularity ranking,
    # but do not includes admins or resource owners
    if request.user != layer.owner and not request.user.is_superuser:
        Layer.objects.filter(id=layer.id).update(
            popular_count=F('popular_count') + 1)

    # center/zoom don't matter; the viewer will center on the layer bounds
    map_obj = GXPMap(projection="EPSG:900913")
    NON_WMS_BASE_LAYERS = [
        la for la in default_map_config()[1] if la.ows_url is None
    ]

    metadata = layer.link_set.metadata().filter(
        name__in=settings.DOWNLOAD_FORMATS_METADATA)

    granules = None
    all_granules = None
    granule_filter = None
    if layer.is_mosaic:
        try:
            cat = gs_catalog
            cat._cache.clear()
            store = cat.get_store(layer.name)
            coverages = cat.mosaic_coverages(store)

            granule_filter = None
            try:
                if request.GET["filter"]:
                    granule_filter = request.GET["filter"]
            except:
                pass

            schema = cat.mosaic_coverage_schema(
                coverages['coverages']['coverage'][0]['name'], store)
            offset = 10 * (request.page - 1)
            granules = cat.mosaic_granules(
                coverages['coverages']['coverage'][0]['name'],
                store,
                limit=10,
                offset=offset,
                filter=granule_filter)
            all_granules = cat.mosaic_granules(
                coverages['coverages']['coverage'][0]['name'],
                store,
                filter=granule_filter)

        except:
            granules = {"features": []}
            all_granules = {"features": []}

            import traceback
            traceback.print_exc()

        #print (' +++++++++++++++++++++++++++++++++++++++++ \n' + str(granules) + '\n +++++++++++++++++++++++++++++++++++++++++ ')

    context_dict = {
        "resource": layer,
        'perms_list': get_perms(request.user, layer.get_self_resource()),
        "permissions_json": _perms_info_json(layer),
        "documents": get_related_documents(layer),
        "metadata": metadata,
        "is_layer": True,
        "wps_enabled": settings.OGC_SERVER['default']['WPS_ENABLED'],
        "is_owner": request.user == layer.owner,
        "is_superuser": request.user.is_superuser,
        "granules": granules,
        "all_granules": all_granules,
        "filter": granule_filter,
    }

    context_dict["viewer"] = json.dumps(
        map_obj.viewer_json(request.user, *(NON_WMS_BASE_LAYERS + [maplayer])))
    context_dict["preview"] = getattr(settings, 'LAYER_PREVIEW_LIBRARY',
                                      'leaflet')

    if request.user.has_perm('download_resourcebase',
                             layer.get_self_resource()):
        if layer.storeType == 'dataStore':
            links = layer.link_set.download().filter(
                name__in=settings.DOWNLOAD_FORMATS_VECTOR)
        else:
            links = layer.link_set.download().filter(
                name__in=settings.DOWNLOAD_FORMATS_RASTER)
        context_dict["links"] = links

    if settings.SOCIAL_ORIGINS:
        context_dict["social_links"] = build_social_links(request, layer)

    #if request.user.is_superuser:
    #logger.debug("Dispatching to admin page")
    #else:
    #logger.debug("Dispatching to user page")

    #template = 'layers/layer_detail_admin.html' if request.user.is_superuser else 'layers/layer_detail_user.html'

    return render_to_response(template, RequestContext(request, context_dict))
示例#45
0
def rndt(request, layername):
    layer = _resolve_layer(request, layername, 'base.view_layer', _PERMISSION_MSG_METADATA)
    rndt = layer.mdextension.rndt_xml
    return HttpResponse(rndt, content_type="text/xml")
示例#46
0
def layer_metadata_create(request,
                          layername,
                          template='layers/cread_layer_metadata.html',
                          publish=False):
    logger.debug("*** ENTER CREAD:layer_metadata_create (pub=%s)", publish)

    layer = _resolve_layer(request, layername,
                           'base.change_resourcebase_metadata',
                           _PERMISSION_MSG_METADATA)

    clayerqs = CReadResource.objects.filter(resource=layer)

    if len(clayerqs) == 0:
        logger.info('cread_resource does not exist for layer %r', layer)
        cread_resource = None
    else:
        logger.debug('cread_resource found for layer %r (%d)', layer,
                     len(clayerqs))
        cread_resource = clayerqs[0]

    layer_attribute_set = inlineformset_factory(
        Layer,
        Attribute,
        extra=0,
        form=LayerAttributeForm,
    )

    topic_category = layer.category
    cread_subcategory = cread_resource.subcategory if cread_resource else None

    poc = layer.poc
    metadata_author = layer.metadata_author

    if request.method == "POST":
        baseinfo_form = CReadBaseInfoForm(request.POST, prefix="baseinfo")
        layer_form = CReadLayerForm(request.POST,
                                    instance=layer,
                                    prefix="resource")
        attribute_form = layer_attribute_set(
            request.POST,
            instance=layer,
            prefix="layer_attribute_set",
            queryset=Attribute.objects.order_by('display_order'))
        category_form = CategoryForm(
            request.POST,
            prefix="category_choice_field",
            initial=int(request.POST["category_choice_field"])
            if "category_choice_field" in request.POST else None)
        #cread_category_form = CReadCategoryForm(
        #request.POST,
        #prefix="cread_category_choice_field",
        #initial=int(
        #request.POST["cread_category_choice_field"]) if "cread_category_choice_field" in request.POST else None)
        cread_subcategory_form = CReadSubCategoryForm(
            request.POST,
            prefix="cread_subcategory_choice_field",
            initial=int(request.POST["cread_subcategory_choice_field"])
            if "cread_subcategory_choice_field" in request.POST else None)
    else:
        baseinfo_form = CReadBaseInfoForm(prefix="baseinfo",
                                          initial={
                                              'title': layer.title,
                                              'abstract': layer.abstract
                                          })
        layer_form = CReadLayerForm(instance=layer, prefix="resource")
        #_preprocess_fields(layer_form)

        attribute_form = layer_attribute_set(
            instance=layer,
            prefix="layer_attribute_set",
            queryset=Attribute.objects.order_by('display_order'))
        category_form = CategoryForm(
            prefix="category_choice_field",
            initial=topic_category.id if topic_category else None)
        #cread_category_form = CReadCategoryForm(
        #prefix="cread_category_choice_field",
        #initial=cread_category.id if cread_category else None)
        cread_subcategory_form = CReadSubCategoryForm(
            prefix="cread_subcategory_choice_field",
            initial=cread_subcategory.id if cread_subcategory else None)

    if request.method == "POST" \
        and baseinfo_form.is_valid() \
        and layer_form.is_valid() \
        and attribute_form.is_valid() \
        and cread_subcategory_form.is_valid():

        new_poc = layer_form.cleaned_data['poc']
        new_author = layer_form.cleaned_data['metadata_author']
        new_keywords = layer_form.cleaned_data['keywords']

        if new_poc is None:
            if poc is None:
                poc_form = ProfileForm(request.POST,
                                       prefix="poc",
                                       instance=poc)
            else:
                poc_form = ProfileForm(request.POST, prefix="poc")
            if poc_form.has_changed and poc_form.is_valid():
                new_poc = poc_form.save()

        if new_author is None:
            if metadata_author is None:
                author_form = ProfileForm(request.POST,
                                          prefix="author",
                                          instance=metadata_author)
            else:
                author_form = ProfileForm(request.POST, prefix="author")
            if author_form.has_changed and author_form.is_valid():
                new_author = author_form.save()

        # CRead category
        # note: call to is_valid is needed to compute the cleaned data
        if (cread_subcategory_form.is_valid()):
            logger.info("Checking CReadLayer record %r ",
                        cread_subcategory_form.is_valid())
            #cread_cat_id = cread_category_form.cleaned_data['cread_category_choice_field']
            #cread_cat_id = cread_cat_id if cread_cat_id else 1
            #new_creadcategory = CReadCategory.objects.get(id=cread_cat_id)
            cread_subcat_id = cread_subcategory_form.cleaned_data[
                'cread_subcategory_choice_field']
            new_creadsubcategory = CReadSubCategory.objects.get(
                id=cread_subcat_id)
            new_creadcategory = new_creadsubcategory.category
            logger.debug("Selected cread cat/subcat: %s : %s / %s",
                         new_creadcategory.identifier, new_creadcategory.name,
                         new_creadsubcategory.identifier)

            if cread_resource:
                logger.info("Update CReadResource record")
            else:
                logger.info("Create new CReadResource record")
                cread_resource = CReadResource()
                cread_resource.resource = layer

            cread_resource.category = new_creadcategory
            cread_resource.subcategory = new_creadsubcategory
            cread_resource.save()
            # End cread category
        else:
            new_creadsubcategory = None
            logger.info("CRead subcategory form is not valid")

        if category_form.is_valid():
            new_category = TopicCategory.objects.get(
                id=category_form.cleaned_data['category_choice_field'])
        elif new_creadsubcategory:
            logger.debug("Assigning default ISO category")
            new_category = TopicCategory.objects.get(
                id=new_creadsubcategory.relatedtopic.id)

        for form in attribute_form.cleaned_data:
            la = Attribute.objects.get(id=int(form['id'].id))
            la.description = form["description"]
            la.attribute_label = form["attribute_label"]
            la.visible = form["visible"]
            la.display_order = form["display_order"]
            la.save()

        if new_poc is not None and new_author is not None:
            new_keywords = layer_form.cleaned_data['keywords']
            layer.keywords.clear()
            layer.keywords.add(*new_keywords)
            the_layer = layer_form.save()
            the_layer.poc = new_poc
            the_layer.metadata_author = new_author
            Layer.objects.filter(id=the_layer.id).update(
                category=new_category,
                title=baseinfo_form.cleaned_data['title'],
                abstract=baseinfo_form.cleaned_data['abstract'])

            if publish is not None:
                logger.debug("Setting publish status to %s for layer %s",
                             publish, layername)

                Layer.objects.filter(id=the_layer.id).update(
                    is_published=publish)

            return HttpResponseRedirect(
                reverse('layer_detail', args=(layer.service_typename, )))

    logger.debug("baseinfo valid %s ", baseinfo_form.is_valid())
    logger.debug("layer valid %s ", layer_form.is_valid())
    logger.debug("attribute valid %s ", attribute_form.is_valid())
    logger.debug("subcat valid %s ", cread_subcategory_form.is_valid())

    if poc is None:
        poc_form = ProfileForm(instance=poc, prefix="poc")
    else:
        layer_form.fields['poc'].initial = poc.id
        poc_form = ProfileForm(prefix="poc")
        poc_form.hidden = True

    if metadata_author is None:
        author_form = ProfileForm(instance=metadata_author, prefix="author")
    else:
        layer_form.fields['metadata_author'].initial = metadata_author.id
        author_form = ProfileForm(prefix="author")
        author_form.hidden = True

    # creates cat - subcat association
    categories_struct = []
    for category in CReadCategory.objects.all():
        subcats = []
        for subcat in CReadSubCategory.objects.filter(category=category):
            subcats.append(subcat.id)
        categories_struct.append((category.id, category.description, subcats))

    return render_to_response(
        template,
        RequestContext(
            request,
            {
                "layer": layer,
                "baseinfo_form": baseinfo_form,
                "layer_form": layer_form,
                "poc_form": poc_form,
                "author_form": author_form,
                "attribute_form": attribute_form,
                "category_form": category_form,
                "cread_form": None,  # read_category_form,
                "cread_sub_form": cread_subcategory_form,
                "cread_categories": categories_struct
            }))
示例#47
0
def layer_detail(request, layername, template='layers/layer_detail.html'):
    layer = _resolve_layer(request, layername, 'base.view_resourcebase',
                           _PERMISSION_MSG_VIEW)
    # assert False, str(layer_bbox)
    config = layer.attribute_config()

    # TODO (Mapstory): This has been commented out to force the client to make a getCapabilities request in order
    # to pull in the time dimension data.  Ideally we would cache time data just like the srs and bbox data to prevent
    # making the getCapabilities request.

    # Add required parameters for GXP lazy-loading
    #layer_bbox = layer.bbox
    #bbox = [float(coord) for coord in list(layer_bbox[0:4])]
    #srid = layer.srid

    # Transform WGS84 to Mercator.
    #config["srs"] = srid if srid != "EPSG:4326" else "EPSG:900913"
    #config["bbox"] = llbbox_to_mercator([float(coord) for coord in bbox])

    #config["title"] = layer.title
    #config["queryable"] = True

    if layer.storeType == "remoteStore":
        service = layer.service
        source_params = {
            "ptype": service.ptype,
            "remote": True,
            "url": service.base_url,
            "name": service.name
        }
        maplayer = GXPLayer(name=layer.typename,
                            ows_url=layer.ows_url,
                            layer_params=json.dumps(config),
                            source_params=json.dumps(source_params))
    else:
        maplayer = GXPLayer(name=layer.name,
                            ows_url=layer.ows_url,
                            layer_params=json.dumps(config))

    # Update count for popularity ranking,
    # but do not includes admins or resource owners
    if request.user != layer.owner and not request.user.is_superuser:
        Layer.objects.filter(id=layer.id).update(
            popular_count=F('popular_count') + 1)

    # center/zoom don't matter; the viewer will center on the layer bounds
    map_obj = GXPMap(projection="EPSG:900913")
    NON_WMS_BASE_LAYERS = [
        la for la in default_map_config()[1] if la.ows_url is None
    ]

    metadata = layer.link_set.metadata().filter(
        name__in=settings.DOWNLOAD_FORMATS_METADATA)

    if request.method == "POST":
        keywords_form = KeywordsForm(request.POST, instance=layer)
        metadata_form = MetadataForm(request.POST, instance=layer)
        published_form = PublishStatusForm(request.POST, instance=layer)

        if keywords_form.is_valid():
            new_keywords = keywords_form.cleaned_data['keywords']
            layer.keywords.clear()
            layer.keywords.add(*new_keywords)
        if metadata_form.is_valid():
            # update all the metadata
            if metadata_form.cleaned_data['category'] is not None:
                new_category = TopicCategory.objects.get(
                    id=metadata_form.cleaned_data['category'].id)
                Layer.objects.filter(id=layer.id).update(category=new_category)
            new_language = metadata_form.cleaned_data['language']
            new_distribution_url = metadata_form.cleaned_data[
                'distribution_url']
            new_data_quality_statement = metadata_form.cleaned_data[
                'data_quality_statement']
            new_purpose = metadata_form.cleaned_data['purpose']
            layer.language = new_language
            layer.distribution_url = new_distribution_url
            layer.data_quality_statement = new_data_quality_statement
            layer.purpose = new_purpose
            layer.save()
        if published_form.is_valid():
            layer.is_published = published_form.cleaned_data['is_published']
            layer.save()

    else:
        keywords_form = KeywordsForm(instance=layer)
        metadata_form = MetadataForm(instance=layer)
        published_form = PublishStatusForm(instance=layer)

    content_moderators = Group.objects.filter(name='content_moderator').first()

    context_dict = {
        "resource": layer,
        "permissions_json": _perms_info_json(layer),
        "documents": get_related_documents(layer),
        "metadata": metadata,
        "is_layer": True,
        "wps_enabled": settings.OGC_SERVER['default']['WPS_ENABLED'],
        "keywords_form": keywords_form,
        "metadata_form": metadata_form,
        "published_form": published_form,
        "content_moderators": content_moderators,
    }

    context_dict["viewer"] = json.dumps(
        map_obj.viewer_json(request.user, *(NON_WMS_BASE_LAYERS + [maplayer])))
    context_dict["preview"] = getattr(settings, 'LAYER_PREVIEW_LIBRARY',
                                      'leaflet')

    if request.user.has_perm('download_resourcebase',
                             layer.get_self_resource()):
        if layer.storeType == 'dataStore':
            links = layer.link_set.download().filter(
                name__in=settings.DOWNLOAD_FORMATS_VECTOR)
        else:
            links = layer.link_set.download().filter(
                name__in=settings.DOWNLOAD_FORMATS_RASTER)
        context_dict["links"] = links

    if settings.SOCIAL_ORIGINS:
        context_dict["social_links"] = build_social_links(request, layer)

    return render_to_response(template, RequestContext(request, context_dict))
示例#48
0
def rndteditor(request, layername):
    layer = _resolve_layer(request, layername, 'layers.change_layer',
                           _PERMISSION_MSG_METADATA)

    queryStringValues = {
        'template': 'RNDT',
        'version': '2.00',
        'parameters': "{}"
    }

    fileid = layer.mdextension.fileid
    pars = {}
    if fileid is not None:
        queryStringValues['edit'] = fileid
        pars = {
            'uid': layer.uuid,
            'westlon': layer.bbox_x0,
            'eastlon': layer.bbox_x1,
            'southlat': layer.bbox_y0,
            'northlat': layer.bbox_y1,
        }

    else:
        pars = {
            'uid':
            layer.uuid,
            # inserire data_md
            'title':
            layer.title,
            'data_md':
            layer.mdextension.md_date.date().isoformat(),
            'data':
            layer.date,
            'tipo_di_data':
            layer.date_type,
            'abstract':
            layer.abstract,
            'spatialrepresentationtype':
            (EDI_MAP_SPATIALREPRESENTATIONTYPE).get(layer.storeType),
            'westlon':
            layer.bbox_x0,
            'eastlon':
            layer.bbox_x1,
            'southlat':
            layer.bbox_y0,
            'northlat':
            layer.bbox_y1,
            'resource':
            '%s%s' % (settings.SITEURL[:-1], layer.get_absolute_url()),
            'referencesystem':
            layer.srid,
        }

    js_pars = json.dumps(pars, cls=DjangoJSONEncoder)

    queryStringValues['parameters'] = json.dumps(pars, cls=DjangoJSONEncoder)

    js_queryStringValues = json.dumps(queryStringValues)
    return render_to_response(
        'mdtools/rndt.html',
        RequestContext(
            request, {
                'layername': layername,
                'queryStringValues': mark_safe(js_queryStringValues)
            }))
示例#49
0
def layer_style_manage(request, layername):
    layer = _resolve_layer(request, layername, 'layers.change_layer_style',
                           _PERMISSION_MSG_MODIFY)

    if request.method == 'GET':
        try:
            cat = gs_catalog

            # First update the layer style info from GS to GeoNode's DB
            try:
                set_styles(layer, cat)
            except AttributeError:
                logger.warn(
                    'Unable to set the default style.  Ensure Geoserver is running and that this layer exists.'
                )

            gs_styles = []
            # Temporary Hack to remove GeoServer temp styles from the list
            Style.objects.filter(
                name__iregex=r'\w{8}-\w{4}-\w{4}-\w{4}-\w{12}_(ms)_\d{13}'
            ).delete()
            for style in Style.objects.values('name', 'sld_title'):
                gs_styles.append((style['name'], style['sld_title']))
            current_layer_styles = layer.styles.all()
            layer_styles = []
            for style in current_layer_styles:
                sld_title = style.name
                try:
                    if style.sld_title:
                        sld_title = style.sld_title
                except Exception:
                    tb = traceback.format_exc()
                    logger.debug(tb)
                layer_styles.append((style.name, sld_title))

            # Render the form
            def_sld_name = None  # noqa
            def_sld_title = None  # noqa
            default_style = None
            if layer.default_style:
                def_sld_name = layer.default_style.name  # noqa
                def_sld_title = layer.default_style.name  # noqa
                try:
                    if layer.default_style.sld_title:
                        def_sld_title = layer.default_style.sld_title
                except Exception:
                    tb = traceback.format_exc()
                    logger.debug(tb)
                default_style = (def_sld_name, def_sld_title)

            return render(request,
                          'layers/layer_style_manage.html',
                          context={
                              "layer": layer,
                              "gs_styles": gs_styles,
                              "layer_styles": layer_styles,
                              "layer_style_names":
                              [s[0] for s in layer_styles],
                              "default_style": default_style
                          })
        except (FailedRequestError, EnvironmentError):
            tb = traceback.format_exc()
            logger.debug(tb)
            msg = ('Could not connect to geoserver at "%s"'
                   'to manage style information for layer "%s"' %
                   (ogc_server_settings.LOCATION, layer.name))
            logger.debug(msg)
            # If geoserver is not online, return an error
            return render(request,
                          'layers/layer_style_manage.html',
                          context={
                              "layer": layer,
                              "error": msg
                          })
    elif request.method in ('POST', 'PUT', 'DELETE'):
        try:
            selected_styles = request.POST.getlist('style-select')
            default_style = request.POST['default_style']

            # Save to GeoServer
            cat = gs_catalog
            gs_layer = cat.get_layer(layer.name)
            if not gs_layer:
                gs_layer = cat.get_layer(layer.alternate)

            if gs_layer:
                gs_layer.default_style = cat.get_style(default_style, workspace=settings.DEFAULT_WORKSPACE) or \
                    cat.get_style(default_style)
                styles = []
                for style in selected_styles:
                    gs_sld = cat.get_style(style,
                                           workspace=settings.DEFAULT_WORKSPACE
                                           ) or cat.get_style(style)
                    if gs_sld:
                        styles.append(gs_sld)
                gs_layer.styles = styles
                cat.save(gs_layer)

            # Save to Django
            set_styles(layer, cat)

            # Invalidate GeoWebCache for the updated resource
            try:
                _stylefilterparams_geowebcache_layer(layer.alternate)
                _invalidate_geowebcache_layer(layer.alternate)
            except Exception:
                pass

            return HttpResponseRedirect(
                reverse('layer_detail', args=(layer.service_typename, )))
        except (FailedRequestError, EnvironmentError, MultiValueDictKeyError):
            tb = traceback.format_exc()
            logger.debug(tb)
            msg = ('Error Saving Styles for Layer "%s"' % (layer.name))
            logger.warn(msg)
            return render(request,
                          'layers/layer_style_manage.html',
                          context={
                              "layer": layer,
                              "error": msg
                          })
示例#50
0
文件: views.py 项目: timlinux/geonode
def add_layers_to_map_config(request,
                             map_obj,
                             layer_names,
                             add_base_layers=True):
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request)
    if 'access_token' in request.session:
        access_token = request.session['access_token']
    else:
        access_token = None

    bbox = []
    layers = []
    for layer_name in layer_names:
        try:
            layer = _resolve_layer(request, layer_name)
        except ObjectDoesNotExist:
            # bad layer, skip
            continue

        if not request.user.has_perm('view_resourcebase',
                                     obj=layer.get_self_resource()):
            # invisible layer, skip inclusion
            continue

        layer_bbox = layer.bbox[0:4]
        bbox = layer_bbox[:]
        bbox[0] = layer_bbox[0]
        bbox[1] = layer_bbox[2]
        bbox[2] = layer_bbox[1]
        bbox[3] = layer_bbox[3]

        # assert False, str(layer_bbox)

        def decimal_encode(bbox):
            import decimal
            _bbox = []
            for o in [float(coord) for coord in bbox]:
                if isinstance(o, decimal.Decimal):
                    o = (str(o) for o in [o])
                _bbox.append(o)
            return _bbox

        def sld_definition(style):
            from urllib import quote
            _sld = {
                "title": style.sld_title or style.name,
                "legend": {
                    "height":
                    "40",
                    "width":
                    "22",
                    "href":
                    layer.ows_url +
                    "?service=wms&request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer="
                    + quote(layer.service_typename, safe=''),
                    "format":
                    "image/png"
                },
                "name": style.name
            }
            return _sld

        config = layer.attribute_config()
        if hasattr(layer, 'srid'):
            config['crs'] = {'type': 'name', 'properties': layer.srid}
        # Add required parameters for GXP lazy-loading
        attribution = "%s %s" % (
            layer.owner.first_name, layer.owner.last_name
        ) if layer.owner.first_name or layer.owner.last_name else str(
            layer.owner)
        srs = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857')
        srs_srid = int(srs.split(":")[1]) if srs != "EPSG:900913" else 3857
        config[
            "attribution"] = "<span class='gx-attribution-title'>%s</span>" % attribution
        config["format"] = getattr(settings, 'DEFAULT_LAYER_FORMAT',
                                   'image/png')
        config["title"] = layer.title
        config["wrapDateLine"] = True
        config["visibility"] = True
        config["srs"] = srs
        config["bbox"] = decimal_encode(
            bbox_to_projection([float(coord) for coord in layer_bbox] + [
                layer.srid,
            ],
                               target_srid=int(srs.split(":")[1]))[:4])
        config["capability"] = {
            "abstract":
            layer.abstract,
            "name":
            layer.alternate,
            "title":
            layer.title,
            "queryable":
            True,
            "bbox": {
                layer.srid: {
                    "srs": layer.srid,
                    "bbox": decimal_encode(bbox)
                },
                srs: {
                    "srs":
                    srs,
                    "bbox":
                    decimal_encode(
                        bbox_to_projection(
                            [float(coord) for coord in layer_bbox] + [
                                layer.srid,
                            ],
                            target_srid=srs_srid)[:4])
                },
                "EPSG:4326": {
                    "srs":
                    "EPSG:4326",
                    "bbox":
                    decimal_encode(bbox)
                    if layer.srid == 'EPSG:4326' else decimal_encode(
                        bbox_to_projection(
                            [float(coord) for coord in layer_bbox] + [
                                layer.srid,
                            ],
                            target_srid=4326)[:4])
                },
                "EPSG:900913": {
                    "srs":
                    "EPSG:900913",
                    "bbox":
                    decimal_encode(bbox)
                    if layer.srid == 'EPSG:900913' else decimal_encode(
                        bbox_to_projection(
                            [float(coord) for coord in layer_bbox] + [
                                layer.srid,
                            ],
                            target_srid=3857)[:4])
                }
            },
            "srs": {
                srs: True
            },
            "formats": [
                "image/png", "application/atom xml", "application/atom+xml",
                "application/json;type=utfgrid", "application/openlayers",
                "application/pdf", "application/rss xml",
                "application/rss+xml", "application/vnd.google-earth.kml",
                "application/vnd.google-earth.kml xml",
                "application/vnd.google-earth.kml+xml",
                "application/vnd.google-earth.kml+xml;mode=networklink",
                "application/vnd.google-earth.kmz",
                "application/vnd.google-earth.kmz xml",
                "application/vnd.google-earth.kmz+xml",
                "application/vnd.google-earth.kmz;mode=networklink", "atom",
                "image/geotiff", "image/geotiff8", "image/gif",
                "image/gif;subtype=animated", "image/jpeg", "image/png8",
                "image/png; mode=8bit", "image/svg", "image/svg xml",
                "image/svg+xml", "image/tiff", "image/tiff8",
                "image/vnd.jpeg-png", "kml", "kmz", "openlayers", "rss",
                "text/html; subtype=openlayers", "utfgrid"
            ],
            "attribution": {
                "title": attribution
            },
            "infoFormats": [
                "text/plain", "application/vnd.ogc.gml", "text/xml",
                "application/vnd.ogc.gml/3.1.1", "text/xml; subtype=gml/3.1.1",
                "text/html", "application/json"
            ],
            "styles": [sld_definition(s) for s in layer.styles.all()],
            "prefix":
            layer.alternate.split(":")[0] if ":" in layer.alternate else "",
            "keywords":
            [k.name for k in layer.keywords.all()] if layer.keywords else [],
            "llbbox":
            decimal_encode(bbox)
            if layer.srid == 'EPSG:4326' else decimal_encode(
                bbox_to_projection([float(coord) for coord in layer_bbox] + [
                    layer.srid,
                ],
                                   target_srid=4326)[:4])
        }

        all_times = None
        if check_ogc_backend(geoserver.BACKEND_PACKAGE):
            from geonode.geoserver.views import get_capabilities
            workspace, layername = layer.alternate.split(
                ":") if ":" in layer.alternate else (None, layer.alternate)
            # WARNING Please make sure to have enabled DJANGO CACHE as per
            # https://docs.djangoproject.com/en/2.0/topics/cache/#filesystem-caching
            wms_capabilities_resp = get_capabilities(request,
                                                     layer.id,
                                                     tolerant=True)
            if wms_capabilities_resp.status_code >= 200 and wms_capabilities_resp.status_code < 400:
                wms_capabilities = wms_capabilities_resp.getvalue()
                if wms_capabilities:
                    import xml.etree.ElementTree as ET
                    e = ET.fromstring(wms_capabilities)
                    for atype in e.findall(
                            "./[Name='%s']/Extent[@name='time']" %
                        (layername)):
                        dim_name = atype.get('name')
                        if dim_name:
                            dim_name = str(dim_name).lower()
                            if dim_name == 'time':
                                dim_values = atype.text
                                if dim_values:
                                    all_times = dim_values.split(",")
                                    break
            if all_times:
                config["capability"]["dimensions"] = {
                    "time": {
                        "name": "time",
                        "units": "ISO8601",
                        "unitsymbol": None,
                        "nearestVal": False,
                        "multipleVal": False,
                        "current": False,
                        "default": "current",
                        "values": all_times
                    }
                }

        if layer.storeType == "remoteStore":
            service = layer.remote_service
            source_params = {}
            if service.type in ('REST_MAP', 'REST_IMG'):
                source_params = {
                    "ptype": service.ptype,
                    "remote": True,
                    "url": service.service_url,
                    "name": service.name,
                    "title": "[R] %s" % service.title
                }
            maplayer = MapLayer(map=map_obj,
                                name=layer.alternate,
                                ows_url=layer.ows_url,
                                layer_params=json.dumps(config),
                                visibility=True,
                                source_params=json.dumps(source_params))
        else:
            ogc_server_url = urlparse.urlsplit(
                ogc_server_settings.PUBLIC_LOCATION).netloc
            layer_url = urlparse.urlsplit(layer.ows_url).netloc

            if access_token and ogc_server_url == layer_url and 'access_token' not in layer.ows_url:
                url = layer.ows_url + '?access_token=' + access_token
            else:
                url = layer.ows_url
            maplayer = MapLayer(
                map=map_obj,
                name=layer.alternate,
                ows_url=url,
                # use DjangoJSONEncoder to handle Decimal values
                layer_params=json.dumps(config, cls=DjangoJSONEncoder),
                visibility=True)

        layers.append(maplayer)

    if bbox and len(bbox) >= 4:
        minx, maxx, miny, maxy = [float(coord) for coord in bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2

        if getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857') == "EPSG:4326":
            center = list((x, y))
        else:
            center = list(forward_mercator((x, y)))

        if center[1] == float('-inf'):
            center[1] = 0

        BBOX_DIFFERENCE_THRESHOLD = 1e-5

        # Check if the bbox is invalid
        valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD
        valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD

        if valid_x:
            width_zoom = math.log(360 / abs(maxx - minx), 2)
        else:
            width_zoom = 15

        if valid_y:
            height_zoom = math.log(360 / abs(maxy - miny), 2)
        else:
            height_zoom = 15

        map_obj.center_x = center[0]
        map_obj.center_y = center[1]
        map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

    map_obj.handle_moderated_uploads()

    if add_base_layers:
        layers_to_add = DEFAULT_BASE_LAYERS + layers
    else:
        layers_to_add = layers
    config = map_obj.viewer_json(request.user, access_token, *layers_to_add)

    config['fromLayer'] = True
    return config
示例#51
0
文件: views.py 项目: ict4eo/geonode
def new_map_config(request):
    '''
    View that creates a new map.

    If the query argument 'copy' is given, the initial map is
    a copy of the map with the id specified, otherwise the
    default map configuration is used.  If copy is specified
    and the map specified does not exist a 404 is returned.
    '''
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config()

    if request.method == 'GET' and 'copy' in request.GET:
        mapid = request.GET['copy']
        map_obj = _resolve_map(request, mapid, 'base.view_resourcebase')

        map_obj.abstract = DEFAULT_ABSTRACT
        map_obj.title = DEFAULT_TITLE
        if request.user.is_authenticated():
            map_obj.owner = request.user
        config = map_obj.viewer_json(request.user)
        del config['id']
    else:
        if request.method == 'GET':
            params = request.GET
        elif request.method == 'POST':
            params = request.POST
        else:
            return HttpResponse(status=405)

        if 'layer' in params:
            bbox = None
            map_obj = Map(projection="EPSG:900913")
            layers = []
            for layer_name in params.getlist('layer'):
                try:
                    layer = _resolve_layer(request, layer_name)
                except ObjectDoesNotExist:
                    # bad layer, skip
                    continue

                if not request.user.has_perm(
                        'view_resourcebase',
                        obj=layer.get_self_resource()):
                    # invisible layer, skip inclusion
                    continue

                layer_bbox = layer.bbox
                # assert False, str(layer_bbox)
                if bbox is None:
                    bbox = list(layer_bbox[0:4])
                else:
                    bbox[0] = min(bbox[0], layer_bbox[0])
                    bbox[1] = max(bbox[1], layer_bbox[1])
                    bbox[2] = min(bbox[2], layer_bbox[2])
                    bbox[3] = max(bbox[3], layer_bbox[3])

                config = layer.attribute_config()

                # Add required parameters for GXP lazy-loading
                config["srs"] = layer.srid
                config["title"] = layer.title
                config["bbox"] = [
                    float(coord) for coord in bbox] if layer.srid == "EPSG:4326" else llbbox_to_mercator(
                    [
                        float(coord) for coord in bbox])
                config["queryable"] = True

                if layer.storeType == "remoteStore":
                    service = layer.service
                    maplayer = MapLayer(map=map_obj,
                                        name=layer.typename,
                                        ows_url=layer.ows_url,
                                        layer_params=json.dumps(config),
                                        visibility=True,
                                        source_params=json.dumps({
                                            "ptype": service.ptype,
                                            "remote": True,
                                            "url": service.base_url,
                                            "name": service.name}))
                else:
                    maplayer = MapLayer(
                        map=map_obj,
                        name=layer.typename,
                        ows_url=layer.ows_url,
                        layer_params=json.dumps(config),
                        visibility=True
                    )

                layers.append(maplayer)

            if bbox is not None:
                minx, miny, maxx, maxy = [float(c) for c in bbox]
                x = (minx + maxx) / 2
                y = (miny + maxy) / 2

                center = list(forward_mercator((x, y)))
                if center[1] == float('-inf'):
                    center[1] = 0

                BBOX_DIFFERENCE_THRESHOLD = 1e-5

                # Check if the bbox is invalid
                valid_x = (maxx - minx) ** 2 > BBOX_DIFFERENCE_THRESHOLD
                valid_y = (maxy - miny) ** 2 > BBOX_DIFFERENCE_THRESHOLD

                if valid_x:
                    width_zoom = math.log(360 / abs(maxx - minx), 2)
                else:
                    width_zoom = 15

                if valid_y:
                    height_zoom = math.log(360 / abs(maxy - miny), 2)
                else:
                    height_zoom = 15

                map_obj.center_x = center[0]
                map_obj.center_y = center[1]
                map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

            config = map_obj.viewer_json(
                request.user, *(DEFAULT_BASE_LAYERS + layers))
            config['fromLayer'] = True
        else:
            config = DEFAULT_MAP_CONFIG
    return json.dumps(config)
示例#52
0
def edit_layer_gazetteer(request, layername):
    """
    Manage the layer in the gazetteer.
    """
    def set_none_if_empty(str):
        if len(str) == 0:
            return None
        return str

    layer = _resolve_layer(request, layername,
                           'base.change_resourcebase_metadata',
                           'permissions message from grazetteer')

    status_message = None
    if request.method == 'POST':
        status_message = ''
        gazetteer_name = set_none_if_empty(
            request.POST.get('gazetteer-name', ''))
        start_attribute = set_none_if_empty(
            request.POST.get('start-attribute', ''))
        end_attribute = set_none_if_empty(request.POST.get(
            'end-attribute', ''))
        sel_start_date_format = set_none_if_empty(
            request.POST.get('sel-start-date-format', ''))
        sel_end_date_format = set_none_if_empty(
            request.POST.get('sel-end-date-format', ''))
        attributes_list = request.POST.getlist('attributes')
        for attribute in layer.attributes:
            if attribute.attribute in attributes_list:
                logger.debug('Adding %s to gazetteer...' % attribute.attribute)
                gaz_att, created = GazetteerAttribute.objects.get_or_create(
                    attribute=attribute)
                gaz_att.in_gazetteer = True
                if start_attribute == attribute.attribute:
                    gaz_att.is_start_date = True
                    gaz_att.date_format = sel_start_date_format
                if end_attribute == attribute.attribute:
                    gaz_att.is_end_date = True
                    gaz_att.date_format = sel_end_date_format
                gaz_att.save()
                status_message += ' %s' % attribute.attribute
            else:
                logger.debug('Removing %s from gazetteer...' %
                             attribute.attribute)
                gaz_att, created = GazetteerAttribute.objects.get_or_create(
                    attribute=attribute)
                gaz_att.in_gazetteer = False
                gaz_att.save()
        # now update the gazetteer
        # TODO use Celery for this
        add_to_gazetteer(layer, attributes_list, start_attribute,
                         end_attribute, gazetteer_name, request.user.username)

    gazetteer_attributes = []
    for attribute in layer.attributes:
        if hasattr(attribute, 'gazetteerattribute'):
            attribute.in_gazetteer = attribute.gazetteerattribute.in_gazetteer
        else:
            attribute.in_gazetteer = False
        gazetteer_attributes.append(attribute)
    template = 'gazetteer/edit_layer_gazetteer.html'

    return render(
        request, template, {
            "layer": layer,
            "gazetteer_attributes": gazetteer_attributes,
            "status_message": status_message,
        })