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 OSError as e: if e.errno == errno.ECONNREFUSED: msg = f'Could not connect to catalog to verify if layer {instance.name} was local' logger.warn(msg) else: raise e # Set dataset if instance.dataset is None: dataset_queryset = Dataset.objects.filter( Q(alternate=instance.name) | Q(name=instance.name)) if instance.local and instance.store: dataset_queryset = dataset_queryset.filter(store=instance.store) elif instance.ows_url: dataset_queryset = dataset_queryset.filter( remote_service__base_url=instance.ows_url) try: instance.dataset = dataset_queryset.get() except Dataset.DoesNotExist: pass
def gs_append_data_to_layer(layer, base_files, user): gs_layer = gs_catalog.get_layer(layer.name) if gs_layer and gs_layer.type == 'VECTOR': # opening upload session for the selected layer upload_session, created = UploadSession.objects.get_or_create( resource=layer, user=user) upload_session.resource = layer upload_session.processed = False upload_session.save() # opening Import session for the selected layer import_session = gs_uploader.start_import( import_id=upload_session.id, name=layer.name, target_store=gs_layer.resource.store.name) import_session.upload_task(base_files) task = import_session.tasks[0] # Changing layer name, mode and target task.layer.set_target_layer_name(layer.name) task.set_update_mode("APPEND") task.set_target(store_name=gs_layer.resource.store.name, workspace=gs_layer.resource.workspace.name) # Starting import process import_session.commit() return upload_session
def saveToGeonode(payload): admin = Profile.objects.filter(is_superuser=True).first() logger.debug('Uploading layer %s to geonode' % payload['zip_name']) # use overwrite to make sure if a layer exists it gets updated uploaded = upload(payload['zipfile_path'], admin, overwrite=True)[0] if uploaded['status'] == 'failed': raise Exception("Failed layer %s with error %s " % (payload['zip_name'], uploaded['error'])) else: uploaded_name = uploaded['name'] if any(s in payload['zip_name'] for s in ['_a', '_p', '_l']): gs_layer = gs_catalog.get_layer(name=uploaded_name) gs_style = gs_catalog.get_style(name=payload['style_name']) if not gs_style: #let's make sure the style is there gs_catalog.create_style(payload['style_name'], payload['style_body']) gs_style = gs_catalog.get_style(name=payload['style_name']) gs_layer.default_style = gs_style gs_catalog.save(gs_layer) # gs_catalog.reload() saved_layer = Layer.objects.get(name=uploaded_name) mapSetLayer = createMapSetLayer(saved_layer, payload['zip_name']) payload['mapset'].layers.add(mapSetLayer) #create_gs_thumbnail(saved_layer, overwrite=True) return uploaded_name
def layer_create(request, data=None, template='upload/layer_create.html'): print 'layer create' if request.method == 'POST': feature_type = json.loads(request.POST.get(u'featureType', None)) datastore = feature_type['store']['name'] store_create_geogig = json.loads(request.POST.get(u'storeCreateGeogig', 'false')) if store_create_geogig: if not feature_type['store']['name']: store_proposed = slugify(' '.join([request.user.username, feature_type['name']])) store_created = create_geoserver_db_featurestore(store_type='geogig', store_name=store_proposed) feature_type['store']['name'] = store_created.name # -- only allow creation of layers in the whitelisted datastores try: settings.ALLOWED_DATASTORE_LAYER_CREATE except AttributeError: return HttpResponse(status=FORBIDDEN, content='ALLOWED_DATASTORE_LAYER_CREATE whitelist is not defined.') if datastore not in settings.ALLOWED_DATASTORE_LAYER_CREATE: return HttpResponse(status=FORBIDDEN, content='datastore specified in featureType is not in the ALLOWED_DATASTORE_LAYER_CREATE whitelist.') post_request = requests.post( '{}/workspaces/{}/datastores/{}/featuretypes.json'.format(ogc_server_settings.rest, feature_type['namespace']['name'], datastore), data='{{"featureType":{}}}'.format(json.dumps(feature_type)), auth=ogc_server_settings.credentials, headers={'content-type': 'application/json'} ) if post_request.status_code == 200 or post_request.status_code == 201: # import the layer from geoserver to geonode response = gs_slurp(filter=feature_type['name'], workspace=feature_type['namespace']['name'], store=feature_type['store']['name']) if 'layers' in response and len(response['layers']) == 1 and 'name' in response['layers'][0] and response['layers'][0]['name'] == feature_type['name']: # configruer layer with time dimension as a list for now. Since importer is being refactored, # we'll change how it is done. layer = gs_catalog.get_layer(feature_type['name']) resource = layer.resource if layer: time_info = DimensionInfo( name='time', enabled=True, presentation='LIST', resolution=None, units=None, unitSymbol=None, attribute='time', end_attribute=None, strategy=None) resource.metadata = {'time': time_info} resource.catalog.save(resource) return HttpResponse(status=post_request.status_code, content=post_request.text) return HttpResponse(status=500, content='failed to configure layer') else: return HttpResponse(status=500, content='failed to add created layer from geoserver to geonode') else: return HttpResponse(status=post_request.status_code, content=post_request.text) print '---- create layer response: ', post_request.text return render_to_response(template, RequestContext(request, {}))
def tearDown(self): layer = gs_catalog.get_layer(self.layer_name) if layer: gs_catalog.delete(layer) if self.datastore: gs_catalog.delete(self.datastore, recurse=True)
def set_default_style(self, layername, style): saved = False try: layer = gs_catalog.get_layer(layername) layer.default_style = style gs_catalog.save(layer) saved = True except Exception as e: logger.error(e.message) return saved
def handle(self, layer, layer_config, *args, **kwargs): """ Configures time on the object. Handler specific params: "configureTime": Must be true for this handler to run. "start_date": Passed as the start time to Geoserver. "end_date" (optional): Passed as the end attribute to Geoserver. """ lyr = gs_catalog.get_layer(layer) configure_time(lyr.resource, attribute=layer_config.get('start_date'), end_attribute=layer_config.get('end_date'))
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: msg = "Could not connect to catalog to verify if layer %s was local" % instance.name logger.warn(msg, e) else: raise e
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 as e: if e.errno == errno.ECONNREFUSED: msg = 'Could not connect to catalog to verify if layer %s was local' % instance.name logger.warn(msg, e) else: raise e
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 as e: if e.errno == errno.ECONNREFUSED: msg = 'Could not connect to catalog to verify if layer %s was local' % instance.name try: # HACK: The logger on signals throws an exception logger.warn(msg, e) except: pass else: raise e
def table_exist(name): data_db_name = settings.OGC_SERVER['default']['DATASTORE'] connection = None for c in connections.all(): if c.alias == data_db_name: connection = c table_names = connection.introspection.table_names() db_exist = name in table_names gs_exist = bool(gs_catalog.get_layer(name)) try: Layer.objects.get(name=name) gn_exist = True except ObjectDoesNotExist: gn_exist = False layer_exist = db_exist or gs_exist or gn_exist if layer_exist: # TODO: using logger instead print('Table name \'{}\' is already exist in {}, {}, {}'.format( name, 'database' if db_exist else '', 'geoserver' if gs_exist else '', 'geonode' if gn_exist else '', )) return layer_exist
def file_upload(filename, name=None, user=None, title=None, abstract=None, style_name=None, skip=True, overwrite=False, keywords=[], charset='UTF-8', category=None, date=None): """Saves a layer in GeoNode asking as little information as possible. Only filename is required, user and title are optional. """ # Get a valid user theuser = get_valid_user(user) # Create a new upload session upload_session = UploadSession.objects.create(user=theuser) # Get all the files uploaded with the layer files = get_files(filename) # Set a default title that looks nice ... if title is None: basename = os.path.splitext(os.path.basename(filename))[0] title = basename.title().replace('_', ' ') # Create a name from the title if it is not passed. if name is None: name = slugify(title).replace('-', '_') if category is not None: category = TopicCategory.objects.get(identifier=category) # Generate a name that is not taken if overwrite is False. valid_name = get_valid_layer_name(name, overwrite) # Add them to the upload session (new file fields are created). assigned_name = None for type_name, fn in files.items(): with open(fn, 'rb') as f: upload_session.layerfile_set.create( name=type_name, file=File(f, name='%s.%s' % (assigned_name or valid_name, type_name))) # save the system assigned name for the remaining files if not assigned_name: the_file = upload_session.layerfile_set.all()[0].file.name assigned_name = os.path.splitext(os.path.basename(the_file))[0] # Get a bounding box bbox_x0, bbox_x1, bbox_y0, bbox_y1 = get_bbox(filename) # by default, if RESOURCE_PUBLISHING=True then layer.is_published # must be set to False is_published = True if settings.RESOURCE_PUBLISHING: is_published = False defaults = { 'upload_session': upload_session, 'title': title, 'abstract': abstract, 'owner': user, 'charset': charset, 'bbox_x0': bbox_x0, 'bbox_x1': bbox_x1, 'bbox_y0': bbox_y0, 'bbox_y1': bbox_y1, 'is_published': is_published, 'category': category } # set metadata if 'xml' in files: xml_file = open(files['xml']) defaults['metadata_uploaded'] = True # get model properties from XML vals, keywords = set_metadata(xml_file.read()) for key, value in vals.items(): if key == 'spatial_representation_type': value = SpatialRepresentationType(identifier=value) elif key == 'topic_category': value, created = TopicCategory.objects.get_or_create( identifier=value.lower(), defaults={ 'description': '', 'gn_description': value }) key = 'category' defaults[key] = value else: defaults[key] = value # If it is a vector file, create the layer in postgis. if is_vector(filename): defaults['storeType'] = 'dataStore' # If it is a raster file, get the resolution. if is_raster(filename): defaults['storeType'] = 'coverageStore' # Create a Django object. layer, created = Layer.objects.get_or_create(name=valid_name, defaults=defaults) # set layer style in geoserver if style_name is not None: # import here because import at top of file fails for some reason from geonode.geoserver.helpers import gs_catalog try: gs_style = gs_catalog.get_style(style_name) except: gs_style = None if gs_style is not None: gs_layer = gs_catalog.get_layer(layer.name) gs_layer.default_style = gs_style gs_catalog.save(gs_layer) # set layer date if date is not None: layer.date = date # Delete the old layers if overwrite is true # and the layer was not just created # process the layer again after that by # doing a layer.save() if not created and overwrite: layer.upload_session.layerfile_set.all().delete() layer.upload_session = upload_session # Pass the parameter overwrite to tell whether the # geoserver_post_save_signal should upload the new file or not layer.overwrite = overwrite layer.save() # Assign the keywords (needs to be done after saving) if len(keywords) > 0: layer.keywords.add(*keywords) return layer
def geoserver_pre_save(instance, sender, **kwargs): """Send information to geoserver. The attributes sent include: * Title * Abstract * Name * Keywords * Metadata Links, * Point of Contact name and url """ # Don't run this signal if is a Layer from a remote service if instance.workspace == 'remoteWorkspace': return # If the store in None then it's a new instance from an upload, # only in this case run the geonode_uplaod method if not instance.store or getattr(instance, 'overwrite', False): base_file = instance.get_base_file() # There is no need to process it if there is not file. if base_file is None: return gs_name, workspace, values = geoserver_upload( instance, base_file.file.path, instance.owner, instance.name, overwrite=True, title=instance.title, abstract=instance.abstract, # keywords=instance.keywords, charset=instance.charset) # Set fields obtained via the geoserver upload. instance.name = gs_name instance.workspace = workspace # Iterate over values from geoserver. for key in ['typename', 'store', 'storeType']: setattr(instance, key, values[key]) gs_resource = gs_catalog.get_resource(instance.name, store=instance.store, workspace=instance.workspace) gs_resource.title = instance.title gs_resource.abstract = instance.abstract gs_resource.name = instance.name # Get metadata links metadata_links = [] for link in instance.link_set.metadata(): metadata_links.append((link.mime, link.name, link.url)) gs_resource.metadata_links = metadata_links # gs_resource should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_resource) gs_layer = gs_catalog.get_layer(instance.name) if instance.poc and instance.poc: gs_layer.attribution = str(instance.poc) profile = Profile.objects.get(username=instance.poc.username) gs_layer.attribution_link = settings.SITEURL[: -1] + profile.get_absolute_url( ) # gs_layer should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_layer) """Get information from geoserver. The attributes retrieved include: * Bounding Box * SRID * Download links (WMS, WCS or WFS and KML) * Styles (SLD) """ gs_resource = gs_catalog.get_resource(instance.name) bbox = gs_resource.latlon_bbox # FIXME(Ariel): Correct srid setting below # self.srid = gs_resource.src instance.srid_url = "http://www.spatialreference.org/ref/" + \ instance.srid.replace(':', '/').lower() + "/" # Set bounding box values instance.bbox_x0 = bbox[0] instance.bbox_x1 = bbox[1] instance.bbox_y0 = bbox[2] instance.bbox_y1 = bbox[3]
def geoserver_pre_save(instance, sender, **kwargs): """Send information to geoserver. The attributes sent include: * Title * Abstract * Name * Keywords * Metadata Links, * Point of Contact name and url """ base_file = instance.get_base_file() # There is no need to process it if there is not file. if base_file is None: return gs_name, workspace, values = geoserver_upload( instance, base_file.file.path, instance.owner, instance.name, overwrite=True, title=instance.title, abstract=instance.abstract, # keywords=instance.keywords, charset=instance.charset, ) # Set fields obtained via the geoserver upload. instance.name = gs_name instance.workspace = workspace # Iterate over values from geoserver. for key in ["typename", "store", "storeType"]: setattr(instance, key, values[key]) url = ogc_server_settings.internal_rest gs_resource = gs_catalog.get_resource(instance.name, store=instance.store, workspace=instance.workspace) gs_resource.title = instance.title gs_resource.abstract = instance.abstract gs_resource.name = instance.name # Get metadata links metadata_links = [] for link in instance.link_set.metadata(): metadata_links.append((link.name, link.mime, link.url)) gs_resource.metadata_links = metadata_links # gs_resource should only be called if ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_resource) gs_layer = gs_catalog.get_layer(instance.name) if instance.poc and instance.poc.user: gs_layer.attribution = str(instance.poc.user) profile = Profile.objects.get(user=instance.poc.user) gs_layer.attribution_link = settings.SITEURL[:-1] + profile.get_absolute_url() # gs_layer should only be called if ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_layer) """Get information from geoserver. The attributes retrieved include: * Bounding Box * SRID * Download links (WMS, WCS or WFS and KML) * Styles (SLD) """ gs_resource = gs_catalog.get_resource(instance.name) bbox = gs_resource.latlon_bbox # FIXME(Ariel): Correct srid setting below # self.srid = gs_resource.src instance.srid_url = "http://www.spatialreference.org/ref/" + instance.srid.replace(":", "/").lower() + "/" # Set bounding box values instance.bbox_x0 = bbox[0] instance.bbox_x1 = bbox[1] instance.bbox_y0 = bbox[2] instance.bbox_y1 = bbox[3]
def geoserver_post_save_local(layer_id, *args, **kwargs): """Send information to geoserver. The attributes sent include: * Title * Abstract * Name * Keywords * Metadata Links, * Point of Contact name and url """ # If it is a layer object, post process it. If not, abort. try: instance = Layer.objects.get(id=layer_id) except Layer.DoesNotExist as e: logger.exception(e) return # raise e # Don't run this signal if is a Layer from a remote service if getattr(instance, "service", None) is not None: return # Don't run this signal handler if it is a tile layer or a remote store (Service) # Currently only gpkg files containing tiles will have this type & will be served via MapProxy. if hasattr(instance, 'storeType') and getattr(instance, 'storeType') in ['tileStore', 'remoteStore']: return instance gs_resource = None values = None # If the store in None then it's a new instance from an upload, # only in this case run the geoserver_upload method if not instance.store or getattr(instance, 'overwrite', False): base_file, info = instance.get_base_file() # There is no need to process it if there is not file. if base_file is None: return gs_name, workspace, values, gs_resource = geoserver_upload(instance, base_file.file.path, instance.owner, instance.name, overwrite=True, title=instance.title, abstract=instance.abstract, # keywords=instance.keywords, charset=instance.charset) if not gs_resource: gs_resource = gs_catalog.get_resource( instance.name, store=instance.store, workspace=instance.workspace) if not gs_resource: gs_resource = gs_catalog.get_resource(instance.alternate) if gs_resource: gs_resource.title = instance.title or "" gs_resource.abstract = instance.abstract or "" gs_resource.name = instance.name or "" if not values: values = dict(store=gs_resource.store.name, storeType=gs_resource.store.resource_type, alternate=gs_resource.store.workspace.name + ':' + gs_resource.name, title=gs_resource.title or gs_resource.store.name, abstract=gs_resource.abstract or '', owner=instance.owner) else: return # Get metadata links metadata_links = [] for link in instance.link_set.metadata(): metadata_links.append((link.mime, link.name, link.url)) gs_resource.metadata_links = metadata_links # gs_resource should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): try: gs_catalog.save(gs_resource) except geoserver.catalog.FailedRequestError as e: msg = ('Error while trying to save resource named %s in GeoServer, ' 'try to use: "%s"' % (gs_resource, str(e))) e.args = (msg,) logger.exception(e) gs_layer = gs_catalog.get_layer(instance.name) if not gs_layer: gs_layer = gs_catalog.get_layer(instance.alternate) if gs_layer and instance.poc: # gsconfig now utilizes an attribution dictionary gs_layer.attribution = {'title': str(instance.poc), 'width': None, 'height': None, 'href': None, 'url': None, 'type': None} profile = Profile.objects.get(username=instance.poc.username) gs_layer.attribution_link = settings.SITEURL[ :-1] + profile.get_absolute_url() # gs_layer should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): try: gs_catalog.save(gs_layer) except geoserver.catalog.FailedRequestError as e: msg = ('Error while trying to save layer named %s in GeoServer, ' 'try to use: "%s"' % (gs_layer, str(e))) e.args = (msg,) logger.exception(e) if type(instance) is ResourceBase: if hasattr(instance, 'layer'): instance = instance.layer else: return if instance.storeType == "remoteStore": # Save layer attributes set_attributes_from_geoserver(instance) return """Get information from geoserver. The attributes retrieved include: * Bounding Box * SRID * Download links (WMS, WCS or WFS and KML) * Styles (SLD) """ # instance.name = instance.name or gs_layer.name # instance.title = instance.title or gs_resource.title instance.abstract = gs_resource.abstract or '' instance.workspace = gs_resource.store.workspace.name instance.store = gs_resource.store.name bbox = gs_resource.latlon_bbox # FIXME(Ariel): Correct srid setting below # self.srid = gs_resource.src instance.srid_url = "http://www.spatialreference.org/ref/" + \ instance.srid.replace(':', '/').lower() + "/" # Set bounding box values instance.bbox_x0 = bbox[0] instance.bbox_x1 = bbox[1] instance.bbox_y0 = bbox[2] instance.bbox_y1 = bbox[3] # Iterate over values from geoserver. for key in ['alternate', 'store', 'storeType']: # attr_name = key if 'typename' not in key else 'alternate' # print attr_name setattr(instance, key, values[key]) if settings.RESOURCE_PUBLISHING: if instance.is_published != gs_resource.advertised: if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_resource.advertised = 'true' if instance.is_published else 'false' gs_catalog.save(gs_resource) if not settings.FREETEXT_KEYWORDS_READONLY: if gs_resource.keywords: for keyword in gs_resource.keywords: instance.keywords.add(keyword) if any(instance.keyword_list()): keywords = instance.keyword_list() if settings.FREETEXT_KEYWORDS_READONLY: if gs_resource.keywords: keywords += gs_resource.keywords gs_resource.keywords = list(set(keywords)) # gs_resource should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): try: gs_catalog.save(gs_resource) except geoserver.catalog.FailedRequestError as e: msg = ('Error while trying to save resource named %s in GeoServer, ' 'try to use: "%s"' % (gs_resource, str(e))) e.args = (msg,) logger.exception(e) to_update = { 'title': instance.title or instance.name, 'abstract': instance.abstract or "", 'alternate': instance.alternate, 'bbox_x0': instance.bbox_x0, 'bbox_x1': instance.bbox_x1, 'bbox_y0': instance.bbox_y0, 'bbox_y1': instance.bbox_y1 } # Update ResourceBase resources = ResourceBase.objects.filter(id=instance.resourcebase_ptr.id) resources.update(**to_update) # to_update['name'] = instance.name, to_update['workspace'] = instance.workspace to_update['store'] = instance.store to_update['storeType'] = instance.storeType to_update['typename'] = instance.alternate # Save all the modified information in the instance without triggering signals. Layer.objects.filter(id=instance.id).update(**to_update) # Refresh from DB instance.refresh_from_db() # store the resource to avoid another geoserver call in the post_save instance.gs_resource = gs_resource bbox = gs_resource.latlon_bbox dx = float(bbox[1]) - float(bbox[0]) dy = float(bbox[3]) - float(bbox[2]) dataAspect = 1 if dy == 0 else dx / dy height = 550 width = int(height * dataAspect) # Set download links for WMS, WCS or WFS and KML links = wms_links(ogc_server_settings.public_url + 'wms?', instance.alternate.encode('utf-8'), instance.bbox_string, instance.srid, height, width) for ext, name, mime, wms_url in links: Link.objects.get_or_create(resource=instance.resourcebase_ptr, name=ugettext(name), defaults=dict( extension=ext, url=wms_url, mime=mime, link_type='image', ) ) if instance.storeType == "dataStore": links = wfs_links( ogc_server_settings.public_url + 'wfs?', instance.alternate.encode('utf-8')) for ext, name, mime, wfs_url in links: if mime == 'SHAPE-ZIP': name = 'Zipped Shapefile' Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=wfs_url, defaults=dict( extension=ext, name=name, mime=mime, url=wfs_url, link_type='data', ) ) gs_store_type = gs_resource.store.type.lower() if gs_resource.store.type else None geogig_repository = gs_resource.store.connection_parameters.get('geogig_repository', '') geogig_repo_name = geogig_repository.replace('geoserver://', '')
def geoserver_post_save_local(instance, *args, **kwargs): """Send information to geoserver. The attributes sent include: * Title * Abstract * Name * Keywords * Metadata Links, * Point of Contact name and url """ # Don't run this signal if is a Layer from a remote service if getattr(instance, "remote_service", None) is not None: return # Don't run this signal handler if it is a tile layer or a remote store (Service) # Currently only gpkg files containing tiles will have this type & will be served via MapProxy. if hasattr(instance, 'storeType') and getattr( instance, 'storeType') in ['tileStore', 'remoteStore']: return instance gs_resource = None values = None # If the store in None then it's a new instance from an upload, # only in this case run the geoserver_upload method if not instance.store or getattr(instance, 'overwrite', False): base_file, info = instance.get_base_file() # There is no need to process it if there is not file. if base_file is None: return gs_name, workspace, values, gs_resource = geoserver_upload( instance, base_file.file.path, instance.owner, instance.name, overwrite=True, title=instance.title, abstract=instance.abstract, # keywords=instance.keywords, charset=instance.charset) if not gs_resource: gs_resource = gs_catalog.get_resource(instance.name, store=instance.store, workspace=instance.workspace) if not gs_resource: gs_resource = gs_catalog.get_resource(instance.alternate) if gs_resource: gs_resource.title = instance.title or "" gs_resource.abstract = instance.abstract or "" gs_resource.name = instance.name or "" if not values: values = dict(store=gs_resource.store.name, storeType=gs_resource.store.resource_type, alternate=gs_resource.store.workspace.name + ':' + gs_resource.name, title=gs_resource.title or gs_resource.store.name, abstract=gs_resource.abstract or '', owner=instance.owner) else: msg = "There isn't a geoserver resource for this layer: %s" % instance.name logger.exception(msg) raise Exception(msg) # Get metadata links metadata_links = [] for link in instance.link_set.metadata(): metadata_links.append((link.mime, link.name, link.url)) gs_resource.metadata_links = metadata_links # gs_resource should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): try: gs_catalog.save(gs_resource) except geoserver.catalog.FailedRequestError as e: msg = ( 'Error while trying to save resource named %s in GeoServer, ' 'try to use: "%s"' % (gs_resource, str(e))) e.args = (msg, ) logger.exception(e) gs_layer = gs_catalog.get_layer(instance.name) if not gs_layer: gs_layer = gs_catalog.get_layer(instance.alternate) if gs_layer and instance.poc: # gsconfig now utilizes an attribution dictionary gs_layer.attribution = { 'title': str(instance.poc), 'width': None, 'height': None, 'href': None, 'url': None, 'type': None } profile = Profile.objects.get(username=instance.poc.username) gs_layer.attribution_link = settings.SITEURL[: -1] + profile.get_absolute_url( ) # gs_layer should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): try: gs_catalog.save(gs_layer) except geoserver.catalog.FailedRequestError as e: msg = ( 'Error while trying to save layer named %s in GeoServer, ' 'try to use: "%s"' % (gs_layer, str(e))) e.args = (msg, ) logger.exception(e) if type(instance) is ResourceBase: if hasattr(instance, 'layer'): instance = instance.layer else: return if instance.storeType == "remoteStore": # Save layer attributes set_attributes_from_geoserver(instance) return """Get information from geoserver. The attributes retrieved include: * Bounding Box * SRID * Download links (WMS, WCS or WFS and KML) * Styles (SLD) """ # instance.name = instance.name or gs_layer.name # instance.title = instance.title or gs_resource.title instance.abstract = gs_resource.abstract or '' instance.workspace = gs_resource.store.workspace.name instance.store = gs_resource.store.name bbox = gs_resource.native_bbox # Set bounding box values instance.bbox_x0 = bbox[0] instance.bbox_x1 = bbox[1] instance.bbox_y0 = bbox[2] instance.bbox_y1 = bbox[3] instance.srid = bbox[4] if instance.srid: instance.srid_url = "http://www.spatialreference.org/ref/" + \ instance.srid.replace(':', '/').lower() + "/" else: raise GeoNodeException("Invalid Projection. Layer is missing CRS!") # Iterate over values from geoserver. for key in ['alternate', 'store', 'storeType']: # attr_name = key if 'typename' not in key else 'alternate' # print attr_name setattr(instance, key, values[key]) if settings.RESOURCE_PUBLISHING: if instance.is_published != gs_resource.advertised: if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_resource.advertised = 'true' if instance.is_published else 'false' gs_catalog.save(gs_resource) if not settings.FREETEXT_KEYWORDS_READONLY: if gs_resource.keywords: for keyword in gs_resource.keywords: if keyword not in instance.keyword_list(): instance.keywords.add(keyword) if any(instance.keyword_list()): keywords = instance.keyword_list() gs_resource.keywords = list(set(keywords)) # gs_resource should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): try: gs_catalog.save(gs_resource) except geoserver.catalog.FailedRequestError as e: msg = ( 'Error while trying to save resource named %s in GeoServer, ' 'try to use: "%s"' % (gs_resource, str(e))) e.args = (msg, ) logger.exception(e) to_update = { 'title': instance.title or instance.name, 'abstract': instance.abstract or "", 'alternate': instance.alternate, 'bbox_x0': instance.bbox_x0, 'bbox_x1': instance.bbox_x1, 'bbox_y0': instance.bbox_y0, 'bbox_y1': instance.bbox_y1, 'srid': instance.srid } # Update ResourceBase resources = ResourceBase.objects.filter(id=instance.resourcebase_ptr.id) resources.update(**to_update) # to_update['name'] = instance.name, to_update['workspace'] = instance.workspace to_update['store'] = instance.store to_update['storeType'] = instance.storeType to_update['typename'] = instance.alternate # Save all the modified information in the instance without triggering signals. Layer.objects.filter(id=instance.id).update(**to_update) # Refresh from DB instance.refresh_from_db() # store the resource to avoid another geoserver call in the post_save instance.gs_resource = gs_resource bbox = gs_resource.native_bbox dx = float(bbox[1]) - float(bbox[0]) dy = float(bbox[3]) - float(bbox[2]) dataAspect = 1 if dy == 0 else dx / dy height = 550 width = int(height * dataAspect) # Set download links for WMS, WCS or WFS and KML links = wms_links(ogc_server_settings.public_url + 'wms?', instance.alternate.encode('utf-8'), instance.bbox_string, instance.srid, height, width) for ext, name, mime, wms_url in links: Link.objects.get_or_create(resource=instance.resourcebase_ptr, name=ugettext(name), defaults=dict( extension=ext, url=wms_url, mime=mime, link_type='image', )) if instance.storeType == "dataStore": links = wfs_links(ogc_server_settings.public_url + 'wfs?', instance.alternate.encode('utf-8')) for ext, name, mime, wfs_url in links: if mime == 'SHAPE-ZIP': name = 'Zipped Shapefile' Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=wfs_url, defaults=dict( extension=ext, name=name, mime=mime, url=wfs_url, link_type='data', )) gs_store_type = gs_resource.store.type.lower( ) if gs_resource.store.type else None geogig_repository = gs_resource.store.connection_parameters.get( 'geogig_repository', '') geogig_repo_name = geogig_repository.replace('geoserver://', '') if gs_store_type == 'geogig' and geogig_repo_name: repo_url = '{url}geogig/repos/{repo_name}'.format( url=ogc_server_settings.public_url, repo_name=geogig_repo_name) path = gs_resource.dom.findall('nativeName') if path: path = 'path={path}'.format(path=path[0].text) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=repo_url, defaults=dict(extension='html', name='Clone in GeoGig', mime='text/xml', link_type='html')) def command_url(command): return "{repo_url}/{command}.json?{path}".format( repo_url=repo_url, path=path, command=command) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=command_url('log'), defaults=dict(extension='json', name='GeoGig log', mime='application/json', link_type='html')) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=command_url('statistics'), defaults=dict(extension='json', name='GeoGig statistics', mime='application/json', link_type='html')) elif instance.storeType == 'coverageStore': links = wcs_links(ogc_server_settings.public_url + 'wcs?', instance.alternate.encode('utf-8'), ','.join(str(x) for x in instance.bbox[0:4]), instance.srid) for ext, name, mime, wcs_url in links: Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=wcs_url, defaults=dict( extension=ext, name=name, mime=mime, link_type='data', )) kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + \ urllib.urlencode({'layers': instance.alternate.encode('utf-8'), 'mode': "download"}) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=kml_reflector_link_download, defaults=dict( extension='kml', name="KML", mime='text/xml', link_type='data', )) kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + \ urllib.urlencode({'layers': instance.alternate.encode('utf-8'), 'mode': "refresh"}) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=kml_reflector_link_view, defaults=dict( extension='kml', name="View in Google Earth", mime='text/xml', link_type='data', )) html_link_url = '%s%s' % (settings.SITEURL[:-1], instance.get_absolute_url()) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=html_link_url, defaults=dict( extension='html', name=instance.alternate, mime='text/html', link_type='html', )) # some thumbnail generators will update thumbnail_url. If so, don't # immediately re-generate the thumbnail here. use layer#save(update_fields=['thumbnail_url']) if not ('update_fields' in kwargs and kwargs['update_fields'] is not None and 'thumbnail_url' in kwargs['update_fields']): logger.info("Creating Thumbnail for Layer [%s]" % (instance.alternate)) create_gs_thumbnail(instance, overwrite=True) legend_url = ogc_server_settings.PUBLIC_LOCATION + \ 'wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER=' + \ instance.alternate + '&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on' Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=legend_url, defaults=dict( extension='png', name='Legend', url=legend_url, mime='image/png', link_type='image', )) ogc_wms_path = '%s/ows' % instance.workspace ogc_wms_url = urljoin(ogc_server_settings.public_url, ogc_wms_path) ogc_wms_name = 'OGC WMS: %s Service' % instance.workspace Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=ogc_wms_url, defaults=dict( extension='html', name=ogc_wms_name, url=ogc_wms_url, mime='text/html', link_type='OGC:WMS', )) if instance.storeType == "dataStore": ogc_wfs_path = '%s/wfs' % instance.workspace ogc_wfs_url = urljoin(ogc_server_settings.public_url, ogc_wfs_path) ogc_wfs_name = 'OGC WFS: %s Service' % instance.workspace Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=ogc_wfs_url, defaults=dict( extension='html', name=ogc_wfs_name, url=ogc_wfs_url, mime='text/html', link_type='OGC:WFS', )) if instance.storeType == "coverageStore": ogc_wcs_path = '%s/wcs' % instance.workspace ogc_wcs_url = urljoin(ogc_server_settings.public_url, ogc_wcs_path) ogc_wcs_name = 'OGC WCS: %s Service' % instance.workspace Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=ogc_wcs_url, defaults=dict( extension='html', name=ogc_wcs_name, url=ogc_wcs_url, mime='text/html', link_type='OGC:WCS', )) # remove links that belong to and old address for link in instance.link_set.all(): if not urlparse(settings.SITEURL).hostname == urlparse( link.url).hostname and not urlparse( ogc_server_settings.public_url).hostname == urlparse( link.url).hostname: link.delete() # Define the link after the cleanup, we should use this more rather then remove # potential parasites tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url + 'layers=%s' % instance.alternate.encode('utf-8') + '&zoom={z}&x={x}&y={y}' + '&format=image/png8') link, created = Link.objects.get_or_create( resource=instance.resourcebase_ptr, extension='tiles', name="Tiles", mime='image/png', link_type='image', ) if created: Link.objects.filter(pk=link.pk).update(url=tile_url) # Save layer attributes set_attributes_from_geoserver(instance) # Save layer styles set_styles(instance, gs_catalog) # NOTTODO by simod: we should not do this! # need to be removed when fixing #2015 catalogue_post_save(instance, Layer)
def layer_create(request, data=None, template='upload/layer_create.html'): print 'layer create' if request.method == 'POST': feature_type = json.loads(request.POST.get(u'featureType', None)) datastore = feature_type['store']['name'] store_create_geogig = json.loads( request.POST.get(u'storeCreateGeogig', 'false')) if store_create_geogig: if not feature_type['store']['name']: store_proposed = slugify(' '.join( [request.user.username, feature_type['name']])) store_created = create_geoserver_db_featurestore( store_type='geogig', store_name=store_proposed) feature_type['store']['name'] = store_created.name # -- only allow creation of layers in the whitelisted datastores try: settings.ALLOWED_DATASTORE_LAYER_CREATE except AttributeError: return HttpResponse( status=FORBIDDEN, content= 'ALLOWED_DATASTORE_LAYER_CREATE whitelist is not defined.') if datastore not in settings.ALLOWED_DATASTORE_LAYER_CREATE: return HttpResponse( status=FORBIDDEN, content= 'datastore specified in featureType is not in the ALLOWED_DATASTORE_LAYER_CREATE whitelist.' ) post_request = requests.post( '{}/workspaces/{}/datastores/{}/featuretypes.json'.format( ogc_server_settings.rest, feature_type['namespace']['name'], datastore), data='{{"featureType":{}}}'.format(json.dumps(feature_type)), auth=ogc_server_settings.credentials, headers={'content-type': 'application/json'}) if post_request.status_code == 200 or post_request.status_code == 201: # import the layer from geoserver to geonode response = gs_slurp(filter=feature_type['name'], workspace=feature_type['namespace']['name'], store=feature_type['store']['name']) if 'layers' in response and len( response['layers'] ) == 1 and 'name' in response['layers'][0] and response['layers'][ 0]['name'] == feature_type['name']: # configruer layer with time dimension as a list for now. Since importer is being refactored, # we'll change how it is done. layer = gs_catalog.get_layer(feature_type['name']) resource = layer.resource if layer: time_info = DimensionInfo(name='time', enabled=True, presentation='LIST', resolution=None, units=None, unitSymbol=None, attribute='time', end_attribute=None, strategy=None) resource.metadata = {'time': time_info} resource.catalog.save(resource) return HttpResponse(status=post_request.status_code, content=post_request.text) return HttpResponse(status=500, content='failed to configure layer') else: return HttpResponse( status=500, content= 'failed to add created layer from geoserver to geonode') else: return HttpResponse(status=post_request.status_code, content=post_request.text) print '---- create layer response: ', post_request.text return render_to_response(template, RequestContext(request, {}))
def reload_data(self, geonode_layer): if self.task: self.task.status = "IN_PROGRESS" self.task.save() # To get layer name from alternate as it is the same as DB table name and geoserver layer name self.config_obj.name = geonode_layer.alternate.split(':')[-1] self.config_obj.overwrite = True feature_iter = iter(self) gtype = self.esri_serializer.get_geometry_type() store = get_store(gs_catalog, geonode_layer.store, geonode_layer.workspace) # get database name and schema name from layer datastore # TODO: get all parameters for the datastore # TODO: find a way to pass the database password also , as it is encrypted in the datastore. db_connection = get_connection( database_name=store.connection_parameters['database'], schema=store.connection_parameters.get('schema', 'public')) with OSGEOManager.open_source(db_connection, update_enabled=1) as source: geoserver_layer = gs_catalog.get_layer(geonode_layer.alternate) # pass native_name to GetLayer as it represents the table name layer = source.GetLayer(geoserver_layer.resource.native_name) try: layer.StartTransaction() # remove all features # Note: remove features one by one allow to rollback if the error raised # TODO: check if truncating the table is possible to enhance the performance old_feature = layer.GetNextFeature() while old_feature: layer.DeleteFeature(old_feature.GetFID()) old_feature = layer.GetNextFeature() # TODO: reset FID sequence otherwise new FIDs will be generated # build fields is mandatory for domain fields and subtypes self.esri_serializer.build_fields() # set outSR by destination layer wkid, to retrieve the features with matched projection self.set_out_sr( int(layer.GetSpatialRef().GetAuthorityCode(None))) # importing the features again for next_feature in feature_iter: self.create_feature(layer, next_feature, gtype) layer.CommitTransaction() geoserver_pub = GeoserverPublisher() # remove layer caching to update rendering. # otherwise changes will not be rendered until layer refreshed geoserver_pub.remove_cached(geonode_layer.typename) if self.task: self.task.status = "FINISHED" self.task.save() # TODO: check the which exceptions should be handled except (StopIteration, EsriFeatureLayerException, ConnectionError, BaseException) as e: layer.RollbackTransaction() logger.error(e) return False else: return True
def geoserver_post_save2(layer_id): """Save keywords to GeoServer The way keywords are implemented requires the layer to be saved to the database before accessing them. """ """Send information to geoserver. The attributes sent include: * Title * Abstract * Name * Keywords * Metadata Links, * Point of Contact name and url """ from geonode.layers.models import Layer instance = Layer.objects.get(id=layer_id) # Don't run this signal if is a Layer from a remote service if getattr(instance, "service", None) is not None: return instance # Don't run this signal handler if it is a tile layer # Currently only gpkg files containing tiles will have this type & will be served via MapProxy. if hasattr(instance, 'storeType') and getattr(instance, 'storeType') == 'tileStore': return instance gs_resource = None # If the store in None then it's a new instance from an upload, # only in this case run the geonode_uplaod method if not instance.store or getattr(instance, 'overwrite', False): base_file, info = instance.get_base_file() # There is no need to process it if there is not file. if base_file is None: return instance gs_name, workspace, values, gs_resource = geoserver_upload( instance, base_file.file.path, instance.owner, instance.name, overwrite=True, title=instance.title, abstract=instance.abstract, # keywords=instance.keywords, charset=instance.charset) # Set fields obtained via the geoserver upload. instance.name = gs_name instance.workspace = workspace instance.store = values['store'] # Iterate over values from geoserver. for key in ['typename', 'store', 'storeType']: setattr(instance, key, values[key]) instance.save() if not gs_resource: gs_resource = gs_catalog.get_resource(instance.name, store=instance.store, workspace=instance.workspace) if gs_resource: gs_resource.title = instance.title if instance.title else "" gs_resource.abstract = instance.abstract if instance.abstract else "" gs_resource.name = instance.name if instance.name else "" # Get metadata links metadata_links = [] for link in instance.link_set.metadata(): metadata_links.append((link.mime, link.name, link.url)) if gs_resource: gs_resource.metadata_links = metadata_links # gs_resource should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if gs_resource and getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_resource) gs_layer = gs_catalog.get_layer(instance.name) if instance.poc and instance.poc: # gsconfig now utilizes an attribution dictionary gs_layer.attribution = { 'title': str(instance.poc), 'width': None, 'height': None, 'href': None, 'url': None, 'type': None } profile = Profile.objects.get(username=instance.poc.username) gs_layer.attribution_link = settings.SITEURL[: -1] + profile.get_absolute_url( ) # gs_layer should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_layer) """Get information from geoserver. The attributes retrieved include: * Bounding Box * SRID * Download links (WMS, WCS or WFS and KML) * Styles (SLD) """ if gs_resource: bbox = gs_resource.latlon_bbox # FIXME(Ariel): Correct srid setting below # self.srid = gs_resource.src instance.srid_url = "http://www.spatialreference.org/ref/" + \ instance.srid.replace(':', '/').lower() + "/" # Set bounding box values instance.bbox_x0 = bbox[0] instance.bbox_x1 = bbox[1] instance.bbox_y0 = bbox[2] instance.bbox_y1 = bbox[3] # store the resource to avoid another geoserver call in the post_save instance.gs_resource = gs_resource instance.save() if type(instance) is ResourceBase: if hasattr(instance, 'layer'): instance = instance.layer else: return instance if instance.storeType == "remoteStore": # Save layer attributes set_attributes_from_geoserver(instance) return instance if not getattr(instance, 'gs_resource', None): try: gs_resource = gs_catalog.get_resource(instance.name, store=instance.store, workspace=instance.workspace) except socket_error as serr: if serr.errno != errno.ECONNREFUSED: # Not the error we are looking for, re-raise raise serr # If the connection is refused, take it easy. return instance else: gs_resource = instance.gs_resource if gs_resource is None: return instance if settings.RESOURCE_PUBLISHING: if instance.is_published != gs_resource.advertised: if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_resource.advertised = instance.is_published gs_catalog.save(gs_resource) if any(instance.keyword_list()): gs_resource.keywords = instance.keyword_list() # gs_resource should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_resource) bbox = gs_resource.latlon_bbox dx = float(bbox[1]) - float(bbox[0]) dy = float(bbox[3]) - float(bbox[2]) dataAspect = 1 if dy == 0 else dx / dy height = 550 width = int(height * dataAspect) # Set download links for WMS, WCS or WFS and KML links = wms_links(ogc_server_settings.public_url + 'wms?', instance.typename.encode('utf-8'), instance.bbox_string, instance.srid, height, width) for ext, name, mime, wms_url in links: Link.objects.get_or_create(resource=instance.resourcebase_ptr, name=ugettext(name), defaults=dict( extension=ext, url=wms_url, mime=mime, link_type='image', )) if instance.storeType == "dataStore": links = wfs_links(ogc_server_settings.public_url + 'wfs?', instance.typename.encode('utf-8')) for ext, name, mime, wfs_url in links: if mime == 'SHAPE-ZIP': name = 'Zipped Shapefile' Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=wfs_url, defaults=dict( extension=ext, name=name, mime=mime, url=wfs_url, link_type='data', )) gs_store_type = gs_resource.store.type.lower( ) if gs_resource.store.type else None geogig_repository = gs_resource.store.connection_parameters.get( 'geogig_repository', '') geogig_repo_name = geogig_repository.replace('geoserver://', '') if gs_store_type == 'geogig' and geogig_repo_name: repo_url = '{url}geogig/repos/{repo_name}'.format( url=ogc_server_settings.public_url, repo_name=geogig_repo_name) path = gs_resource.dom.findall('nativeName') if path: path = 'path={path}'.format(path=path[0].text) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=repo_url, defaults=dict(extension='html', name='Clone in GeoGig', mime='text/xml', link_type='html')) def command_url(command): return "{repo_url}/{command}.json?{path}".format( repo_url=repo_url, path=path, command=command) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=command_url('log'), defaults=dict(extension='json', name='GeoGig log', mime='application/json', link_type='html')) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=command_url('statistics'), defaults=dict(extension='json', name='GeoGig statistics', mime='application/json', link_type='html')) elif instance.storeType == 'coverageStore': links = wcs_links(ogc_server_settings.public_url + 'wcs?', instance.typename.encode('utf-8')) for ext, name, mime, wcs_url in links: Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=wcs_url, defaults=dict( extension=ext, name=name, mime=mime, link_type='data', )) kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + \ urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "download"}) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=kml_reflector_link_download, defaults=dict( extension='kml', name="KML", mime='text/xml', link_type='data', )) kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + \ urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "refresh"}) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=kml_reflector_link_view, defaults=dict( extension='kml', name="View in Google Earth", mime='text/xml', link_type='data', )) html_link_url = '%s%s' % (settings.SITEURL[:-1], instance.get_absolute_url()) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=html_link_url, defaults=dict( extension='html', name=instance.typename, mime='text/html', link_type='html', )) create_gs_thumbnail(instance, overwrite=False) legend_url = ogc_server_settings.PUBLIC_LOCATION + \ 'wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER=' + \ instance.typename + '&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on' Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=legend_url, defaults=dict( extension='png', name='Legend', url=legend_url, mime='image/png', link_type='image', )) ogc_wms_path = '%s/wms' % instance.workspace ogc_wms_url = urljoin(ogc_server_settings.public_url, ogc_wms_path) ogc_wms_name = 'OGC WMS: %s Service' % instance.workspace Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=ogc_wms_url, defaults=dict( extension='html', name=ogc_wms_name, url=ogc_wms_url, mime='text/html', link_type='OGC:WMS', )) if instance.storeType == "dataStore": ogc_wfs_path = '%s/wfs' % instance.workspace ogc_wfs_url = urljoin(ogc_server_settings.public_url, ogc_wfs_path) ogc_wfs_name = 'OGC WFS: %s Service' % instance.workspace Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=ogc_wfs_url, defaults=dict( extension='html', name=ogc_wfs_name, url=ogc_wfs_url, mime='text/html', link_type='OGC:WFS', )) if instance.storeType == "coverageStore": ogc_wcs_path = '%s/wcs' % instance.workspace ogc_wcs_url = urljoin(ogc_server_settings.public_url, ogc_wcs_path) ogc_wcs_name = 'OGC WCS: %s Service' % instance.workspace Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=ogc_wcs_url, defaults=dict( extension='html', name=ogc_wcs_name, url=ogc_wcs_url, mime='text/html', link_type='OGC:WCS', )) # remove links that belong to and old address for link in instance.link_set.all(): if not urlparse(settings.SITEURL).hostname == urlparse( link.url).hostname and not urlparse( ogc_server_settings.public_url).hostname == urlparse( link.url).hostname: link.delete() # Define the link after the cleanup, we should use this more rather then remove # potential parasites tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url + 'layers=%s' % instance.typename.encode('utf-8') + '&zoom={z}&x={x}&y={y}' + '&format=image/png8') link, created = Link.objects.get_or_create( resource=instance.resourcebase_ptr, extension='tiles', name="Tiles", mime='image/png', link_type='image', ) if created: Link.objects.filter(pk=link.pk).update(url=tile_url) # Save layer attributes set_attributes_from_geoserver(instance) # Save layer styles set_styles(instance, gs_catalog) # NOTTODO by simod: we should not do this! # need to be removed when fixing #2015 from geonode.catalogue.models import catalogue_post_save from geonode.layers.models import Layer catalogue_post_save(instance, Layer) return instance
def geoserver_pre_save(instance, sender, **kwargs): """Send information to geoserver. The attributes sent include: * Title * Abstract * Name * Keywords * Metadata Links, * Point of Contact name and url """ # Don't run this signal if is a Layer from a remote service if getattr(instance, "service", None) is not None: return gs_resource = None # If the store in None then it's a new instance from an upload, # only in this case run the geonode_uplaod method if not instance.store or getattr(instance, 'overwrite', False): base_file, info = instance.get_base_file() # There is no need to process it if there is not file. if base_file is None: return gs_name, workspace, values, gs_resource = geoserver_upload(instance, base_file.file.path, instance.owner, instance.name, overwrite=True, title=instance.title, abstract=instance.abstract, # keywords=instance.keywords, charset=instance.charset) # Set fields obtained via the geoserver upload. instance.name = gs_name instance.workspace = workspace # Iterate over values from geoserver. for key in ['typename', 'store', 'storeType']: setattr(instance, key, values[key]) if not gs_resource: gs_resource = gs_catalog.get_resource( instance.name, store=instance.store, workspace=instance.workspace) gs_resource.title = instance.title gs_resource.abstract = instance.abstract gs_resource.name = instance.name # Get metadata links metadata_links = [] for link in instance.link_set.metadata(): metadata_links.append((link.mime, link.name, link.url)) gs_resource.metadata_links = metadata_links # gs_resource should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_resource) gs_layer = gs_catalog.get_layer(instance.name) if instance.poc and instance.poc: # gsconfig now utilizes an attribution dictionary gs_layer.attribution = {'title': str(instance.poc), 'width': None, 'height': None, 'href': None, 'url': None, 'type': None} profile = Profile.objects.get(username=instance.poc.username) gs_layer.attribution_link = settings.SITEURL[ :-1] + profile.get_absolute_url() # gs_layer should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_layer) """Get information from geoserver. The attributes retrieved include: * Bounding Box * SRID * Download links (WMS, WCS or WFS and KML) * Styles (SLD) """ bbox = gs_resource.latlon_bbox # FIXME(Ariel): Correct srid setting below # self.srid = gs_resource.src instance.srid_url = "http://www.spatialreference.org/ref/" + \ instance.srid.replace(':', '/').lower() + "/" # Set bounding box values instance.bbox_x0 = bbox[0] instance.bbox_x1 = bbox[1] instance.bbox_y0 = bbox[2] instance.bbox_y1 = bbox[3] # store the resource to avoid another geoserver call in the post_save instance.gs_resource = gs_resource
def validate_input_source(layer, filename, files, gtype=None, action_type='replace'): if layer.is_vector() and is_raster(filename): raise Exception( _(f"You are attempting to {action_type} a vector layer with a raster." )) elif (not layer.is_vector()) and is_vector(filename): raise Exception( _(f"You are attempting to {action_type} a raster layer with a vector." )) if layer.is_vector(): absolute_base_file = None try: if 'shp' in files and os.path.exists(files['shp']): absolute_base_file = _fixup_base_file(files['shp']) elif 'zip' in files and os.path.exists(files['zip']): absolute_base_file = _fixup_base_file(files['zip']) except Exception: absolute_base_file = None if not absolute_base_file or \ os.path.splitext(absolute_base_file)[1].lower() != '.shp': raise Exception( _(f"You are attempting to {action_type} a vector layer with an unknown format." )) else: try: gtype = layer.gtype if not gtype else gtype inDataSource = ogr.Open(absolute_base_file) lyr = inDataSource.GetLayer(str(layer.name)) if not lyr: raise Exception( _(f"Please ensure the name is consistent with the file you are trying to {action_type}." )) schema_is_compliant = False _ff = json.loads(lyr.GetFeature(0).ExportToJson()) if gtype: logger.warning( _("Local GeoNode layer has no geometry type.")) if _ff["geometry"]["type"] in gtype or gtype in _ff[ "geometry"]["type"]: schema_is_compliant = True elif "geometry" in _ff and _ff["geometry"]["type"]: schema_is_compliant = True if not schema_is_compliant: raise Exception( _(f"Please ensure there is at least one geometry type \ that is consistent with the file you are trying to {action_type}." )) new_schema_fields = [field.name for field in lyr.schema] gs_layer = gs_catalog.get_layer(layer.name) if not gs_layer: raise Exception( _("The selected Layer does not exists in the catalog.") ) gs_layer = gs_layer.resource.attributes schema_is_compliant = all( [x in gs_layer for x in new_schema_fields]) if not schema_is_compliant: raise Exception( _("Please ensure that the layer structure is consistent " f"with the file you are trying to {action_type}.")) return True except Exception as e: raise Exception( _(f"Some error occurred while trying to access the uploaded schema: {str(e)}" ))
def geoserver_pre_save(instance, sender, **kwargs): """Send information to geoserver. The attributes sent include: * Title * Abstract * Name * Keywords * Metadata Links, * Point of Contact name and url """ # Don't run this signal handler if it is a tile layer or a remote store (Service) # Currently only gpkg files containing tiles will have this type & will be served via MapProxy. if hasattr(instance, 'storeType') and getattr( instance, 'storeType') in ['tileStore', 'remoteStore']: return gs_resource = None # If the store in None then it's a new instance from an upload, # only in this case run the geonode_uplaod method if not instance.store or getattr(instance, 'overwrite', False): base_file, info = instance.get_base_file() # There is no need to process it if there is not file. if base_file is None: return gs_name, workspace, values, gs_resource = geoserver_upload( instance, base_file.file.path, instance.owner, instance.name, overwrite=True, title=instance.title, abstract=instance.abstract, # keywords=instance.keywords, charset=instance.charset) # Set fields obtained via the geoserver upload. instance.name = gs_name instance.workspace = workspace # Iterate over values from geoserver. for key in ['typename', 'store', 'storeType']: setattr(instance, key, values[key]) if not gs_resource: gs_resource = gs_catalog.get_resource(instance.name, store=instance.store, workspace=instance.workspace) if gs_resource: gs_resource.title = instance.title if instance.title else "" gs_resource.abstract = instance.abstract if instance.abstract else "" gs_resource.name = instance.name if instance.name else "" # Get metadata links metadata_links = [] for link in instance.link_set.metadata(): metadata_links.append((link.mime, link.name, link.url)) if gs_resource: gs_resource.metadata_links = metadata_links # gs_resource should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if gs_resource and getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_resource) if instance.storeType and instance.storeType == 'layerGroup': gs_layer = gs_catalog.get_layergroup(name=instance.name, workspace=instance.workspace) else: gs_layer = gs_catalog.get_layer(instance.name) if instance.poc and instance.poc: # gsconfig now utilizes an attribution dictionary gs_layer.attribution = { 'title': str(instance.poc), 'width': None, 'height': None, 'href': None, 'url': None, 'type': None } profile = Profile.objects.get(username=instance.poc.username) gs_layer.attribution_link = settings.SITEURL[: -1] + profile.get_absolute_url( ) # gs_layer should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): try: # Some geogig layers will return a 500 on save gs_catalog.save(gs_layer) except geoserver.catalog.FailedRequestError: pass """Get information from geoserver. The attributes retrieved include: * Bounding Box * SRID * Download links (WMS, WCS or WFS and KML) * Styles (SLD) """ if gs_resource: bbox = gs_resource.latlon_bbox # FIXME(Ariel): Correct srid setting below # self.srid = gs_resource.src instance.srid_url = "http://www.spatialreference.org/ref/" + \ instance.srid.replace(':', '/').lower() + "/" # Set bounding box values instance.bbox_x0 = bbox[0] instance.bbox_x1 = bbox[1] instance.bbox_y0 = bbox[2] instance.bbox_y1 = bbox[3] # store the resource to avoid another geoserver call in the post_save instance.gs_resource = gs_resource
def set_default_layer_style(self, layername, stylename): gs_layer = gs_catalog.get_layer(layername) gs_layer.default_style = gs_catalog.get_style( stylename, workspace=settings.DEFAULT_WORKSPACE) gs_catalog.save(gs_layer)
def geoserver_pre_save(instance, sender, **kwargs): """Send information to geoserver. The attributes sent include: * Title * Abstract * Name * Keywords * Metadata Links, * Point of Contact name and url """ url = ogc_server_settings.internal_rest try: gs_resource = gs_catalog.get_resource(instance.name, store=instance.store, workspace=instance.workspace) except (EnvironmentError, FailedRequestError) as e: gs_resource = None msg = ('Could not connect to geoserver at "%s"' 'to save information for layer "%s"' % (ogc_server_settings.LOCATION, instance.name.encode('utf-8'))) logger.warn(msg, e) # If geoserver is not online, there is no need to continue return # If there is no resource returned it could mean one of two things: # a) There is a synchronization problem in geoserver # b) The unit tests are running and another geoserver is running in the # background. # For both cases it is sensible to stop processing the layer if gs_resource is None: logger.warn('Could not get geoserver resource for %s' % instance) return gs_resource.title = instance.title gs_resource.abstract = instance.abstract gs_resource.name = instance.name # Get metadata links metadata_links = [] for link in instance.link_set.metadata(): metadata_links.append((link.name, link.mime, link.url)) gs_resource.metadata_links = metadata_links #gs_resource should only be called if ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_resource) gs_layer = gs_catalog.get_layer(instance.name) if instance.poc and instance.poc.user: gs_layer.attribution = str(instance.poc.user) profile = Profile.objects.get(user=instance.poc.user) gs_layer.attribution_link = settings.SITEURL[: -1] + profile.get_absolute_url( ) #gs_layer should only be called if ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_layer) """Get information from geoserver. The attributes retrieved include: * Bounding Box * SRID * Download links (WMS, WCS or WFS and KML) * Styles (SLD) """ gs_resource = gs_catalog.get_resource(instance.name) bbox = gs_resource.latlon_bbox #FIXME(Ariel): Correct srid setting below #self.srid = gs_resource.src instance.srid_url = "http://www.spatialreference.org/ref/" + instance.srid.replace( ':', '/').lower() + "/" # Set bounding box values instance.bbox_x0 = bbox[0] instance.bbox_x1 = bbox[1] instance.bbox_y0 = bbox[2] instance.bbox_y1 = bbox[3] instance.thumbnail, created = Thumbnail.objects.get_or_create( resourcebase__id=instance.id)
def geoserver_post_save2(layer_id): """Save keywords to GeoServer The way keywords are implemented requires the layer to be saved to the database before accessing them. """ """Send information to geoserver. The attributes sent include: * Title * Abstract * Name * Keywords * Metadata Links, * Point of Contact name and url """ from geonode.layers.models import Layer instance = Layer.objects.get(id=layer_id) # Don't run this signal if is a Layer from a remote service if getattr(instance, "service", None) is not None: return instance # Don't run this signal handler if it is a tile layer or a remote store (Service) # Currently only gpkg files containing tiles will have this type & will be served via MapProxy. if hasattr(instance, 'storeType') and getattr(instance, 'storeType') in ['tileStore', 'remoteStore']: return instance gs_resource = None # If the store in None then it's a new instance from an upload, # only in this case run the geonode_uplaod method if not instance.store or getattr(instance, 'overwrite', False): base_file, info = instance.get_base_file() # There is no need to process it if there is not file. if base_file is None: return instance gs_name, workspace, values, gs_resource = geoserver_upload(instance, base_file.file.path, instance.owner, instance.name, overwrite=True, title=instance.title, abstract=instance.abstract, # keywords=instance.keywords, charset=instance.charset) # Set fields obtained via the geoserver upload. instance.name = gs_name instance.workspace = workspace instance.store = values['store'] # Iterate over values from geoserver. for key in ['typename', 'store', 'storeType']: setattr(instance, key, values[key]) instance.save() if not gs_resource: gs_resource = gs_catalog.get_resource( instance.name, store=instance.store, workspace=instance.workspace) if gs_resource: gs_resource.title = instance.title if instance.title else "" gs_resource.abstract = instance.abstract if instance.abstract else "" gs_resource.name = instance.name if instance.name else "" # Get metadata links metadata_links = [] for link in instance.link_set.metadata(): metadata_links.append((link.mime, link.name, link.url)) if gs_resource: gs_resource.metadata_links = metadata_links # gs_resource should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if gs_resource and getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_resource) gs_layer = gs_catalog.get_layer(instance.name) if instance.poc and instance.poc: # gsconfig now utilizes an attribution dictionary gs_layer.attribution = {'title': str(instance.poc), 'width': None, 'height': None, 'href': None, 'url': None, 'type': None} profile = Profile.objects.get(username=instance.poc.username) gs_layer.attribution_link = settings.SITEURL[ :-1] + profile.get_absolute_url() # gs_layer should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_layer) """Get information from geoserver. The attributes retrieved include: * Bounding Box * SRID * Download links (WMS, WCS or WFS and KML) * Styles (SLD) """ if gs_resource: bbox = gs_resource.latlon_bbox # FIXME(Ariel): Correct srid setting below # self.srid = gs_resource.src instance.srid_url = "http://www.spatialreference.org/ref/" + \ instance.srid.replace(':', '/').lower() + "/" # Set bounding box values instance.bbox_x0 = bbox[0] instance.bbox_x1 = bbox[1] instance.bbox_y0 = bbox[2] instance.bbox_y1 = bbox[3] # store the resource to avoid another geoserver call in the post_save instance.gs_resource = gs_resource instance.save() if type(instance) is ResourceBase: if hasattr(instance, 'layer'): instance = instance.layer else: return instance if instance.storeType == "remoteStore": # Save layer attributes set_attributes_from_geoserver(instance) return instance if not getattr(instance, 'gs_resource', None): try: gs_resource = gs_catalog.get_resource( instance.name, store=instance.store, workspace=instance.workspace) except socket_error as serr: if serr.errno != errno.ECONNREFUSED: # Not the error we are looking for, re-raise raise serr # If the connection is refused, take it easy. return instance else: gs_resource = instance.gs_resource if gs_resource is None: return instance if settings.RESOURCE_PUBLISHING: if instance.is_published != gs_resource.advertised: if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_resource.advertised = instance.is_published gs_catalog.save(gs_resource) if any(instance.keyword_list()): gs_resource.keywords = instance.keyword_list() # gs_resource should only be called if # ogc_server_settings.BACKEND_WRITE_ENABLED == True if getattr(ogc_server_settings, "BACKEND_WRITE_ENABLED", True): gs_catalog.save(gs_resource) bbox = gs_resource.latlon_bbox dx = float(bbox[1]) - float(bbox[0]) dy = float(bbox[3]) - float(bbox[2]) dataAspect = 1 if dy == 0 else dx / dy height = 550 width = int(height * dataAspect) # Set download links for WMS, WCS or WFS and KML links = wms_links(ogc_server_settings.public_url + 'wms?', instance.typename.encode('utf-8'), instance.bbox_string, instance.srid, height, width) for ext, name, mime, wms_url in links: Link.objects.get_or_create(resource=instance.resourcebase_ptr, name=ugettext(name), defaults=dict( extension=ext, url=wms_url, mime=mime, link_type='image', ) ) if instance.storeType == "dataStore": links = wfs_links( ogc_server_settings.public_url + 'wfs?', instance.typename.encode('utf-8')) for ext, name, mime, wfs_url in links: if mime == 'SHAPE-ZIP': name = 'Zipped Shapefile' Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=wfs_url, defaults=dict( extension=ext, name=name, mime=mime, url=wfs_url, link_type='data', ) ) gs_store_type = gs_resource.store.type.lower() if gs_resource.store.type else None geogig_repository = gs_resource.store.connection_parameters.get('geogig_repository', '') geogig_repo_name = geogig_repository.replace('geoserver://', '') if gs_store_type == 'geogig' and geogig_repo_name: repo_url = '{url}geogig/repos/{repo_name}'.format( url=ogc_server_settings.public_url, repo_name=geogig_repo_name) path = gs_resource.dom.findall('nativeName') if path: path = 'path={path}'.format(path=path[0].text) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=repo_url, defaults=dict(extension='html', name='Clone in GeoGig', mime='text/xml', link_type='html' ) ) def command_url(command): return "{repo_url}/{command}.json?{path}".format(repo_url=repo_url, path=path, command=command) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=command_url('log'), defaults=dict(extension='json', name='GeoGig log', mime='application/json', link_type='html' ) ) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=command_url('statistics'), defaults=dict(extension='json', name='GeoGig statistics', mime='application/json', link_type='html' ) ) elif instance.storeType == 'coverageStore': links = wcs_links(ogc_server_settings.public_url + 'wcs?', instance.typename.encode('utf-8')) for ext, name, mime, wcs_url in links: Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=wcs_url, defaults=dict( extension=ext, name=name, mime=mime, link_type='data', ) ) kml_reflector_link_download = ogc_server_settings.public_url + "wms/kml?" + \ urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "download"}) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=kml_reflector_link_download, defaults=dict( extension='kml', name="KML", mime='text/xml', link_type='data', ) ) kml_reflector_link_view = ogc_server_settings.public_url + "wms/kml?" + \ urllib.urlencode({'layers': instance.typename.encode('utf-8'), 'mode': "refresh"}) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=kml_reflector_link_view, defaults=dict( extension='kml', name="View in Google Earth", mime='text/xml', link_type='data', ) ) html_link_url = '%s%s' % ( settings.SITEURL[:-1], instance.get_absolute_url()) Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=html_link_url, defaults=dict( extension='html', name=instance.typename, mime='text/html', link_type='html', ) ) create_gs_thumbnail(instance, overwrite=False) legend_url = ogc_server_settings.PUBLIC_LOCATION + \ 'wms?request=GetLegendGraphic&format=image/png&WIDTH=20&HEIGHT=20&LAYER=' + \ instance.typename + '&legend_options=fontAntiAliasing:true;fontSize:12;forceLabels:on' Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=legend_url, defaults=dict( extension='png', name='Legend', url=legend_url, mime='image/png', link_type='image', ) ) ogc_wms_path = '%s/wms' % instance.workspace ogc_wms_url = urljoin(ogc_server_settings.public_url, ogc_wms_path) ogc_wms_name = 'OGC WMS: %s Service' % instance.workspace Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=ogc_wms_url, defaults=dict( extension='html', name=ogc_wms_name, url=ogc_wms_url, mime='text/html', link_type='OGC:WMS', ) ) if instance.storeType == "dataStore": ogc_wfs_path = '%s/wfs' % instance.workspace ogc_wfs_url = urljoin(ogc_server_settings.public_url, ogc_wfs_path) ogc_wfs_name = 'OGC WFS: %s Service' % instance.workspace Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=ogc_wfs_url, defaults=dict( extension='html', name=ogc_wfs_name, url=ogc_wfs_url, mime='text/html', link_type='OGC:WFS', ) ) if instance.storeType == "coverageStore": ogc_wcs_path = '%s/wcs' % instance.workspace ogc_wcs_url = urljoin(ogc_server_settings.public_url, ogc_wcs_path) ogc_wcs_name = 'OGC WCS: %s Service' % instance.workspace Link.objects.get_or_create(resource=instance.resourcebase_ptr, url=ogc_wcs_url, defaults=dict( extension='html', name=ogc_wcs_name, url=ogc_wcs_url, mime='text/html', link_type='OGC:WCS', ) ) # remove links that belong to and old address for link in instance.link_set.all(): if not urlparse( settings.SITEURL).hostname == urlparse( link.url).hostname and not urlparse( ogc_server_settings.public_url).hostname == urlparse( link.url).hostname: link.delete() # Define the link after the cleanup, we should use this more rather then remove # potential parasites tile_url = ('%sgwc/service/gmaps?' % ogc_server_settings.public_url + 'layers=%s' % instance.typename.encode('utf-8') + '&zoom={z}&x={x}&y={y}' + '&format=image/png8' ) link, created = Link.objects.get_or_create(resource=instance.resourcebase_ptr, extension='tiles', name="Tiles", mime='image/png', link_type='image', ) if created: Link.objects.filter(pk=link.pk).update(url=tile_url) # Save layer attributes set_attributes_from_geoserver(instance) # Save layer styles set_styles(instance, gs_catalog) # NOTTODO by simod: we should not do this! # need to be removed when fixing #2015 from geonode.catalogue.models import catalogue_post_save from geonode.layers.models import Layer catalogue_post_save(instance, Layer) return instance