예제 #1
0
파일: signals.py 프로젝트: mdomox/geonode
    def fetch_gs_resource(values, tries):
        _max_tries = getattr(ogc_server_settings, "MAX_RETRIES", 5)
        gs_resource = gs_catalog.get_resource(name=instance.name,
                                              store=instance.store,
                                              workspace=instance.workspace)
        if not gs_resource:
            gs_resource = gs_catalog.get_resource(name=instance.alternate)

        if gs_resource:
            gs_resource.title = instance.title or ""
            gs_resource.abstract = instance.abstract or ""
            gs_resource.name = instance.name or ""

            if not values:
                values = dict(store=gs_resource.store.name,
                              storeType=gs_resource.store.resource_type,
                              alternate=gs_resource.store.workspace.name +
                              ':' + gs_resource.name,
                              title=gs_resource.title
                              or gs_resource.store.name,
                              abstract=gs_resource.abstract or '',
                              owner=instance.owner)
        else:
            msg = "There isn't a geoserver resource for this layer: %s" % instance.name
            logger.exception(msg)
            if tries >= _max_tries:
                raise GeoNodeException(msg)
            gs_resource = None
            sleep(3.00)

        return (values, gs_resource)
예제 #2
0
    def publish(self, layername):
        resource = gs_catalog.get_resource(layername,
                                           store=self.store,
                                           workspace=self.workspace)
        if not resource:
            raise Exception("Cannot Find Layer In Geoserver")
        name = resource.name
        logger.error(resource.__dict__)
        the_store = resource.store
        workspace = the_store.workspace
        layer = None
        try:
            logger.warning("=========> Creating the Layer in Django")
            layer, created = Layer.objects.get_or_create(
                name=name,
                workspace=workspace.name,
                defaults={
                    "store": the_store.name,
                    "storeType": the_store.resource_type,
                    "alternate": "%s:%s" % (workspace.name, resource.name),
                    "title": (resource.title or 'No title provided'),
                    "abstract": (resource.abstract
                                 or _('No abstract provided')),
                    "owner": self.owner,
                    "uuid": str(uuid.uuid4()),
                    "bbox_x0": Decimal(resource.native_bbox[0]),
                    "bbox_x1": Decimal(resource.native_bbox[1]),
                    "bbox_y0": Decimal(resource.native_bbox[2]),
                    "bbox_y1": Decimal(resource.native_bbox[3]),
                    "srid": resource.projection
                })
            logger.warning("=========> Settting permissions")
            # sync permissions in GeoFence
            perm_spec = json.loads(_perms_info_json(layer))
            layer.set_permissions(perm_spec)
            logger.warning("=========> Settting Attributes")
            # recalculate the layer statistics
            set_attributes_from_geoserver(layer, overwrite=True)
            layer.save()
            logger.warning("=========> Fixing Metadata Links")
            # Fix metadata links if the ip has changed
            if layer.link_set.metadata().count() > 0:
                if not created and settings.SITEURL \
                        not in layer.link_set.metadata()[0].url:
                    layer.link_set.metadata().delete()
                    layer.save()
                    metadata_links = []
                    for link in layer.link_set.metadata():
                        metadata_links.append((link.mime, link.name, link.url))
                    resource.metadata_links = metadata_links
                    gs_catalog.save(resource)

        except Exception as e:
            logger.error(e.message)
            exception_type, error, traceback = sys.exc_info()
        else:
            if layer:
                layer.set_default_permissions()
            return layer
예제 #3
0
def is_gs_resource_valid(layer):
    gs_resource = gs_catalog.get_resource(name=layer.name,
                                          store=layer.store,
                                          workspace=layer.workspace)
    if gs_resource:
        return True
    else:
        return False
def is_gs_resource_valid(layer):
    gs_resource = gs_catalog.get_resource(
            layer.name,
            store=layer.store,
            workspace=layer.workspace)
    if gs_resource:
        return True
    else:
        return False
예제 #5
0
    def fetch_gs_resource(values, tries):
        try:
            gs_resource = gs_catalog.get_resource(name=instance.name,
                                                  store=instance.store,
                                                  workspace=instance.workspace)
        except Exception:
            try:
                gs_resource = gs_catalog.get_resource(
                    name=instance.alternate,
                    store=instance.store,
                    workspace=instance.workspace)
            except Exception:
                try:
                    gs_resource = gs_catalog.get_resource(
                        name=instance.alternate or instance.typename)
                except Exception:
                    gs_resource = None

        if gs_resource:
            gs_resource.title = instance.title or ""
            gs_resource.abstract = instance.abstract or ""
            gs_resource.name = instance.name or ""

            if not values:
                values = dict(store=gs_resource.store.name,
                              storeType=gs_resource.store.resource_type,
                              alternate=gs_resource.store.workspace.name +
                              ':' + gs_resource.name,
                              title=gs_resource.title
                              or gs_resource.store.name,
                              abstract=gs_resource.abstract or '',
                              owner=instance.owner)
        else:
            msg = "There isn't a geoserver resource for this layer: %s" % instance.name
            logger.exception(msg)
            if tries >= _max_tries:
                # raise GeoNodeException(msg)
                return (values, None)
            gs_resource = None
            sleep(3.00)

        return (values, gs_resource)
예제 #6
0
파일: signals.py 프로젝트: iwlearn/geonode
 def get_gs_resource(instance):
     if type(instance) is ResourceBase:
         if hasattr(instance, 'layer'):
             resource = instance.layer
         else:
             return None
     else:
         resource = instance
     try:
         return gs_catalog.get_resource(
             resource.name,
             store=resource.store,
             workspace=resource.workspace)
     except socket_error as serr:
         if serr.errno != errno.ECONNREFUSED:
             # Not the error we are looking for, re-raise
             raise serr
         # If the connection is refused, take it easy.
         return
예제 #7
0
파일: signals.py 프로젝트: glarrain/geonode
def geoserver_pre_save(instance, sender, **kwargs):
    """Send information to geoserver.

       The attributes sent include:

        * Title
        * Abstract
        * Name
        * Keywords
        * Metadata Links,
        * Point of Contact name and url
    """

    # Don't run this signal if is a Layer from a remote service
    if getattr(instance, "service", None) is not None:
        return

    gs_resource = None

    # If the store in None then it's a new instance from an upload,
    # only in this case run the geonode_uplaod method
    if not instance.store or getattr(instance, 'overwrite', False):
        base_file, info = instance.get_base_file()

        # There is no need to process it if there is not file.
        if base_file is None:
            return
        gs_name, workspace, values, gs_resource = geoserver_upload(instance,
                                                                   base_file.file.path,
                                                                   instance.owner,
                                                                   instance.name,
                                                                   overwrite=True,
                                                                   title=instance.title,
                                                                   abstract=instance.abstract,
                                                                   # keywords=instance.keywords,
                                                                   charset=instance.charset)
        # Set fields obtained via the geoserver upload.
        instance.name = gs_name
        instance.workspace = workspace
        # Iterate over values from geoserver.
        for key in ['typename', 'store', 'storeType']:
            setattr(instance, key, values[key])

    if not gs_resource:
        gs_resource = gs_catalog.get_resource(
            instance.name,
            store=instance.store,
            workspace=instance.workspace)

    gs_resource.title = instance.title
    gs_resource.abstract = instance.abstract
    gs_resource.name = instance.name

    # Get metadata links
    metadata_links = []
    for link in instance.link_set.metadata():
        metadata_links.append((link.mime, link.name, link.url))

    gs_resource.metadata_links = metadata_links
    # gs_resource should only be called if
    # ogc_server_settings.BACKEND_WRITE_ENABLED == True
    if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
        gs_catalog.save(gs_resource)

    gs_layer = gs_catalog.get_layer(instance.name)

    if instance.poc and instance.poc:
        # gsconfig now utilizes an attribution dictionary
        gs_layer.attribution = {'title': str(instance.poc),
                                'width': None,
                                'height': None,
                                'href': None,
                                'url': None,
                                'type': None}
        profile = Profile.objects.get(username=instance.poc.username)
        gs_layer.attribution_link = settings.SITEURL[
            :-1] + profile.get_absolute_url()
        # gs_layer should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_layer)

    """Get information from geoserver.

       The attributes retrieved include:

       * Bounding Box
       * SRID
       * Download links (WMS, WCS or WFS and KML)
       * Styles (SLD)
    """

    bbox = gs_resource.latlon_bbox

    # FIXME(Ariel): Correct srid setting below
    # self.srid = gs_resource.src

    instance.srid_url = "http://www.spatialreference.org/ref/" + \
        instance.srid.replace(':', '/').lower() + "/"

    # Set bounding box values
    instance.bbox_x0 = bbox[0]
    instance.bbox_x1 = bbox[1]
    instance.bbox_y0 = bbox[2]
    instance.bbox_y1 = bbox[3]

    # store the resource to avoid another geoserver call in the post_save
    instance.gs_resource = gs_resource
예제 #8
0
파일: signals.py 프로젝트: glarrain/geonode
def geoserver_post_save(instance, sender, **kwargs):
    """Save keywords to GeoServer

       The way keywords are implemented requires the layer
       to be saved to the database before accessing them.
    """

    if type(instance) is ResourceBase:
        if hasattr(instance, 'layer'):
            instance = instance.layer
        else:
            return

    if instance.storeType == "remoteStore":
        # Save layer attributes
        set_attributes(instance)
        return

    if not getattr(instance, 'gs_resource', None):
        try:
            gs_resource = gs_catalog.get_resource(
                instance.name,
                store=instance.store,
                workspace=instance.workspace)
        except socket_error as serr:
            if serr.errno != errno.ECONNREFUSED:
                # Not the error we are looking for, re-raise
                raise serr
            # If the connection is refused, take it easy.
            return
    else:
        gs_resource = instance.gs_resource

    if gs_resource is None:
        return

    if settings.RESOURCE_PUBLISHING:
        if instance.is_published != gs_resource.advertised:
            if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
                gs_resource.advertised = instance.is_published
                gs_catalog.save(gs_resource)

    if any(instance.keyword_list()):
        gs_resource.keywords = instance.keyword_list()
        # gs_resource should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_resource)

    bbox = gs_resource.latlon_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML
    links = wms_links(ogc_server_settings.public_url + 'wms?',
                      instance.typename.encode('utf-8'), instance.bbox_string,
                      instance.srid, height, width)

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   name=ugettext(name),
                                   defaults=dict(
                                       extension=ext,
                                       url=wms_url,
                                       mime=mime,
                                       link_type='image',
                                   )
                                   )

    if instance.storeType == "dataStore":
        links = wfs_links(
            ogc_server_settings.public_url +
            'wfs?',
            instance.typename.encode('utf-8'))
        for ext, name, mime, wfs_url in links:
            if mime == 'SHAPE-ZIP':
                name = 'Zipped Shapefile'
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wfs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           url=wfs_url,
                                           link_type='data',
                                       )
                                       )

        if gs_resource.store.type and gs_resource.store.type.lower() == 'geogig' and \
                gs_resource.store.connection_parameters.get('geogig_repository'):

            repo_url = '{url}geogig/{geogig_repository}'.format(
                url=ogc_server_settings.public_url,
                geogig_repository=gs_resource.store.connection_parameters.get('geogig_repository'))

            path = gs_resource.dom.findall('nativeName')

            if path:
                path = 'path={path}'.format(path=path[0].text)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=repo_url,
                                       defaults=dict(extension='html',
                                                     name='Clone in GeoGig',
                                                     mime='text/xml',
                                                     link_type='html'
                                                     )
                                       )

            def command_url(command):
                return "{repo_url}/{command}.json?{path}".format(repo_url=repo_url,
                                                                 path=path,
                                                                 command=command)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('log'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig log',
                                                     mime='application/json',
                                                     link_type='html'
                                                     )
                                       )

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('statistics'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig statistics',
                                                     mime='application/json',
                                                     link_type='html'
                                                     )
                                       )

    elif instance.storeType == 'coverageStore':

        links = wcs_links(ogc_server_settings.public_url + 'wcs?',
                          instance.typename.encode('utf-8'))

    for ext, name, mime, wcs_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=wcs_url,
                                   defaults=dict(
                                       extension=ext,
                                       name=name,
                                       mime=mime,
                                       link_type='data',
                                   )
                                   )

    kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "download"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_download,
                               defaults=dict(
                                   extension='kml',
                                   name="KML",
                                   mime='text/xml',
                                   link_type='data',
                               )
                               )

    kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "refresh"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_view,
                               defaults=dict(
                                   extension='kml',
                                   name="View in Google Earth",
                                   mime='text/xml',
                                   link_type='data',
                               )
                               )

    tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url +
                'layers=%s' % instance.typename.encode('utf-8') +
                '&zoom={z}&x={x}&y={y}' +
                '&format=image/png8'
                )

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=tile_url,
                               defaults=dict(
                                   extension='tiles',
                                   name="Tiles",
                                   mime='image/png',
                                   link_type='image',
                               )
                               )

    html_link_url = '%s%s' % (
        settings.SITEURL[:-1], instance.get_absolute_url())

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=html_link_url,
                               defaults=dict(
                                   extension='html',
                                   name=instance.typename,
                                   mime='text/html',
                                   link_type='html',
                               )
                               )

    params = {
        'layers': instance.typename.encode('utf-8'),
        'format': 'image/png8',
        'width': 200,
        'height': 150,
        'TIME': '-99999999999-01-01T00:00:00.0Z/99999999999-01-01T00:00:00.0Z'

    }

    # Avoid using urllib.urlencode here because it breaks the url.
    # commas and slashes in values get encoded and then cause trouble
    # with the WMS parser.
    p = "&".join("%s=%s" % item for item in params.items())

    thumbnail_remote_url = ogc_server_settings.PUBLIC_LOCATION + \
        "wms/reflect?" + p

    thumbnail_create_url = ogc_server_settings.LOCATION + \
        "wms/reflect?" + p

    create_thumbnail(instance, thumbnail_remote_url, thumbnail_create_url, ogc_client=http_client)

    legend_url = ogc_server_settings.PUBLIC_LOCATION + \
        'wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER=' + \
        instance.typename + '&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on'

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=legend_url,
                               defaults=dict(
                                   extension='png',
                                   name='Legend',
                                   url=legend_url,
                                   mime='image/png',
                                   link_type='image',
                               )
                               )

    ogc_wms_path = '%s/wms' % instance.workspace
    ogc_wms_url = urljoin(ogc_server_settings.public_url, ogc_wms_path)
    ogc_wms_name = 'OGC WMS: %s Service' % instance.workspace
    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=ogc_wms_url,
                               defaults=dict(
                                   extension='html',
                                   name=ogc_wms_name,
                                   url=ogc_wms_url,
                                   mime='text/html',
                                   link_type='OGC:WMS',
                               )
                               )

    if instance.storeType == "dataStore":
        ogc_wfs_path = '%s/wfs' % instance.workspace
        ogc_wfs_url = urljoin(ogc_server_settings.public_url, ogc_wfs_path)
        ogc_wfs_name = 'OGC WFS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wfs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wfs_name,
                                       url=ogc_wfs_url,
                                       mime='text/html',
                                       link_type='OGC:WFS',
                                   )
                                   )

    if instance.storeType == "coverageStore":
        ogc_wcs_path = '%s/wcs' % instance.workspace
        ogc_wcs_url = urljoin(ogc_server_settings.public_url, ogc_wcs_path)
        ogc_wcs_name = 'OGC WCS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wcs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wcs_name,
                                       url=ogc_wcs_url,
                                       mime='text/html',
                                       link_type='OGC:WCS',
                                   )
                                   )

    # remove links that belong to and old address

    for link in instance.link_set.all():
        if not urlparse(
            settings.SITEURL).hostname == urlparse(
            link.url).hostname and not urlparse(
            ogc_server_settings.public_url).hostname == urlparse(
                link.url).hostname:
            link.delete()

    # Save layer attributes
    set_attributes(instance)

    # Save layer styles
    set_styles(instance, gs_catalog)
    # NOTTODO by simod: we should not do this!
    # need to be removed when fixing #2015
    from geonode.catalogue.models import catalogue_post_save
    from geonode.layers.models import Layer
    catalogue_post_save(instance, Layer)
예제 #9
0
def geoserver_post_save(instance, sender, **kwargs):
    """Save keywords to GeoServer

       The way keywords are implemented requires the layer
       to be saved to the database before accessing them.
    """

    if instance.storeType == "remoteStore":
        #Save layer attributes
        set_attributes(instance)
        return

    url = ogc_server_settings.internal_rest

    try:
        gs_resource = gs_catalog.get_resource(instance.name,
                                              store=instance.store,
                                              workspace=instance.workspace)
    except socket_error as serr:
        if serr.errno != errno.ECONNREFUSED:
            # Not the error we are looking for, re-raise
            raise serr
        # If the connection is refused, take it easy.
        return

    if gs_resource is None:
        return

    if any(instance.keyword_list()):
        gs_resource.keywords = instance.keyword_list()

        #gs_resource should only be called if ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_resource)

    bbox = gs_resource.latlon_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML

    links = wms_links(ogc_server_settings.public_url + 'wms?',
                      instance.typename.encode('utf-8'), instance.bbox_string,
                      instance.srid, height, width)

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   name=ugettext(name),
                                   defaults=dict(
                                       extension=ext,
                                       url=wms_url,
                                       mime=mime,
                                       link_type='image',
                                   ))

    if instance.storeType == "dataStore":
        links = wfs_links(ogc_server_settings.public_url + 'wfs?',
                          instance.typename.encode('utf-8'))
        for ext, name, mime, wfs_url in links:
            if mime == 'SHAPE-ZIP':
                name = 'Zipped Shapefile'
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wfs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           url=wfs_url,
                                           link_type='data',
                                       ))

    elif instance.storeType == 'coverageStore':
        #FIXME(Ariel): This works for public layers, does it work for restricted too?
        # would those end up with no geotiff links, like, forever?
        permissions = instance.get_all_level_info()

        instance.set_permissions(
            {'users': {
                'AnonymousUser': ['view_resourcebase']
            }})

        try:
            #Potentially 3 dimensions can be returned by the grid if there is a z
            #axis.  Since we only want width/height, slice to the second dimension
            covWidth, covHeight = get_coverage_grid_extent(instance)[:2]
        except GeoNodeException, e:
            msg = _('Could not create a download link for layer.')
            logger.warn(msg, e)
        else:

            links = wcs_links(ogc_server_settings.public_url + 'wcs?',
                              instance.typename.encode('utf-8'),
                              bbox=gs_resource.native_bbox[:-1],
                              crs=gs_resource.native_bbox[-1],
                              height=str(covHeight),
                              width=str(covWidth))

            for ext, name, mime, wcs_url in links:
                Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                           url=wcs_url,
                                           defaults=dict(
                                               extension=ext,
                                               name=name,
                                               mime=mime,
                                               link_type='data',
                                           ))

        instance.set_permissions(permissions)
