Esempio n. 1
0
    def test_set_attributes(self):
        """Test attributes syncronization
        """

        # upload a shapefile
        shp_file = os.path.join(
            gisdata.VECTOR_DATA,
            'san_andres_y_providencia_poi.shp')
        layer = file_upload(shp_file)

        # set attributes for resource
        for attribute in layer.attribute_set.all():
            attribute.attribute_label = '%s_label' % attribute.attribute
            attribute.description = '%s_description' % attribute.attribute
            attribute.save()

        # sync the attributes with GeoServer
        set_attributes(layer)

        # tests if everything is synced properly
        for attribute in layer.attribute_set.all():
            self.assertEquals(
                attribute.attribute_label,
                '%s_label' % attribute.attribute
            )
            self.assertEquals(
                attribute.description,
                '%s_description' % attribute.attribute
            )
    def test_set_attributes(self):
        """Test attributes syncronization
        """

        # upload a shapefile
        shp_file = os.path.join(
            gisdata.VECTOR_DATA,
            'san_andres_y_providencia_poi.shp')
        layer = file_upload(shp_file)

        # set attributes for resource
        for attribute in layer.attribute_set.all():
            attribute.attribute_label = '%s_label' % attribute.attribute
            attribute.description = '%s_description' % attribute.attribute
            attribute.save()

        # sync the attributes with GeoServer
        set_attributes(layer)

        # tests if everything is synced properly
        for attribute in layer.attribute_set.all():
            self.assertEquals(
                attribute.attribute_label,
                '%s_label' % attribute.attribute
            )
            self.assertEquals(
                attribute.description,
                '%s_description' % attribute.attribute
            )
Esempio n. 3
0
    def handle(self, *args, **options):
        ignore_errors = options.get('ignore_errors')
        filter = options.get('filter')
        if not options.get('username'):
            username = None
        else:
            username = options.get('username')

        all_layers = Layer.objects.all().order_by('name')
        if filter:
            all_layers = all_layers.filter(name__icontains=filter)
        if username:
            all_layers = all_layers.filter(owner__username=username)

        for index, layer in enumerate(all_layers):
            print "[%s / %s] Updating Layer [%s] ..." % ((index + 1), len(all_layers), layer.name)
            try:
                # recalculate the layer statistics
                set_attributes(layer, overwrite=True)

                # refresh metadata links
                set_resource_default_links(layer, layer, prune=True)

                # refresh catalogue metadata records
                catalogue_post_save(instance=layer, sender=layer.__class__)
            except BaseException as e:
                # import traceback
                # traceback.print_exc()
                if ignore_errors:
                    print "[ERROR] Layer [%s] couldn't be updated" % (layer.name)
                else:
                    raise e
    def handle(self, *args, **options):
        ignore_errors = options.get('ignore_errors')
        remove_duplicates = options.get('remove_duplicates')
        filter = options.get('filter')
        if not options.get('username'):
            username = None
        else:
            username = options.get('username')

        all_layers = Layer.objects.all().order_by('name')
        if filter:
            all_layers = all_layers.filter(name__icontains=filter)
        if username:
            all_layers = all_layers.filter(owner__username=username)

        for index, layer in enumerate(all_layers):
            print "[%s / %s] Updating Layer [%s] ..." % (
                (index + 1), len(all_layers), layer.name)
            try:
                # recalculate the layer statistics
                set_attributes(layer, overwrite=True)

                # refresh metadata links
                set_resource_default_links(layer, layer, prune=False)

                # refresh catalogue metadata records
                catalogue_post_save(instance=layer, sender=layer.__class__)

                if remove_duplicates:
                    # remove duplicates
                    for _n in _names:
                        _links = Link.objects.filter(resource__id=layer.id,
                                                     name=_n)
                        while _links.count() > 1:
                            _links.last().delete()
                            print '.',
                    # fixup Legend links
                    legend_url_template = ogc_server_settings.PUBLIC_LOCATION + \
                        'ows?service=WMS&request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER=' + \
                        '{alternate}&STYLE={style_name}' + \
                        '&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on'
                    if layer.default_style and not layer.get_legend_url(
                            style_name=layer.default_style.name):
                        Link.objects.update_or_create(
                            resource=layer.resourcebase_ptr,
                            name='Legend',
                            extension='png',
                            url=legend_url_template.format(
                                alternate=layer.alternate,
                                style_name=layer.default_style.name),
                            mime='image/png',
                            link_type='image')
            except BaseException as e:
                import traceback
                traceback.print_exc()
                if ignore_errors:
                    print "[ERROR] Layer [%s] couldn't be updated" % (
                        layer.name)
                else:
                    raise e
    def handle(self, *args, **options):
        ignore_errors = options.get('ignore_errors')
        filter = options.get('filter')
        if not options.get('username'):
            username = None
        else:
            username = options.get('username')

        all_layers = Layer.objects.all().order_by('name')
        if filter:
            all_layers = all_layers.filter(name__icontains=filter)
        if username:
            all_layers = all_layers.filter(owner__username=username)

        for index, layer in enumerate(all_layers):
            print "[%s / %s] Updating Layer [%s] ..." % (
                (index + 1), len(all_layers), layer.name)
            try:
                # recalculate the layer statistics
                set_attributes(layer, overwrite=True)

                # refresh metadata links
                set_resource_default_links(layer, layer, prune=False)

                # refresh catalogue metadata records
                catalogue_post_save(instance=layer, sender=layer.__class__)
            except BaseException as e:
                # import traceback
                # traceback.print_exc()
                if ignore_errors:
                    print "[ERROR] Layer [%s] couldn't be updated" % (
                        layer.name)
                else:
                    raise e
Esempio n. 6
0
    def handle(self, *args, **options):
        ignore_errors = options.get('ignore_errors')
        remove_duplicates = options.get('remove_duplicates')
        prune = options.get('prune')
        set_uuid = ast.literal_eval(options.get('set_uuid', 'False'))
        set_attrib = ast.literal_eval(options.get('set_attrib', 'True'))
        set_links = ast.literal_eval(options.get('set_links', 'True'))

        delete_orphaned_thumbnails = options.get('delete_orphaned_thumbnails')
        filter = options.get('filter')
        if not options.get('username'):
            username = None
        else:
            username = options.get('username')

        all_layers = Layer.objects.all().order_by('name')
        if filter:
            all_layers = all_layers.filter(name__icontains=filter)
        if username:
            all_layers = all_layers.filter(owner__username=username)

        for index, layer in enumerate(all_layers):
            print(f"[{(index + 1)} / {len(all_layers)}] Updating Layer [{layer.name}] ...")
            try:
                # recalculate the layer statistics
                if set_attrib:
                    set_attributes(layer, overwrite=True)

                if set_uuid and hasattr(settings, 'LAYER_UUID_HANDLER') and settings.LAYER_UUID_HANDLER != '':
                    from geonode.layers.utils import get_uuid_handler
                    uuid = get_uuid_handler()(layer).create_uuid()
                    la = Layer.objects.filter(resourcebase_ptr=layer.resourcebase_ptr)
                    la.update(uuid=uuid)
                    layer.refresh_from_db()
                # refresh metadata links

                if set_links:
                    set_resource_default_links(layer, layer, prune=prune)

                # refresh catalogue metadata records
                catalogue_post_save(instance=layer, sender=layer.__class__)

                # remove duplicates
                if remove_duplicates:
                    remove_duplicate_links(layer)
            except Exception as e:
                import traceback
                traceback.print_exc()
                if ignore_errors:
                    logger.error(f"[ERROR] Layer [{layer.name}] couldn't be updated")
                else:
                    raise e

        # delete orphaned thumbs
        if delete_orphaned_thumbnails:
            delete_orphaned_thumbs()
    def handle(self, *args, **options):
        ignore_errors = options.get('ignore_errors')
        remove_duplicates = options.get('remove_duplicates')
        prune = options.get('prune')
        delete_orphaned_thumbnails = options.get('delete_orphaned_thumbnails')
        filter = options.get('filter')
        if not options.get('username'):
            username = None
        else:
            username = options.get('username')

        all_layers = Layer.objects.all().order_by('name')
        if filter:
            all_layers = all_layers.filter(name__icontains=filter)
        if username:
            all_layers = all_layers.filter(owner__username=username)

        for index, layer in enumerate(all_layers):
            print(
                f"[{(index + 1)} / {len(all_layers)}] Updating Layer [{layer.name}] ..."
            )
            try:
                # recalculate the layer statistics
                set_attributes(layer, overwrite=True)

                # refresh metadata links
                set_resource_default_links(layer, layer, prune=prune)

                # refresh catalogue metadata records
                catalogue_post_save(instance=layer, sender=layer.__class__)

                # remove duplicates
                if remove_duplicates:
                    remove_duplicate_links(layer)
            except Exception as e:
                import traceback
                traceback.print_exc()
                if ignore_errors:
                    logger.error(
                        f"[ERROR] Layer [{layer.name}] couldn't be updated")
                else:
                    raise e

        # delete orphaned thumbs
        if delete_orphaned_thumbnails:
            delete_orphaned_thumbs()