예제 #10
0
def geoserver_post_save(instance, sender, **kwargs):
    """Save keywords to GeoServer

       The way keywords are implemented requires the layer
       to be saved to the database before accessing them.
    """
    # Don't run this signal handler if it is a tile layer
    #    Currently only gpkg files containing tiles will have this type & will be served via MapProxy.
    if hasattr(instance, 'storeType') and getattr(instance,
                                                  'storeType') == 'tileStore':
        return

    if type(instance) is ResourceBase:
        if hasattr(instance, 'layer'):
            instance = instance.layer
        else:
            return

    if instance.storeType == "remoteStore":
        # Save layer attributes
        set_attributes_from_geoserver(instance)
        return

    if not getattr(instance, 'gs_resource', None):
        try:
            gs_resource = gs_catalog.get_resource(instance.name,
                                                  store=instance.store,
                                                  workspace=instance.workspace)
        except socket_error as serr:
            if serr.errno != errno.ECONNREFUSED:
                # Not the error we are looking for, re-raise
                raise serr
            # If the connection is refused, take it easy.
            return
    else:
        gs_resource = instance.gs_resource

    if gs_resource is None:
        return

    if settings.RESOURCE_PUBLISHING:
        if instance.is_published != gs_resource.advertised:
            if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
                gs_resource.advertised = instance.is_published
                gs_catalog.save(gs_resource)

    if any(instance.keyword_list()):
        gs_resource.keywords = instance.keyword_list()
        # gs_resource should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_resource)

    bbox = gs_resource.latlon_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML
    links = wms_links(ogc_server_settings.public_url + 'wms?',
                      instance.typename.encode('utf-8'), instance.bbox_string,
                      instance.srid, height, width)

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   name=ugettext(name),
                                   defaults=dict(
                                       extension=ext,
                                       url=wms_url,
                                       mime=mime,
                                       link_type='image',
                                   ))

    if instance.storeType == "dataStore":
        links = wfs_links(ogc_server_settings.public_url + 'wfs?',
                          instance.typename.encode('utf-8'))
        for ext, name, mime, wfs_url in links:
            if mime == 'SHAPE-ZIP':
                name = 'Zipped Shapefile'
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wfs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           url=wfs_url,
                                           link_type='data',
                                       ))

        gs_store_type = gs_resource.store.type.lower(
        ) if gs_resource.store.type else None
        geogig_repository = gs_resource.store.connection_parameters.get(
            'geogig_repository', '')
        geogig_repo_name = geogig_repository.replace('geoserver://', '')

        if gs_store_type == 'geogig' and geogig_repo_name:

            repo_url = '{url}geogig/repos/{repo_name}'.format(
                url=ogc_server_settings.public_url, repo_name=geogig_repo_name)

            path = gs_resource.dom.findall('nativeName')

            if path:
                path = 'path={path}'.format(path=path[0].text)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=repo_url,
                                       defaults=dict(extension='html',
                                                     name='Clone in GeoGig',
                                                     mime='text/xml',
                                                     link_type='html'))

            def command_url(command):
                return "{repo_url}/{command}.json?{path}".format(
                    repo_url=repo_url, path=path, command=command)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('log'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig log',
                                                     mime='application/json',
                                                     link_type='html'))

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('statistics'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig statistics',
                                                     mime='application/json',
                                                     link_type='html'))

    elif instance.storeType == 'coverageStore':

        links = wcs_links(ogc_server_settings.public_url + 'wcs?',
                          instance.typename.encode('utf-8'))

    for ext, name, mime, wcs_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=wcs_url,
                                   defaults=dict(
                                       extension=ext,
                                       name=name,
                                       mime=mime,
                                       link_type='data',
                                   ))

    kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "download"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_download,
                               defaults=dict(
                                   extension='kml',
                                   name="KML",
                                   mime='text/xml',
                                   link_type='data',
                               ))

    kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "refresh"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_view,
                               defaults=dict(
                                   extension='kml',
                                   name="View in Google Earth",
                                   mime='text/xml',
                                   link_type='data',
                               ))

    html_link_url = '%s%s' % (settings.SITEURL[:-1],
                              instance.get_absolute_url())

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=html_link_url,
                               defaults=dict(
                                   extension='html',
                                   name=instance.typename,
                                   mime='text/html',
                                   link_type='html',
                               ))

    create_gs_thumbnail(instance, overwrite=True)

    legend_url = ogc_server_settings.PUBLIC_LOCATION + \
        'wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER=' + \
        instance.typename + '&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on'

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=legend_url,
                               defaults=dict(
                                   extension='png',
                                   name='Legend',
                                   url=legend_url,
                                   mime='image/png',
                                   link_type='image',
                               ))

    ogc_wms_path = '%s/wms' % instance.workspace
    ogc_wms_url = urljoin(ogc_server_settings.public_url, ogc_wms_path)
    ogc_wms_name = 'OGC WMS: %s Service' % instance.workspace
    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=ogc_wms_url,
                               defaults=dict(
                                   extension='html',
                                   name=ogc_wms_name,
                                   url=ogc_wms_url,
                                   mime='text/html',
                                   link_type='OGC:WMS',
                               ))

    if instance.storeType == "dataStore":
        ogc_wfs_path = '%s/wfs' % instance.workspace
        ogc_wfs_url = urljoin(ogc_server_settings.public_url, ogc_wfs_path)
        ogc_wfs_name = 'OGC WFS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wfs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wfs_name,
                                       url=ogc_wfs_url,
                                       mime='text/html',
                                       link_type='OGC:WFS',
                                   ))

    if instance.storeType == "coverageStore":
        ogc_wcs_path = '%s/wcs' % instance.workspace
        ogc_wcs_url = urljoin(ogc_server_settings.public_url, ogc_wcs_path)
        ogc_wcs_name = 'OGC WCS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wcs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wcs_name,
                                       url=ogc_wcs_url,
                                       mime='text/html',
                                       link_type='OGC:WCS',
                                   ))

    # remove links that belong to and old address

    for link in instance.link_set.all():
        if not urlparse(settings.SITEURL).hostname == urlparse(
                link.url).hostname and not urlparse(
                    ogc_server_settings.public_url).hostname == urlparse(
                        link.url).hostname:
            link.delete()

    # Define the link after the cleanup, we should use this more rather then remove
    # potential parasites
    tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url +
                'layers=%s' % instance.typename.encode('utf-8') +
                '&zoom={z}&x={x}&y={y}' + '&format=image/png8')

    link, created = Link.objects.get_or_create(
        resource=instance.resourcebase_ptr,
        extension='tiles',
        name="Tiles",
        mime='image/png',
        link_type='image',
    )
    if created:
        Link.objects.filter(pk=link.pk).update(url=tile_url)

    # Save layer attributes
    set_attributes_from_geoserver(instance)

    # Save layer styles
    set_styles(instance, gs_catalog)
    # NOTTODO by simod: we should not do this!
    # need to be removed when fixing #2015
    from geonode.catalogue.models import catalogue_post_save
    from geonode.layers.models import Layer
    catalogue_post_save(instance, Layer)
예제 #11
0
def geoserver_pre_save(instance, sender, **kwargs):
    """Send information to geoserver.

       The attributes sent include:

        * Title
        * Abstract
        * Name
        * Keywords
        * Metadata Links,
        * Point of Contact name and url
    """

    # Don't run this signal handler if it is a tile layer or a remote store (Service)
    #    Currently only gpkg files containing tiles will have this type & will be served via MapProxy.
    if hasattr(instance, 'storeType') and getattr(
            instance, 'storeType') in ['tileStore', 'remoteStore']:
        return

    gs_resource = None

    # If the store in None then it's a new instance from an upload,
    # only in this case run the geonode_uplaod method
    if not instance.store or getattr(instance, 'overwrite', False):
        base_file, info = instance.get_base_file()

        # There is no need to process it if there is not file.
        if base_file is None:
            return
        gs_name, workspace, values, gs_resource = geoserver_upload(
            instance,
            base_file.file.path,
            instance.owner,
            instance.name,
            overwrite=True,
            title=instance.title,
            abstract=instance.abstract,
            # keywords=instance.keywords,
            charset=instance.charset)
        # Set fields obtained via the geoserver upload.
        instance.name = gs_name
        instance.workspace = workspace
        # Iterate over values from geoserver.
        for key in ['typename', 'store', 'storeType']:
            setattr(instance, key, values[key])

    if not gs_resource:
        gs_resource = gs_catalog.get_resource(instance.name,
                                              store=instance.store,
                                              workspace=instance.workspace)

    if gs_resource:
        gs_resource.title = instance.title if instance.title else ""
        gs_resource.abstract = instance.abstract if instance.abstract else ""
        gs_resource.name = instance.name if instance.name else ""

    # Get metadata links
    metadata_links = []
    for link in instance.link_set.metadata():
        metadata_links.append((link.mime, link.name, link.url))

    if gs_resource:
        gs_resource.metadata_links = metadata_links
    # gs_resource should only be called if
    # ogc_server_settings.BACKEND_WRITE_ENABLED == True
    if gs_resource and getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED",
                               True):
        gs_catalog.save(gs_resource)

    if instance.storeType and instance.storeType == 'layerGroup':
        gs_layer = gs_catalog.get_layergroup(name=instance.name,
                                             workspace=instance.workspace)
    else:
        gs_layer = gs_catalog.get_layer(instance.name)

    if instance.poc and instance.poc:
        # gsconfig now utilizes an attribution dictionary
        gs_layer.attribution = {
            'title': str(instance.poc),
            'width': None,
            'height': None,
            'href': None,
            'url': None,
            'type': None
        }
        profile = Profile.objects.get(username=instance.poc.username)
        gs_layer.attribution_link = settings.SITEURL[:
                                                     -1] + profile.get_absolute_url(
                                                     )
        # gs_layer should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            try:
                # Some geogig layers will return a 500 on save
                gs_catalog.save(gs_layer)
            except geoserver.catalog.FailedRequestError:
                pass
    """Get information from geoserver.

       The attributes retrieved include:

       * Bounding Box
       * SRID
       * Download links (WMS, WCS or WFS and KML)
       * Styles (SLD)
    """

    if gs_resource:
        bbox = gs_resource.latlon_bbox

        # FIXME(Ariel): Correct srid setting below
        # self.srid = gs_resource.src

        instance.srid_url = "http://www.spatialreference.org/ref/" + \
            instance.srid.replace(':', '/').lower() + "/"

        # Set bounding box values
        instance.bbox_x0 = bbox[0]
        instance.bbox_x1 = bbox[1]
        instance.bbox_y0 = bbox[2]
        instance.bbox_y1 = bbox[3]

        # store the resource to avoid another geoserver call in the post_save
        instance.gs_resource = gs_resource
예제 #12
0
파일: signals.py 프로젝트: jsiochi/geonode
def geoserver_post_save(instance, sender, **kwargs):
    """Save keywords to GeoServer

       The way keywords are implemented requires the layer
       to be saved to the database before accessing them.
    """
    url = ogc_server_settings.internal_rest

    try:
        gs_resource = gs_catalog.get_resource(instance.name)
    except socket_error as serr:
        if serr.errno != errno.ECONNREFUSED:
            # Not the error we are looking for, re-raise
            raise serr
        # If the connection is refused, take it easy.
        return

    if any(instance.keyword_list()):
        gs_resource.keywords = instance.keyword_list()

        # gs_resource should only be called if ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_resource)

    bbox = gs_resource.latlon_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML

    links = wms_links(
        ogc_server_settings.public_url + "wms?",
        instance.typename.encode("utf-8"),
        instance.bbox_string,
        instance.srid,
        height,
        width,
    )

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(
            resource=instance.resourcebase_ptr,
            name=ugettext(name),
            defaults=dict(extension=ext, url=wms_url, mime=mime, link_type="image"),
        )

    if instance.storeType == "dataStore":
        links = wfs_links(ogc_server_settings.public_url + "wfs?", instance.typename.encode("utf-8"))
        for ext, name, mime, wfs_url in links:
            if mime == "SHAPE-ZIP":
                name = "Zipped Shapefile"
            Link.objects.get_or_create(
                resource=instance.resourcebase_ptr,
                url=wfs_url,
                defaults=dict(extension=ext, name=name, mime=mime, url=wfs_url, link_type="data"),
            )

    elif instance.storeType == "coverageStore":
        # FIXME(Ariel): This works for public layers, does it work for restricted too?
        # would those end up with no geotiff links, like, forever?
        permissions = {}
        permissions["anonymous"] = instance.get_gen_level(ANONYMOUS_USERS)
        permissions["authenticated"] = instance.get_gen_level(AUTHENTICATED_USERS)
        instance.set_gen_level(ANONYMOUS_USERS, "layer_readonly")

        try:
            # Potentially 3 dimensions can be returned by the grid if there is a z
            # axis.  Since we only want width/height, slice to the second dimension
            covWidth, covHeight = get_coverage_grid_extent(instance)[:2]
        except GeoNodeException, e:
            msg = _("Could not create a download link for layer.")
            logger.warn(msg, e)
        else:

            links = wcs_links(
                ogc_server_settings.public_url + "wcs?",
                instance.typename.encode("utf-8"),
                bbox=gs_resource.native_bbox[:-1],
                crs=gs_resource.native_bbox[-1],
                height=str(covHeight),
                width=str(covWidth),
            )

            for ext, name, mime, wcs_url in links:
                Link.objects.get_or_create(
                    resource=instance.resourcebase_ptr,
                    url=wcs_url,
                    defaults=dict(extension=ext, name=name, mime=mime, link_type="data"),
                )

        instance.set_gen_level(ANONYMOUS_USERS, permissions["anonymous"])
        instance.set_gen_level(AUTHENTICATED_USERS, permissions["authenticated"])