Esempio n. 8
0
    def test_set_attributes_creates_attributes(self):
        """ Test utility function set_attributes() which creates Attribute instances attached
            to a Layer instance.
        """
        # Creating a layer requires being logged in
        self.client.login(username='******', password='******')

        # Disconnect the geoserver-specific post_save signal attached to Layer creation.
        # The geoserver signal handler assumes things about the store where the Layer is placed.
        # this is a workaround.
        disconnected_post_save = signals.post_save.disconnect(geoserver_post_save, sender=Layer)

        # Create dummy layer to attach attributes to
        _l = Layer.objects.create(
            name='dummy_layer',
            bbox_x0=-180,
            bbox_x1=180,
            bbox_y0=-90,
            bbox_y1=90,
            srid='EPSG:4326')

        # Reconnect the signal if it was disconnected
        if disconnected_post_save:
            signals.post_save.connect(geoserver_post_save, sender=Layer)

        attribute_map = [
            ['id', 'Integer'],
            ['date', 'IntegerList'],
            ['enddate', 'Real'],
            ['date_as_date', 'xsd:dateTime'],
        ]

        # attribute_map gets modified as a side-effect of the call to set_attributes()
        expected_results = copy.deepcopy(attribute_map)

        # set attributes for resource
        set_attributes(_l, attribute_map)

        # 2 items in attribute_map should translate into 2 Attribute instances
        self.assertEqual(_l.attributes.count(), len(expected_results))

        # The name and type should be set as provided by attribute map
        for a in _l.attributes:
            self.assertIn([a.attribute, a.attribute_type], expected_results)
Esempio n. 9
0
    def test_set_attributes_creates_attributes(self):
        """ Test utility function set_attributes() which creates Attribute instances attached
            to a Layer instance.
        """
        # Creating a layer requires being logged in
        self.client.login(username='******', password='******')

        # Disconnect the geoserver-specific post_save signal attached to Layer creation.
        # The geoserver signal handler assumes things about the store where the Layer is placed.
        # this is a workaround.
        disconnected_post_save = signals.post_save.disconnect(geoserver_post_save, sender=Layer)

        # Create dummy layer to attach attributes to
        _l = Layer.objects.create(
            name='dummy_layer',
            bbox_x0=-180,
            bbox_x1=180,
            bbox_y0=-90,
            bbox_y1=90,
            srid='EPSG:4326')

        # Reconnect the signal if it was disconnected
        if disconnected_post_save:
            signals.post_save.connect(geoserver_post_save, sender=Layer)

        attribute_map = [
            ['id', 'Integer'],
            ['date', 'IntegerList'],
            ['enddate', 'Real'],
            ['date_as_date', 'xsd:dateTime'],
        ]

        # attribute_map gets modified as a side-effect of the call to set_attributes()
        expected_results = copy.deepcopy(attribute_map)

        # set attributes for resource
        set_attributes(_l, attribute_map)

        # 2 items in attribute_map should translate into 2 Attribute instances
        self.assertEquals(_l.attributes.count(), len(expected_results))

        # The name and type should be set as provided by attribute map
        for a in _l.attributes:
            self.assertIn([a.attribute, a.attribute_type], expected_results)