예제 #13
0
def geoserver_post_save_local(instance, *args, **kwargs):
    """Send information to geoserver.

       The attributes sent include:

        * Title
        * Abstract
        * Name
        * Keywords
        * Metadata Links,
        * Point of Contact name and url
    """
    # Don't run this signal if is a Layer from a remote service
    if getattr(instance, "remote_service", None) is not None:
        return

    # Don't run this signal handler if it is a tile layer or a remote store (Service)
    #    Currently only gpkg files containing tiles will have this type & will be served via MapProxy.
    if hasattr(instance, 'storeType') and getattr(
            instance, 'storeType') in ['tileStore', 'remoteStore']:
        return instance

    gs_resource = None
    values = None

    # If the store in None then it's a new instance from an upload,
    # only in this case run the geoserver_upload method
    if not instance.store or getattr(instance, 'overwrite', False):
        base_file, info = instance.get_base_file()

        # There is no need to process it if there is not file.
        if base_file is None:
            return
        gs_name, workspace, values, gs_resource = geoserver_upload(
            instance,
            base_file.file.path,
            instance.owner,
            instance.name,
            overwrite=True,
            title=instance.title,
            abstract=instance.abstract,
            # keywords=instance.keywords,
            charset=instance.charset)

    if not gs_resource:
        gs_resource = gs_catalog.get_resource(instance.name,
                                              store=instance.store,
                                              workspace=instance.workspace)
        if not gs_resource:
            gs_resource = gs_catalog.get_resource(instance.alternate)

    if gs_resource:
        gs_resource.title = instance.title or ""
        gs_resource.abstract = instance.abstract or ""
        gs_resource.name = instance.name or ""

        if not values:
            values = dict(store=gs_resource.store.name,
                          storeType=gs_resource.store.resource_type,
                          alternate=gs_resource.store.workspace.name + ':' +
                          gs_resource.name,
                          title=gs_resource.title or gs_resource.store.name,
                          abstract=gs_resource.abstract or '',
                          owner=instance.owner)
    else:
        msg = "There isn't a geoserver resource for this layer: %s" % instance.name
        logger.exception(msg)
        raise Exception(msg)

    # Get metadata links
    metadata_links = []
    for link in instance.link_set.metadata():
        metadata_links.append((link.mime, link.name, link.url))

    gs_resource.metadata_links = metadata_links
    # gs_resource should only be called if
    # ogc_server_settings.BACKEND_WRITE_ENABLED == True
    if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
        try:
            gs_catalog.save(gs_resource)
        except geoserver.catalog.FailedRequestError as e:
            msg = (
                'Error while trying to save resource named %s in GeoServer, '
                'try to use: "%s"' % (gs_resource, str(e)))
            e.args = (msg, )
            logger.exception(e)

    gs_layer = gs_catalog.get_layer(instance.name)

    if not gs_layer:
        gs_layer = gs_catalog.get_layer(instance.alternate)

    if gs_layer and instance.poc:
        # gsconfig now utilizes an attribution dictionary
        gs_layer.attribution = {
            'title': str(instance.poc),
            'width': None,
            'height': None,
            'href': None,
            'url': None,
            'type': None
        }
        profile = Profile.objects.get(username=instance.poc.username)
        gs_layer.attribution_link = settings.SITEURL[:
                                                     -1] + profile.get_absolute_url(
                                                     )
        # gs_layer should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            try:
                gs_catalog.save(gs_layer)
            except geoserver.catalog.FailedRequestError as e:
                msg = (
                    'Error while trying to save layer named %s in GeoServer, '
                    'try to use: "%s"' % (gs_layer, str(e)))
                e.args = (msg, )
                logger.exception(e)

    if type(instance) is ResourceBase:
        if hasattr(instance, 'layer'):
            instance = instance.layer
        else:
            return

    if instance.storeType == "remoteStore":
        # Save layer attributes
        set_attributes_from_geoserver(instance)
        return
    """Get information from geoserver.

       The attributes retrieved include:

       * Bounding Box
       * SRID
       * Download links (WMS, WCS or WFS and KML)
       * Styles (SLD)
    """
    # instance.name = instance.name or gs_layer.name
    # instance.title = instance.title or gs_resource.title
    instance.abstract = gs_resource.abstract or ''
    instance.workspace = gs_resource.store.workspace.name
    instance.store = gs_resource.store.name

    bbox = gs_resource.native_bbox

    # Set bounding box values
    instance.bbox_x0 = bbox[0]
    instance.bbox_x1 = bbox[1]
    instance.bbox_y0 = bbox[2]
    instance.bbox_y1 = bbox[3]
    instance.srid = bbox[4]

    if instance.srid:
        instance.srid_url = "http://www.spatialreference.org/ref/" + \
            instance.srid.replace(':', '/').lower() + "/"
    else:
        raise GeoNodeException("Invalid Projection. Layer is missing CRS!")

    # Iterate over values from geoserver.
    for key in ['alternate', 'store', 'storeType']:
        # attr_name = key if 'typename' not in key else 'alternate'
        # print attr_name
        setattr(instance, key, values[key])

    if settings.RESOURCE_PUBLISHING:
        if instance.is_published != gs_resource.advertised:
            if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
                gs_resource.advertised = 'true' if instance.is_published else 'false'
                gs_catalog.save(gs_resource)

    if not settings.FREETEXT_KEYWORDS_READONLY:
        if gs_resource.keywords:
            for keyword in gs_resource.keywords:
                if keyword not in instance.keyword_list():
                    instance.keywords.add(keyword)

    if any(instance.keyword_list()):
        keywords = instance.keyword_list()
        gs_resource.keywords = list(set(keywords))

        # gs_resource should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            try:
                gs_catalog.save(gs_resource)
            except geoserver.catalog.FailedRequestError as e:
                msg = (
                    'Error while trying to save resource named %s in GeoServer, '
                    'try to use: "%s"' % (gs_resource, str(e)))
                e.args = (msg, )
                logger.exception(e)

    to_update = {
        'title': instance.title or instance.name,
        'abstract': instance.abstract or "",
        'alternate': instance.alternate,
        'bbox_x0': instance.bbox_x0,
        'bbox_x1': instance.bbox_x1,
        'bbox_y0': instance.bbox_y0,
        'bbox_y1': instance.bbox_y1,
        'srid': instance.srid
    }

    # Update ResourceBase
    resources = ResourceBase.objects.filter(id=instance.resourcebase_ptr.id)
    resources.update(**to_update)

    # to_update['name'] = instance.name,
    to_update['workspace'] = instance.workspace
    to_update['store'] = instance.store
    to_update['storeType'] = instance.storeType
    to_update['typename'] = instance.alternate

    # Save all the modified information in the instance without triggering signals.
    Layer.objects.filter(id=instance.id).update(**to_update)

    # Refresh from DB
    instance.refresh_from_db()

    # store the resource to avoid another geoserver call in the post_save
    instance.gs_resource = gs_resource

    bbox = gs_resource.native_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML
    links = wms_links(ogc_server_settings.public_url + 'wms?',
                      instance.alternate.encode('utf-8'), instance.bbox_string,
                      instance.srid, height, width)

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   name=ugettext(name),
                                   defaults=dict(
                                       extension=ext,
                                       url=wms_url,
                                       mime=mime,
                                       link_type='image',
                                   ))

    if instance.storeType == "dataStore":
        links = wfs_links(ogc_server_settings.public_url + 'wfs?',
                          instance.alternate.encode('utf-8'))
        for ext, name, mime, wfs_url in links:
            if mime == 'SHAPE-ZIP':
                name = 'Zipped Shapefile'
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wfs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           url=wfs_url,
                                           link_type='data',
                                       ))

        gs_store_type = gs_resource.store.type.lower(
        ) if gs_resource.store.type else None
        geogig_repository = gs_resource.store.connection_parameters.get(
            'geogig_repository', '')
        geogig_repo_name = geogig_repository.replace('geoserver://', '')

        if gs_store_type == 'geogig' and geogig_repo_name:

            repo_url = '{url}geogig/repos/{repo_name}'.format(
                url=ogc_server_settings.public_url, repo_name=geogig_repo_name)

            path = gs_resource.dom.findall('nativeName')

            if path:
                path = 'path={path}'.format(path=path[0].text)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=repo_url,
                                       defaults=dict(extension='html',
                                                     name='Clone in GeoGig',
                                                     mime='text/xml',
                                                     link_type='html'))

            def command_url(command):
                return "{repo_url}/{command}.json?{path}".format(
                    repo_url=repo_url, path=path, command=command)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('log'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig log',
                                                     mime='application/json',
                                                     link_type='html'))

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('statistics'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig statistics',
                                                     mime='application/json',
                                                     link_type='html'))

    elif instance.storeType == 'coverageStore':
        links = wcs_links(ogc_server_settings.public_url + 'wcs?',
                          instance.alternate.encode('utf-8'),
                          ','.join(str(x) for x in instance.bbox[0:4]),
                          instance.srid)

    for ext, name, mime, wcs_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=wcs_url,
                                   defaults=dict(
                                       extension=ext,
                                       name=name,
                                       mime=mime,
                                       link_type='data',
                                   ))

    kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.alternate.encode('utf-8'), 'mode': "download"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_download,
                               defaults=dict(
                                   extension='kml',
                                   name="KML",
                                   mime='text/xml',
                                   link_type='data',
                               ))

    kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.alternate.encode('utf-8'), 'mode': "refresh"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_view,
                               defaults=dict(
                                   extension='kml',
                                   name="View in Google Earth",
                                   mime='text/xml',
                                   link_type='data',
                               ))

    html_link_url = '%s%s' % (settings.SITEURL[:-1],
                              instance.get_absolute_url())

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=html_link_url,
                               defaults=dict(
                                   extension='html',
                                   name=instance.alternate,
                                   mime='text/html',
                                   link_type='html',
                               ))

    # some thumbnail generators will update thumbnail_url.  If so, don't
    # immediately re-generate the thumbnail here.  use layer#save(update_fields=['thumbnail_url'])
    if not ('update_fields' in kwargs and kwargs['update_fields'] is not None
            and 'thumbnail_url' in kwargs['update_fields']):
        logger.info("Creating Thumbnail for Layer [%s]" % (instance.alternate))
        create_gs_thumbnail(instance, overwrite=True)

    legend_url = ogc_server_settings.PUBLIC_LOCATION + \
        'wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER=' + \
        instance.alternate + '&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on'

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=legend_url,
                               defaults=dict(
                                   extension='png',
                                   name='Legend',
                                   url=legend_url,
                                   mime='image/png',
                                   link_type='image',
                               ))

    ogc_wms_path = '%s/ows' % instance.workspace
    ogc_wms_url = urljoin(ogc_server_settings.public_url, ogc_wms_path)
    ogc_wms_name = 'OGC WMS: %s Service' % instance.workspace
    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=ogc_wms_url,
                               defaults=dict(
                                   extension='html',
                                   name=ogc_wms_name,
                                   url=ogc_wms_url,
                                   mime='text/html',
                                   link_type='OGC:WMS',
                               ))

    if instance.storeType == "dataStore":
        ogc_wfs_path = '%s/wfs' % instance.workspace
        ogc_wfs_url = urljoin(ogc_server_settings.public_url, ogc_wfs_path)
        ogc_wfs_name = 'OGC WFS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wfs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wfs_name,
                                       url=ogc_wfs_url,
                                       mime='text/html',
                                       link_type='OGC:WFS',
                                   ))

    if instance.storeType == "coverageStore":
        ogc_wcs_path = '%s/wcs' % instance.workspace
        ogc_wcs_url = urljoin(ogc_server_settings.public_url, ogc_wcs_path)
        ogc_wcs_name = 'OGC WCS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wcs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wcs_name,
                                       url=ogc_wcs_url,
                                       mime='text/html',
                                       link_type='OGC:WCS',
                                   ))

    # remove links that belong to and old address
    for link in instance.link_set.all():
        if not urlparse(settings.SITEURL).hostname == urlparse(
                link.url).hostname and not urlparse(
                    ogc_server_settings.public_url).hostname == urlparse(
                        link.url).hostname:
            link.delete()

    # Define the link after the cleanup, we should use this more rather then remove
    # potential parasites
    tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url +
                'layers=%s' % instance.alternate.encode('utf-8') +
                '&zoom={z}&x={x}&y={y}' + '&format=image/png8')

    link, created = Link.objects.get_or_create(
        resource=instance.resourcebase_ptr,
        extension='tiles',
        name="Tiles",
        mime='image/png',
        link_type='image',
    )
    if created:
        Link.objects.filter(pk=link.pk).update(url=tile_url)

    # Save layer attributes
    set_attributes_from_geoserver(instance)

    # Save layer styles
    set_styles(instance, gs_catalog)

    # NOTTODO by simod: we should not do this!
    # need to be removed when fixing #2015
    catalogue_post_save(instance, Layer)
예제 #14
0
def geoserver_post_save(instance, sender, **kwargs):
    """Save keywords to GeoServer

       The way keywords are implemented requires the layer
       to be saved to the database before accessing them.
    """

    if type(instance) is ResourceBase:
        if hasattr(instance, 'layer'):
            instance = instance.layer
        else:
            return

    if instance.storeType == "remoteStore":
        # Save layer attributes
        set_attributes(instance)
        return

    try:
        gs_resource = gs_catalog.get_resource(instance.name,
                                              store=instance.store,
                                              workspace=instance.workspace)
    except socket_error as serr:
        if serr.errno != errno.ECONNREFUSED:
            # Not the error we are looking for, re-raise
            raise serr
        # If the connection is refused, take it easy.
        return

    if gs_resource is None:
        return

    if settings.RESOURCE_PUBLISHING:
        if instance.is_published != gs_resource.advertised:
            if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
                gs_resource.advertised = instance.is_published
                gs_catalog.save(gs_resource)

    if any(instance.keyword_list()):
        gs_resource.keywords = instance.keyword_list()
        # gs_resource should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_resource)

    bbox = gs_resource.latlon_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML
    links = wms_links(ogc_server_settings.public_url + 'wms?',
                      instance.typename.encode('utf-8'), instance.bbox_string,
                      instance.srid, height, width)

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   name=ugettext(name),
                                   defaults=dict(
                                       extension=ext,
                                       url=wms_url,
                                       mime=mime,
                                       link_type='image',
                                   ))

    if instance.storeType == "dataStore":
        links = wfs_links(ogc_server_settings.public_url + 'wfs?',
                          instance.typename.encode('utf-8'))
        for ext, name, mime, wfs_url in links:
            if mime == 'SHAPE-ZIP':
                name = 'Zipped Shapefile'
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wfs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           url=wfs_url,
                                           link_type='data',
                                       ))

        if gs_resource.store.type and gs_resource.store.type.lower() == 'geogig' and \
                gs_resource.store.connection_parameters.get('geogig_repository'):

            repo_url = '{url}geogig/{geogig_repository}'.format(
                url=ogc_server_settings.public_url,
                geogig_repository=gs_resource.store.connection_parameters.get(
                    'geogig_repository'))

            path = gs_resource.dom.findall('nativeName')

            if path:
                path = 'path={path}'.format(path=path[0].text)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=repo_url,
                                       defaults=dict(extension='html',
                                                     name='Clone in GeoGig',
                                                     mime='text/xml',
                                                     link_type='html'))

            command_url = lambda command: "{repo_url}/{command}.json?{path}".format(
                repo_url=repo_url, path=path, command=command)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('log'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig log',
                                                     mime='application/json',
                                                     link_type='html'))

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('statistics'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig statistics',
                                                     mime='application/json',
                                                     link_type='html'))

    elif instance.storeType == 'coverageStore':
        # FIXME(Ariel): This works for public layers, does it work for restricted too?
        # would those end up with no geotiff links, like, forever?
        permissions = instance.get_all_level_info()

        instance.set_permissions(
            {'users': {
                'AnonymousUser': ['view_resourcebase']
            }})

        try:
            # Potentially 3 dimensions can be returned by the grid if there is a z
            # axis.  Since we only want width/height, slice to the second
            # dimension
            covWidth, covHeight = get_coverage_grid_extent(instance)[:2]
        except GeoNodeException as e:
            msg = _('Could not create a download link for layer.')
            logger.warn(msg, e)
        else:

            links = wcs_links(ogc_server_settings.public_url + 'wcs?',
                              instance.typename.encode('utf-8'),
                              bbox=gs_resource.native_bbox[:-1],
                              crs=gs_resource.native_bbox[-1],
                              height=str(covHeight),
                              width=str(covWidth))

            for ext, name, mime, wcs_url in links:
                Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                           url=wcs_url,
                                           defaults=dict(
                                               extension=ext,
                                               name=name,
                                               mime=mime,
                                               link_type='data',
                                           ))

        instance.set_permissions(permissions)

    kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "download"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_download,
                               defaults=dict(
                                   extension='kml',
                                   name=_("KML"),
                                   mime='text/xml',
                                   link_type='data',
                               ))

    kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "refresh"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_view,
                               defaults=dict(
                                   extension='kml',
                                   name="View in Google Earth",
                                   mime='text/xml',
                                   link_type='data',
                               ))

    tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url +
                'layers=%s' % instance.typename.encode('utf-8') +
                '&zoom={z}&x={x}&y={y}' + '&format=image/png8')

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=tile_url,
                               defaults=dict(
                                   extension='tiles',
                                   name=_("Tiles"),
                                   mime='image/png',
                                   link_type='image',
                               ))

    html_link_url = '%s%s' % (settings.SITEURL[:-1],
                              instance.get_absolute_url())

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=html_link_url,
                               defaults=dict(
                                   extension='html',
                                   name=instance.typename,
                                   mime='text/html',
                                   link_type='html',
                               ))

    params = {
        'layers': instance.typename.encode('utf-8'),
        'format': 'image/png8',
        'width': 200,
        'height': 150,
    }

    # Avoid using urllib.urlencode here because it breaks the url.
    # commas and slashes in values get encoded and then cause trouble
    # with the WMS parser.
    p = "&".join("%s=%s" % item for item in params.items())

    thumbnail_remote_url = ogc_server_settings.PUBLIC_LOCATION + \
        "wms/reflect?" + p

    thumbnail_create_url = ogc_server_settings.LOCATION + \
        "wms/reflect?" + p

    create_thumbnail(instance,
                     thumbnail_remote_url,
                     thumbnail_create_url,
                     ogc_client=http_client)

    legend_url = ogc_server_settings.PUBLIC_LOCATION + \
        'wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER=' + \
        instance.typename + '&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on'

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=legend_url,
                               defaults=dict(
                                   extension='png',
                                   name=_('Legend'),
                                   url=legend_url,
                                   mime='image/png',
                                   link_type='image',
                               ))

    ogc_wms_path = '%s/wms' % instance.workspace
    ogc_wms_url = urljoin(ogc_server_settings.public_url, ogc_wms_path)
    ogc_wms_name = 'OGC WMS: %s Service' % instance.workspace
    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=ogc_wms_url,
                               defaults=dict(
                                   extension='html',
                                   name=ogc_wms_name,
                                   url=ogc_wms_url,
                                   mime='text/html',
                                   link_type='OGC:WMS',
                               ))

    if instance.storeType == "dataStore":
        ogc_wfs_path = '%s/wfs' % instance.workspace
        ogc_wfs_url = urljoin(ogc_server_settings.public_url, ogc_wfs_path)
        ogc_wfs_name = 'OGC WFS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wfs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wfs_name,
                                       url=ogc_wfs_url,
                                       mime='text/html',
                                       link_type='OGC:WFS',
                                   ))

    if instance.storeType == "coverageStore":
        ogc_wcs_path = '%s/wcs' % instance.workspace
        ogc_wcs_url = urljoin(ogc_server_settings.public_url, ogc_wcs_path)
        ogc_wcs_name = 'OGC WCS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wcs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wcs_name,
                                       url=ogc_wcs_url,
                                       mime='text/html',
                                       link_type='OGC:WCS',
                                   ))

    # remove links that belong to and old address

    for link in instance.link_set.all():
        if not urlparse(settings.SITEURL).hostname == urlparse(
                link.url).hostname and not urlparse(
                    ogc_server_settings.public_url).hostname == urlparse(
                        link.url).hostname:
            link.delete()

    # Save layer attributes
    set_attributes(instance)

    # Save layer styles
    set_styles(instance, gs_catalog)
예제 #15
0
def geoserver_post_save(instance, sender, **kwargs):
    """Save keywords to GeoServer

       The way keywords are implemented requires the layer
       to be saved to the database before accessing them.
    """
    url = ogc_server_settings.internal_rest

    try:
        gs_resource = gs_catalog.get_resource(instance.name)
    except socket_error as serr:
        if serr.errno != errno.ECONNREFUSED:
            # Not the error we are looking for, re-raise
            raise serr
        # If the connection is refused, take it easy.
        return

    if any(instance.keyword_list()):
        gs_resource.keywords = instance.keyword_list()

        #gs_resource should only be called if ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_resource)

    bbox = gs_resource.latlon_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML

    links = wms_links(ogc_server_settings.public_url + 'wms?',
                      instance.typename.encode('utf-8'), instance.bbox_string,
                      instance.srid, height, width)

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   name=ugettext(name),
                                   defaults=dict(
                                       extension=ext,
                                       url=wms_url,
                                       mime=mime,
                                       link_type='image',
                                   ))

    if instance.storeType == "dataStore":
        links = wfs_links(ogc_server_settings.public_url + 'wfs?',
                          instance.typename.encode('utf-8'))
        for ext, name, mime, wfs_url in links:
            if mime == 'SHAPE-ZIP':
                name = 'Zipped Shapefile'
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wfs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           url=wfs_url,
                                           link_type='data',
                                       ))

    elif instance.storeType == 'coverageStore':
        #FIXME(Ariel): This works for public layers, does it work for restricted too?
        # would those end up with no geotiff links, like, forever?
        permissions = {}
        permissions['anonymous'] = instance.get_gen_level(ANONYMOUS_USERS)
        permissions['authenticated'] = instance.get_gen_level(
            AUTHENTICATED_USERS)
        instance.set_gen_level(ANONYMOUS_USERS, 'layer_readonly')

        #Potentially 3 dimensions can be returned by the grid if there is a z
        #axis.  Since we only want width/height, slice to the second dimension
        covWidth, covHeight = get_coverage_grid_extent(instance)[:2]
        links = wcs_links(ogc_server_settings.public_url + 'wcs?',
                          instance.typename.encode('utf-8'),
                          bbox=gs_resource.native_bbox[:-1],
                          crs=gs_resource.native_bbox[-1],
                          height=str(covHeight),
                          width=str(covWidth))
        for ext, name, mime, wcs_url in links:
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wcs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           link_type='data',
                                       ))

        instance.set_gen_level(ANONYMOUS_USERS, permissions['anonymous'])
        instance.set_gen_level(AUTHENTICATED_USERS,
                               permissions['authenticated'])

    kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + urllib.urlencode(
        {
            'layers': instance.typename.encode('utf-8'),
            'mode': "download"
        })

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_download,
                               defaults=dict(
                                   extension='kml',
                                   name=_("KML"),
                                   mime='text/xml',
                                   link_type='data',
                               ))

    kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + urllib.urlencode(
        {
            'layers': instance.typename.encode('utf-8'),
            'mode': "refresh"
        })

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_view,
                               defaults=dict(
                                   extension='kml',
                                   name="View in Google Earth",
                                   mime='text/xml',
                                   link_type='data',
                               ))

    tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url +
                'layers=%s' % instance.typename.encode('utf-8') +
                '&zoom={z}&x={x}&y={y}' + '&format=image/png8')

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=tile_url,
                               defaults=dict(
                                   extension='tiles',
                                   name=_("Tiles"),
                                   mime='image/png',
                                   link_type='image',
                               ))

    wms_path = '%s/%s/wms' % (instance.workspace, instance.name)
    ows_url = urljoin(ogc_server_settings.public_url, wms_path)

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=ows_url,
                               defaults=dict(
                                   extension='html',
                                   name=_("OWS"),
                                   url=ows_url,
                                   mime='text/html',
                                   link_type='OGC:WMS',
                               ))

    html_link_url = '%s%s' % (settings.SITEURL[:-1],
                              instance.get_absolute_url())

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=html_link_url,
                               defaults=dict(
                                   extension='html',
                                   name=instance.typename,
                                   mime='text/html',
                                   link_type='html',
                               ))

    params = {
        'layers': instance.typename.encode('utf-8'),
        'format': 'image/png8',
        'width': 200,
        'height': 150,
    }

    # Avoid using urllib.urlencode here because it breaks the url.
    # commas and slashes in values get encoded and then cause trouble
    # with the WMS parser.
    p = "&".join("%s=%s" % item for item in params.items())

    thumbnail_remote_url = ogc_server_settings.PUBLIC_LOCATION + "wms/reflect?" + p

    create_thumbnail(instance, thumbnail_remote_url)

    legend_url = ogc_server_settings.PUBLIC_LOCATION + 'wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER=' + instance.typename + '&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on'

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=legend_url,
                               defaults=dict(
                                   extension='png',
                                   name=_('Legend'),
                                   url=legend_url,
                                   mime='image/png',
                                   link_type='image',
                               ))

    ogc_wms_url = ogc_server_settings.public_url + 'wms?'
    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=ogc_wms_url,
                               defaults=dict(
                                   extension='html',
                                   name=instance.name,
                                   url=ogc_wms_url,
                                   mime='text/html',
                                   link_type='OGC:WMS',
                               ))

    if instance.storeType == "dataStore":
        ogc_wfs_url = ogc_server_settings.public_url + 'wfs?'
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wfs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=instance.name,
                                       url=ogc_wfs_url,
                                       mime='text/html',
                                       link_type='OGC:WFS',
                                   ))

    if instance.storeType == "coverageStore":
        ogc_wcs_url = ogc_server_settings.public_url + 'wcs?'
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wcs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=instance.name,
                                       url=ogc_wcs_url,
                                       mime='text/html',
                                       link_type='OGC:WCS',
                                   ))

    #remove links that belong to and old address

    for link in instance.link_set.all():
        if not urlparse(settings.SITEURL).hostname == urlparse(link.url).hostname and not \
                    urlparse(ogc_server_settings.public_url).hostname == urlparse(link.url).hostname:
            link.delete()

    #Save layer attributes
    set_attributes(instance)

    #Save layer styles
    set_styles(instance, gs_catalog)