Esempio n. 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.
    """

    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)
Esempio n. 11
0
                                       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)


def geoserver_pre_save_maplayer(instance, sender, **kwargs):
    # If this object was saved via fixtures,
    # do not do post processing.
    if kwargs.get('raw', False):
        return

    try:
        instance.local = isinstance(gs_catalog.get_layer(instance.name),
                                    GsLayer)
    except EnvironmentError, e:
Esempio n. 12
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)
Esempio n. 13
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)
Esempio n. 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

    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)
Esempio n. 15
0
    def test_set_attributes_creates_attributes(self):
        """ Test utility function set_attributes() which creates Attribute instances attached
            to a Dataset instance.
        """
        # Creating a dataset requires being logged in
        self.client.login(username='******', password='******')

        # Create dummy dataset to attach attributes to
        _l = Dataset.objects.create(owner=self.user,
                                    name='dummy_dataset',
                                    bbox_polygon=Polygon.from_bbox(
                                        (-180, -90, 180, 90)),
                                    srid='EPSG:4326')

        attribute_map = [
            ['id', 'Integer'],
            ['date', 'IntegerList'],
            ['enddate', 'Real'],
            ['date_as_date', 'xsd:dateTime'],
        ]

        # attribute_map gets modified as a side-effect of the call to set_attributes()
        expected_results = copy.deepcopy(attribute_map)

        # set attributes for resource
        set_attributes(_l, attribute_map.copy())

        # 2 items in attribute_map should translate into 2 Attribute instances
        self.assertEqual(_l.attributes.count(), len(expected_results))

        # The name and type should be set as provided by attribute map
        for a in _l.attributes:
            self.assertIn([a.attribute, a.attribute_type], expected_results)

        # GeoNode cleans up local duplicated attributes
        for attribute in attribute_map:
            field = attribute[0]
            ftype = attribute[1]
            if field:
                la = Attribute.objects.create(dataset=_l, attribute=field)
                la.visible = ftype.find("gml:") != 0
                la.attribute_type = ftype
                la.description = None
                la.attribute_label = None
                la.display_order = 0

        # set attributes for resource
        set_attributes(_l, attribute_map.copy())

        # 2 items in attribute_map should translate into 2 Attribute instances
        self.assertEqual(_l.attributes.count(), len(expected_results))

        # The name and type should be set as provided by attribute map
        for a in _l.attributes:
            self.assertIn([a.attribute, a.attribute_type], expected_results)

        # Test that deleted attributes from GeoServer gets deleted on GeoNode too
        attribute_map = [
            ['id', 'Integer'],
            ['date_as_date', 'xsd:dateTime'],
        ]

        # attribute_map gets modified as a side-effect of the call to set_attributes()
        expected_results = copy.deepcopy(attribute_map)

        # set attributes for resource
        set_attributes(_l, attribute_map.copy())

        # 2 items in attribute_map should translate into 2 Attribute instances
        self.assertEqual(_l.attributes.count(), len(expected_results))

        # The name and type should be set as provided by attribute map
        for a in _l.attributes:
            self.assertIn([a.attribute, a.attribute_type], expected_results)
Esempio n. 16
0
    def test_set_attributes_creates_attributes(self):
        """ Test utility function set_attributes() which creates Attribute instances attached
            to a Layer instance.
        """
        # Creating a layer requires being logged in
        self.client.login(username='******', password='******')

        # Disconnect the geoserver-specific post_save signal attached to Layer creation.
        # The geoserver signal handler assumes things about the store where the Layer is placed.
        # this is a workaround.
        disconnected_post_save = signals.post_save.disconnect(
            geoserver_post_save, sender=Layer)

        # Create dummy layer to attach attributes to
        _l = Layer.objects.create(name='dummy_layer',
                                  bbox_polygon=Polygon.from_bbox(
                                      (-180, -90, 180, 90)),
                                  srid='EPSG:4326')

        # Reconnect the signal if it was disconnected
        if disconnected_post_save:
            signals.post_save.connect(geoserver_post_save, sender=Layer)

        attribute_map = [
            ['id', 'Integer'],
            ['date', 'IntegerList'],
            ['enddate', 'Real'],
            ['date_as_date', 'xsd:dateTime'],
        ]

        # attribute_map gets modified as a side-effect of the call to set_attributes()
        expected_results = copy.deepcopy(attribute_map)

        # set attributes for resource
        set_attributes(_l, attribute_map.copy())

        # 2 items in attribute_map should translate into 2 Attribute instances
        self.assertEqual(_l.attributes.count(), len(expected_results))

        # The name and type should be set as provided by attribute map
        for a in _l.attributes:
            self.assertIn([a.attribute, a.attribute_type], expected_results)

        # GeoNode cleans up local duplicated attributes
        for attribute in attribute_map:
            field = attribute[0]
            ftype = attribute[1]
            if field:
                la = Attribute.objects.create(layer=_l, attribute=field)
                la.visible = ftype.find("gml:") != 0
                la.attribute_type = ftype
                la.description = None
                la.attribute_label = None
                la.display_order = 0

        # set attributes for resource
        set_attributes(_l, attribute_map.copy())

        # 2 items in attribute_map should translate into 2 Attribute instances
        self.assertEqual(_l.attributes.count(), len(expected_results))

        # The name and type should be set as provided by attribute map
        for a in _l.attributes:
            self.assertIn([a.attribute, a.attribute_type], expected_results)

        # Test that deleted attributes from GeoServer gets deleted on GeoNode too
        attribute_map = [
            ['id', 'Integer'],
            ['date_as_date', 'xsd:dateTime'],
        ]

        # attribute_map gets modified as a side-effect of the call to set_attributes()
        expected_results = copy.deepcopy(attribute_map)

        # set attributes for resource
        set_attributes(_l, attribute_map.copy())

        # 2 items in attribute_map should translate into 2 Attribute instances
        self.assertEqual(_l.attributes.count(), len(expected_results))

        # The name and type should be set as provided by attribute map
        for a in _l.attributes:
            self.assertIn([a.attribute, a.attribute_type], expected_results)
Esempio n. 17
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)
Esempio n. 18
0
def _register_indexed_layers(service, wms=None, verbosity=False):
    """
    Register layers for an indexed service (only WMS/OWS currently supported)
    """
    logger.info("Registering layers for %s" % service.base_url)
    if re.match("WMS|OWS", service.type):
        wms = wms or WebMapService(service.base_url)
        count = 0
        for layer in list(wms.contents):
            wms_layer = wms[layer]
            if wms_layer is None or wms_layer.name is None:
                continue
            logger.info("Registering layer %s" % wms_layer.name)
            if verbosity:
                print "Importing layer %s" % layer
            layer_uuid = str(uuid.uuid1())
            try:
                keywords = map(lambda x: x[:100], wms_layer.keywords)
            except:
                keywords = []
            if not wms_layer.abstract:
                abstract = ""
            else:
                abstract = wms_layer.abstract

            srid = None
            # Some ArcGIS WMSServers indicate they support 900913 but really
            # don't
            if 'EPSG:900913' in wms_layer.crsOptions and "MapServer/WmsServer" not in service.base_url:
                srid = 'EPSG:900913'
            elif len(wms_layer.crsOptions) > 0:
                matches = re.findall('EPSG\:(3857|102100|102113)',
                                     ' '.join(wms_layer.crsOptions))
                if matches:
                    srid = 'EPSG:%s' % matches[0]
            if srid is None:
                message = "%d Incompatible projection - try setting the service as cascaded" % count
                return_dict = {'status': 'ok', 'msg': message}
                return HttpResponse(json.dumps(return_dict),
                                    mimetype='application/json',
                                    status=200)

            bbox = list(wms_layer.boundingBoxWGS84
                        or (-179.0, -89.0, 179.0, 89.0))

            # Need to check if layer already exists??
            saved_layer, created = Layer.objects.get_or_create(
                typename=wms_layer.name,
                service=service,
                defaults=dict(
                    name=wms_layer.name,
                    store=service.name,  # ??
                    storeType="remoteStore",
                    workspace="remoteWorkspace",
                    title=wms_layer.title or wms_layer.name,
                    abstract=abstract or _("Not provided"),
                    uuid=layer_uuid,
                    owner=None,
                    srid=srid,
                    bbox_x0=bbox[0],
                    bbox_x1=bbox[2],
                    bbox_y0=bbox[1],
                    bbox_y1=bbox[3]))
            if created:
                saved_layer.save()
                saved_layer.set_default_permissions()
                saved_layer.keywords.add(*keywords)
                set_attributes(saved_layer)

                service_layer, created = ServiceLayer.objects.get_or_create(
                    typename=wms_layer.name, service=service)
                service_layer.layer = saved_layer
                service_layer.title = wms_layer.title
                service_layer.description = wms_layer.abstract
                service_layer.styles = wms_layer.styles
                service_layer.save()
            count += 1
        message = "%d Layers Registered" % count
        return_dict = {'status': 'ok', 'msg': message}
        return HttpResponse(json.dumps(return_dict),
                            mimetype='application/json',
                            status=200)
    elif service.type == 'WFS':
        return HttpResponse('Not Implemented (Yet)', status=501)
    elif service.type == 'WCS':
        return HttpResponse('Not Implemented (Yet)', status=501)
    else:
        return HttpResponse('Invalid Service Type', status=400)
Esempio n. 19
0
def _register_indexed_layers(service, wms=None, verbosity=False):
    """
    Register layers for an indexed service (only WMS/OWS currently supported)
    """
    logger.info("Registering layers for %s" % service.base_url)
    if re.match("WMS|OWS", service.type):
        wms = wms or WebMapService(service.base_url)
        count = 0
        for layer in list(wms.contents):
            wms_layer = wms[layer]
            if wms_layer is None or wms_layer.name is None:
                continue
            logger.info("Registering layer %s" % wms_layer.name)
            if verbosity:
                print "Importing layer %s" % layer
            layer_uuid = str(uuid.uuid1())
            try:
                keywords = map(lambda x: x[:100], wms_layer.keywords)
            except:
                keywords = []
            if not wms_layer.abstract:
                abstract = ""
            else:
                abstract = wms_layer.abstract

            srid = None
            # Some ArcGIS WMSServers indicate they support 900913 but really
            # don't
            if "EPSG:900913" in wms_layer.crsOptions and "MapServer/WmsServer" not in service.base_url:
                srid = "EPSG:900913"
            elif len(wms_layer.crsOptions) > 0:
                matches = re.findall("EPSG\:(3857|102100|102113)", " ".join(wms_layer.crsOptions))
                if matches:
                    srid = "EPSG:%s" % matches[0]
            if srid is None:
                message = "%d Incompatible projection - try setting the service as cascaded" % count
                return_dict = {"status": "ok", "msg": message}
                return HttpResponse(json.dumps(return_dict), mimetype="application/json", status=200)

            bbox = list(wms_layer.boundingBoxWGS84 or (-179.0, -89.0, 179.0, 89.0))

            # Need to check if layer already exists??
            saved_layer, created = Layer.objects.get_or_create(
                typename=wms_layer.name,
                service=service,
                defaults=dict(
                    name=wms_layer.name,
                    store=service.name,  # ??
                    storeType="remoteStore",
                    workspace="remoteWorkspace",
                    title=wms_layer.title or wms_layer.name,
                    abstract=abstract or _("Not provided"),
                    uuid=layer_uuid,
                    owner=None,
                    srid=srid,
                    bbox_x0=bbox[0],
                    bbox_x1=bbox[2],
                    bbox_y0=bbox[1],
                    bbox_y1=bbox[3],
                ),
            )
            if created:
                saved_layer.save()
                saved_layer.set_default_permissions()
                saved_layer.keywords.add(*keywords)
                set_attributes(saved_layer)

                service_layer, created = ServiceLayer.objects.get_or_create(typename=wms_layer.name, service=service)
                service_layer.layer = saved_layer
                service_layer.title = wms_layer.title
                service_layer.description = wms_layer.abstract
                service_layer.styles = wms_layer.styles
                service_layer.save()
            count += 1
        message = "%d Layers Registered" % count
        return_dict = {"status": "ok", "msg": message}
        return HttpResponse(json.dumps(return_dict), mimetype="application/json", status=200)
    elif service.type == "WFS":
        return HttpResponse("Not Implemented (Yet)", status=501)
    elif service.type == "WCS":
        return HttpResponse("Not Implemented (Yet)", status=501)
    else:
        return HttpResponse("Invalid Service Type", status=400)
Esempio n. 20
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)
Esempio n. 21
0
def process_wmts_service(url, name, type, username, password, wmts=None, owner=None, parent=None):
    """
    Create a new WMTS service
    """
    if wmts is None:
        wmts = WebMapTileService(url)
    try:
        base_url = _clean_url(wmts.getOperationByName("GetTile").methods["Get"]["url"])

        if base_url and base_url != url:
            url = base_url
            wmts = WebMapTileService(base_url)
    except:
        logger.info("Could not retrieve GetMap url, using originally supplied URL %s" % url)
        pass
    try:
        service = Service.objects.get(base_url=url)
        return_dict = [
            {
                "status": "ok",
                "msg": _("This is an existing service"),
                "service_id": service.pk,
                "service_name": service.name,
                "service_title": service.title,
            }
        ]
        return HttpResponse(json.dumps(return_dict), mimetype="application/json", status=200)
    except:
        pass
    title = wmts.identification.title
    if not name:
        if title:
            name = wmts.identification.title
        else:
            name = urlsplit(url).netloc
    for layer, layer_metadata in wmts.contents.items():
        if layer is None or layer_metadata.name is None:
            continue
        logger.info("Registering layer %s" % layer_metadata.name)
        layer_uuid = str(uuid.uuid1())
        try:
            keywords = map(lambda x: x[:100], layer_metadata.keywords)
        except:
            keywords = []
        if not layer_metadata.abstract:
            abstract = ""
        else:
            abstract = layer_metadata.abstract

        bbox = list(layer_metadata.boundingBoxWGS84 or (-179.0, -89.0, 179.0, 89.0))

        # Need to check if layer already exists??
        saved_layer, created = Layer.objects.get_or_create(
            typename=layer_metadata.name,
            service=service,
            defaults=dict(
                name=layer_metadata.name,
                store=service.name,  # ??
                storeType="remoteStore",
                workspace="remoteWorkspace",
                title=layer_metadata.title or layer_metadata.name,
                abstract=layer_metadata.abstract or ("Not provided"),
                uuid=layer_uuid,
                owner=None,
                srid=layer_metadata.tilematrixsets,
                bbox_x0=bbox[0],
                bbox_x1=bbox[2],
                bbox_y0=bbox[1],
                bbox_y1=bbox[3],
            ),
        )
        if created:
            saved_layer.save()
            saved_layer.set_default_permissions()
            saved_layer.keywords.add(*keywords)
            set_attributes(saved_layer)

            service_layer, created = ServiceLayer.objects.get_or_create(typename=layer_metadata.name, service=service)
            service_layer.layer = saved_layer
            service_layer.title = layer_metadata.title
            service_layer.description = layer_metadata.abstract
            service_layer.styles = layer_metadata.styles
            service_layer.save()
    message = "%d Layers Registered" % count
    return_dict = {"status": "ok", "msg": message}
    return HttpResponse(json.dumps(return_dict), mimetype="application/json", status=200)
Esempio n. 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.
    """

    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',
                                       )
                                       )

        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',
                               )
                               )

    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()

    # 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(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)