예제 #16
0
def geoserver_post_save_local(instance, *args, **kwargs):
    """Send information to geoserver.

       The attributes sent include:

        * Title
        * Abstract
        * Name
        * Keywords
        * Metadata Links,
        * Point of Contact name and url
    """
    # Don't run this signal if is a Layer from a remote service
    if getattr(instance, "remote_service", None) is not None:
        return

    # Don't run this signal handler if it is a tile layer or a remote store (Service)
    #    Currently only gpkg files containing tiles will have this type & will be served via MapProxy.
    if hasattr(instance, 'storeType') and getattr(instance, 'storeType') in ['tileStore', 'remoteStore']:
        return instance

    gs_resource = None
    values = None

    # If the store in None then it's a new instance from an upload,
    # only in this case run the geoserver_upload method
    if not instance.store or getattr(instance, 'overwrite', False):
        base_file, info = instance.get_base_file()

        # There is no need to process it if there is not file.
        if base_file is None:
            return
        gs_name, workspace, values, gs_resource = geoserver_upload(instance,
                                                                   base_file.file.path,
                                                                   instance.owner,
                                                                   instance.name,
                                                                   overwrite=True,
                                                                   title=instance.title,
                                                                   abstract=instance.abstract,
                                                                   # keywords=instance.keywords,
                                                                   charset=instance.charset)

    if not gs_resource:
        gs_resource = gs_catalog.get_resource(
            instance.name,
            store=instance.store,
            workspace=instance.workspace)
        if not gs_resource:
            gs_resource = gs_catalog.get_resource(instance.alternate)

    if gs_resource:
        gs_resource.title = instance.title or ""
        gs_resource.abstract = instance.abstract or ""
        gs_resource.name = instance.name or ""

        if not values:
            values = dict(store=gs_resource.store.name,
                          storeType=gs_resource.store.resource_type,
                          alternate=gs_resource.store.workspace.name + ':' + gs_resource.name,
                          title=gs_resource.title or gs_resource.store.name,
                          abstract=gs_resource.abstract or '',
                          owner=instance.owner)
    else:
        msg = "There isn't a geoserver resource for this layer: %s" % instance.name
        logger.exception(msg)
        raise Exception(msg)

    # Get metadata links
    metadata_links = []
    for link in instance.link_set.metadata():
        metadata_links.append((link.mime, link.name, link.url))

    gs_resource.metadata_links = metadata_links
    # gs_resource should only be called if
    # ogc_server_settings.BACKEND_WRITE_ENABLED == True
    if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
        try:
            gs_catalog.save(gs_resource)
        except geoserver.catalog.FailedRequestError as e:
            msg = ('Error while trying to save resource named %s in GeoServer, '
                   'try to use: "%s"' % (gs_resource, str(e)))
            e.args = (msg,)
            logger.exception(e)

    # Update Attribution link
    if instance.poc:
        # gsconfig now utilizes an attribution dictionary
        gs_resource.attribution = {'title': str(instance.poc),
                                   'width': None,
                                   'height': None,
                                   'href': None,
                                   'url': None,
                                   'type': None}
        profile = Profile.objects.get(username=instance.poc.username)
        site_url = settings.SITEURL.rstrip('/') if settings.SITEURL.startswith('http') else settings.SITEURL
        gs_resource.attribution_link = site_url + profile.get_absolute_url()
        # gs_resource should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            try:
                gs_catalog.save(gs_resource)
            except geoserver.catalog.FailedRequestError as e:
                msg = ('Error while trying to save layer named %s in GeoServer, '
                       'try to use: "%s"' % (gs_resource, str(e)))
                e.args = (msg,)
                logger.exception(e)

    if isinstance(instance, ResourceBase):
        if hasattr(instance, 'layer'):
            instance = instance.layer
        else:
            return

    # Save layer attributes
    set_attributes_from_geoserver(instance)

    # Save layer styles
    set_styles(instance, gs_catalog)

    # set SLD
    sld = instance.default_style.sld_body if instance.default_style else None
    if sld:
        set_layer_style(instance, instance.alternate, sld)

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

    if instance.storeType == "remoteStore":
        # Save layer attributes
        set_attributes_from_geoserver(instance)
        return

    """Get information from geoserver.

       The attributes retrieved include:

       * Bounding Box
       * SRID
       * Download links (WMS, WCS or WFS and KML)
       * Styles (SLD)
    """
    # instance.name = instance.name or gs_resource.name
    # instance.title = instance.title or gs_resource.title
    instance.abstract = gs_resource.abstract or ''
    instance.workspace = gs_resource.store.workspace.name
    instance.store = gs_resource.store.name

    try:
        bbox = gs_resource.native_bbox

        # Set bounding box values
        instance.bbox_x0 = bbox[0]
        instance.bbox_x1 = bbox[1]
        instance.bbox_y0 = bbox[2]
        instance.bbox_y1 = bbox[3]
        instance.srid = bbox[4]
    except BaseException:
        pass

    if instance.srid:
        instance.srid_url = "http://www.spatialreference.org/ref/" + \
            instance.srid.replace(':', '/').lower() + "/"
    else:
        raise GeoNodeException("Invalid Projection. Layer is missing CRS!")

    # Iterate over values from geoserver.
    for key in ['alternate', 'store', 'storeType']:
        # attr_name = key if 'typename' not in key else 'alternate'
        # print attr_name
        setattr(instance, key, values[key])

    if settings.RESOURCE_PUBLISHING:
        if instance.is_published != gs_resource.advertised:
            if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
                gs_resource.advertised = 'true' if instance.is_published else 'false'
                gs_catalog.save(gs_resource)

    if not settings.FREETEXT_KEYWORDS_READONLY:
        try:
            if len(instance.keyword_list()) == 0 and gs_resource.keywords:
                for keyword in gs_resource.keywords:
                    if keyword not in instance.keyword_list():
                        instance.keywords.add(keyword)
        except BaseException:
            pass

    if any(instance.keyword_list()):
        keywords = instance.keyword_list()
        gs_resource.keywords = [kw.decode("utf-8", "replace") for kw in list(set(keywords))]

        # gs_resource should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            try:
                gs_catalog.save(gs_resource)
            except geoserver.catalog.FailedRequestError as e:
                msg = ('Error while trying to save resource named %s in GeoServer, '
                       'try to use: "%s"' % (gs_resource, str(e)))
                e.args = (msg,)
                logger.exception(e)

    to_update = {
        'title': instance.title or instance.name,
        'abstract': instance.abstract or "",
        'alternate': instance.alternate,
        'bbox_x0': instance.bbox_x0,
        'bbox_x1': instance.bbox_x1,
        'bbox_y0': instance.bbox_y0,
        'bbox_y1': instance.bbox_y1,
        'srid': instance.srid
    }

    # Update ResourceBase
    resources = ResourceBase.objects.filter(id=instance.resourcebase_ptr.id)
    resources.update(**to_update)

    # to_update['name'] = instance.name,
    to_update['workspace'] = instance.workspace
    to_update['store'] = instance.store
    to_update['storeType'] = instance.storeType
    to_update['typename'] = instance.alternate

    # Save all the modified information in the instance without triggering signals.
    Layer.objects.filter(id=instance.id).update(**to_update)

    # Refresh from DB
    instance.refresh_from_db()

    # store the resource to avoid another geoserver call in the post_save
    instance.gs_resource = gs_resource

    try:
        bbox = gs_resource.native_bbox
    except BaseException:
        bbox = instance.bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Parse Layer BBOX and SRID
    srid = instance.srid if instance.srid else getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:4326')
    if srid and instance.bbox_x0:
        bbox = ','.join(str(x) for x in [instance.bbox_x0, instance.bbox_y0,
                                         instance.bbox_x1, instance.bbox_y1])

    # Create Raw Data download link
    try:
        path = gs_resource.dom.findall('nativeName')
    except BaseException:
        path = instance.alternate
    download_url = urljoin(settings.SITEURL,
                           reverse('download', args=[instance.id]))
    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=download_url,
                               defaults=dict(extension='zip',
                                             name='Original Dataset',
                                             mime='application/octet-stream',
                                             link_type='original',
                                             )
                               )

    # Set download links for WMS, WCS or WFS and KML
    links = wms_links(ogc_server_settings.public_url + 'wms?',
                      instance.alternate.encode('utf-8'),
                      bbox,
                      srid,
                      height,
                      width)

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   name=ugettext(name),
                                   defaults=dict(
                                       extension=ext,
                                       url=wms_url,
                                       mime=mime,
                                       link_type='image',
                                   )
                                   )

    if instance.storeType == "dataStore":
        links = wfs_links(ogc_server_settings.public_url + 'wfs?',
                          instance.alternate.encode('utf-8'),
                          bbox=None,  # bbox filter should be set at runtime otherwise conflicting with CQL
                          srid=srid)
        for ext, name, mime, wfs_url in links:
            if mime == 'SHAPE-ZIP':
                name = 'Zipped Shapefile'
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wfs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           url=wfs_url,
                                           link_type='data',
                                       )
                                       )

        gs_store_type = gs_resource.store.type.lower() if gs_resource.store.type else None
        geogig_repository = gs_resource.store.connection_parameters.get('geogig_repository', '')
        geogig_repo_name = geogig_repository.replace('geoserver://', '')

        if gs_store_type == 'geogig' and geogig_repo_name:

            repo_url = '{url}geogig/repos/{repo_name}'.format(
                url=ogc_server_settings.public_url,
                repo_name=geogig_repo_name)

            try:
                path = gs_resource.dom.findall('nativeName')
            except BaseException:
                path = instance.alternate

            if path:
                path = 'path={path}'.format(path=path[0].text)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=repo_url,
                                       defaults=dict(extension='html',
                                                     name='Clone in GeoGig',
                                                     mime='text/xml',
                                                     link_type='html'
                                                     )
                                       )

            def command_url(command):
                return "{repo_url}/{command}.json?{path}".format(repo_url=repo_url,
                                                                 path=path,
                                                                 command=command)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('log'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig log',
                                                     mime='application/json',
                                                     link_type='html'
                                                     )
                                       )

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('statistics'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig statistics',
                                                     mime='application/json',
                                                     link_type='html'
                                                     )
                                       )

    elif instance.storeType == 'coverageStore':
        links = wcs_links(ogc_server_settings.public_url + 'wcs?',
                          instance.alternate.encode('utf-8'),
                          bbox,
                          srid)

    for ext, name, mime, wcs_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=wcs_url,
                                   defaults=dict(
                                       extension=ext,
                                       name=name,
                                       mime=mime,
                                       link_type='data',
                                   )
                                   )

    kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.alternate.encode('utf-8'), 'mode': "download"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_download,
                               defaults=dict(
                                   extension='kml',
                                   name="KML",
                                   mime='text/xml',
                                   link_type='data',
                               )
                               )

    kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.alternate.encode('utf-8'), 'mode': "refresh"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_view,
                               defaults=dict(
                                   extension='kml',
                                   name="View in Google Earth",
                                   mime='text/xml',
                                   link_type='data',
                               )
                               )

    site_url = settings.SITEURL.rstrip('/') if settings.SITEURL.startswith('http') else settings.SITEURL
    html_link_url = '%s%s' % (
        site_url, instance.get_absolute_url())

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=html_link_url,
                               defaults=dict(
                                   extension='html',
                                   name=instance.alternate,
                                   mime='text/html',
                                   link_type='html',
                               )
                               )

    # some thumbnail generators will update thumbnail_url.  If so, don't
    # immediately re-generate the thumbnail here.  use layer#save(update_fields=['thumbnail_url'])
    if 'update_fields' in kwargs and kwargs['update_fields'] is not None and \
            'thumbnail_url' in kwargs['update_fields']:
        logger.info("... Creating Thumbnail for Layer [%s]" % (instance.alternate))
        create_gs_thumbnail(instance, overwrite=True)

    try:
        Link.objects.filter(resource=instance.resourcebase_ptr, name='Legend').delete()
    except BaseException:
        pass

    for style in instance.styles.all():
        legend_url = ogc_server_settings.PUBLIC_LOCATION + \
            'wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER=' + \
            instance.alternate + '&STYLE=' + style.name + \
            '&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on'

        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=legend_url,
                                   defaults=dict(
                                       extension='png',
                                       name='Legend',
                                       url=legend_url,
                                       mime='image/png',
                                       link_type='image',
                                   )
                                   )

    # ogc_wms_path = '%s/ows' % instance.workspace
    ogc_wms_path = 'ows'
    ogc_wms_url = urljoin(ogc_server_settings.public_url, ogc_wms_path)
    ogc_wms_name = 'OGC WMS: %s Service' % instance.workspace
    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=ogc_wms_url,
                               defaults=dict(
                                   extension='html',
                                   name=ogc_wms_name,
                                   url=ogc_wms_url,
                                   mime='text/html',
                                   link_type='OGC:WMS',
                               )
                               )

    if instance.storeType == "dataStore":
        # ogc_wfs_path = '%s/wfs' % instance.workspace
        ogc_wfs_path = 'wfs'
        ogc_wfs_url = urljoin(ogc_server_settings.public_url, ogc_wfs_path)
        ogc_wfs_name = 'OGC WFS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wfs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wfs_name,
                                       url=ogc_wfs_url,
                                       mime='text/html',
                                       link_type='OGC:WFS',
                                   )
                                   )

    if instance.storeType == "coverageStore":
        # ogc_wcs_path = '%s/wcs' % instance.workspace
        ogc_wcs_path = 'wcs'
        ogc_wcs_url = urljoin(ogc_server_settings.public_url, ogc_wcs_path)
        ogc_wcs_name = 'OGC WCS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wcs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wcs_name,
                                       url=ogc_wcs_url,
                                       mime='text/html',
                                       link_type='OGC:WCS',
                                   )
                                   )

    # remove links that belong to and old address
    for link in instance.link_set.all():
        if not urlparse(
            settings.SITEURL).hostname == urlparse(
            link.url).hostname and not urlparse(
            ogc_server_settings.public_url).hostname == urlparse(
                link.url).hostname:
            link.delete()

    # Define the link after the cleanup, we should use this more rather then remove
    # potential parasites
    tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url +
                'layers=%s' % instance.alternate.encode('utf-8') +
                '&zoom={z}&x={x}&y={y}' +
                '&format=image/png8'
                )

    link, created = Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                               extension='tiles',
                                               name="Tiles",
                                               mime='image/png',
                                               link_type='image',
                                               )
    if created:
        Link.objects.filter(pk=link.pk).update(url=tile_url)

    # NOTTODO by simod: we should not do this!
    # need to be removed when fixing #2015
    catalogue_post_save(instance, Layer)

    # Updating HAYSTACK Indexes if needed
    if settings.HAYSTACK_SEARCH:
        from django.core.management import call_command
        call_command('update_index')