Esempio n. 23
0
def process_wmts_service(url,
                         name,
                         type,
                         username,
                         password,
                         wmts=None,
                         owner=None,
                         parent=None):
    """
    Create a new WMTS service
    """
    if wmts is None:
        wmts = WebMapTileService(url)
    try:
        base_url = _clean_url(
            wmts.getOperationByName('GetTile').methods['Get']['url'])

        if base_url and base_url != url:
            url = base_url
            wmts = WebMapTileService(base_url)
    except:
        logger.info(
            "Could not retrieve GetMap url, using originally supplied URL %s" %
            url)
        pass
    try:
        service = Service.objects.get(base_url=url)
        return_dict = [{
            'status': 'ok',
            'msg': _("This is an existing service"),
            'service_id': service.pk,
            'service_name': service.name,
            'service_title': service.title
        }]
        return HttpResponse(json.dumps(return_dict),
                            mimetype='application/json',
                            status=200)
    except:
        pass
    title = wmts.identification.title
    if not name:
        if title:
            name = wmts.identification.title
        else:
            name = urlsplit(url).netloc
    for layer, layer_metadata in wmts.contents.items():
        if layer is None or layer_metadata.name is None:
            continue
        logger.info("Registering layer %s" % layer_metadata.name)
        layer_uuid = str(uuid.uuid1())
        try:
            keywords = map(lambda x: x[:100], layer_metadata.keywords)
        except:
            keywords = []
        if not layer_metadata.abstract:
            abstract = ""
        else:
            abstract = layer_metadata.abstract

        bbox = list(layer_metadata.boundingBoxWGS84
                    or (-179.0, -89.0, 179.0, 89.0))

        # Need to check if layer already exists??
        saved_layer, created = Layer.objects.get_or_create(
            typename=layer_metadata.name,
            service=service,
            defaults=dict(
                name=layer_metadata.name,
                store=service.name,  # ??
                storeType="remoteStore",
                workspace="remoteWorkspace",
                title=layer_metadata.title or layer_metadata.name,
                abstract=layer_metadata.abstract or ("Not provided"),
                uuid=layer_uuid,
                owner=None,
                srid=layer_metadata.tilematrixsets,
                bbox_x0=bbox[0],
                bbox_x1=bbox[2],
                bbox_y0=bbox[1],
                bbox_y1=bbox[3]))
        if created:
            saved_layer.save()
            saved_layer.set_default_permissions()
            saved_layer.keywords.add(*keywords)
            set_attributes(saved_layer)

            service_layer, created = ServiceLayer.objects.get_or_create(
                typename=layer_metadata.name, service=service)
            service_layer.layer = saved_layer
            service_layer.title = layer_metadata.title
            service_layer.description = layer_metadata.abstract
            service_layer.styles = layer_metadata.styles
            service_layer.save()
    message = "%d Layers Registered" % count
    return_dict = {'status': 'ok', 'msg': message}
    return HttpResponse(json.dumps(return_dict),
                        mimetype='application/json',
                        status=200)
Esempio n. 24
0
            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)


def geoserver_pre_save_maplayer(instance, sender, **kwargs):
    # If this object was saved via fixtures,
    # do not do post processing.
    if kwargs.get("raw", False):
        return

    try:
        instance.local = isinstance(gs_catalog.get_layer(instance.name), GsLayer)
    except EnvironmentError, e:
        if e.errno == errno.ECONNREFUSED:
Esempio n. 25
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

    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)
Esempio n. 26
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)
Esempio n. 27
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)