예제 #17
0
def geoserver_post_save2(layer_id):
    """Save keywords to GeoServer

       The way keywords are implemented requires the layer
       to be saved to the database before accessing them.
    """
    """Send information to geoserver.

           The attributes sent include:

            * Title
            * Abstract
            * Name
            * Keywords
            * Metadata Links,
            * Point of Contact name and url
        """

    from geonode.layers.models import Layer
    instance = Layer.objects.get(id=layer_id)
    # Don't run this signal if is a Layer from a remote service
    if getattr(instance, "service", None) is not None:
        return instance

    # Don't run this signal handler if it is a tile layer or a remote store (Service)
    #    Currently only gpkg files containing tiles will have this type & will be served via MapProxy.
    if hasattr(instance, 'storeType') and getattr(instance, 'storeType') in ['tileStore', 'remoteStore']:
        return instance

    gs_resource = None

    # If the store in None then it's a new instance from an upload,
    # only in this case run the geonode_uplaod method
    if not instance.store or getattr(instance, 'overwrite', False):
        base_file, info = instance.get_base_file()

        # There is no need to process it if there is not file.
        if base_file is None:
            return instance

        gs_name, workspace, values, gs_resource = geoserver_upload(instance,
                                                                   base_file.file.path,
                                                                   instance.owner,
                                                                   instance.name,
                                                                   overwrite=True,
                                                                   title=instance.title,
                                                                   abstract=instance.abstract,
                                                                   # keywords=instance.keywords,
                                                                   charset=instance.charset)

        # Set fields obtained via the geoserver upload.
        instance.name = gs_name
        instance.workspace = workspace
        instance.store = values['store']
        # Iterate over values from geoserver.
        for key in ['typename', 'store', 'storeType']:
            setattr(instance, key, values[key])

        instance.save()

    if not gs_resource:
        gs_resource = gs_catalog.get_resource(
            instance.name,
            store=instance.store,
            workspace=instance.workspace)

    if gs_resource:
        gs_resource.title = instance.title if instance.title else ""
        gs_resource.abstract = instance.abstract if instance.abstract else ""
        gs_resource.name = instance.name if instance.name else ""

    # Get metadata links
    metadata_links = []
    for link in instance.link_set.metadata():
        metadata_links.append((link.mime, link.name, link.url))

    if gs_resource:
        gs_resource.metadata_links = metadata_links
    # gs_resource should only be called if
    # ogc_server_settings.BACKEND_WRITE_ENABLED == True
    if gs_resource and getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED",
                               True):
        gs_catalog.save(gs_resource)

    gs_layer = gs_catalog.get_layer(instance.name)

    if instance.poc and instance.poc:
        # gsconfig now utilizes an attribution dictionary
        gs_layer.attribution = {'title': str(instance.poc),
                                'width': None,
                                'height': None,
                                'href': None,
                                'url': None,
                                'type': None}
        profile = Profile.objects.get(username=instance.poc.username)
        gs_layer.attribution_link = settings.SITEURL[
                                    :-1] + profile.get_absolute_url()
        # gs_layer should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_layer)

    """Get information from geoserver.

       The attributes retrieved include:

       * Bounding Box
       * SRID
       * Download links (WMS, WCS or WFS and KML)
       * Styles (SLD)
    """

    if gs_resource:
        bbox = gs_resource.latlon_bbox

        # FIXME(Ariel): Correct srid setting below
        # self.srid = gs_resource.src

        instance.srid_url = "http://www.spatialreference.org/ref/" + \
                            instance.srid.replace(':', '/').lower() + "/"

        # Set bounding box values
        instance.bbox_x0 = bbox[0]
        instance.bbox_x1 = bbox[1]
        instance.bbox_y0 = bbox[2]
        instance.bbox_y1 = bbox[3]

        # store the resource to avoid another geoserver call in the post_save
        instance.gs_resource = gs_resource

    instance.save()

    if type(instance) is ResourceBase:
        if hasattr(instance, 'layer'):
            instance = instance.layer
        else:
            return instance

    if instance.storeType == "remoteStore":
        # Save layer attributes
        set_attributes_from_geoserver(instance)
        return instance

    if not getattr(instance, 'gs_resource', None):
        try:
            gs_resource = gs_catalog.get_resource(
                instance.name,
                store=instance.store,
                workspace=instance.workspace)
        except socket_error as serr:
            if serr.errno != errno.ECONNREFUSED:
                # Not the error we are looking for, re-raise
                raise serr
            # If the connection is refused, take it easy.
            return instance
    else:
        gs_resource = instance.gs_resource

    if gs_resource is None:
        return instance

    if settings.RESOURCE_PUBLISHING:
        if instance.is_published != gs_resource.advertised:
            if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
                gs_resource.advertised = instance.is_published
                gs_catalog.save(gs_resource)

    if any(instance.keyword_list()):
        gs_resource.keywords = instance.keyword_list()
        # gs_resource should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_resource)

    bbox = gs_resource.latlon_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML
    links = wms_links(ogc_server_settings.public_url + 'wms?',
                      instance.typename.encode('utf-8'), instance.bbox_string,
                      instance.srid, height, width)

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   name=ugettext(name),
                                   defaults=dict(
                                       extension=ext,
                                       url=wms_url,
                                       mime=mime,
                                       link_type='image',
                                   )
                                   )

    if instance.storeType == "dataStore":
        links = wfs_links(
            ogc_server_settings.public_url +
            'wfs?',
            instance.typename.encode('utf-8'))
        for ext, name, mime, wfs_url in links:
            if mime == 'SHAPE-ZIP':
                name = 'Zipped Shapefile'
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wfs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           url=wfs_url,
                                           link_type='data',
                                       )
                                       )

        gs_store_type = gs_resource.store.type.lower() if gs_resource.store.type else None
        geogig_repository = gs_resource.store.connection_parameters.get('geogig_repository', '')
        geogig_repo_name = geogig_repository.replace('geoserver://', '')

        if gs_store_type == 'geogig' and geogig_repo_name:

            repo_url = '{url}geogig/repos/{repo_name}'.format(
                url=ogc_server_settings.public_url,
                repo_name=geogig_repo_name)

            path = gs_resource.dom.findall('nativeName')

            if path:
                path = 'path={path}'.format(path=path[0].text)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=repo_url,
                                       defaults=dict(extension='html',
                                                     name='Clone in GeoGig',
                                                     mime='text/xml',
                                                     link_type='html'
                                                     )
                                       )

            def command_url(command):
                return "{repo_url}/{command}.json?{path}".format(repo_url=repo_url,
                                                                 path=path,
                                                                 command=command)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('log'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig log',
                                                     mime='application/json',
                                                     link_type='html'
                                                     )
                                       )

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('statistics'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig statistics',
                                                     mime='application/json',
                                                     link_type='html'
                                                     )
                                       )

    elif instance.storeType == 'coverageStore':

        links = wcs_links(ogc_server_settings.public_url + 'wcs?',
                          instance.typename.encode('utf-8'))

    for ext, name, mime, wcs_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=wcs_url,
                                   defaults=dict(
                                       extension=ext,
                                       name=name,
                                       mime=mime,
                                       link_type='data',
                                   )
                                   )

    kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "download"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_download,
                               defaults=dict(
                                   extension='kml',
                                   name="KML",
                                   mime='text/xml',
                                   link_type='data',
                               )
                               )

    kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "refresh"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_view,
                               defaults=dict(
                                   extension='kml',
                                   name="View in Google Earth",
                                   mime='text/xml',
                                   link_type='data',
                               )
                               )

    html_link_url = '%s%s' % (
        settings.SITEURL[:-1], instance.get_absolute_url())

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=html_link_url,
                               defaults=dict(
                                   extension='html',
                                   name=instance.typename,
                                   mime='text/html',
                                   link_type='html',
                               )
                               )

    create_gs_thumbnail(instance, overwrite=False)

    legend_url = ogc_server_settings.PUBLIC_LOCATION + \
        'wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER=' + \
        instance.typename + '&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on'

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=legend_url,
                               defaults=dict(
                                   extension='png',
                                   name='Legend',
                                   url=legend_url,
                                   mime='image/png',
                                   link_type='image',
                               )
                               )

    ogc_wms_path = '%s/wms' % instance.workspace
    ogc_wms_url = urljoin(ogc_server_settings.public_url, ogc_wms_path)
    ogc_wms_name = 'OGC WMS: %s Service' % instance.workspace
    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=ogc_wms_url,
                               defaults=dict(
                                   extension='html',
                                   name=ogc_wms_name,
                                   url=ogc_wms_url,
                                   mime='text/html',
                                   link_type='OGC:WMS',
                               )
                               )

    if instance.storeType == "dataStore":
        ogc_wfs_path = '%s/wfs' % instance.workspace
        ogc_wfs_url = urljoin(ogc_server_settings.public_url, ogc_wfs_path)
        ogc_wfs_name = 'OGC WFS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wfs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wfs_name,
                                       url=ogc_wfs_url,
                                       mime='text/html',
                                       link_type='OGC:WFS',
                                   )
                                   )

    if instance.storeType == "coverageStore":
        ogc_wcs_path = '%s/wcs' % instance.workspace
        ogc_wcs_url = urljoin(ogc_server_settings.public_url, ogc_wcs_path)
        ogc_wcs_name = 'OGC WCS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wcs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wcs_name,
                                       url=ogc_wcs_url,
                                       mime='text/html',
                                       link_type='OGC:WCS',
                                   )
                                   )

    # remove links that belong to and old address

    for link in instance.link_set.all():
        if not urlparse(
            settings.SITEURL).hostname == urlparse(
            link.url).hostname and not urlparse(
            ogc_server_settings.public_url).hostname == urlparse(
                link.url).hostname:
            link.delete()

    # Define the link after the cleanup, we should use this more rather then remove
    # potential parasites
    tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url +
                'layers=%s' % instance.typename.encode('utf-8') +
                '&zoom={z}&x={x}&y={y}' +
                '&format=image/png8'
                )

    link, created = Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                               extension='tiles',
                                               name="Tiles",
                                               mime='image/png',
                                               link_type='image',
                                               )
    if created:
        Link.objects.filter(pk=link.pk).update(url=tile_url)

    # Save layer attributes
    set_attributes_from_geoserver(instance)

    # Save layer styles
    set_styles(instance, gs_catalog)
    # NOTTODO by simod: we should not do this!
    # need to be removed when fixing #2015
    from geonode.catalogue.models import catalogue_post_save
    from geonode.layers.models import Layer
    catalogue_post_save(instance, Layer)
    return instance
예제 #18
0
def geoserver_post_save_local(instance, *args, **kwargs):
    """Send information to geoserver.

       The attributes sent include:

        * Title
        * Abstract
        * Name
        * Keywords
        * Metadata Links,
        * Point of Contact name and url
    """
    # Don't run this signal if is a Layer from a remote service
    if getattr(instance, "remote_service", None) is not None:
        return

    # Don't run this signal handler if it is a tile layer or a remote store (Service)
    #    Currently only gpkg files containing tiles will have this type & will be served via MapProxy.
    if hasattr(instance, 'storeType') and getattr(instance, 'storeType') in ['tileStore', 'remoteStore']:
        return instance

    gs_resource = None
    values = None

    # If the store in None then it's a new instance from an upload,
    # only in this case run the geoserver_upload method
    if not instance.store or getattr(instance, 'overwrite', False):
        base_file, info = instance.get_base_file()

        # There is no need to process it if there is not file.
        if base_file is None:
            return
        gs_name, workspace, values, gs_resource = geoserver_upload(instance,
                                                                   base_file.file.path,
                                                                   instance.owner,
                                                                   instance.name,
                                                                   overwrite=True,
                                                                   title=instance.title,
                                                                   abstract=instance.abstract,
                                                                   # keywords=instance.keywords,
                                                                   charset=instance.charset)

    if not gs_resource:
        gs_resource = gs_catalog.get_resource(
            instance.name,
            store=instance.store,
            workspace=instance.workspace)
        if not gs_resource:
            gs_resource = gs_catalog.get_resource(instance.alternate)

    if gs_resource:
        gs_resource.title = instance.title or ""
        gs_resource.abstract = instance.abstract or ""
        gs_resource.name = instance.name or ""

        if not values:
            values = dict(store=gs_resource.store.name,
                          storeType=gs_resource.store.resource_type,
                          alternate=gs_resource.store.workspace.name + ':' + gs_resource.name,
                          title=gs_resource.title or gs_resource.store.name,
                          abstract=gs_resource.abstract or '',
                          owner=instance.owner)
    else:
        msg = "There isn't a geoserver resource for this layer: %s" % instance.name
        logger.exception(msg)
        raise Exception(msg)

    # Get metadata links
    metadata_links = []
    for link in instance.link_set.metadata():
        metadata_links.append((link.mime, link.name, link.url))

    gs_resource.metadata_links = metadata_links
    # gs_resource should only be called if
    # ogc_server_settings.BACKEND_WRITE_ENABLED == True
    if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
        try:
            gs_catalog.save(gs_resource)
        except geoserver.catalog.FailedRequestError as e:
            msg = ('Error while trying to save resource named %s in GeoServer, '
                   'try to use: "%s"' % (gs_resource, str(e)))
            e.args = (msg,)
            logger.exception(e)

    # Update Attribution link
    if instance.poc:
        # gsconfig now utilizes an attribution dictionary
        gs_resource.attribution = {'title': str(instance.poc),
                                   'width': None,
                                   'height': None,
                                   'href': None,
                                   'url': None,
                                   'type': None}
        profile = Profile.objects.get(username=instance.poc.username)
        site_url = settings.SITEURL.rstrip('/') if settings.SITEURL.startswith('http') else settings.SITEURL
        gs_resource.attribution_link = site_url + profile.get_absolute_url()
        # gs_resource should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            try:
                gs_catalog.save(gs_resource)
            except geoserver.catalog.FailedRequestError as e:
                msg = ('Error while trying to save layer named %s in GeoServer, '
                       'try to use: "%s"' % (gs_resource, str(e)))
                e.args = (msg,)
                logger.exception(e)

    if isinstance(instance, ResourceBase):
        if hasattr(instance, 'layer'):
            instance = instance.layer
        else:
            return

    # Save layer attributes
    set_attributes_from_geoserver(instance)

    # Save layer styles
    set_styles(instance, gs_catalog)

    # set SLD
    sld = instance.default_style.sld_body if instance.default_style else None
    if sld:
        set_layer_style(instance, instance.alternate, sld)

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

    if instance.storeType == "remoteStore":
        # Save layer attributes
        set_attributes_from_geoserver(instance)
        return

    """Get information from geoserver.

       The attributes retrieved include:

       * Bounding Box
       * SRID
       * Download links (WMS, WCS or WFS and KML)
       * Styles (SLD)
    """
    # instance.name = instance.name or gs_resource.name
    # instance.title = instance.title or gs_resource.title
    instance.abstract = gs_resource.abstract or ''
    instance.workspace = gs_resource.store.workspace.name
    instance.store = gs_resource.store.name

    try:
        logger.debug(" -------------------------------------------------- ")
        bbox = gs_resource.native_bbox
        logger.debug(bbox)
        logger.debug(" -------------------------------------------------- ")
        # Set bounding box values
        instance.bbox_x0 = bbox[0]
        instance.bbox_x1 = bbox[1]
        instance.bbox_y0 = bbox[2]
        instance.bbox_y1 = bbox[3]
        instance.srid = bbox[4]
    except BaseException:
        pass

    if instance.srid:
        instance.srid_url = "http://www.spatialreference.org/ref/" + \
            instance.srid.replace(':', '/').lower() + "/"
    elif instance.bbox_x0 and instance.bbox_x1 and instance.bbox_y0 and instance.bbox_y1:
        # Guessing 'EPSG:4326' by default
        instance.srid = 'EPSG:4326'
    else:
        raise GeoNodeException("Invalid Projection. Layer is missing CRS!")

    # Iterate over values from geoserver.
    for key in ['alternate', 'store', 'storeType']:
        # attr_name = key if 'typename' not in key else 'alternate'
        # print attr_name
        setattr(instance, key, values[key])

    if settings.RESOURCE_PUBLISHING:
        if instance.is_published != gs_resource.advertised:
            if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
                gs_resource.advertised = 'true'
                gs_catalog.save(gs_resource)

    if not settings.FREETEXT_KEYWORDS_READONLY:
        try:
            if len(instance.keyword_list()) == 0 and gs_resource.keywords:
                for keyword in gs_resource.keywords:
                    if keyword not in instance.keyword_list():
                        instance.keywords.add(keyword)
        except BaseException:
            pass

    if any(instance.keyword_list()):
        keywords = instance.keyword_list()
        gs_resource.keywords = [kw for kw in list(set(keywords))]

        # gs_resource should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            try:
                gs_catalog.save(gs_resource)
            except geoserver.catalog.FailedRequestError as e:
                msg = ('Error while trying to save resource named %s in GeoServer, '
                       'try to use: "%s"' % (gs_resource, str(e)))
                e.args = (msg,)
                logger.exception(e)

    to_update = {
        'title': instance.title or instance.name,
        'abstract': instance.abstract or "",
        'alternate': instance.alternate,
        'bbox_x0': instance.bbox_x0,
        'bbox_x1': instance.bbox_x1,
        'bbox_y0': instance.bbox_y0,
        'bbox_y1': instance.bbox_y1,
        'srid': instance.srid
    }

    # Update ResourceBase
    resources = ResourceBase.objects.filter(id=instance.resourcebase_ptr.id)
    resources.update(**to_update)

    # to_update['name'] = instance.name,
    to_update['workspace'] = instance.workspace
    to_update['store'] = instance.store
    to_update['storeType'] = instance.storeType
    to_update['typename'] = instance.alternate

    # Save all the modified information in the instance without triggering signals.
    Layer.objects.filter(id=instance.id).update(**to_update)

    # Refresh from DB
    instance.refresh_from_db()

    # store the resource to avoid another geoserver call in the post_save
    instance.gs_resource = gs_resource

    # Refresh and create the instance default links
    layer = Layer.objects.get(id=instance.id)
    set_resource_default_links(instance, layer, prune=True)

    # some thumbnail generators will update thumbnail_url.  If so, don't
    # immediately re-generate the thumbnail here.  use layer#save(update_fields=['thumbnail_url'])
    if 'update_fields' in kwargs and kwargs['update_fields'] is not None and \
            'thumbnail_url' in kwargs['update_fields']:
        logger.info("... Creating Thumbnail for Layer [%s]" % (instance.alternate))
        create_gs_thumbnail(instance, overwrite=True)

    # NOTTODO by simod: we should not do this!
    # need to be removed when fixing #2015
    catalogue_post_save(instance, Layer)

    # Updating HAYSTACK Indexes if needed
    if settings.HAYSTACK_SEARCH:
        from django.core.management import call_command
        call_command('update_index')
예제 #19
0
def geoserver_post_save(instance, sender, **kwargs):
    """Save keywords to GeoServer

       The way keywords are implemented requires the layer
       to be saved to the database before accessing them.
    """

    if type(instance) is ResourceBase:
        if hasattr(instance, "layer"):
            instance = instance.layer
        else:
            return

    if instance.storeType == "remoteStore":
        # Save layer attributes
        set_attributes(instance)
        return

    if not getattr(instance, "gs_resource", None):
        try:
            gs_resource = gs_catalog.get_resource(instance.name, store=instance.store, workspace=instance.workspace)
        except socket_error as serr:
            if serr.errno != errno.ECONNREFUSED:
                # Not the error we are looking for, re-raise
                raise serr
            # If the connection is refused, take it easy.
            return
    else:
        gs_resource = instance.gs_resource

    if gs_resource is None:
        return

    if settings.RESOURCE_PUBLISHING:
        if instance.is_published != gs_resource.advertised:
            if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
                gs_resource.advertised = instance.is_published
                gs_catalog.save(gs_resource)

    if any(instance.keyword_list()):
        gs_resource.keywords = instance.keyword_list()
        # gs_resource should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_resource)

    bbox = gs_resource.latlon_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML
    links = wms_links(
        ogc_server_settings.public_url + "wms?",
        instance.typename.encode("utf-8"),
        instance.bbox_string,
        instance.srid,
        height,
        width,
    )

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(
            resource=instance.resourcebase_ptr,
            name=ugettext(name),
            defaults=dict(extension=ext, url=wms_url, mime=mime, link_type="image"),
        )

    if instance.storeType == "dataStore":
        links = wfs_links(ogc_server_settings.public_url + "wfs?", instance.typename.encode("utf-8"))
        for ext, name, mime, wfs_url in links:
            if mime == "SHAPE-ZIP":
                name = "Zipped Shapefile"
            Link.objects.get_or_create(
                resource=instance.resourcebase_ptr,
                url=wfs_url,
                defaults=dict(extension=ext, name=name, mime=mime, url=wfs_url, link_type="data"),
            )

        if (
            gs_resource.store.type
            and gs_resource.store.type.lower() == "geogig"
            and gs_resource.store.connection_parameters.get("geogig_repository")
        ):

            repo_url = "{url}geogig/{geogig_repository}".format(
                url=ogc_server_settings.public_url,
                geogig_repository=gs_resource.store.connection_parameters.get("geogig_repository"),
            )

            path = gs_resource.dom.findall("nativeName")

            if path:
                path = "path={path}".format(path=path[0].text)

            Link.objects.get_or_create(
                resource=instance.resourcebase_ptr,
                url=repo_url,
                defaults=dict(extension="html", name="Clone in GeoGig", mime="text/xml", link_type="html"),
            )

            def command_url(command):
                return "{repo_url}/{command}.json?{path}".format(repo_url=repo_url, path=path, command=command)

            Link.objects.get_or_create(
                resource=instance.resourcebase_ptr,
                url=command_url("log"),
                defaults=dict(extension="json", name="GeoGig log", mime="application/json", link_type="html"),
            )

            Link.objects.get_or_create(
                resource=instance.resourcebase_ptr,
                url=command_url("statistics"),
                defaults=dict(extension="json", name="GeoGig statistics", mime="application/json", link_type="html"),
            )

    elif instance.storeType == "coverageStore":
        # FIXME(Ariel): This works for public layers, does it work for restricted too?
        # would those end up with no geotiff links, like, forever?
        permissions = instance.get_all_level_info()

        instance.set_permissions({"users": {"AnonymousUser": ["view_resourcebase"]}})

        try:
            # Potentially 3 dimensions can be returned by the grid if there is a z
            # axis.  Since we only want width/height, slice to the second
            # dimension
            covWidth, covHeight = get_coverage_grid_extent(instance)[:2]
        except GeoNodeException as e:
            msg = _("Could not create a download link for layer.")
            try:
                # HACK: The logger on signals throws an exception
                logger.warn(msg, e)
            except:
                pass
        else:

            links = wcs_links(
                ogc_server_settings.public_url + "wcs?",
                instance.typename.encode("utf-8"),
                bbox=gs_resource.native_bbox[:-1],
                crs=gs_resource.native_bbox[-1],
                height=str(covHeight),
                width=str(covWidth),
            )

            for ext, name, mime, wcs_url in links:
                Link.objects.get_or_create(
                    resource=instance.resourcebase_ptr,
                    url=wcs_url,
                    defaults=dict(extension=ext, name=name, mime=mime, link_type="data"),
                )

        instance.set_permissions(permissions)

    kml_reflector_link_download = (
        ogc_server_settings.public_url
        + "wms/kml?"
        + urllib.urlencode({"layers": instance.typename.encode("utf-8"), "mode": "download"})
    )

    Link.objects.get_or_create(
        resource=instance.resourcebase_ptr,
        url=kml_reflector_link_download,
        defaults=dict(extension="kml", name="KML", mime="text/xml", link_type="data"),
    )

    kml_reflector_link_view = (
        ogc_server_settings.public_url
        + "wms/kml?"
        + urllib.urlencode({"layers": instance.typename.encode("utf-8"), "mode": "refresh"})
    )

    Link.objects.get_or_create(
        resource=instance.resourcebase_ptr,
        url=kml_reflector_link_view,
        defaults=dict(extension="kml", name="View in Google Earth", mime="text/xml", link_type="data"),
    )

    tile_url = (
        "%sgwc/service/gmaps?" % ogc_server_settings.public_url
        + "layers=%s" % instance.typename.encode("utf-8")
        + "&zoom={z}&x={x}&y={y}"
        + "&format=image/png8"
    )

    Link.objects.get_or_create(
        resource=instance.resourcebase_ptr,
        url=tile_url,
        defaults=dict(extension="tiles", name="Tiles", mime="image/png", link_type="image"),
    )

    html_link_url = "%s%s" % (settings.SITEURL[:-1], instance.get_absolute_url())

    Link.objects.get_or_create(
        resource=instance.resourcebase_ptr,
        url=html_link_url,
        defaults=dict(extension="html", name=instance.typename, mime="text/html", link_type="html"),
    )

    params = {"layers": instance.typename.encode("utf-8"), "format": "image/png8", "width": 200, "height": 150}

    # Avoid using urllib.urlencode here because it breaks the url.
    # commas and slashes in values get encoded and then cause trouble
    # with the WMS parser.
    p = "&".join("%s=%s" % item for item in params.items())

    thumbnail_remote_url = ogc_server_settings.PUBLIC_LOCATION + "wms/reflect?" + p

    thumbnail_create_url = ogc_server_settings.LOCATION + "wms/reflect?" + p

    create_thumbnail(instance, thumbnail_remote_url, thumbnail_create_url, ogc_client=http_client)

    legend_url = (
        ogc_server_settings.PUBLIC_LOCATION
        + "wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER="
        + instance.typename
        + "&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on"
    )

    Link.objects.get_or_create(
        resource=instance.resourcebase_ptr,
        url=legend_url,
        defaults=dict(extension="png", name="Legend", url=legend_url, mime="image/png", link_type="image"),
    )

    ogc_wms_path = "%s/wms" % instance.workspace
    ogc_wms_url = urljoin(ogc_server_settings.public_url, ogc_wms_path)
    ogc_wms_name = "OGC WMS: %s Service" % instance.workspace
    Link.objects.get_or_create(
        resource=instance.resourcebase_ptr,
        url=ogc_wms_url,
        defaults=dict(extension="html", name=ogc_wms_name, url=ogc_wms_url, mime="text/html", link_type="OGC:WMS"),
    )

    if instance.storeType == "dataStore":
        ogc_wfs_path = "%s/wfs" % instance.workspace
        ogc_wfs_url = urljoin(ogc_server_settings.public_url, ogc_wfs_path)
        ogc_wfs_name = "OGC WFS: %s Service" % instance.workspace
        Link.objects.get_or_create(
            resource=instance.resourcebase_ptr,
            url=ogc_wfs_url,
            defaults=dict(extension="html", name=ogc_wfs_name, url=ogc_wfs_url, mime="text/html", link_type="OGC:WFS"),
        )

    if instance.storeType == "coverageStore":
        ogc_wcs_path = "%s/wcs" % instance.workspace
        ogc_wcs_url = urljoin(ogc_server_settings.public_url, ogc_wcs_path)
        ogc_wcs_name = "OGC WCS: %s Service" % instance.workspace
        Link.objects.get_or_create(
            resource=instance.resourcebase_ptr,
            url=ogc_wcs_url,
            defaults=dict(extension="html", name=ogc_wcs_name, url=ogc_wcs_url, mime="text/html", link_type="OGC:WCS"),
        )

    # remove links that belong to and old address

    for link in instance.link_set.all():
        if (
            not urlparse(settings.SITEURL).hostname == urlparse(link.url).hostname
            and not urlparse(ogc_server_settings.public_url).hostname == urlparse(link.url).hostname
        ):
            link.delete()

    # Save layer attributes
    set_attributes(instance)

    # Save layer styles
    set_styles(instance, gs_catalog)
    # NOTTODO by simod: we should not do this!
    # need to be removed when fixing #2015
    from geonode.catalogue.models import catalogue_post_save
    from geonode.layers.models import Layer

    catalogue_post_save(instance, Layer)
예제 #20
0
def geoserver_post_save2(layer_id):
    """Save keywords to GeoServer

       The way keywords are implemented requires the layer
       to be saved to the database before accessing them.
    """
    """Send information to geoserver.

           The attributes sent include:

            * Title
            * Abstract
            * Name
            * Keywords
            * Metadata Links,
            * Point of Contact name and url
        """

    from geonode.layers.models import Layer
    instance = Layer.objects.get(id=layer_id)
    # Don't run this signal if is a Layer from a remote service
    if getattr(instance, "service", None) is not None:
        return instance

    # Don't run this signal handler if it is a tile layer
    #    Currently only gpkg files containing tiles will have this type & will be served via MapProxy.
    if hasattr(instance, 'storeType') and getattr(instance,
                                                  'storeType') == 'tileStore':
        return instance

    gs_resource = None

    # If the store in None then it's a new instance from an upload,
    # only in this case run the geonode_uplaod method
    if not instance.store or getattr(instance, 'overwrite', False):
        base_file, info = instance.get_base_file()

        # There is no need to process it if there is not file.
        if base_file is None:
            return instance

        gs_name, workspace, values, gs_resource = geoserver_upload(
            instance,
            base_file.file.path,
            instance.owner,
            instance.name,
            overwrite=True,
            title=instance.title,
            abstract=instance.abstract,
            # keywords=instance.keywords,
            charset=instance.charset)

        # Set fields obtained via the geoserver upload.
        instance.name = gs_name
        instance.workspace = workspace
        instance.store = values['store']
        # Iterate over values from geoserver.
        for key in ['typename', 'store', 'storeType']:
            setattr(instance, key, values[key])

        instance.save()

    if not gs_resource:
        gs_resource = gs_catalog.get_resource(instance.name,
                                              store=instance.store,
                                              workspace=instance.workspace)

    if gs_resource:
        gs_resource.title = instance.title if instance.title else ""
        gs_resource.abstract = instance.abstract if instance.abstract else ""
        gs_resource.name = instance.name if instance.name else ""

    # Get metadata links
    metadata_links = []
    for link in instance.link_set.metadata():
        metadata_links.append((link.mime, link.name, link.url))

    if gs_resource:
        gs_resource.metadata_links = metadata_links
    # gs_resource should only be called if
    # ogc_server_settings.BACKEND_WRITE_ENABLED == True
    if gs_resource and getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED",
                               True):
        gs_catalog.save(gs_resource)

    gs_layer = gs_catalog.get_layer(instance.name)

    if instance.poc and instance.poc:
        # gsconfig now utilizes an attribution dictionary
        gs_layer.attribution = {
            'title': str(instance.poc),
            'width': None,
            'height': None,
            'href': None,
            'url': None,
            'type': None
        }
        profile = Profile.objects.get(username=instance.poc.username)
        gs_layer.attribution_link = settings.SITEURL[:
                                                     -1] + profile.get_absolute_url(
                                                     )
        # gs_layer should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_layer)
    """Get information from geoserver.

       The attributes retrieved include:

       * Bounding Box
       * SRID
       * Download links (WMS, WCS or WFS and KML)
       * Styles (SLD)
    """

    if gs_resource:
        bbox = gs_resource.latlon_bbox

        # FIXME(Ariel): Correct srid setting below
        # self.srid = gs_resource.src

        instance.srid_url = "http://www.spatialreference.org/ref/" + \
                            instance.srid.replace(':', '/').lower() + "/"

        # Set bounding box values
        instance.bbox_x0 = bbox[0]
        instance.bbox_x1 = bbox[1]
        instance.bbox_y0 = bbox[2]
        instance.bbox_y1 = bbox[3]

        # store the resource to avoid another geoserver call in the post_save
        instance.gs_resource = gs_resource

    instance.save()

    if type(instance) is ResourceBase:
        if hasattr(instance, 'layer'):
            instance = instance.layer
        else:
            return instance

    if instance.storeType == "remoteStore":
        # Save layer attributes
        set_attributes_from_geoserver(instance)
        return instance

    if not getattr(instance, 'gs_resource', None):
        try:
            gs_resource = gs_catalog.get_resource(instance.name,
                                                  store=instance.store,
                                                  workspace=instance.workspace)
        except socket_error as serr:
            if serr.errno != errno.ECONNREFUSED:
                # Not the error we are looking for, re-raise
                raise serr
            # If the connection is refused, take it easy.
            return instance
    else:
        gs_resource = instance.gs_resource

    if gs_resource is None:
        return instance

    if settings.RESOURCE_PUBLISHING:
        if instance.is_published != gs_resource.advertised:
            if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
                gs_resource.advertised = instance.is_published
                gs_catalog.save(gs_resource)

    if any(instance.keyword_list()):
        gs_resource.keywords = instance.keyword_list()
        # gs_resource should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_resource)

    bbox = gs_resource.latlon_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML
    links = wms_links(ogc_server_settings.public_url + 'wms?',
                      instance.typename.encode('utf-8'), instance.bbox_string,
                      instance.srid, height, width)

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   name=ugettext(name),
                                   defaults=dict(
                                       extension=ext,
                                       url=wms_url,
                                       mime=mime,
                                       link_type='image',
                                   ))

    if instance.storeType == "dataStore":
        links = wfs_links(ogc_server_settings.public_url + 'wfs?',
                          instance.typename.encode('utf-8'))
        for ext, name, mime, wfs_url in links:
            if mime == 'SHAPE-ZIP':
                name = 'Zipped Shapefile'
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wfs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           url=wfs_url,
                                           link_type='data',
                                       ))

        gs_store_type = gs_resource.store.type.lower(
        ) if gs_resource.store.type else None
        geogig_repository = gs_resource.store.connection_parameters.get(
            'geogig_repository', '')
        geogig_repo_name = geogig_repository.replace('geoserver://', '')

        if gs_store_type == 'geogig' and geogig_repo_name:

            repo_url = '{url}geogig/repos/{repo_name}'.format(
                url=ogc_server_settings.public_url, repo_name=geogig_repo_name)

            path = gs_resource.dom.findall('nativeName')

            if path:
                path = 'path={path}'.format(path=path[0].text)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=repo_url,
                                       defaults=dict(extension='html',
                                                     name='Clone in GeoGig',
                                                     mime='text/xml',
                                                     link_type='html'))

            def command_url(command):
                return "{repo_url}/{command}.json?{path}".format(
                    repo_url=repo_url, path=path, command=command)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('log'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig log',
                                                     mime='application/json',
                                                     link_type='html'))

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('statistics'),
                                       defaults=dict(extension='json',
                                                     name='GeoGig statistics',
                                                     mime='application/json',
                                                     link_type='html'))

    elif instance.storeType == 'coverageStore':

        links = wcs_links(ogc_server_settings.public_url + 'wcs?',
                          instance.typename.encode('utf-8'))

    for ext, name, mime, wcs_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=wcs_url,
                                   defaults=dict(
                                       extension=ext,
                                       name=name,
                                       mime=mime,
                                       link_type='data',
                                   ))

    kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "download"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_download,
                               defaults=dict(
                                   extension='kml',
                                   name="KML",
                                   mime='text/xml',
                                   link_type='data',
                               ))

    kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "refresh"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_view,
                               defaults=dict(
                                   extension='kml',
                                   name="View in Google Earth",
                                   mime='text/xml',
                                   link_type='data',
                               ))

    html_link_url = '%s%s' % (settings.SITEURL[:-1],
                              instance.get_absolute_url())

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=html_link_url,
                               defaults=dict(
                                   extension='html',
                                   name=instance.typename,
                                   mime='text/html',
                                   link_type='html',
                               ))

    create_gs_thumbnail(instance, overwrite=False)

    legend_url = ogc_server_settings.PUBLIC_LOCATION + \
        'wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER=' + \
        instance.typename + '&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on'

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=legend_url,
                               defaults=dict(
                                   extension='png',
                                   name='Legend',
                                   url=legend_url,
                                   mime='image/png',
                                   link_type='image',
                               ))

    ogc_wms_path = '%s/wms' % instance.workspace
    ogc_wms_url = urljoin(ogc_server_settings.public_url, ogc_wms_path)
    ogc_wms_name = 'OGC WMS: %s Service' % instance.workspace
    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=ogc_wms_url,
                               defaults=dict(
                                   extension='html',
                                   name=ogc_wms_name,
                                   url=ogc_wms_url,
                                   mime='text/html',
                                   link_type='OGC:WMS',
                               ))

    if instance.storeType == "dataStore":
        ogc_wfs_path = '%s/wfs' % instance.workspace
        ogc_wfs_url = urljoin(ogc_server_settings.public_url, ogc_wfs_path)
        ogc_wfs_name = 'OGC WFS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wfs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wfs_name,
                                       url=ogc_wfs_url,
                                       mime='text/html',
                                       link_type='OGC:WFS',
                                   ))

    if instance.storeType == "coverageStore":
        ogc_wcs_path = '%s/wcs' % instance.workspace
        ogc_wcs_url = urljoin(ogc_server_settings.public_url, ogc_wcs_path)
        ogc_wcs_name = 'OGC WCS: %s Service' % instance.workspace
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wcs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=ogc_wcs_name,
                                       url=ogc_wcs_url,
                                       mime='text/html',
                                       link_type='OGC:WCS',
                                   ))

    # remove links that belong to and old address

    for link in instance.link_set.all():
        if not urlparse(settings.SITEURL).hostname == urlparse(
                link.url).hostname and not urlparse(
                    ogc_server_settings.public_url).hostname == urlparse(
                        link.url).hostname:
            link.delete()

    # Define the link after the cleanup, we should use this more rather then remove
    # potential parasites
    tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url +
                'layers=%s' % instance.typename.encode('utf-8') +
                '&zoom={z}&x={x}&y={y}' + '&format=image/png8')

    link, created = Link.objects.get_or_create(
        resource=instance.resourcebase_ptr,
        extension='tiles',
        name="Tiles",
        mime='image/png',
        link_type='image',
    )
    if created:
        Link.objects.filter(pk=link.pk).update(url=tile_url)

    # Save layer attributes
    set_attributes_from_geoserver(instance)

    # Save layer styles
    set_styles(instance, gs_catalog)
    # NOTTODO by simod: we should not do this!
    # need to be removed when fixing #2015
    from geonode.catalogue.models import catalogue_post_save
    from geonode.layers.models import Layer
    catalogue_post_save(instance, Layer)
    return instance
예제 #21
0
def geoserver_post_save_local(layer_id, *args, **kwargs):
    """Send information to geoserver.

       The attributes sent include:

        * Title
        * Abstract
        * Name
        * Keywords
        * Metadata Links,
        * Point of Contact name and url
    """
    # If it is a layer object, post process it. If not, abort.
    try:
        instance = Layer.objects.get(id=layer_id)
    except Layer.DoesNotExist as e:
        logger.exception(e)
        return
        # raise e

    # Don't run this signal if is a Layer from a remote service
    if getattr(instance, "service", None) is not None:
        return

    # Don't run this signal handler if it is a tile layer or a remote store (Service)
    #    Currently only gpkg files containing tiles will have this type & will be served via MapProxy.
    if hasattr(instance, 'storeType') and getattr(instance, 'storeType') in ['tileStore', 'remoteStore']:
        return instance

    gs_resource = None
    values = None

    # If the store in None then it's a new instance from an upload,
    # only in this case run the geoserver_upload method
    if not instance.store or getattr(instance, 'overwrite', False):
        base_file, info = instance.get_base_file()

        # There is no need to process it if there is not file.
        if base_file is None:
            return
        gs_name, workspace, values, gs_resource = geoserver_upload(instance,
                                                                   base_file.file.path,
                                                                   instance.owner,
                                                                   instance.name,
                                                                   overwrite=True,
                                                                   title=instance.title,
                                                                   abstract=instance.abstract,
                                                                   # keywords=instance.keywords,
                                                                   charset=instance.charset)

    if not gs_resource:
        gs_resource = gs_catalog.get_resource(
            instance.name,
            store=instance.store,
            workspace=instance.workspace)
        if not gs_resource:
            gs_resource = gs_catalog.get_resource(instance.alternate)

    if gs_resource:
        gs_resource.title = instance.title or ""
        gs_resource.abstract = instance.abstract or ""
        gs_resource.name = instance.name or ""

        if not values:
            values = dict(store=gs_resource.store.name,
                          storeType=gs_resource.store.resource_type,
                          alternate=gs_resource.store.workspace.name + ':' + gs_resource.name,
                          title=gs_resource.title or gs_resource.store.name,
                          abstract=gs_resource.abstract or '',
                          owner=instance.owner)
    else:
        return

    # Get metadata links
    metadata_links = []
    for link in instance.link_set.metadata():
        metadata_links.append((link.mime, link.name, link.url))

    gs_resource.metadata_links = metadata_links
    # gs_resource should only be called if
    # ogc_server_settings.BACKEND_WRITE_ENABLED == True
    if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
        try:
            gs_catalog.save(gs_resource)
        except geoserver.catalog.FailedRequestError as e:
            msg = ('Error while trying to save resource named %s in GeoServer, '
                   'try to use: "%s"' % (gs_resource, str(e)))
            e.args = (msg,)
            logger.exception(e)

    gs_layer = gs_catalog.get_layer(instance.name)

    if not gs_layer:
        gs_layer = gs_catalog.get_layer(instance.alternate)

    if gs_layer and instance.poc:
        # gsconfig now utilizes an attribution dictionary
        gs_layer.attribution = {'title': str(instance.poc),
                                'width': None,
                                'height': None,
                                'href': None,
                                'url': None,
                                'type': None}
        profile = Profile.objects.get(username=instance.poc.username)
        gs_layer.attribution_link = settings.SITEURL[
            :-1] + profile.get_absolute_url()
        # gs_layer should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            try:
                gs_catalog.save(gs_layer)
            except geoserver.catalog.FailedRequestError as e:
                msg = ('Error while trying to save layer named %s in GeoServer, '
                       'try to use: "%s"' % (gs_layer, str(e)))
                e.args = (msg,)
                logger.exception(e)

    if type(instance) is ResourceBase:
        if hasattr(instance, 'layer'):
            instance = instance.layer
        else:
            return

    if instance.storeType == "remoteStore":
        # Save layer attributes
        set_attributes_from_geoserver(instance)
        return

    """Get information from geoserver.

       The attributes retrieved include:

       * Bounding Box
       * SRID
       * Download links (WMS, WCS or WFS and KML)
       * Styles (SLD)
    """
    # instance.name = instance.name or gs_layer.name
    # instance.title = instance.title or gs_resource.title
    instance.abstract = gs_resource.abstract or ''
    instance.workspace = gs_resource.store.workspace.name
    instance.store = gs_resource.store.name

    bbox = gs_resource.latlon_bbox

    # FIXME(Ariel): Correct srid setting below
    # self.srid = gs_resource.src

    instance.srid_url = "http://www.spatialreference.org/ref/" + \
        instance.srid.replace(':', '/').lower() + "/"

    # Set bounding box values
    instance.bbox_x0 = bbox[0]
    instance.bbox_x1 = bbox[1]
    instance.bbox_y0 = bbox[2]
    instance.bbox_y1 = bbox[3]

    # Iterate over values from geoserver.
    for key in ['alternate', 'store', 'storeType']:
        # attr_name = key if 'typename' not in key else 'alternate'
        # print attr_name
        setattr(instance, key, values[key])

    if settings.RESOURCE_PUBLISHING:
        if instance.is_published != gs_resource.advertised:
            if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
                gs_resource.advertised = 'true' if instance.is_published else 'false'
                gs_catalog.save(gs_resource)

    if not settings.FREETEXT_KEYWORDS_READONLY:
        if gs_resource.keywords:
            for keyword in gs_resource.keywords:
                instance.keywords.add(keyword)

    if any(instance.keyword_list()):
        keywords = instance.keyword_list()
        if settings.FREETEXT_KEYWORDS_READONLY:
            if gs_resource.keywords:
                keywords += gs_resource.keywords
        gs_resource.keywords = list(set(keywords))

        # gs_resource should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            try:
                gs_catalog.save(gs_resource)
            except geoserver.catalog.FailedRequestError as e:
                msg = ('Error while trying to save resource named %s in GeoServer, '
                       'try to use: "%s"' % (gs_resource, str(e)))
                e.args = (msg,)
                logger.exception(e)

    to_update = {
        'title': instance.title or instance.name,
        'abstract': instance.abstract or "",
        'alternate': instance.alternate,
        'bbox_x0': instance.bbox_x0,
        'bbox_x1': instance.bbox_x1,
        'bbox_y0': instance.bbox_y0,
        'bbox_y1': instance.bbox_y1
    }

    # Update ResourceBase
    resources = ResourceBase.objects.filter(id=instance.resourcebase_ptr.id)
    resources.update(**to_update)

    # to_update['name'] = instance.name,
    to_update['workspace'] = instance.workspace
    to_update['store'] = instance.store
    to_update['storeType'] = instance.storeType
    to_update['typename'] = instance.alternate

    # Save all the modified information in the instance without triggering signals.
    Layer.objects.filter(id=instance.id).update(**to_update)

    # Refresh from DB
    instance.refresh_from_db()

    # store the resource to avoid another geoserver call in the post_save
    instance.gs_resource = gs_resource

    bbox = gs_resource.latlon_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML
    links = wms_links(ogc_server_settings.public_url + 'wms?',
                      instance.alternate.encode('utf-8'), instance.bbox_string,
                      instance.srid, height, width)

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   name=ugettext(name),
                                   defaults=dict(
                                       extension=ext,
                                       url=wms_url,
                                       mime=mime,
                                       link_type='image',
                                   )
                                   )

    if instance.storeType == "dataStore":
        links = wfs_links(
            ogc_server_settings.public_url +
            'wfs?',
            instance.alternate.encode('utf-8'))
        for ext, name, mime, wfs_url in links:
            if mime == 'SHAPE-ZIP':
                name = 'Zipped Shapefile'
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wfs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           url=wfs_url,
                                           link_type='data',
                                       )
                                       )

        gs_store_type = gs_resource.store.type.lower() if gs_resource.store.type else None
        geogig_repository = gs_resource.store.connection_parameters.get('geogig_repository', '')
        geogig_repo_name = geogig_repository.replace('geoserver://', '')
예제 #22
0
def geoserver_post_save(instance, sender, **kwargs):
    """Save keywords to GeoServer

       The way keywords are implemented requires the layer
       to be saved to the database before accessing them.
    """
    url = ogc_server_settings.internal_rest

    try:
        gs_resource= gs_catalog.get_resource(instance.name)
    except socket_error as serr:
        if serr.errno != errno.ECONNREFUSED:
            # Not the error we are looking for, re-raise
            raise serr
        # If the connection is refused, take it easy.
        return

    if any(instance.keyword_list()):
        gs_resource.keywords = instance.keyword_list()

        #gs_resource should only be called if ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings,"BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_resource)

    bbox = gs_resource.latlon_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML

    links = wms_links(ogc_server_settings.public_url + 'wms?',
                    instance.typename.encode('utf-8'), instance.bbox_string,
                    instance.srid, height, width)

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(resource= instance.resourcebase_ptr,
                        name=ugettext(name),
                        defaults=dict(
                            extension=ext,
                            url=wms_url,
                            mime=mime,
                            link_type='image',
                           )
                        )

    if instance.storeType == "dataStore":
        links = wfs_links(ogc_server_settings.public_url + 'wfs?', instance.typename.encode('utf-8'))
        for ext, name, mime, wfs_url in links:
            if mime=='SHAPE-ZIP':
                name = 'Zipped Shapefile'
            Link.objects.get_or_create(resource= instance.resourcebase_ptr,
                            url=wfs_url,
                            defaults=dict(
                                extension=ext,
                                name=name,
                                mime=mime,
                                url=wfs_url,
                                link_type='data',
                            )
                        )

    elif instance.storeType == 'coverageStore':
        #FIXME(Ariel): This works for public layers, does it work for restricted too?
        # would those end up with no geotiff links, like, forever?
        permissions = {}
        permissions['anonymous'] = instance.get_gen_level(ANONYMOUS_USERS)
        permissions['authenticated'] = instance.get_gen_level(AUTHENTICATED_USERS)
        instance.set_gen_level(ANONYMOUS_USERS,'layer_readonly')

        #Potentially 3 dimensions can be returned by the grid if there is a z
        #axis.  Since we only want width/height, slice to the second dimension
        covWidth, covHeight = get_coverage_grid_extent(instance)[:2]
        links = wcs_links(ogc_server_settings.public_url + 'wcs?', instance.typename.encode('utf-8'),
                          bbox=gs_resource.native_bbox[:-1],
                          crs=gs_resource.native_bbox[-1],
                          height=str(covHeight), width=str(covWidth))
        for ext, name, mime, wcs_url in links:
            Link.objects.get_or_create(resource= instance.resourcebase_ptr,
                                url=wcs_url,
                                defaults=dict(
                                    extension=ext,
                                    name=name,
                                    mime=mime,
                                    link_type='data',
                                )
                            )

        instance.set_gen_level(ANONYMOUS_USERS,permissions['anonymous'])
        instance.set_gen_level(AUTHENTICATED_USERS,permissions['authenticated'])

    kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + urllib.urlencode({
        'layers': instance.typename.encode('utf-8'),
        'mode': "download"
    })

    Link.objects.get_or_create(resource= instance.resourcebase_ptr,
                        url=kml_reflector_link_download,
                        defaults=dict(
                            extension='kml',
                            name=_("KML"),
                            mime='text/xml',
                            link_type='data',
                        )
                    )

    kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + urllib.urlencode({
        'layers': instance.typename.encode('utf-8'),
        'mode': "refresh"
    })

    Link.objects.get_or_create(resource= instance.resourcebase_ptr,
                        url=kml_reflector_link_view,
                        defaults=dict(
                            extension='kml',
                            name="View in Google Earth",
                            mime='text/xml',
                            link_type='data',
                        )
                    )

    tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url +
                'layers=%s' % instance.typename.encode('utf-8') +
                '&zoom={z}&x={x}&y={y}' +
                '&format=image/png8'
                )

    Link.objects.get_or_create(resource= instance.resourcebase_ptr,
                        url=tile_url,
                        defaults=dict(
                            extension='tiles',
                            name=_("Tiles"),
                            mime='image/png',
                            link_type='image',
                            )
                        )


    wms_path = '%s/%s/wms' % (instance.workspace, instance.name)
    ows_url = urljoin(ogc_server_settings.public_url, wms_path)

    Link.objects.get_or_create(resource= instance.resourcebase_ptr,
                        url=ows_url,
                        defaults=dict(
                            extension='html',
                            name=_("OWS"),
                            url=ows_url,
                            mime='text/html',
                            link_type='OGC:WMS',
                            )
                        )


    html_link_url = '%s%s' % (settings.SITEURL[:-1], instance.get_absolute_url())

    Link.objects.get_or_create(resource= instance.resourcebase_ptr,
                        url=html_link_url,
                        defaults=dict(
                            extension='html',
                            name=instance.typename,
                            mime='text/html',
                            link_type='html',
                            )
                        )

    params = {
        'layers': instance.typename.encode('utf-8'),
        'format': 'image/png8',
        'width': 200,
        'height': 150,
    }

    # Avoid using urllib.urlencode here because it breaks the url.
    # commas and slashes in values get encoded and then cause trouble
    # with the WMS parser.
    p = "&".join("%s=%s"%item for item in params.items())

    thumbnail_remote_url = ogc_server_settings.PUBLIC_LOCATION + "wms/reflect?" + p

    create_thumbnail(instance, thumbnail_remote_url)

    legend_url = ogc_server_settings.PUBLIC_LOCATION +'wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER='+instance.typename+'&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on'

    Link.objects.get_or_create(resource= instance.resourcebase_ptr,
                        url=legend_url,
                        defaults=dict(
                            extension='png',
                            name=_('Legend'),
                            url=legend_url,
                            mime='image/png',
                            link_type='image',
                        )
                    )

    ogc_wms_url = ogc_server_settings.public_url + 'wms?'
    Link.objects.get_or_create(resource= instance.resourcebase_ptr,
                        url=ogc_wms_url,
                        defaults=dict(
                            extension='html',
                            name=instance.name,
                            url=ogc_wms_url,
                            mime='text/html',
                            link_type='OGC:WMS',
                        )
                    )
                        
    if instance.storeType == "dataStore":
        ogc_wfs_url = ogc_server_settings.public_url + 'wfs?'
        Link.objects.get_or_create(resource= instance.resourcebase_ptr,
                            url=ogc_wfs_url,
                            defaults=dict(
                                extension='html',
                                name=instance.name,
                                url=ogc_wfs_url,
                                mime='text/html',
                                link_type='OGC:WFS',
                            )
                        )

    if instance.storeType == "coverageStore":
        ogc_wcs_url = ogc_server_settings.public_url + 'wcs?'
        Link.objects.get_or_create(resource= instance.resourcebase_ptr,
                            url=ogc_wcs_url,
                            defaults=dict(
                                extension='html',
                                name=instance.name,
                                url=ogc_wcs_url,
                                mime='text/html',
                                link_type='OGC:WCS',
                            )
                        )

    #remove links that belong to and old address

    for link in instance.link_set.all():
        if not urlparse(settings.SITEURL).hostname == urlparse(link.url).hostname and not \
                    urlparse(ogc_server_settings.public_url).hostname == urlparse(link.url).hostname:
            link.delete()

    #Save layer attributes
    set_attributes(instance)

    #Save layer styles
    set_styles(instance, gs_catalog)
예제 #23
0
def geoserver_post_save(instance, sender, **kwargs):
    """Save keywords to GeoServer

       The way keywords are implemented requires the layer
       to be saved to the database before accessing them.
    """
    url = ogc_server_settings.internal_rest

    try:
        gs_resource = gs_catalog.get_resource(instance.name)
    except (FailedRequestError, EnvironmentError) as e:
        msg = ('Could not connect to geoserver at "%s"'
               'to save information for layer "%s"' %
               (ogc_server_settings.LOCATION, instance.name.encode('utf-8')))
        logger.warn(msg, e)
        # If geoserver is not online, there is no need to continue
        return

    # If there is no resource returned it could mean one of two things:
    # a) There is a synchronization problem in geoserver
    # b) The unit tests are running and another geoserver is running in the
    # background.
    # For both cases it is sensible to stop processing the layer
    if gs_resource is None:
        logger.warn('Could not get geoserver resource for %s' % instance)
        return

    gs_resource.keywords = instance.keyword_list()
    #gs_resource should only be called if ogc_server_settings.BACKEND_WRITE_ENABLED == True
    if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
        gs_catalog.save(gs_resource)

    bbox = gs_resource.latlon_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML

    links = wms_links(ogc_server_settings.public_url + 'wms?',
                      instance.typename.encode('utf-8'), instance.bbox_string,
                      instance.srid, height, width)

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   name=ugettext(name),
                                   defaults=dict(
                                       extension=ext,
                                       url=wms_url,
                                       mime=mime,
                                       link_type='image',
                                   ))

    if instance.storeType == "dataStore":
        links = wfs_links(ogc_server_settings.public_url + 'wfs?',
                          instance.typename.encode('utf-8'))
        for ext, name, mime, wfs_url in links:
            if mime == 'SHAPE-ZIP':
                name = 'Zipped Shapefile'
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wfs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           url=wfs_url,
                                           link_type='data',
                                       ))

    elif instance.storeType == 'coverageStore':
        #FIXME(Ariel): This works for public layers, does it work for restricted too?
        # would those end up with no geotiff links, like, forever?
        permissions = {}
        permissions['anonymous'] = instance.get_gen_level(ANONYMOUS_USERS)
        permissions['authenticated'] = instance.get_gen_level(
            AUTHENTICATED_USERS)
        instance.set_gen_level(ANONYMOUS_USERS, 'layer_readonly')

        #Potentially 3 dimensions can be returned by the grid if there is a z
        #axis.  Since we only want width/height, slice to the second dimension
        covWidth, covHeight = get_coverage_grid_extent(instance)[:2]
        links = wcs_links(ogc_server_settings.public_url + 'wcs?',
                          instance.typename.encode('utf-8'),
                          bbox=gs_resource.native_bbox[:-1],
                          crs=gs_resource.native_bbox[-1],
                          height=str(covHeight),
                          width=str(covWidth))
        for ext, name, mime, wcs_url in links:
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wcs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           link_type='data',
                                       ))

        instance.set_gen_level(ANONYMOUS_USERS, permissions['anonymous'])
        instance.set_gen_level(AUTHENTICATED_USERS,
                               permissions['authenticated'])

    kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + urllib.urlencode(
        {
            'layers': instance.typename.encode('utf-8'),
            'mode': "download"
        })

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_download,
                               defaults=dict(
                                   extension='kml',
                                   name=_("KML"),
                                   mime='text/xml',
                                   link_type='data',
                               ))

    kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + urllib.urlencode(
        {
            'layers': instance.typename.encode('utf-8'),
            'mode': "refresh"
        })

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_view,
                               defaults=dict(
                                   extension='kml',
                                   name="View in Google Earth",
                                   mime='text/xml',
                                   link_type='data',
                               ))

    tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url +
                'layers=%s' % instance.typename.encode('utf-8') +
                '&zoom={z}&x={x}&y={y}' + '&format=image/png8')

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=tile_url,
                               defaults=dict(
                                   extension='tiles',
                                   name=_("Tiles"),
                                   mime='image/png',
                                   link_type='image',
                               ))

    wms_path = '%s/%s/wms' % (instance.workspace, instance.name)
    ows_url = urljoin(ogc_server_settings.public_url, wms_path)

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=ows_url,
                               defaults=dict(
                                   extension='html',
                                   name=_("OWS"),
                                   url=ows_url,
                                   mime='text/html',
                                   link_type='OGC:WMS',
                               ))

    html_link_url = '%s%s' % (settings.SITEURL[:-1],
                              instance.get_absolute_url())

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=html_link_url,
                               defaults=dict(
                                   extension='html',
                                   name=instance.typename,
                                   mime='text/html',
                                   link_type='html',
                               ))

    params = {
        'layers': instance.typename.encode('utf-8'),
        'format': 'image/png8',
        'width': 200,
        'height': 150,
    }

    # Avoid using urllib.urlencode here because it breaks the url.
    # commas and slashes in values get encoded and then cause trouble
    # with the WMS parser.
    p = "&".join("%s=%s" % item for item in params.items())

    thumbnail_url = ogc_server_settings.LOCATION + "wms/reflect?" + p

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=thumbnail_url,
                               defaults=dict(
                                   extension='png',
                                   name=_("Remote Thumbnail"),
                                   mime='image/png',
                                   link_type='image',
                               ))

    # Download thumbnail and save it locally.
    resp, image = http_client.request(thumbnail_url)

    if 'ServiceException' in image or resp.status < 200 or resp.status > 299:
        msg = 'Unable to obtain thumbnail: %s' % image
        logger.debug(msg)
        # Replace error message with None.
        image = None

    if image is not None:
        #Clean any orphan Thumbnail before
        Thumbnail.objects.filter(resourcebase__id=None).delete()
        thumbnail, created = Thumbnail.objects.get_or_create(
            resourcebase__id=instance.id)
        thumbnail.thumb_spec = thumbnail_url
        thumbnail.save_thumb(image, instance._thumbnail_path())

        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=settings.SITEURL +
                                   instance._thumbnail_path(),
                                   defaults=dict(
                                       extension='png',
                                       name=_("Thumbnail"),
                                       mime='image/png',
                                       link_type='image',
                                   ))

    ogc_wms_url = ogc_server_settings.public_url + 'wms?'
    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=ogc_wms_url,
                               defaults=dict(
                                   extension='html',
                                   name=instance.name,
                                   url=ogc_wms_url,
                                   mime='text/html',
                                   link_type='OGC:WMS',
                               ))

    if instance.storeType == "dataStore":
        ogc_wfs_url = ogc_server_settings.public_url + 'wfs?'
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wfs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=instance.name,
                                       url=ogc_wfs_url,
                                       mime='text/html',
                                       link_type='OGC:WFS',
                                   ))

    if instance.storeType == "coverageStore":
        ogc_wcs_url = ogc_server_settings.public_url + 'wcs?'
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wcs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=instance.name,
                                       url=ogc_wcs_url,
                                       mime='text/html',
                                       link_type='OGC:WCS',
                                   ))

    #remove links that belong to and old address

    for link in instance.link_set.all():
        if not urlparse(settings.SITEURL).hostname == urlparse(link.url).hostname and not \
                    urlparse(ogc_server_settings.public_url).hostname == urlparse(link.url).hostname:
            link.delete()

    #Save layer attributes
    set_attributes(instance)

    #Save layer styles
    set_styles(instance, gs_catalog)
예제 #24
0
def attributes_sats_refresh(request):
    from geonode.geoserver.helpers import gs_catalog, set_attributes_from_geoserver
    uuid = request.POST['uuid']
    resource = get_object_or_404(ResourceBase, uuid=uuid)
    can_change_data = request.user.has_perm('change_resourcebase', resource)
    layer = Layer.objects.get(id=resource.id)
    if layer and can_change_data:
        try:
            # recalculate the layer statistics
            set_attributes_from_geoserver(layer, overwrite=True)
            gs_resource = gs_catalog.get_resource(name=layer.name,
                                                  store=layer.store,
                                                  workspace=layer.workspace)
            if not gs_resource:
                gs_resource = gs_catalog.get_resource(
                    name=layer.name, workspace=layer.workspace)
            if not gs_resource:
                gs_resource = gs_catalog.get_resource(name=layer.name)

            if not gs_resource:
                return HttpResponse(json.dumps({
                    'success':
                    'false',
                    'message':
                    'Error trying to fetch the resource "%s" from GeoServer!' %
                    layer.store
                }),
                                    status=302,
                                    content_type='text/plain')
            from decimal import Decimal
            layer.bbox_x0 = Decimal(gs_resource.native_bbox[0])
            layer.bbox_x1 = Decimal(gs_resource.native_bbox[1])
            layer.bbox_y0 = Decimal(gs_resource.native_bbox[2])
            layer.bbox_y1 = Decimal(gs_resource.native_bbox[3])
            layer.srid = gs_resource.projection
            layer.save()
        except Exception as e:
            # traceback.print_exc()
            return HttpResponse(json.dumps({
                'success':
                'false',
                'message':
                'Exception occurred: "%s"' % str(e)
            }),
                                status=302,
                                content_type='text/plain')
        return HttpResponse(json.dumps({
            'success':
            'ok',
            'message':
            _('Attributes/Stats Refreshed Successfully!')
        }),
                            status=200,
                            content_type='text/plain')
    else:
        return HttpResponse(json.dumps({
            'success':
            'false',
            'message':
            _('You cannot modify this resource!')
        }),
                            status=200,
                            content_type='text/plain')
예제 #25
0
def geoserver_pre_save(instance, sender, **kwargs):
    """Send information to geoserver.

       The attributes sent include:

        * Title
        * Abstract
        * Name
        * Keywords
        * Metadata Links,
        * Point of Contact name and url
    """
    url = ogc_server_settings.internal_rest
    try:
        gs_resource = gs_catalog.get_resource(instance.name,
                                              store=instance.store,
                                              workspace=instance.workspace)
    except (EnvironmentError, FailedRequestError) as e:
        gs_resource = None
        msg = ('Could not connect to geoserver at "%s"'
               'to save information for layer "%s"' %
               (ogc_server_settings.LOCATION, instance.name.encode('utf-8')))
        logger.warn(msg, e)
        # If geoserver is not online, there is no need to continue
        return

    # If there is no resource returned it could mean one of two things:
    # a) There is a synchronization problem in geoserver
    # b) The unit tests are running and another geoserver is running in the
    # background.
    # For both cases it is sensible to stop processing the layer
    if gs_resource is None:
        logger.warn('Could not get geoserver resource for %s' % instance)
        return

    gs_resource.title = instance.title
    gs_resource.abstract = instance.abstract
    gs_resource.name = instance.name

    # Get metadata links
    metadata_links = []
    for link in instance.link_set.metadata():
        metadata_links.append((link.name, link.mime, link.url))

    gs_resource.metadata_links = metadata_links
    #gs_resource should only be called if ogc_server_settings.BACKEND_WRITE_ENABLED == True
    if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
        gs_catalog.save(gs_resource)

    gs_layer = gs_catalog.get_layer(instance.name)

    if instance.poc and instance.poc.user:
        gs_layer.attribution = str(instance.poc.user)
        profile = Profile.objects.get(user=instance.poc.user)
        gs_layer.attribution_link = settings.SITEURL[:
                                                     -1] + profile.get_absolute_url(
                                                     )
        #gs_layer should only be called if ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_layer)
    """Get information from geoserver.

       The attributes retrieved include:

       * Bounding Box
       * SRID
       * Download links (WMS, WCS or WFS and KML)
       * Styles (SLD)
    """
    gs_resource = gs_catalog.get_resource(instance.name)

    bbox = gs_resource.latlon_bbox

    #FIXME(Ariel): Correct srid setting below
    #self.srid = gs_resource.src

    instance.srid_url = "http://www.spatialreference.org/ref/" + instance.srid.replace(
        ':', '/').lower() + "/"
    # Set bounding box values

    instance.bbox_x0 = bbox[0]
    instance.bbox_x1 = bbox[1]
    instance.bbox_y0 = bbox[2]
    instance.bbox_y1 = bbox[3]

    instance.thumbnail, created = Thumbnail.objects.get_or_create(
        resourcebase__id=instance.id)
예제 #26
0
파일: signals.py 프로젝트: jsiochi/geonode
def geoserver_pre_save(instance, sender, **kwargs):
    """Send information to geoserver.

       The attributes sent include:

        * Title
        * Abstract
        * Name
        * Keywords
        * Metadata Links,
        * Point of Contact name and url
    """
    base_file = instance.get_base_file()

    # There is no need to process it if there is not file.
    if base_file is None:
        return

    gs_name, workspace, values = geoserver_upload(
        instance,
        base_file.file.path,
        instance.owner,
        instance.name,
        overwrite=True,
        title=instance.title,
        abstract=instance.abstract,
        #               keywords=instance.keywords,
        charset=instance.charset,
    )

    # Set fields obtained via the geoserver upload.
    instance.name = gs_name
    instance.workspace = workspace

    # Iterate over values from geoserver.
    for key in ["typename", "store", "storeType"]:
        setattr(instance, key, values[key])

    url = ogc_server_settings.internal_rest
    gs_resource = gs_catalog.get_resource(instance.name, store=instance.store, workspace=instance.workspace)

    gs_resource.title = instance.title
    gs_resource.abstract = instance.abstract
    gs_resource.name = instance.name

    # Get metadata links
    metadata_links = []
    for link in instance.link_set.metadata():
        metadata_links.append((link.name, link.mime, link.url))

    gs_resource.metadata_links = metadata_links
    # gs_resource should only be called if ogc_server_settings.BACKEND_WRITE_ENABLED == True
    if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
        gs_catalog.save(gs_resource)

    gs_layer = gs_catalog.get_layer(instance.name)

    if instance.poc and instance.poc.user:
        gs_layer.attribution = str(instance.poc.user)
        profile = Profile.objects.get(user=instance.poc.user)
        gs_layer.attribution_link = settings.SITEURL[:-1] + profile.get_absolute_url()
        # gs_layer should only be called if ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_layer)

    """Get information from geoserver.

       The attributes retrieved include:

       * Bounding Box
       * SRID
       * Download links (WMS, WCS or WFS and KML)
       * Styles (SLD)
    """
    gs_resource = gs_catalog.get_resource(instance.name)

    bbox = gs_resource.latlon_bbox

    # FIXME(Ariel): Correct srid setting below
    # self.srid = gs_resource.src

    instance.srid_url = "http://www.spatialreference.org/ref/" + instance.srid.replace(":", "/").lower() + "/"

    # Set bounding box values
    instance.bbox_x0 = bbox[0]
    instance.bbox_x1 = bbox[1]
    instance.bbox_y0 = bbox[2]
    instance.bbox_y1 = bbox[3]
예제 #27
0
def attributes_sats_refresh(request):
    from geonode.geoserver.helpers import gs_catalog, set_attributes_from_geoserver
    uuid = request.POST['uuid']
    resource = get_object_or_404(ResourceBase, uuid=uuid)
    can_change_data = request.user.has_perm('change_resourcebase', resource)
    layer = Layer.objects.get(id=resource.id)
    if layer and can_change_data:
        try:
            # recalculate the layer statistics
            set_attributes_from_geoserver(layer, overwrite=False)
            gs_resource = gs_catalog.get_resource(name=layer.name,
                                                  store=layer.store,
                                                  workspace=layer.workspace)
            if not gs_resource:
                gs_resource = gs_catalog.get_resource(
                    name=layer.name, workspace=layer.workspace)
            if not gs_resource:
                gs_resource = gs_catalog.get_resource(name=layer.name)

            if not gs_resource:
                return HttpResponse(json.dumps({
                    'success':
                    'false',
                    'message':
                    f'Error trying to fetch the resource "{layer.store}" from GeoServer!'
                }),
                                    status=302,
                                    content_type='text/plain')

            bbox = gs_resource.native_bbox
            ll_bbox = gs_resource.latlon_bbox
            try:
                layer.set_bbox_polygon([bbox[0], bbox[2], bbox[1], bbox[3]],
                                       gs_resource.projection)
            except GeoNodeException as e:
                if not ll_bbox:
                    raise
                else:
                    logger.exception(e)
                    layer.srid = 'EPSG:4326'
            layer.set_ll_bbox_polygon(
                [ll_bbox[0], ll_bbox[2], ll_bbox[1], ll_bbox[3]])
            layer.save()
        except Exception as e:
            # traceback.print_exc()
            return HttpResponse(json.dumps({
                'success':
                'false',
                'message':
                f'Exception occurred: "{str(e)}"'
            }),
                                status=302,
                                content_type='text/plain')
        return HttpResponse(json.dumps({
            'success':
            'ok',
            'message':
            _('Attributes/Stats Refreshed Successfully!')
        }),
                            status=200,
                            content_type='text/plain')
    else:
        return HttpResponse(json.dumps({
            'success':
            'false',
            'message':
            _('You cannot modify this resource!')
        }),
                            status=200,
                            content_type='text/plain')
예제 #28
0
def geoserver_pre_save(instance, sender, **kwargs):
    """Send information to geoserver.

       The attributes sent include:

        * Title
        * Abstract
        * Name
        * Keywords
        * Metadata Links,
        * Point of Contact name and url
    """

    # Don't run this signal if is a Layer from a remote service
    if instance.workspace == 'remoteWorkspace':
        return

    # If the store in None then it's a new instance from an upload,
    # only in this case run the geonode_uplaod method
    if not instance.store or getattr(instance, 'overwrite', False):
        base_file = instance.get_base_file()

        # There is no need to process it if there is not file.
        if base_file is None:
            return
        gs_name, workspace, values = geoserver_upload(
            instance,
            base_file.file.path,
            instance.owner,
            instance.name,
            overwrite=True,
            title=instance.title,
            abstract=instance.abstract,
            # keywords=instance.keywords,
            charset=instance.charset)
        # Set fields obtained via the geoserver upload.
        instance.name = gs_name
        instance.workspace = workspace
        # Iterate over values from geoserver.
        for key in ['typename', 'store', 'storeType']:
            setattr(instance, key, values[key])

    gs_resource = gs_catalog.get_resource(instance.name,
                                          store=instance.store,
                                          workspace=instance.workspace)

    gs_resource.title = instance.title
    gs_resource.abstract = instance.abstract
    gs_resource.name = instance.name

    # Get metadata links
    metadata_links = []
    for link in instance.link_set.metadata():
        metadata_links.append((link.mime, link.name, link.url))

    gs_resource.metadata_links = metadata_links
    # gs_resource should only be called if
    # ogc_server_settings.BACKEND_WRITE_ENABLED == True
    if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
        gs_catalog.save(gs_resource)

    gs_layer = gs_catalog.get_layer(instance.name)

    if instance.poc and instance.poc:
        gs_layer.attribution = str(instance.poc)
        profile = Profile.objects.get(username=instance.poc.username)
        gs_layer.attribution_link = settings.SITEURL[:
                                                     -1] + profile.get_absolute_url(
                                                     )
        # gs_layer should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_layer)
    """Get information from geoserver.

       The attributes retrieved include:

       * Bounding Box
       * SRID
       * Download links (WMS, WCS or WFS and KML)
       * Styles (SLD)
    """
    gs_resource = gs_catalog.get_resource(instance.name)

    bbox = gs_resource.latlon_bbox

    # FIXME(Ariel): Correct srid setting below
    # self.srid = gs_resource.src

    instance.srid_url = "http://www.spatialreference.org/ref/" + \
        instance.srid.replace(':', '/').lower() + "/"

    # Set bounding box values
    instance.bbox_x0 = bbox[0]
    instance.bbox_x1 = bbox[1]
    instance.bbox_y0 = bbox[2]
    instance.bbox_y1 = bbox[3]
예제 #29
0
파일: signals.py 프로젝트: brylie/geonode
def geoserver_post_save(instance, sender, **kwargs):
    """Save keywords to GeoServer

       The way keywords are implemented requires the layer
       to be saved to the database before accessing them.
    """

    if instance.storeType == "remoteStore":
        # Save layer attributes
        set_attributes(instance)
        return

    try:
        gs_resource = gs_catalog.get_resource(
            instance.name,
            store=instance.store,
            workspace=instance.workspace)
    except socket_error as serr:
        if serr.errno != errno.ECONNREFUSED:
            # Not the error we are looking for, re-raise
            raise serr
        # If the connection is refused, take it easy.
        return

    if gs_resource is None:
        return

    if any(instance.keyword_list()):
        gs_resource.keywords = instance.keyword_list()

        # gs_resource should only be called if
        # ogc_server_settings.BACKEND_WRITE_ENABLED == True
        if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True):
            gs_catalog.save(gs_resource)

    bbox = gs_resource.latlon_bbox
    dx = float(bbox[1]) - float(bbox[0])
    dy = float(bbox[3]) - float(bbox[2])

    dataAspect = 1 if dy == 0 else dx / dy

    height = 550
    width = int(height * dataAspect)

    # Set download links for WMS, WCS or WFS and KML

    links = wms_links(ogc_server_settings.public_url + 'wms?',
                      instance.typename.encode('utf-8'), instance.bbox_string,
                      instance.srid, height, width)

    for ext, name, mime, wms_url in links:
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   name=ugettext(name),
                                   defaults=dict(
                                       extension=ext,
                                       url=wms_url,
                                       mime=mime,
                                       link_type='image',
                                   )
                                   )

    if instance.storeType == "dataStore":
        links = wfs_links(
            ogc_server_settings.public_url +
            'wfs?',
            instance.typename.encode('utf-8'))
        for ext, name, mime, wfs_url in links:
            if mime == 'SHAPE-ZIP':
                name = 'Zipped Shapefile'
            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=wfs_url,
                                       defaults=dict(
                                           extension=ext,
                                           name=name,
                                           mime=mime,
                                           url=wfs_url,
                                           link_type='data',
                                       )
                                       )

        if gs_resource.store.type.lower() == 'geogit':
            repo_url = '{url}geogit/{workspace}:{store}'.format(
                url=ogc_server_settings.public_url,
                workspace=instance.workspace,
                store=instance.store)

            path = gs_resource.dom.findall('nativeName')

            if path:
                path = 'path={path}'.format(path=path[0].text)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=repo_url,
                                       defaults=dict(extension='html',
                                                     name='Clone in GeoGit',
                                                     mime='text/xml',
                                                     link_type='html'
                                                     )
                                       )

            command_url = lambda command: "{repo_url}/{command}.json?{path}".format(
                repo_url=repo_url,
                path=path,
                command=command)

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('log'),
                                       defaults=dict(extension='json',
                                                     name='GeoGit log',
                                                     mime='application/json',
                                                     link_type='html'
                                                     )
                                       )

            Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                       url=command_url('statistics'),
                                       defaults=dict(extension='json',
                                                     name='GeoGit statistics',
                                                     mime='application/json',
                                                     link_type='html'
                                                     )
                                       )

    elif instance.storeType == 'coverageStore':
        # FIXME(Ariel): This works for public layers, does it work for restricted too?
        # would those end up with no geotiff links, like, forever?
        permissions = instance.get_all_level_info()

        instance.set_permissions(
            {'users': {'AnonymousUser': ['view_resourcebase']}})

        try:
            # Potentially 3 dimensions can be returned by the grid if there is a z
            # axis.  Since we only want width/height, slice to the second
            # dimension
            covWidth, covHeight = get_coverage_grid_extent(instance)[:2]
        except GeoNodeException as e:
            msg = _('Could not create a download link for layer.')
            logger.warn(msg, e)
        else:

            links = wcs_links(ogc_server_settings.public_url + 'wcs?',
                              instance.typename.encode('utf-8'),
                              bbox=gs_resource.native_bbox[:-1],
                              crs=gs_resource.native_bbox[-1],
                              height=str(covHeight),
                              width=str(covWidth))

            for ext, name, mime, wcs_url in links:
                Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                           url=wcs_url,
                                           defaults=dict(
                                               extension=ext,
                                               name=name,
                                               mime=mime,
                                               link_type='data',
                                           )
                                           )

        instance.set_permissions(permissions)

    kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "download"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_download,
                               defaults=dict(
                                   extension='kml',
                                   name=_("KML"),
                                   mime='text/xml',
                                   link_type='data',
                               )
                               )

    kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + \
        urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "refresh"})

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=kml_reflector_link_view,
                               defaults=dict(
                                   extension='kml',
                                   name="View in Google Earth",
                                   mime='text/xml',
                                   link_type='data',
                               )
                               )

    tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url +
                'layers=%s' % instance.typename.encode('utf-8') +
                '&zoom={z}&x={x}&y={y}' +
                '&format=image/png8'
                )

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=tile_url,
                               defaults=dict(
                                   extension='tiles',
                                   name=_("Tiles"),
                                   mime='image/png',
                                   link_type='image',
                               )
                               )

    wms_path = '%s/%s/wms' % (instance.workspace, instance.name)
    ows_url = urljoin(ogc_server_settings.public_url, wms_path)

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=ows_url,
                               defaults=dict(
                                   extension='html',
                                   name=_("OWS"),
                                   url=ows_url,
                                   mime='text/html',
                                   link_type='OGC:WMS',
                               )
                               )

    html_link_url = '%s%s' % (
        settings.SITEURL[:-1], instance.get_absolute_url())

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=html_link_url,
                               defaults=dict(
                                   extension='html',
                                   name=instance.typename,
                                   mime='text/html',
                                   link_type='html',
                               )
                               )

    params = {
        'layers': instance.typename.encode('utf-8'),
        'format': 'image/png8',
        'width': 200,
        'height': 150,
    }

    # Avoid using urllib.urlencode here because it breaks the url.
    # commas and slashes in values get encoded and then cause trouble
    # with the WMS parser.
    p = "&".join("%s=%s" % item for item in params.items())

    thumbnail_remote_url = ogc_server_settings.PUBLIC_LOCATION + \
        "wms/reflect?" + p
    thumbail_create_url = ogc_server_settings.LOCATION + \
        "wms/reflect?" + p

    # This is a workaround for development mode where cookies are not shared and the layer is not public so
    # not visible through geoserver
    if settings.DEBUG:
        from geonode.security.views import _perms_info_json
        current_perms = _perms_info_json(instance.get_self_resource())
        instance.set_default_permissions()

    create_thumbnail(instance, thumbnail_remote_url, thumbail_create_url)

    if settings.DEBUG:
        instance.set_permissions(json.loads(current_perms))

    legend_url = ogc_server_settings.PUBLIC_LOCATION + 'wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER=' + \
        instance.typename + '&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on'

    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=legend_url,
                               defaults=dict(
                                   extension='png',
                                   name=_('Legend'),
                                   url=legend_url,
                                   mime='image/png',
                                   link_type='image',
                               )
                               )

    ogc_wms_url = ogc_server_settings.public_url + 'wms?'
    Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                               url=ogc_wms_url,
                               defaults=dict(
                                   extension='html',
                                   name=instance.name,
                                   url=ogc_wms_url,
                                   mime='text/html',
                                   link_type='OGC:WMS',
                               )
                               )

    if instance.storeType == "dataStore":
        ogc_wfs_url = ogc_server_settings.public_url + 'wfs?'
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wfs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=instance.name,
                                       url=ogc_wfs_url,
                                       mime='text/html',
                                       link_type='OGC:WFS',
                                   )
                                   )

    if instance.storeType == "coverageStore":
        ogc_wcs_url = ogc_server_settings.public_url + 'wcs?'
        Link.objects.get_or_create(resource=instance.resourcebase_ptr,
                                   url=ogc_wcs_url,
                                   defaults=dict(
                                       extension='html',
                                       name=instance.name,
                                       url=ogc_wcs_url,
                                       mime='text/html',
                                       link_type='OGC:WCS',
                                   )
                                   )

    # remove links that belong to and old address

    for link in instance.link_set.all():
        if not urlparse(
            settings.SITEURL).hostname == urlparse(
            link.url).hostname and not urlparse(
            ogc_server_settings.public_url).hostname == urlparse(
                link.url).hostname:
            link.delete()

    # Save layer attributes
    set_attributes(instance)

    # Save layer styles
    set_styles(instance, gs_catalog)