Beispiel #1
0
def set_style(layer_name, style):
    cat = Catalog(GEOSERVER_REST_URL, GS_USERNAME, GS_PASSWORD)
    layer = cat.get_layer(layer_name)
    
    style = cat.get_style(style)
    layer.default_style = style
    cat.save(layer)
Beispiel #2
0
    def publish_layer_group(self):
        """
        Publishes local map layers as WMS layer group on local OWS.
        """
        # temporary permission workaround: 
        # only allow public maps to be published
        if not self.is_public:
            return 'Only public maps can be saved as layer group.'

        map_layers = MapLayer.objects.filter(map=self.id)
        
        # Local Group Layer layers and corresponding styles
        layers = []
        lg_styles = []
        for ml in map_layers:
            if ml.local:
                layer = Layer.objects.get(typename=ml.name)
                style = ml.styles or getattr(layer.default_style, 'name', '')
                layers.append(layer)
                lg_styles.append(style)
        lg_layers = [l.name for l in layers]

        # Group layer bounds and name             
        lg_bounds = [str(coord) for coord in self.bbox] 
        lg_name = '%s_%d' % (slugify(self.title), self.id)

        # Update existing or add new group layer
        cat = Catalog(ogc_server_settings.rest, _user, _password)
        lg = self.layer_group
        if lg is None:
            lg = GsUnsavedLayerGroup(cat, lg_name, lg_layers, lg_styles, lg_bounds)
        else:
            lg.layers, lg.styles, lg.bounds = lg_layers, lg_styles, lg_bounds
        cat.save(lg)
        return lg_name
Beispiel #3
0
 def createDataStore(self, options):
     try:
         cat = Catalog(self.geoserver_rest_url, options["geoserveradmin"], options["gpw"])
         # create datastore for URB schema
         try:
             ws = cat.create_workspace(options["alias"], options["uri"])
         except Exception as e:
             raise Exception("Le nom du workspace ou l'alias est déja utiliser")
         try:
             ds = cat.create_datastore(options["alias"], ws)
             ds.connection_parameters.update(
                 host=options["urbanUrl"],
                 port=options["dbport"],
                 database=options["database"],
                 user=options["postuser"],
                 passwd=options["ropw"],
                 dbtype="postgis",
             )
             cat.save(ds)
         except Exception as e:
             print(str(e))
             raise Exception("Erreur de connexion au Geoserver lors de la création du DataStore")
     except Exception as e:
         raise Exception(str(e))
     return ws.name, ds.name, ds.resource_type
Beispiel #4
0
def create_geogig_datastore(store_name):
    """
    Args:
        store_name: name of geogig repo
    Returns:
        None
    """

    ogc_server = get_ogc_server()
    url = "{}/rest".format(ogc_server.get('LOCATION').rstrip('/'))
    workspace_name = "geonode"
    workspace_uri = "http://www.geonode.org/"
    cat = Catalog(url)
    # Check if local workspace exists and if not create it
    workspace = cat.get_workspace(workspace_name)
    if workspace is None:
        cat.create_workspace(workspace_name, workspace_uri)
        print "Workspace " + workspace_name + " created."

    # Get list of datastores
    datastores = cat.get_stores()
    datastore = None
    # Check if remote datastore exists on local system
    for ds in datastores:
        if ds.name.lower() == store_name.lower():
            datastore = ds

    if not datastore:
        datastore = cat.create_datastore(store_name, workspace_name)
        datastore.connection_parameters.update(geogig_repository=os.path.join(
            ogc_server.get('GEOGIG_DATASTORE_DIR'), store_name))
        cat.save(datastore)
Beispiel #5
0
def main(options):
  #connect to geoserver
  cat = Catalog("http://localhost:8080/geoserver/rest", "admin", options.gpw)
  
  #create datrastore for URB schema
  ws = cat.create_workspace(options.alias,'imio.be')
  
  ds = cat.create_datastore(options.alias, ws)
  ds.connection_parameters.update(
      host=options.urbanUrl,
      port="5432",
      database=options.database,
      user="******",
      passwd=options.ropw,
      dbtype="postgis")
  
  cat.save(ds)
  ds = cat.get_store(options.alias)
  
  #config object
  urb = {
  	"capa":"Parcelles",
  	"toli":"cadastre_ln_toponymiques",
  	"canu":"cadastre_pt_num",
  	"cabu":"Batiments",
  	"gept":"cadastre_points_generaux",
  	"gepn":"cadastre_pol_gen",
  	"inpt":"point",
  	"geli":"cadastre_ln_generales",
  	"inli":"cadastre_ln_informations",
  	"topt":"point",
  	}   	
  	
  #connect to tables and create layers and correct urban styles
  for table in urb:
    style = urb[table]
    ft = cat.publish_featuretype(table, ds, 'EPSG:31370', srs='EPSG:31370')
    ft.default_style = style
    cat.save(ft)
    resource = ft.resource
    resource.title = options.alias+"_"+table
    resource.save()
    
    layer, created = Layer.objects.get_or_create(name=layerName, defaults={
      	            "workspace": ws.name,
                    "store": ds.name,
                    "storeType": ds.resource_type,
                    "typename": "%s:%s" % (ws.name.encode('utf-8'), resource.name.encode('utf-8')),
                    "title": resource.title or 'No title provided',
                    "abstract": resource.abstract or 'No abstract provided',
                    #"owner": owner,
                    "uuid": str(uuid.uuid4()),
                    "bbox_x0": Decimal(resource.latlon_bbox[0]),
                    "bbox_x1": Decimal(resource.latlon_bbox[1]),
                    "bbox_y0": Decimal(resource.latlon_bbox[2]),
                    "bbox_y1": Decimal(resource.latlon_bbox[3])
      	         })
    set_attributes(layer, overwrite=True)
    if created: layer.set_default_permissions()
Beispiel #6
0
def _create_geoserver_geonode_layer(new_table, sld_type, title, the_user,
                                    permissions):
    # Create the Layer in GeoServer from the table
    try:
        cat = Catalog(settings.OGC_SERVER['default']['LOCATION'] + "rest",
                      settings.OGC_SERVER['default']['USER'],
                      settings.OGC_SERVER['default']['PASSWORD'])
        ds = cat.get_store("uploaded")  # name of store in WFP-Geonode
        cat.publish_featuretype(new_table, ds, "EPSG:4326", srs="EPSG:4326")

        # changing the layer's title in the title set by the user
        resource = cat.get_resource(new_table, workspace="geonode")
        resource.title = title
        cat.save(resource)

    except Exception as e:

        msg = "Error creating GeoServer layer for %s: %s" % (new_table, str(e))
        print msg
        return None, msg

    # Create the Layer in GeoNode from the GeoServer Layer
    try:

        link_to_sld = "{location}styles/{sld_type}".format(
            **{
                'location': settings.OGC_SERVER['default']['LOCATION'],
                'sld_type': sld_type
            })

        r = requests.get(link_to_sld)
        sld = r.text
        sld = sld.replace(
            "name_of_layer", new_table
        )  # "name_of_layer" is set in the predefined sld in geoserver (polygon_style, line_style, point_style)
        cat.create_style(new_table, sld, overwrite=True)
        style = cat.get_style(new_table)
        layer = cat.get_layer(new_table)
        layer.default_style = style
        cat.save(layer)
        gs_slurp(owner=the_user, filter=new_table)

        from geonode.base.models import ResourceBase
        layer = ResourceBase.objects.get(title=title)
        geoserver_post_save(layer, ResourceBase)

        # assign permissions for this layer
        permissions_dict = json.loads(permissions)  # needs to be dictionary
        if permissions_dict is not None and len(permissions_dict.keys()) > 0:
            layer.set_permissions(permissions_dict)

    except Exception as e:
        msg = "Error creating GeoNode layer for %s: %s" % (new_table, str(e))
        return None, msg
def rename_layers_old_postfix():
    """ Rename the layers adding an _old suffix.
    """
    # fixme it does not work, as name cannot be assigned with gsconfig
    # filing a bug
    cat = Catalog("%srest" % settings.GEOSERVER_URL)
    for l in layers_to_process:
        print 'Renaming layer %s' % l
        layer = cat.get_layer(l)
        layer.name = '%s_old' % l
        cat.save(layer)
        cat.reload()
Beispiel #8
0
def set_default_style(server_name, filelist, style_name):
    url = settings.GEOSERVER[server_name]['URL']
    geoserver_user = settings.GEOSERVER[server_name]['USER']
    geoserver_password = settings.GEOSERVER[server_name]['PASSWORD']
    cat = Catalog(url, username=geoserver_user, password=geoserver_password)
    for shape in filelist:
        base, type = os.path.splitext(shape)
        name = os.path.basename(base)
        layer = cat.get_layer(name)
        print layer, style_name
        layer._set_default_style(style_name)
        cat.save(layer)
    def updateBbox(self):
        sql = u"with geom_union as (select st_envelope(st_union(the_geom)) as geom from " + self.DATABASE_TABLE_NAME + u") " \
              u"select st_xmin(geom), st_xmax(geom), st_ymin(geom), st_ymax(geom) from geom_union"
        self.cur.execute(sql)

        result = self.cur.fetchone()

        cat = Catalog(self.HTTP + self.GEOSERVER_URL + "/geoserver/rest",username = self.GEOSERVER_USER, password=self.GEOSERVER_PASSWORD)
        print self.HTTP + self.GEOSERVER_URL + "/geoserver/rest/workspaces/uos/coveragestores/" + "uos_upload_image/coverages/" + self.DATABASE_TABLE_NAME + ".xml"
        coverage = cat.get_resource_by_url(self.HTTP + self.GEOSERVER_URL + "/geoserver/rest/workspaces/uos/coveragestores/" + "uos_upload_image/coverages/" + self.GEOSERVER_LAYER_NAME + ".xml")

        coverage.native_bbox = (str(result[0]),str(result[1]),str(result[2]),str(result[3]),"EPSG:4326")
        cat.save(coverage)
    def updateBbox(self):
        sql = u"with geom_union as (select st_envelope(st_union(the_geom)) as geom from uos_fast) " \
              u"select st_xmin(geom), st_xmax(geom), st_ymin(geom), st_ymax(geom) from geom_union"
        self.cur.execute(sql)

        result = self.cur.fetchone()

        cat = Catalog("http://localhost:8081/geoserver/rest",username ="******",password="******")
        coverage = cat.get_resource_by_url("http://localhost:8081/geoserver/rest/workspaces/uos/coveragestores/"
                                           "uos_image/coverages/uos_fast.xml")

        coverage.native_bbox = (str(result[0]),str(result[1]),str(result[2]),str(result[3]),"EPSG:4326")
        cat.save(coverage)
Beispiel #11
0
def handle_geoserver_layers(view_names,
                            store_name,
                            db_params,
                            schema_name,
                            logger=print):
    """Publish database views as GeoServer layers

    Parameters
    ----------
    view_pairs: list
        An iterable of two-element tuples with the names of the
        ``coarse`` and ``detail`` database views that are to be published
        as GeoServer layers
    store_name: str
        Name of the GeoServer store to use. This store will be created in case
        it does not exist
    db_params: dict
        A mapping with parameters used for connecting to the database
    schema_name: str
        Name of the database schema where the views to publish reside
    logger: function, optional
        A function that is used to output information.

    Returns
    -------
    list
        An iterable with the geoserver layers that have been published

    """

    gs_catalog = Catalog(
        service_url=settings.OGC_SERVER["default"]["LOCATION"] + "rest",
        username=settings.OGC_SERVER["default"]["USER"],
        password=settings.OGC_SERVER["default"]["PASSWORD"])
    logger("Retrieving geoserver workspace...")
    workspace = get_geoserver_workspace(gs_catalog)
    store = gs_catalog.get_store(store_name, workspace=workspace)
    if store is None:
        logger("Creating geoserver store...")
        store = get_postgis_store(gs_catalog, store_name, workspace, db_params,
                                  schema_name)
    layers = []
    for view_name in view_names:
        logger("Adding {!r} as a geoserver layer...".format(view_name))
        featuretype = gs_catalog.publish_featuretype(view_name,
                                                     store,
                                                     "EPSG:4326",
                                                     srs="EPSG:4326")
        gs_catalog.save(featuretype)
        layers.append(featuretype)
    return layers
Beispiel #12
0
def style_update(layer, style_template):

    # Get geoserver catalog
    cat = Catalog(settings.OGC_SERVER['default']['LOCATION'] + 'rest',
                  username=settings.OGC_SERVER['default']['USER'],
                  password=settings.OGC_SERVER['default']['PASSWORD'])

    # Get equivalent geoserver layer
    gs_layer = cat.get_layer(layer.name)
    print layer.name, ': gs_layer:', gs_layer.name

    # Get current style
    # pprint(dir(gs_layer))
    cur_def_gs_style = gs_layer._get_default_style()
    # pprint(dir(cur_def_gs_style))
    if cur_def_gs_style is not None:
        print layer.name, ': cur_def_gs_style.name:', cur_def_gs_style.name

    # Get proper style
    attributes = [a.attribute for a in layer.attributes]
    gs_style = None
    if '_fh' in layer.name:
        if 'Var' in attributes:
            gs_style = cat.get_style(style_template)
        elif 'Merge' in attributes:
            gs_style = cat.get_style("fhm_merge")
        elif 'UVar' in attributes:
            gs_style = cat.get_style('fhm_uvar')
    else:
        gs_style = cat.get_style(style_template)

    # has_layer_changes = False
    try:
        if gs_style is not None:
            print layer.name, ': gs_style.name:', gs_style.name

            if cur_def_gs_style and cur_def_gs_style.name != gs_style.name:

                print layer.name, ': Setting default style...'
                gs_layer._set_default_style(gs_style)
                cat.save(gs_layer)

                print layer.name, ': Deleting old default style from geoserver...'
                cat.delete(cur_def_gs_style)

                print layer.name, ': Deleting old default style from geonode...'
                gn_style = Style.objects.get(name=layer.name)
                gn_style.delete()
    except Exception as e:
        logger.exception("Error setting style")
    def updateBbox(self):
        sql = u"with geom_union as (select st_envelope(st_union(the_geom)) as geom from " + self.DATABASE_TABLE_NAME + u") " \
              u"select st_xmin(geom), st_xmax(geom), st_ymin(geom), st_ymax(geom) from geom_union"
        self.cur.execute(sql)

        result = self.cur.fetchone()

        #self.cur.close()

        cat = Catalog(self.HTTP + self.GEOSERVER_URL + "/geoserver/rest",username = self.GEOSERVER_USER, password=self.GEOSERVER_PASSWORD)
        print self.HTTP + self.GEOSERVER_URL + "/geoserver/rest/workspaces/uos/coveragestores/" + "uos_upload_image/coverages/" + self.DATABASE_TABLE_NAME + ".xml"
        coverage = cat.get_resource_by_url(self.HTTP + self.GEOSERVER_URL + "/geoserver/rest/workspaces/uos/coveragestores/" + "uos_upload_image/coverages/" + self.GEOSERVER_LAYER_NAME + ".xml")

        coverage.native_bbox = (str(result[0]),str(result[1]),str(result[2]),str(result[3]),"EPSG:4326")
        cat.save(coverage)
Beispiel #14
0
def handle_geoserver_layer(table_name, store_name, db_params, schema_name,
                           default_style_name="", logger=print):
    """Publish a database table/view as a GeoServer layer

    Parameters
    ----------
    store_name: str
        Name of the GeoServer store to use. This store will be created in case
        it does not exist
    db_params: dict
        A mapping with parameters used for connecting to the database
    schema_name: str
        Name of the database schema where the views to publish reside
    logger: function, optional
        A function that is used to output information.

    Returns
    -------
    list
        An iterable with the geoserver layers that have been published

    """

    logger("inside handle_geoserver_layer: {}".format(locals()))

    gs_catalog = Catalog(
        service_url=settings.OGC_SERVER["default"]["LOCATION"] + "rest",
        username=settings.OGC_SERVER["default"]["USER"],
        password=settings.OGC_SERVER["default"]["PASSWORD"]
    )
    logger("Retrieving geoserver workspace...")
    workspace = get_geoserver_workspace(gs_catalog)
    store = gs_catalog.get_store(store_name, workspace=workspace)
    if store is None:
        logger("Creating geoserver store...")
        store = get_postgis_store(gs_catalog, store_name, workspace, db_params,
                                  schema_name)
    logger("Adding {!r} as a geoserver layer...".format(table_name))
    featuretype = gs_catalog.publish_featuretype(
        table_name, store, "EPSG:4326", srs="EPSG:4326")
    logger("dir(featuretype): {}".format(dir(featuretype)))
    layer = gs_catalog.get_layer(featuretype.name)
    if default_style_name != "":
        logger("Setting default style for layer...")
        layer._set_default_style(default_style_name)
    gs_catalog.save(featuretype)
    gs_catalog.save(layer)
    return featuretype
Beispiel #15
0
    def add_new_sld_to_layer(self, formatted_sld_object):
        """
        (3) Add new SLD to Layer
        """
        # get the catalog
        geoserver_catalog = Catalog(settings.GEOSERVER_BASE_URL + "rest",\
                    settings.GEOSERVER_CREDENTIALS[0],\
                    settings.GEOSERVER_CREDENTIALS[1])

        # pull the layer
        the_layer = geoserver_catalog.get_layer(self.layer_name)

        # set the new style
        the_layer.default_style.update_body(formatted_sld_object.formatted_sld_xml)

        # save it
        try:
            server_resp = geoserver_catalog.save(the_layer)
            print ('------server_resp----\n', server_resp)
        except FailedRequestError as fail_obj:
            # Attempt to restore previous SLD
            self.restore_old_sld(the_layer)
            #
            self.add_err_msg("Failed to add a new style.  Error: %s" % fail_obj.message)
            return False
        except:
            # Attempt to restore previous SLD
            self.restore_old_sld(the_layer)
            #
            err_msg = "Unexpected error: %s" % sys.exc_info()[0]
            self.add_err_msg("Failed to add the new style.  Error: %s" % err_msg)
            return False

        self.layer_metadata = LayerMetadata.create_metadata_using_layer_name(self.layer_name)
        return True
Beispiel #16
0
    def _submit_sld(self,sld_body):
	try:
	    geoserver_url=config['ckanext-vectorstorer.geoserver_url']
            cat = Catalog(geoserver_url+"/rest")
	    layer = cat.get_layer(c.layer_id)
	    default_style=layer._get_default_style()
	    if default_style.name ==c.layer_id:
		cat.create_style(default_style.name, sld_body, overwrite=True)
	    else:
		cat.create_style(c.layer_id, sld_body, overwrite=True)
		layer._set_default_style(c.layer_id)
		cat.save(layer)
		
	    c.success=True
		
	except UploadError, e:
	    c.sld_body=sld_body
	    c.error=e
    def _submit_sld(self,sld_body):
	try:
	    geoserver_url=config['ckanext-vectorstorer.geoserver_url']
            cat = Catalog(geoserver_url+"/rest")
	    layer = cat.get_layer(c.layer_id)
	    default_style=layer._get_default_style()
	    if default_style.name ==c.layer_id:
		cat.create_style(default_style.name, sld_body, overwrite=True)
	    else:
		cat.create_style(c.layer_id, sld_body, overwrite=True)
		layer._set_default_style(c.layer_id)
		cat.save(layer)
		
	    c.success=True
		
	except UploadError, e:
	    c.sld_body=sld_body
	    c.error=e
Beispiel #18
0
class catalog:
    def __init__(self,path):
        self.cat = Catalog(path)
    
    def createWkspace(self,name):
        vk = self.cat.create_workspace(name,name)
        vk.enabled = True
        return vk

    def addImage(self,name,workspace,data):
        pdb.set_trace()
        self.cat.create_coveragestore(name,"/usr/share/tomcat/webapps/geoserver/data/data/DE2_MS__L1CT___20140220T104454.tif",workspace)

        inf = CoverageStore(self.cat,workspace,name)

        inf.fetch()

        self.cat.save(inf)
Beispiel #19
0
def fh_style_update(layer,filename):
    cat = Catalog(settings.OGC_SERVER['default']['LOCATION'] + 'rest',
                    username=settings.OGC_SERVER['default']['USER'],
                    password=settings.OGC_SERVER['default']['PASSWORD'])

    #layer_list = Layer.objects.filter(name__icontains='fh')#initial run of script includes all fhm layers for cleaning of styles in GN + GS
    #layer_list = Layer.objects.filter(name__icontains='fh').exclude(styles__name__icontains='fhm'
    #total_layers = len(layer_list)
    fhm_style = cat.get_style("fhm")
    ctr = 0
    #for layer in layer_list:
        #print "[FH STYLE] {0}/{1} : {2} ".format(ctr,total_layers,layer.name)
        #delete thumbnail first because of permissions
    try:
        print "Layer thumbnail url: %s " % layer.thumbnail_url
        if "192" in settings.BASEURL:
            url = "geonode/uploaded/thumbs/layer-"+ layer.uuid + "-thumb.png" #if on local
            os.remove(url)
        else:
            url = "/var/www/geonode/uploaded/thumbs/layer-" +layer.uuid + "-thumb.png" #if on lipad
            os.remove(url)

        gs_layer = cat.get_layer(layer.name)
        print "GS LAYER: %s " % gs_layer.name
        gs_layer._set_default_style(fhm_style)
        cat.save(gs_layer) #save in geoserver

        ctr+=1

        gs_style = cat.get_style(layer.name)
        print "GS STYLE: %s " % gs_style.name
        print "Geoserver: Will delete style %s " % gs_style.name
        cat.delete(gs_style) #erase in geoserver the default layer_list
        gn_style = Style.objects.get(name=layer.name)
        print "Geonode: Will delete style %s " % gn_style.name
        gn_style.delete()#erase in geonode

        layer.sld_body = fhm_style.sld_body
        layer.save() #save in geonode
    except Exception as e:
        print "%s" % e
        pass
Beispiel #20
0
    def updateGs(self):
        gs = settings.GEOSERVER
        cat = Catalog(gs['host'], gs['user'], gs['password'])
        ws = cat.get_workspace(gs['workspace'])
        epsg = 'EPSG:404000'

        for kuva in self.all():
            image = kuva.jpgImage
            path = os.path.join(settings.MEDIA_ROOT, image.name)

            layerName = kuva.gsName()

            kuva.createWld()
            cs = cat.create_coveragestore2(layerName, workspace=ws)
            cs.url = 'file://' + path
            cs.type = 'WorldImage'
            cat.save(cs)

            coverage = cat.publish_coverage(layerName, cs, epsg)
            cat.addToGwc(coverage, 'kuva404000')
Beispiel #21
0
    def updateGs(self):
        gs = settings.GEOSERVER
        cat = Catalog(gs['host'], gs['user'], gs['password'])
        ws = cat.get_workspace(gs['workspace'])
        epsg = 'EPSG:404000'

        for kuva in self.all():
            image = kuva.jpgImage
            path = os.path.join(settings.MEDIA_ROOT, image.name)

            layerName = kuva.gsName()

            kuva.createWld()
            cs = cat.create_coveragestore2(layerName, workspace=ws)
            cs.url = 'file://' + path
            cs.type = 'WorldImage'
            cat.save(cs)

            coverage = cat.publish_coverage(layerName, cs, epsg)
            cat.addToGwc(coverage, 'kuva404000')
    def uploadGS(self):
        shpFile = os.path.join(self.tempFolder, 'diff_simplify')

        cat = Catalog("http://localhost:8080/geoserver/rest", username="******", password="******")
        gsWorkspace = cat.get_workspace("SJ")
        shapefileData = geoserver.util.shapefile_and_friends(shpFile)

        # TODO: 레이어명 구분이 필요
        layerName = self.resId
        # layerName = time.strftime("%Y%m%d_%H%M%S")
        cat.create_featurestore(layerName, shapefileData, gsWorkspace)

        cat.reload()

        layer = cat.get_layer(layerName)
        diffStyle = cat.get_style('SJ:diff_style')

        if diffStyle is not None:
            layer._set_default_style('SJ:diff_style')
            cat.save(layer)
Beispiel #23
0
class catalog:
    def __init__(self, path):
        self.cat = Catalog(path)

    def createWkspace(self, name):
        vk = self.cat.create_workspace(name, name)
        vk.enabled = True
        return vk

    def addImage(self, name, workspace, data):
        pdb.set_trace()
        self.cat.create_coveragestore(
            name,
            "/usr/share/tomcat/webapps/geoserver/data/data/DE2_MS__L1CT___20140220T104454.tif",
            workspace)

        inf = CoverageStore(self.cat, workspace, name)

        inf.fetch()

        self.cat.save(inf)
Beispiel #24
0
def style_update(layer, style_template):
    cat = Catalog(settings.OGC_SERVER['default']['LOCATION'] + 'rest',
                  username=settings.OGC_SERVER['default']['USER'],
                  password=settings.OGC_SERVER['default']['PASSWORD'])
    try:
        layer_attrib = layer.attributes[0].attribute.encode("utf-8")
    except Exception as e:
        print "No layer attribute %s" % e
    ctr = 0

    if 'fh' in layer.name:
        style = None
        if layer_attrib == "Var":
            style = cat.get_style(style_template)
        else:
            style = cat.get_style("fhm_merge")
    else:
        style = cat.get_style(style_template)

    if style is not None:
        try:
            gs_layer = cat.get_layer(layer.name)
            print "GS LAYER: %s " % gs_layer.name
            gs_layer._set_default_style(style)
            cat.save(gs_layer)
            ctr += 1
            gs_style = cat.get_style(layer.name)
            if gs_style:
                print "GS STYLE: %s " % gs_style.name
                print "Geoserver: Will delete style %s " % gs_style.name
                cat.delete(gs_style)
                gn_style = Style.objects.get(name=layer.name)
                print "Geonode: Will delete style %s " % gn_style.name
                gn_style.delete()

            layer.sld_body = style.sld_body
            layer.save()
        except Exception as e:
            # print "%s" % e
            traceback.print_exc()
Beispiel #25
0
    def addLayersToGeoserver(self, options):
        cat = Catalog(self.geoserver_rest_url, options["geoserveradmin"], options["gpw"])

        try:
            ds = cat.get_store(options["alias"])
        except Exception as e:
            raise Exception("Erreur de récupération du workspace")

        layers = []
        try:
            # connect to tables and create layers and correct urban styles
            for table in self.urb:
                try:
                    style = self.urb[table]
                    ft = cat.publish_featuretype(table, ds, "EPSG:31370", srs="EPSG:31370")
                    gs_style = cat.get_style(style)
                    cat.save(ft)
                    res_name = ft.dirty["name"]
                    res_title = options["alias"] + "_" + table
                    cat.save(ft)
                    layer_name = ds.workspace.name + ":" + res_name
                    new_layer = cat.get_layer(layer_name)
                    new_layer.default_style = gs_style
                    cat.save(new_layer)
                    layers.append({"res_name": res_name, "res_title": res_title})
                except Exception as e:
                    # a verifier une fois un possesion des styles
                    print(str(e))

        except Exception as e:
            print(str(e))
            raise Exception("Erreur lors de la récupération des couches depuis Geoserver")

        return layers
Beispiel #26
0
    def addLayersToGeoserver(self, options):
        cat = Catalog(self.geoserver_rest_url, options['geoserveradmin'], options['gpw'])

        try:
            ds = cat.get_store(options['alias'])
        except Exception as e:
            raise Exception('Erreur de récupération du workspace')

        layers = []
        try:
            #connect to tables and create layers and correct urban styles
            for table in self.urb:
                try:
                    style = self.urb[table]
                    ft = cat.publish_featuretype(table, ds, 'EPSG:31370', srs='EPSG:31370')
                    gs_style = cat.get_style(style)
                    cat.save(ft)
                    res_name = ft.dirty['name']
                    res_title = options['alias']+"_"+table
                    cat.save(ft)
                    layer_name = ds.workspace.name + ':' + res_name
                    new_layer = cat.get_layer(layer_name)
                    new_layer.default_style = gs_style
                    cat.save(new_layer)
                    layers.append({ 'res_name' : res_name, 'res_title' : res_title })
                except Exception as e:
                    # a verifier une fois un possesion des styles
                    print(str(e))

        except Exception as e:
            print(str(e))
            raise Exception('Erreur lors de la récupération des couches depuis Geoserver')

        return layers
Beispiel #27
0
 def save_mask():
     try:
         ct=CoordTransform(SpatialReference('WGS84'), SpatialReference('4527'))
         label_path=os.path.join(uploadfiles[0],'labelRPC.tif')
         dataset = gdal.Open(label_path)
         GeoTransform = dataset.GetGeoTransform()
         if dataset == None:
             return
         im_width = dataset.RasterXSize  # 栅格矩阵的列数
         im_height = dataset.RasterYSize  # 栅格矩阵的行数
         cood_trans=lambda L,C:(GeoTransform[0] + C * GeoTransform[1] + L * GeoTransform[2],GeoTransform[3] + C * GeoTransform[4] + L * GeoTransform[5])
         map_polygon=Polygon(LinearRing(cood_trans(0,0),cood_trans(0,im_width),cood_trans(im_height,im_width),cood_trans(im_height,0),cood_trans(0,0)))
         Bmap.objects.filter(id=id).update(polygon=map_polygon)
         im_data = dataset.ReadAsArray(0, 0, im_width, im_height)  # 获取数据
         dataset = None
         types = np.unique(im_data)
         for label_type in types:
             # if label_type in (0,):
             #     continue
             mp = fit_by_contours((im_data == label_type).astype(np.uint8), GeoTransform)
             m = Mask(map=Bmap.objects.get(id=id),type_id=int(label_type), mask=mp,area=round(mp.transform(ct,clone=True).area/1000000,2))
             m.save()
             # img[im_data == label_type]=127
             # cv2.imwrite(str(label_type)+".jpg",img)
             if label_type!=0:
                 payload = "<featureType><name>" + str(id) + '_' + str(m.type_id) + "</name><nativeName>myweb_mask</nativeName>"" \
                 ""<cqlFilter>type_id=" + str(m.type_id) + " and map_id=" + str(id) + "</cqlFilter></featureType>"
                 headers = {'Content-type': 'text/xml'}
                 resp = requests.post(mask_url, auth=('admin', 'geoserver'), data=payload, headers=headers)
                 if resp.status_code != 201:
                     raise Exception('Upload to geoserver error')
                 else:
                     cat = Catalog(map_url, 'admin', 'geoserver')
                     layer = cat.get_layer('Mask:'+str(id)+'_'+str(m.type_id))
                     layer.default_style=cat.get_style(str(label_type), 'Mask')
                     cat.save(layer)
                     cat.reload()
         return "上传成功"
     except Exception as e:
         return Exception("上传失败,拟合图斑出错:"+str(e))
Beispiel #28
0
def connect_database(database_name):

    #connect catalog
    cat = Catalog(GEOSERVER_URL + '/rest')

    #create workspace
    ws = cat.create_workspace(LAB_NAME, LAB_URI)

    #create datastore
    ds = cat.create_datastore(LAB_NAME + '_Datastore', LAB_NAME)

    #connect database
    ds.connection_parameters.update(host=POSTGRES_URL,
                                    port=POSTGRES_PORT,
                                    database=database_name,
                                    user=POSTGRES_USER,
                                    passwd=POSTGRES_PW,
                                    dbtype='postgis',
                                    schema='public')

    #save
    cat.save(ds)
Beispiel #29
0
    def createDataStore(self, options):
        try:
            cat = Catalog(self.geoserver_rest_url, options['geoserveradmin'], options['gpw'])
            #create datastore for URB schema
            ws = cat.create_workspace(options['alias'],options['uri'])

            try:
                ds = cat.create_datastore(options['alias'], ws)
                ds.connection_parameters.update(
                    host=options['dbadr'],
                    port=options['dbport'],
                    database=options['database'],
                    user=options['postuser'],
                    passwd=options['ropw'],
                    dbtype="postgis")
                cat.save(ds)
            except Exception as e:
                print(str(e))
                raise Exception('Erreur de connexion au Geoserver lors de la création du DataStore')
        except Exception as e:
            raise Exception(str(e))
        return ws.name , ds.name, ds.resource_type
def styles2sde_using_gsconfig():
    """ Migrate the layers styles from postgis to sde using gsconfig.
    """
    #geoserver_url = settings.GEOSERVER_URL # http://localhost:8080/geoserver/
    geoserver_url = 'http://geonode.wfp.org/geoserver/'
    user = settings.OGC_SERVER['default']['USER']
    pwd = settings.OGC_SERVER['default']['PASSWORD']
    cat = Catalog("%srest" % geoserver_url, "admin", "zeeD4ies")
    for l in layers_to_process:
        print 'Processing layer %s' % l
        layer_old = cat.get_layer('%s_old' % l)
        layer = cat.get_layer(l)
        #import ipdb;ipdb.set_trace()
        print 'Copying stuff from %s to %s...' % (layer_old.name, layer.name)
        print 'Default style: %s' % layer_old.default_style
        # change default style
        layer.default_style = layer_old.default_style
        # associate styles
        layer.styles = layer_old.styles
        cat.save(layer)
        cat.reload()
        print 'You need to run updatelayers now!'
    def update_geonode(self, layer_name, title="", bounds=None):
        """
        Update a layer and it's title in GeoNode
        :param layer_name: Name of the layer
        :param title: New title for layer
        """
        # Update the layer in GeoNode
        ulc = UpdateLayersCommand()
        ulc.handle(verbosity=1, filter=layer_name)

        if title:
            from geonode.layers.models import Layer
            lyr = Layer.objects.get(typename='geonode:{}'.format(layer_name))
            lyr.title = title
            lyr.save()
            if bounds:
                from geonode.layers.models import Layer
                res = lyr.gs_resource
                res.native_bbox = bounds
                _user, _password = ogc_server_settings.credentials
                url = ogc_server_settings.rest
                gs_catalog = Catalog(url, _user, _password)
                gs_catalog.save(res)
Beispiel #32
0
    def publish_layer_group(self):
        """
        Publishes local map layers as WMS layer group on local OWS.
        """
        # temporary permission workaround:
        # only allow public maps to be published
        if not self.is_public:
            return 'Only public maps can be saved as layer group.'

        map_layers = MapLayer.objects.filter(map=self.id)

        # Local Group Layer layers and corresponding styles
        layers = []
        lg_styles = []
        for ml in map_layers:
            if ml.local:
                layer = Layer.objects.get(typename=ml.name)
                style = ml.styles or getattr(layer.default_style, 'name', '')
                layers.append(layer)
                lg_styles.append(style)
        lg_layers = [l.name for l in layers]

        # Group layer bounds and name
        lg_bounds = [str(coord) for coord in self.bbox]
        lg_name = '%s_%d' % (slugify(self.title), self.id)

        # Update existing or add new group layer
        cat = Catalog(ogc_server_settings.rest, _user, _password)
        lg = self.layer_group
        if lg is None:
            lg = GsUnsavedLayerGroup(cat, lg_name, lg_layers, lg_styles,
                                     lg_bounds)
        else:
            lg.layers, lg.styles, lg.bounds = lg_layers, lg_styles, lg_bounds
        cat.save(lg)
        return lg_name
Beispiel #33
0
class CatalogTests(unittest.TestCase):
    def setUp(self):
        self.cat = Catalog(GSPARAMS['GSURL'], username=GSPARAMS['GSUSER'], password=GSPARAMS['GSPASSWORD'])

    def testAbout(self):
        about_html = self.cat.about()
        self.assertTrue('<html xmlns="http://www.w3.org/1999/xhtml"' in about_html)

    def testGSVersion(self):
        version = self.cat.gsversion()
        pat = re.compile('\d\.\d(\.[\dx]|-SNAPSHOT)')
        self.assertTrue(pat.match('2.2.x'))
        self.assertTrue(pat.match('2.3.2'))
        self.assertTrue(pat.match('2.3-SNAPSHOT'))
        self.assertFalse(pat.match('2.3.y'))
        self.assertFalse(pat.match('233'))
        self.assertTrue(pat.match(version))

    def testWorkspaces(self):
        self.assertEqual(7, len(self.cat.get_workspaces()))
        # marking out test since geoserver default workspace is not consistent
        # self.assertEqual("cite", self.cat.get_default_workspace().name)
        self.assertEqual("topp", self.cat.get_workspace("topp").name)


    def testStores(self):
        topp = self.cat.get_workspace("topp")
        sf = self.cat.get_workspace("sf")
        self.assertEqual(9, len(self.cat.get_stores()))
        self.assertEqual(2, len(self.cat.get_stores(topp)))
        self.assertEqual(2, len(self.cat.get_stores(sf)))
        self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile", topp).name)
        self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile").name)
        self.assertEqual("states_shapefile", self.cat.get_store("states_shapefile").name)
        self.assertEqual("sfdem", self.cat.get_store("sfdem", sf).name)
        self.assertEqual("sfdem", self.cat.get_store("sfdem").name)


    def testResources(self):
        topp = self.cat.get_workspace("topp")
        sf = self.cat.get_workspace("sf")
        states = self.cat.get_store("states_shapefile", topp)
        sfdem = self.cat.get_store("sfdem", sf)
        self.assertEqual(19, len(self.cat.get_resources()))
        self.assertEqual(1, len(self.cat.get_resources(states)))
        self.assertEqual(5, len(self.cat.get_resources(workspace=topp)))
        self.assertEqual(1, len(self.cat.get_resources(sfdem)))
        self.assertEqual(6, len(self.cat.get_resources(workspace=sf)))

        self.assertEqual("states", self.cat.get_resource("states", states).name)
        self.assertEqual("states", self.cat.get_resource("states", workspace=topp).name)
        self.assertEqual("states", self.cat.get_resource("states").name)
        states = self.cat.get_resource("states")

        fields = [
            states.title,
            states.abstract,
            states.native_bbox,
            states.latlon_bbox,
            states.projection,
            states.projection_policy
        ]

        self.assertFalse(None in fields, str(fields))
        self.assertFalse(len(states.keywords) == 0)
        self.assertFalse(len(states.attributes) == 0)
        self.assertTrue(states.enabled)

        self.assertEqual("sfdem", self.cat.get_resource("sfdem", sfdem).name)
        self.assertEqual("sfdem", self.cat.get_resource("sfdem", workspace=sf).name)
        self.assertEqual("sfdem", self.cat.get_resource("sfdem").name)

    def testResourcesUpdate(self):
        res_dest = self.cat.get_resources()
        count = 0

        for rd in res_dest:
            # only wms layers
            if rd.resource_type != "wmsLayer": continue
            # looking for same name
            ro = self.cat.get_resource(rd.name)

            if ro is not None:
                rd.title  = ro.title
                rd.abstract  = ro.abstract
                rd.keywords  = ro.keywords
                rd.projection  = ro.projection
                rd.native_bbox  = ro.native_bbox
                rd.latlon_bbox  = ro.latlon_bbox
                rd.projection_policy  = ro.projection_policy
                rd.enabled  = ro.enabled
                rd.advertised  = ro.advertised
                rd.metadata_links = ro.metadata_links or None

                self.cat.save(rd)
                self.cat.reload()

                # print "Updated layer: " + rd.name
                count += 1

        # print "Total updated layers: " + str(count)

    def testLayers(self):
        expected = set(["Arc_Sample", "Pk50095", "Img_Sample", "mosaic", "sfdem",
            "bugsites", "restricted", "streams", "archsites", "roads",
            "tasmania_roads", "tasmania_water_bodies", "tasmania_state_boundaries",
            "tasmania_cities", "states", "poly_landmarks", "tiger_roads", "poi",
            "giant_polygon"
        ])
        actual = set(l.name for l in self.cat.get_layers())
        missing = expected - actual
        extras = actual - expected
        message = "Actual layer list did not match expected! (Extras: %s) (Missing: %s)" % (extras, missing)
        self.assert_(len(expected ^ actual) == 0, message)

        states = self.cat.get_layer("states")

        self.assert_("states", states.name)
        self.assert_(isinstance(states.resource, ResourceInfo))
        self.assertEqual(set(s.name for s in states.styles), set(['pophatch', 'polygon']))
        self.assertEqual(states.default_style.name, "population")

    def testLayerGroups(self):
        expected = set(["tasmania", "tiger-ny", "spearfish"])
        actual = set(l.name for l in self.cat.get_layergroups())
        missing = expected - actual
        extras = actual - expected
        message = "Actual layergroup list did not match expected! (Extras: %s) (Missing: %s)" % (extras, missing)
        self.assert_(len(expected ^ actual) == 0, message)

        tas = self.cat.get_layergroup("tasmania")

        self.assert_("tasmania", tas.name)
        self.assert_(isinstance(tas, LayerGroup))
        self.assertEqual(tas.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities'], tas.layers)
        self.assertEqual(tas.styles, [None, None, None, None], tas.styles)

        # Try to create a new Layer Group into the "topp" workspace
        self.assert_(self.cat.get_workspace("topp") is not None)
        tas2 = self.cat.create_layergroup("tasmania_reloaded", tas.layers, workspace = "topp")
        self.cat.save(tas2)
        self.assert_(self.cat.get_layergroup("tasmania_reloaded") is None)
        self.assert_(self.cat.get_layergroup("tasmania_reloaded", "topp") is not None)
        tas2 = self.cat.get_layergroup("tasmania_reloaded", "topp")
        self.assert_("tasmania_reloaded", tas2.name)
        self.assert_(isinstance(tas2, LayerGroup))
        self.assertEqual(tas2.workspace, "topp", tas2.workspace)
        self.assertEqual(tas2.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities'], tas2.layers)
        self.assertEqual(tas2.styles, [None, None, None, None], tas2.styles)

    def testStyles(self):
        self.assertEqual("population", self.cat.get_style("population").name)
        self.assertEqual("popshade.sld", self.cat.get_style("population").filename)
        self.assertEqual("population", self.cat.get_style("population").sld_name)
        self.assert_(self.cat.get_style('non-existing-style') is None)

    def testEscaping(self):
        # GSConfig is inconsistent about using exceptions vs. returning None
        # when a resource isn't found.
        # But the basic idea is that none of them should throw HTTP errors from
        # misconstructed URLS
        self.cat.get_style("best style ever")
        self.cat.get_workspace("best workspace ever")
        try:
            self.cat.get_store(workspace="best workspace ever",
                name="best store ever")
            self.fail('expected exception')
        except FailedRequestError, fre:
            self.assertEqual('No store found named: best store ever', fre.message)
        try:
            self.cat.get_resource(workspace="best workspace ever",
                store="best store ever",
                name="best resource ever")
        except FailedRequestError, fre:
            self.assertEqual('No store found named: best store ever', fre.message)
Beispiel #34
0
class ModifyingTests(unittest.TestCase):

    def setUp(self):
        self.cat = Catalog(GSPARAMS['GSURL'], username=GSPARAMS['GSUSER'], password=GSPARAMS['GSPASSWORD'])

    def testFeatureTypeSave(self):
        # test saving round trip
        rs = self.cat.get_resource("bugsites")
        old_abstract = rs.abstract
        new_abstract = "Not the original abstract"
        enabled = rs.enabled

        # Change abstract on server
        rs.abstract = new_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(new_abstract, rs.abstract)
        self.assertEqual(enabled, rs.enabled)

        # Change keywords on server
        rs.keywords = ["bugsites", "gsconfig"]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(["bugsites", "gsconfig"], rs.keywords)
        self.assertEqual(enabled, rs.enabled)

        # Change metadata links on server
        rs.metadata_links = [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(
                        [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")],
                        rs.metadata_links)
        self.assertEqual(enabled, rs.enabled)


        # Restore abstract
        rs.abstract = old_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(old_abstract, rs.abstract)

    def testDataStoreCreate(self):
        ds = self.cat.create_datastore("vector_gsconfig")
        ds.connection_parameters.update(**DBPARAMS)
        self.cat.save(ds)

    def testPublishFeatureType(self):
        # Use the other test and store creation to load vector data into a database
        # @todo maybe load directly to database?
        try:
            self.testDataStoreCreateAndThenAlsoImportData()
        except FailedRequestError:
            pass
        try:
            lyr = self.cat.get_layer('import')
            # Delete the existing layer and resource to allow republishing.
            self.cat.delete(lyr)
            self.cat.delete(lyr.resource)
            ds = self.cat.get_store("gsconfig_import_test")
            # make sure it's gone
            self.assert_(self.cat.get_layer('import') is None)
            self.cat.publish_featuretype("import", ds, native_crs="EPSG:4326")
            # and now it's not
            self.assert_(self.cat.get_layer('import') is not None)
        finally:
            # tear stuff down to allow the other test to pass if we run first
            ds = self.cat.get_store("gsconfig_import_test")
            lyr = self.cat.get_layer('import')
            # Delete the existing layer and resource to allow republishing.
            try:
                if lyr:
                    self.cat.delete(lyr)
                    self.cat.delete(lyr.resource)
                if ds:
                    self.cat.delete(ds)
            except:
                pass

    def testDataStoreModify(self):
        ds = self.cat.get_store("sf")
        self.assertFalse("foo" in ds.connection_parameters)
        ds.connection_parameters = ds.connection_parameters
        ds.connection_parameters["foo"] = "bar"
        orig_ws = ds.workspace.name
        self.cat.save(ds)
        ds = self.cat.get_store("sf")
        self.assertTrue("foo" in ds.connection_parameters)
        self.assertEqual("bar", ds.connection_parameters["foo"])
        self.assertEqual(orig_ws, ds.workspace.name)

    @drop_table('import')
    def testDataStoreCreateAndThenAlsoImportData(self):
        ds = self.cat.create_datastore("gsconfig_import_test")
        ds.connection_parameters.update(**DBPARAMS)
        self.cat.save(ds)
        ds = self.cat.get_store("gsconfig_import_test")
        self.cat.add_data_to_store(ds, "import", {
            'shp': 'test/data/states.shp',
            'shx': 'test/data/states.shx',
            'dbf': 'test/data/states.dbf',
            'prj': 'test/data/states.prj'
        })

    @drop_table('import2')
    def testVirtualTables(self):
        ds = self.cat.create_datastore("gsconfig_import_test2")
        ds.connection_parameters.update(**DBPARAMS)
        self.cat.save(ds)
        ds = self.cat.get_store("gsconfig_import_test2")
        self.cat.add_data_to_store(ds, "import2", {
            'shp': 'test/data/states.shp',
            'shx': 'test/data/states.shx',
            'dbf': 'test/data/states.dbf',
            'prj': 'test/data/states.prj'
        })
        store = self.cat.get_store("gsconfig_import_test2")
        geom = JDBCVirtualTableGeometry('the_geom','MultiPolygon','4326')
        ft_name = 'my_jdbc_vt_test'
        epsg_code = 'EPSG:4326'
        sql = "select * from import2 where 'STATE_NAME' = 'Illinois'"
        keyColumn = None
        parameters = None

        jdbc_vt = JDBCVirtualTable(ft_name, sql, 'false', geom, keyColumn, parameters)
        ft = self.cat.publish_featuretype(ft_name, store, epsg_code, jdbc_virtual_table=jdbc_vt)

    # DISABLED; this test works only in the very particular case
    # "mytiff.tiff" is already present into the GEOSERVER_DATA_DIR
    # def testCoverageStoreCreate(self):
    #     ds = self.cat.create_coveragestore2("coverage_gsconfig")
    #     ds.data_url = "file:test/data/mytiff.tiff"
    #     self.cat.save(ds)

    def testCoverageStoreModify(self):
        cs = self.cat.get_store("sfdem")
        self.assertEqual("GeoTIFF", cs.type)
        cs.type = "WorldImage"
        self.cat.save(cs)
        cs = self.cat.get_store("sfdem")
        self.assertEqual("WorldImage", cs.type)

        # not sure about order of test runs here, but it might cause problems
        # for other tests if this layer is misconfigured
        cs.type = "GeoTIFF"
        self.cat.save(cs)

    def testCoverageSave(self):
        # test saving round trip
        rs = self.cat.get_resource("Arc_Sample")
        old_abstract = rs.abstract
        new_abstract = "Not the original abstract"

        # # Change abstract on server
        rs.abstract = new_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(new_abstract, rs.abstract)

        # Restore abstract
        rs.abstract = old_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(old_abstract, rs.abstract)

        # Change metadata links on server
        rs.metadata_links = [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(
            [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")],
            rs.metadata_links)
        self.assertEqual(enabled, rs.enabled)

        srs_before = set(['EPSG:4326'])
        srs_after = set(['EPSG:4326', 'EPSG:3785'])
        formats = set(['ARCGRID', 'ARCGRID-GZIP', 'GEOTIFF', 'PNG', 'GIF', 'TIFF'])
        formats_after = set(["PNG", "GIF", "TIFF"])

        # set and save request_srs_list
        self.assertEquals(set(rs.request_srs_list), srs_before, str(rs.request_srs_list))
        rs.request_srs_list = rs.request_srs_list + ['EPSG:3785']
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEquals(set(rs.request_srs_list), srs_after, str(rs.request_srs_list))

        # set and save response_srs_list
        self.assertEquals(set(rs.response_srs_list), srs_before, str(rs.response_srs_list))
        rs.response_srs_list = rs.response_srs_list + ['EPSG:3785']
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEquals(set(rs.response_srs_list), srs_after, str(rs.response_srs_list))

        # set and save supported_formats
        self.assertEquals(set(rs.supported_formats), formats, str(rs.supported_formats))
        rs.supported_formats = ["PNG", "GIF", "TIFF"]
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEquals(set(rs.supported_formats), formats_after, str(rs.supported_formats))

    def testWmsStoreCreate(self):
        ws = self.cat.create_wmsstore("wmsstore_gsconfig")
        ws.capabilitiesURL = "http://suite.opengeo.org/geoserver/ows?service=wms&version=1.1.1&request=GetCapabilities"
        ws.type = "WMS"
        self.cat.save(ws)

    def testWmsLayer(self):
        self.cat.create_workspace("wmstest", "http://example.com/wmstest")
        wmstest = self.cat.get_workspace("wmstest")
        wmsstore = self.cat.create_wmsstore("wmsstore", wmstest)
        wmsstore.capabilitiesURL = "http://suite.opengeo.org/geoserver/ows?service=wms&version=1.1.1&request=GetCapabilities"
        wmsstore.type = "WMS"
        self.cat.save(wmsstore)
        wmsstore = self.cat.get_store("wmsstore")
        self.assertEqual(1, len(self.cat.get_stores(wmstest)))
        available_layers = wmsstore.get_resources(available=True)
        for layer in available_layers:
            # sanitize the layer name - validation will fail on newer geoservers
            name = layer.replace(':', '_')
            new_layer = self.cat.create_wmslayer(wmstest, wmsstore, name, nativeName=layer)
        added_layers = wmsstore.get_resources()
        self.assertEqual(len(available_layers), len(added_layers))

        changed_layer = added_layers[0]
        self.assertEqual(True, changed_layer.advertised)
        self.assertEqual(True, changed_layer.enabled)
        changed_layer.advertised = False
        changed_layer.enabled = False
        self.cat.save(changed_layer)
        self.cat._cache.clear()
        changed_layer = wmsstore.get_resources()[0]
        changed_layer.fetch()
        self.assertEqual(False, changed_layer.advertised)
        self.assertEqual(False, changed_layer.enabled)

        # Testing projection and projection policy changes
        changed_layer.projection = "EPSG:900913"
        changed_layer.projection_policy = "REPROJECT_TO_DECLARED"
        self.cat.save(changed_layer)
        self.cat._cache.clear()
        layer = self.cat.get_layer(changed_layer.name)
        self.assertEqual(layer.resource.projection_policy, changed_layer.projection_policy)
        self.assertEqual(layer.resource.projection, changed_layer.projection)

    def testFeatureTypeCreate(self):
        shapefile_plus_sidecars = shapefile_and_friends("test/data/states")
        expected = {
            'shp': 'test/data/states.shp',
            'shx': 'test/data/states.shx',
            'dbf': 'test/data/states.dbf',
            'prj': 'test/data/states.prj'
        }

        self.assertEqual(len(expected), len(shapefile_plus_sidecars))
        for k, v in expected.iteritems():
            self.assertEqual(v, shapefile_plus_sidecars[k])

        sf = self.cat.get_workspace("sf")
        self.cat.create_featurestore("states_test", shapefile_plus_sidecars, sf)

        self.assert_(self.cat.get_resource("states_test", workspace=sf) is not None)

        self.assertRaises(
            ConflictingDataError,
            lambda: self.cat.create_featurestore("states_test", shapefile_plus_sidecars, sf)
        )

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_coveragestore("states_raster_test", shapefile_plus_sidecars, sf)
        )

        bogus_shp = {
            'shp': 'test/data/Pk50095.tif',
            'shx': 'test/data/Pk50095.tif',
            'dbf': 'test/data/Pk50095.tfw',
            'prj': 'test/data/Pk50095.prj'
        }

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_featurestore("bogus_shp", bogus_shp, sf)
        )

        lyr = self.cat.get_layer("states_test")
        self.cat.delete(lyr)
        self.assert_(self.cat.get_layer("states_test") is None)


    def testCoverageCreate(self):
        tiffdata = {
            'tiff': 'test/data/Pk50095.tif',
            'tfw':  'test/data/Pk50095.tfw',
            'prj':  'test/data/Pk50095.prj'
        }

        sf = self.cat.get_workspace("sf")
        ft = self.cat.create_coveragestore("Pk50095", tiffdata, sf)

        self.assert_(self.cat.get_resource("Pk50095", workspace=sf) is not None)

        self.assertRaises(
                ConflictingDataError,
                lambda: self.cat.create_coveragestore("Pk50095", tiffdata, sf)
        )

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_featurestore("Pk50095_vector", tiffdata, sf)
        )

        bogus_tiff = {
            'tiff': 'test/data/states.shp',
            'tfw':  'test/data/states.shx',
            'prj':  'test/data/states.prj'
        }

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_coveragestore("states_raster", bogus_tiff)
        )

        ft_ext = self.cat.create_coveragestore_external_geotiff("Pk50095_ext", 'file:test/data/Pk50095.tif', sf)

    def testLayerSave(self):
        # test saving round trip
        lyr = self.cat.get_layer("states")
        old_attribution = lyr.attribution
        new_attribution = { 'title': 'Not the original attribution',
                            'width': '123',
                            'height': '321',
                            'href': 'http://www.georchestra.org',
                            'url': 'https://www.cigalsace.org/portail/cigal/documents/page/mentions-legales/Logo_geOrchestra.jpg',
                            'type': 'image/jpeg' }

        # change attribution on server
        lyr.attribution = new_attribution
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(new_attribution, lyr.attribution)

        # Restore attribution
        lyr.attribution = old_attribution
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(old_attribution, lyr.attribution)

        self.assertEqual(lyr.default_style.name, "population")

        old_default_style = lyr.default_style
        lyr.default_style = (s for s in lyr.styles if s.name == "pophatch").next()
        lyr.styles = [old_default_style]
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(lyr.default_style.name, "pophatch")
        self.assertEqual([s.name for s in lyr.styles], ["population"])


    def testStyles(self):
        # check count before tests (upload)
        count = len(self.cat.get_styles())

        # upload new style, verify existence
        self.cat.create_style("fred", open("test/fred.sld").read())
        fred = self.cat.get_style("fred")
        self.assert_(fred is not None)
        self.assertEqual("Fred", fred.sld_title)

        # replace style, verify changes
        self.cat.create_style("fred", open("test/ted.sld").read(), overwrite=True)
        fred = self.cat.get_style("fred")
        self.assert_(fred is not None)
        self.assertEqual("Ted", fred.sld_title)

        # delete style, verify non-existence
        self.cat.delete(fred, purge=True)
        self.assert_(self.cat.get_style("fred") is None)

        # attempt creating new style
        self.cat.create_style("fred", open("test/fred.sld").read())
        fred = self.cat.get_style("fred")
        self.assertEqual("Fred", fred.sld_title)

        # verify it can be found via URL and check the name
        f = self.cat.get_style_by_url(fred.href)
        self.assert_(f is not None)
        self.assertEqual(f.name, fred.name)

        # compare count after upload
        self.assertEqual(count +1, len(self.cat.get_styles()))

        # attempt creating a new style without "title"
        self.cat.create_style("notitle", open("test/notitle.sld").read())
        notitle = self.cat.get_style("notitle")
        self.assertEqual(None, notitle.sld_title)

    def testWorkspaceStyles(self):
        # upload new style, verify existence
        self.cat.create_style("jed", open("test/fred.sld").read(), workspace="topp")

        jed = self.cat.get_style("jed", workspace="blarny")
        self.assert_(jed is None)
        jed = self.cat.get_style("jed", workspace="topp")
        self.assert_(jed is not None)
        self.assertEqual("Fred", jed.sld_title)
        jed = self.cat.get_style("topp:jed")
        self.assert_(jed is not None)
        self.assertEqual("Fred", jed.sld_title)

        # replace style, verify changes
        self.cat.create_style("jed", open("test/ted.sld").read(), overwrite=True, workspace="topp")
        jed = self.cat.get_style("jed", workspace="topp")
        self.assert_(jed is not None)
        self.assertEqual("Ted", jed.sld_title)

        # delete style, verify non-existence
        self.cat.delete(jed, purge=True)
        self.assert_(self.cat.get_style("jed", workspace="topp") is None)

        # attempt creating new style
        self.cat.create_style("jed", open("test/fred.sld").read(), workspace="topp")
        jed = self.cat.get_style("jed", workspace="topp")
        self.assertEqual("Fred", jed.sld_title)

        # verify it can be found via URL and check the full name
        f = self.cat.get_style_by_url(jed.href)
        self.assert_(f is not None)
        self.assertEqual(f.fqn, jed.fqn)

    def testLayerWorkspaceStyles(self):
        # upload new style, verify existence
        self.cat.create_style("ned", open("test/fred.sld").read(), overwrite=True, workspace="topp")
        self.cat.create_style("zed", open("test/ted.sld").read(), overwrite=True, workspace="topp")
        ned = self.cat.get_style("ned", workspace="topp")
        zed = self.cat.get_style("zed", workspace="topp")
        self.assert_(ned is not None)
        self.assert_(zed is not None)

        lyr = self.cat.get_layer("states")
        lyr.default_style = ned
        lyr.styles = [zed]
        self.cat.save(lyr)
        self.assertEqual("topp:ned", lyr.default_style)
        self.assertEqual([zed], lyr.styles)

        lyr.refresh()
        self.assertEqual("topp:ned", lyr.default_style.fqn)
        self.assertEqual([zed.fqn], [s.fqn for s in lyr.styles])

    def testWorkspaceCreate(self):
        ws = self.cat.get_workspace("acme")
        self.assertEqual(None, ws)
        self.cat.create_workspace("acme", "http://example.com/acme")
        ws = self.cat.get_workspace("acme")
        self.assertEqual("acme", ws.name)

    def testWorkspaceDelete(self):
        self.cat.create_workspace("foo", "http://example.com/foo")
        ws = self.cat.get_workspace("foo")
        self.cat.delete(ws)
        ws = self.cat.get_workspace("foo")
        self.assert_(ws is None)

    def testWorkspaceDefault(self):
        # save orig
        orig = self.cat.get_default_workspace()
        neu = self.cat.create_workspace("neu", "http://example.com/neu")
        try:
            # make sure setting it works
            self.cat.set_default_workspace("neu")
            ws = self.cat.get_default_workspace()
            self.assertEqual('neu', ws.name)
        finally:
            # cleanup and reset to the way things were
            self.cat.delete(neu)
            self.cat.set_default_workspace(orig.name)
            ws = self.cat.get_default_workspace()
            self.assertEqual(orig.name, ws.name)

    def testFeatureTypeDelete(self):
        pass

    def testCoverageDelete(self):
        pass

    def testDataStoreDelete(self):
        states = self.cat.get_store('states_shapefile')
        self.assert_(states.enabled == True)
        states.enabled = False
        self.assert_(states.enabled == False)
        self.cat.save(states)

        states = self.cat.get_store('states_shapefile')
        self.assert_(states.enabled == False)

        states.enabled = True
        self.cat.save(states)

        states = self.cat.get_store('states_shapefile')
        self.assert_(states.enabled == True)

    def testLayerGroupSave(self):
        tas = self.cat.get_layergroup("tasmania")

        self.assertEqual(tas.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities'], tas.layers)
        self.assertEqual(tas.styles, [None, None, None, None], tas.styles)

        tas.layers = tas.layers[:-1]
        tas.styles = tas.styles[:-1]

        self.cat.save(tas)

        # this verifies the local state
        self.assertEqual(tas.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads'], tas.layers)
        self.assertEqual(tas.styles, [None, None, None], tas.styles)

        # force a refresh to check the remote state
        tas.refresh()
        self.assertEqual(tas.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads'], tas.layers)
        self.assertEqual(tas.styles, [None, None, None], tas.styles)

    def testImageMosaic(self):
        """
            Test case for Issue #110
        """
        # testing the mosaic creation
        name = 'cea_mosaic'
        data = open('test/data/mosaic/cea.zip', 'rb')
        self.cat.create_imagemosaic(name, data)

        # get the layer resource back
        self.cat._cache.clear()
        resource = self.cat.get_layer(name).resource

        self.assert_(resource is not None)

        # delete granule from mosaic
        coverage = name
        store = self.cat.get_store(name)
        granule_id = name + '.1'
        self.cat.mosaic_delete_granule(coverage, store, granule_id)


    def testTimeDimension(self):
        sf = self.cat.get_workspace("sf")
        files = shapefile_and_friends(os.path.join(gisdata.GOOD_DATA, "time", "boxes_with_end_date"))
        self.cat.create_featurestore("boxes_with_end_date", files, sf)

        get_resource = lambda: self.cat._cache.clear() or self.cat.get_layer('boxes_with_end_date').resource

        # configure time as LIST
        resource = get_resource()
        timeInfo = DimensionInfo("time", "true", "LIST", None, "ISO8601", None, attribute="date")
        resource.metadata = {'time':timeInfo}
        self.cat.save(resource)
        # and verify
        resource = get_resource()
        timeInfo = resource.metadata['time']
        self.assertEqual("LIST", timeInfo.presentation)
        self.assertEqual(True, timeInfo.enabled)
        self.assertEqual("date", timeInfo.attribute)
        self.assertEqual("ISO8601", timeInfo.units)

        # disable time dimension
        timeInfo = resource.metadata['time']
        timeInfo.enabled = False
        # since this is an xml property, it won't get written unless we modify it
        resource.metadata = {'time' : timeInfo}
        self.cat.save(resource)
        # and verify
        resource = get_resource()
        timeInfo = resource.metadata['time']
        self.assertEqual(False, timeInfo.enabled)

        # configure with interval, end_attribute and enable again
        timeInfo.enabled = True
        timeInfo.presentation = 'DISCRETE_INTERVAL'
        timeInfo.resolution = '3 days'
        timeInfo.end_attribute = 'enddate'
        resource.metadata = {'time' : timeInfo}
        self.cat.save(resource)
        # and verify
        resource = get_resource()
        timeInfo = resource.metadata['time']
        self.assertEqual(True, timeInfo.enabled)
        self.assertEqual('DISCRETE_INTERVAL', timeInfo.presentation)
        self.assertEqual('3 days', timeInfo.resolution_str())
        self.assertEqual('enddate', timeInfo.end_attribute)
Beispiel #35
0
class ModifyingTests(unittest.TestCase):
    def setUp(self):
        self.cat = Catalog(GSPARAMS['GSURL'],
                           username=GSPARAMS['GSUSER'],
                           password=GSPARAMS['GSPASSWORD'])

    def testFeatureTypeSave(self):
        # test saving round trip
        rs = self.cat.get_resource("bugsites")
        old_abstract = rs.abstract
        new_abstract = "Not the original abstract"
        enabled = rs.enabled

        # Change abstract on server
        rs.abstract = new_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(new_abstract, rs.abstract)
        self.assertEqual(enabled, rs.enabled)

        # Change keywords on server
        rs.keywords = ["bugsites", "gsconfig"]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(["bugsites", "gsconfig"], rs.keywords)
        self.assertEqual(enabled, rs.enabled)

        # Change metadata links on server
        rs.metadata_links = [("text/xml", "TC211",
                              "http://example.com/gsconfig.test.metadata")]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual([
            ("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")
        ], rs.metadata_links)
        self.assertEqual(enabled, rs.enabled)

        # Restore abstract
        rs.abstract = old_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(old_abstract, rs.abstract)

    def testDataStoreCreate(self):
        ds = self.cat.create_datastore("vector_gsconfig")
        ds.connection_parameters.update(**DBPARAMS)
        self.cat.save(ds)

    def testPublishFeatureType(self):
        # Use the other test and store creation to load vector data into a database
        # @todo maybe load directly to database?
        try:
            self.testDataStoreCreateAndThenAlsoImportData()
        except FailedRequestError:
            pass
        try:
            lyr = self.cat.get_layer('import')
            # Delete the existing layer and resource to allow republishing.
            self.cat.delete(lyr)
            self.cat.delete(lyr.resource)
            ds = self.cat.get_store("gsconfig_import_test")
            # make sure it's gone
            self.assertIsNone(self.cat.get_layer('import'))
            self.cat.publish_featuretype("import", ds, native_crs="EPSG:4326")
            # and now it's not
            self.assertIsNotNone(self.cat.get_layer('import'))
        finally:
            # tear stuff down to allow the other test to pass if we run first
            ds = self.cat.get_store("gsconfig_import_test")
            lyr = self.cat.get_layer('import')
            # Delete the existing layer and resource to allow republishing.
            try:
                if lyr:
                    self.cat.delete(lyr)
                    self.cat.delete(lyr.resource)
                if ds:
                    self.cat.delete(ds)
            except Exception:
                pass

    def testDataStoreModify(self):
        ds = self.cat.get_store("sf")
        self.assertFalse("foo" in ds.connection_parameters)
        ds.connection_parameters = ds.connection_parameters
        ds.connection_parameters["foo"] = "bar"
        orig_ws = ds.workspace.name
        self.cat.save(ds)
        ds = self.cat.get_store("sf")
        self.assertTrue("foo" in ds.connection_parameters)
        self.assertEqual("bar", ds.connection_parameters["foo"])
        self.assertEqual(orig_ws, ds.workspace.name)

    @drop_table('import')
    def testDataStoreCreateAndThenAlsoImportData(self):
        ds = self.cat.create_datastore("gsconfig_import_test")
        ds.connection_parameters.update(**DBPARAMS)
        self.cat.save(ds)
        ds = self.cat.get_store("gsconfig_import_test")
        self.cat.add_data_to_store(
            ds, "import", {
                'shp': 'test/data/states.shp',
                'shx': 'test/data/states.shx',
                'dbf': 'test/data/states.dbf',
                'prj': 'test/data/states.prj'
            })

    @drop_table('import2')
    def testVirtualTables(self):
        ds = self.cat.create_datastore("gsconfig_import_test2")
        ds.connection_parameters.update(**DBPARAMS)
        self.cat.save(ds)
        ds = self.cat.get_store("gsconfig_import_test2")
        self.cat.add_data_to_store(
            ds, "import2", {
                'shp': 'test/data/states.shp',
                'shx': 'test/data/states.shx',
                'dbf': 'test/data/states.dbf',
                'prj': 'test/data/states.prj'
            })
        store = self.cat.get_store("gsconfig_import_test2")
        geom = JDBCVirtualTableGeometry('the_geom', 'MultiPolygon', '4326')
        ft_name = 'my_jdbc_vt_test'
        epsg_code = 'EPSG:4326'
        sql = "select * from import2 where 'STATE_NAME' = 'Illinois'"
        keyColumn = None
        parameters = None

        jdbc_vt = JDBCVirtualTable(ft_name, sql, 'false', geom, keyColumn,
                                   parameters)
        self.cat.publish_featuretype(ft_name,
                                     store,
                                     epsg_code,
                                     jdbc_virtual_table=jdbc_vt)

    # DISABLED; this test works only in the very particular case
    # "mytiff.tiff" is already present into the GEOSERVER_DATA_DIR
    # def testCoverageStoreCreate(self):
    #     ds = self.cat.create_coveragestore2("coverage_gsconfig")
    #     ds.data_url = "file:test/data/mytiff.tiff"
    #     self.cat.save(ds)

    def testCoverageStoreModify(self):
        cs = self.cat.get_store("sfdem")
        self.assertEqual("GeoTIFF", cs.type)
        cs.type = "WorldImage"
        self.cat.save(cs)
        cs = self.cat.get_store("sfdem")
        self.assertEqual("WorldImage", cs.type)

        # not sure about order of test runs here, but it might cause problems
        # for other tests if this layer is misconfigured
        cs.type = "GeoTIFF"
        self.cat.save(cs)

    def testCoverageSave(self):
        # test saving round trip
        rs = self.cat.get_resource("Arc_Sample")
        old_abstract = rs.abstract
        new_abstract = "Not the original abstract"

        # # Change abstract on server
        rs.abstract = new_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(new_abstract, rs.abstract)

        # Restore abstract
        rs.abstract = old_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(old_abstract, rs.abstract)

        # Change metadata links on server
        rs.metadata_links = [("text/xml", "TC211",
                              "http://example.com/gsconfig.test.metadata")]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual([
            ("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")
        ], rs.metadata_links)
        self.assertEqual(enabled, rs.enabled)

        srs_before = set(['EPSG:4326'])
        srs_after = set(['EPSG:4326', 'EPSG:3785'])
        formats = set(
            ['ARCGRID', 'ARCGRID-GZIP', 'GEOTIFF', 'PNG', 'GIF', 'TIFF'])
        formats_after = set(["PNG", "GIF", "TIFF"])

        # set and save request_srs_list
        self.assertEqual(set(rs.request_srs_list), srs_before,
                         str(rs.request_srs_list))
        rs.request_srs_list = rs.request_srs_list + ['EPSG:3785']
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(set(rs.request_srs_list), srs_after,
                         str(rs.request_srs_list))

        # set and save response_srs_list
        self.assertEqual(set(rs.response_srs_list), srs_before,
                         str(rs.response_srs_list))
        rs.response_srs_list = rs.response_srs_list + ['EPSG:3785']
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(set(rs.response_srs_list), srs_after,
                         str(rs.response_srs_list))

        # set and save supported_formats
        self.assertEqual(set(rs.supported_formats), formats,
                         str(rs.supported_formats))
        rs.supported_formats = ["PNG", "GIF", "TIFF"]
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(set(rs.supported_formats), formats_after,
                         str(rs.supported_formats))

    def testWmsStoreCreate(self):
        ws = self.cat.create_wmsstore("wmsstore_gsconfig")
        ws.capabilitiesURL = "http://mesonet.agron.iastate.edu/cgi-bin/wms/iowa/rainfall.cgi?VERSION=1.1.1&REQUEST=GetCapabilities&SERVICE=WMS&"  # noqa: E501
        ws.type = "WMS"
        self.cat.save(ws)

    def testWmsLayer(self):
        self.cat.create_workspace("wmstest", "http://example.com/wmstest")
        wmstest = self.cat.get_workspace("wmstest")
        wmsstore = self.cat.create_wmsstore("wmsstore", wmstest)
        wmsstore.capabilitiesURL = "http://mesonet.agron.iastate.edu/cgi-bin/wms/iowa/rainfall.cgi?VERSION=1.1.1&REQUEST=GetCapabilities&SERVICE=WMS&"  # noqa: E501
        wmsstore.type = "WMS"
        self.cat.save(wmsstore)
        wmsstore = self.cat.get_store("wmsstore")
        self.assertEqual(1, len(self.cat.get_stores(workspace=wmstest)))
        available_layers = wmsstore.get_resources(available=True)
        for layer in available_layers:
            # sanitize the layer name - validation will fail on newer geoservers
            name = layer.replace(':', '_')
            self.cat.create_wmslayer(wmstest, wmsstore, name, nativeName=layer)
        added_layers = wmsstore.get_resources()
        self.assertEqual(len(available_layers), len(added_layers))

        changed_layer = added_layers[0]
        self.assertEqual(True, changed_layer.advertised)
        self.assertEqual(True, changed_layer.enabled)
        changed_layer.advertised = False
        changed_layer.enabled = False
        self.cat.save(changed_layer)
        self.cat._cache.clear()
        changed_layer = wmsstore.get_resources()[0]
        changed_layer.fetch()
        self.assertEqual(False, changed_layer.advertised)
        self.assertEqual(False, changed_layer.enabled)

        # Testing projection and projection policy changes
        changed_layer.projection = "EPSG:900913"
        changed_layer.projection_policy = "REPROJECT_TO_DECLARED"
        self.cat.save(changed_layer)
        self.cat._cache.clear()
        layer = self.cat.get_layer(changed_layer.name)
        self.assertEqual(layer.resource.projection_policy,
                         changed_layer.projection_policy)
        self.assertEqual(layer.resource.projection, changed_layer.projection)

    def testFeatureTypeCreate(self):
        shapefile_plus_sidecars = shapefile_and_friends("test/data/states")
        expected = {
            'shp': 'test/data/states.shp',
            'shx': 'test/data/states.shx',
            'dbf': 'test/data/states.dbf',
            'prj': 'test/data/states.prj'
        }

        self.assertEqual(len(expected), len(shapefile_plus_sidecars))
        for k, v in expected.items():
            self.assertEqual(v, shapefile_plus_sidecars[k])

        sf = self.cat.get_workspace("sf")
        self.cat.create_featurestore("states_test", shapefile_plus_sidecars,
                                     sf)

        self.assertIsNotNone(self.cat.get_resource("states_test",
                                                   workspace=sf))

        self.assertRaises(
            ConflictingDataError, lambda: self.cat.create_featurestore(
                "states_test", shapefile_plus_sidecars, sf))

        self.assertRaises(
            UploadError, lambda: self.cat.create_coveragestore(
                "states_raster_test", shapefile_plus_sidecars, sf))

        bogus_shp = {
            'shp': 'test/data/Pk50095.tif',
            'shx': 'test/data/Pk50095.tif',
            'dbf': 'test/data/Pk50095.tfw',
            'prj': 'test/data/Pk50095.prj'
        }

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_featurestore("bogus_shp", bogus_shp, sf))

        lyr = self.cat.get_layer("states_test")
        self.cat.delete(lyr)
        self.assertIsNone(self.cat.get_layer("states_test"))

    def testCoverageCreate(self):
        tiffdata = {
            'tiff': 'test/data/Pk50095.tif',
            'tfw': 'test/data/Pk50095.tfw',
            'prj': 'test/data/Pk50095.prj'
        }

        sf = self.cat.get_workspace("sf")
        self.cat.create_coveragestore("Pk50095", tiffdata, sf)

        self.assertIsNotNone(self.cat.get_resource("Pk50095", workspace=sf))

        self.assertRaises(
            ConflictingDataError,
            lambda: self.cat.create_coveragestore("Pk50095", tiffdata, sf))

        self.assertRaises(
            UploadError, lambda: self.cat.create_featurestore(
                "Pk50095_vector", tiffdata, sf))

        bogus_tiff = {
            'tiff': 'test/data/states.shp',
            'tfw': 'test/data/states.shx',
            'prj': 'test/data/states.prj'
        }

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_coveragestore("states_raster", bogus_tiff))

        self.cat.create_coveragestore_external_geotiff(
            "Pk50095_ext", 'file:test/data/Pk50095.tif', sf)

    def testLayerSave(self):
        # test saving round trip
        lyr = self.cat.get_layer("states")
        old_attribution = lyr.attribution
        new_attribution = {
            'title': 'Not the original attribution',
            'width': '123',
            'height': '321',
            'href': 'http://www.georchestra.org',
            'url':
            'https://www.cigalsace.org/portail/cigal/documents/page/mentions-legales/Logo_geOrchestra.jpg',
            'type': 'image/jpeg'
        }

        # change attribution on server
        lyr.attribution = new_attribution
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(new_attribution, lyr.attribution)

        # Restore attribution
        lyr.attribution = old_attribution
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(old_attribution, lyr.attribution)

        self.assertEqual(lyr.default_style.name, "population")

        old_default_style = lyr.default_style
        lyr.default_style = next(
            (s for s in lyr.styles if s.name == "pophatch"))
        lyr.styles = [old_default_style]
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(lyr.default_style.name, "pophatch")
        self.assertEqual([s.name for s in lyr.styles], ["population"])

    def testStyles(self):
        # check count before tests (upload)
        count = len(self.cat.get_styles())

        # upload new style, verify existence
        with open("test/fred.sld") as fred_sld:
            self.cat.create_style("fred", fred_sld.read())
        fred = self.cat.get_style("fred")
        self.assertIsNotNone(fred)
        self.assertEqual("Fred", fred.sld_title)

        # replace style, verify changes
        with open("test/ted.sld") as ted_sld:
            self.cat.create_style("fred", ted_sld.read(), overwrite=True)
        fred = self.cat.get_style("fred")
        self.assertIsNotNone(fred)
        self.assertEqual("Ted", fred.sld_title)

        # delete style, verify non-existence
        self.cat.delete(fred, purge=True)
        self.assertIsNone(self.cat.get_style("fred"))

        # attempt creating new style
        with open("test/fred.sld") as fred_sld:
            self.cat.create_style("fred", fred_sld.read())
        fred = self.cat.get_style("fred")
        self.assertEqual("Fred", fred.sld_title)

        # verify it can be found via URL and check the name
        f = self.cat.get_style_by_url(fred.href)
        self.assertIsNotNone(f)
        self.assertEqual(f.name, fred.name)

        # compare count after upload
        self.assertEqual(count + 1, len(self.cat.get_styles()))

        # attempt creating a new style without "title"
        with open("test/notitle.sld") as notitle_sld:
            self.cat.create_style("notitle", notitle_sld.read())
        notitle = self.cat.get_style("notitle")
        self.assertEqual(None, notitle.sld_title)

    def testWorkspaceStyles(self):
        # upload new style, verify existence
        with open("test/fred.sld") as fred_sld:
            self.cat.create_style("jed", fred_sld.read(), workspace="topp")

        jed = self.cat.get_style("jed", workspace="blarny")
        self.assertIsNone(jed)
        jed = self.cat.get_style("jed", workspace="topp")
        self.assertIsNotNone(jed)
        self.assertEqual("Fred", jed.sld_title)
        jed = self.cat.get_style("topp:jed")
        self.assertIsNotNone(jed)
        self.assertEqual("Fred", jed.sld_title)

        # replace style, verify changes
        with open("test/ted.sld") as ted_sld:
            self.cat.create_style("jed",
                                  ted_sld.read(),
                                  overwrite=True,
                                  workspace="topp")
        jed = self.cat.get_style("jed", workspace="topp")
        self.assertIsNotNone(jed)
        self.assertEqual("Ted", jed.sld_title)

        # delete style, verify non-existence
        self.cat.delete(jed, purge=True)
        self.assertIsNone(self.cat.get_style("jed", workspace="topp"))

        # attempt creating new style
        with open("test/fred.sld") as fred_sld:
            self.cat.create_style("jed", fred_sld.read(), workspace="topp")
        jed = self.cat.get_style("jed", workspace="topp")
        self.assertEqual("Fred", jed.sld_title)

        # verify it can be found via URL and check the full name
        f = self.cat.get_style_by_url(jed.href)
        self.assertIsNotNone(f)
        self.assertEqual(f.fqn, jed.fqn)

    def testLayerWorkspaceStyles(self):
        # upload new style, verify existence
        with open("test/fred.sld") as fred_sld:
            self.cat.create_style("ned",
                                  fred_sld.read(),
                                  overwrite=True,
                                  workspace="topp")
        with open("test/fred.sld") as ted_sld:
            self.cat.create_style("zed",
                                  ted_sld.read(),
                                  overwrite=True,
                                  workspace="topp")
        ned = self.cat.get_style("ned", workspace="topp")
        zed = self.cat.get_style("zed", workspace="topp")
        self.assertIsNotNone(ned)
        self.assertIsNotNone(zed)

        lyr = self.cat.get_layer("states")
        lyr.default_style = ned
        lyr.styles = [zed]
        self.cat.save(lyr)
        self.assertEqual("topp:ned", lyr.default_style)
        self.assertEqual([zed], lyr.styles)

        lyr.refresh()
        if lyr.default_style is not None:
            self.assertEqual("topp:ned", lyr.default_style.fqn)
            self.assertEqual([zed.fqn], [s.fqn for s in lyr.styles])

    def testWorkspaceCreate(self):
        ws = self.cat.get_workspace("acme")
        self.assertEqual(None, ws)
        self.cat.create_workspace("acme", "http://example.com/acme")
        ws = self.cat.get_workspace("acme")
        self.assertEqual("acme", ws.name)

    def testWorkspaceDelete(self):
        self.cat.create_workspace("foo", "http://example.com/foo")
        ws = self.cat.get_workspace("foo")
        self.cat.delete(ws)
        ws = self.cat.get_workspace("foo")
        self.assertIsNone(ws)

    def testWorkspaceDefault(self):
        # save orig
        orig = self.cat.get_default_workspace()
        neu = self.cat.create_workspace("neu", "http://example.com/neu")
        try:
            # make sure setting it works
            self.cat.set_default_workspace("neu")
            ws = self.cat.get_default_workspace()
            self.assertEqual('neu', ws.name)
        finally:
            # cleanup and reset to the way things were
            self.cat.delete(neu)
            self.cat.set_default_workspace(orig.name)
            ws = self.cat.get_default_workspace()
            self.assertEqual(orig.name, ws.name)

    def testFeatureTypeDelete(self):
        pass

    def testCoverageDelete(self):
        pass

    def testDataStoreDelete(self):
        states = self.cat.get_store('states_shapefile')
        self.assertTrue(states.enabled)
        states.enabled = False
        self.assertFalse(states.enabled)
        self.cat.save(states)

        states = self.cat.get_store('states_shapefile')
        self.assertFalse(states.enabled)

        states.enabled = True
        self.cat.save(states)

        states = self.cat.get_store('states_shapefile')
        self.assertTrue(states.enabled)

    def testLayerGroupSave(self):
        tas = self.cat.get_layergroup("tasmania")

        self.assertEqual(tas.layers, [
            'tasmania_state_boundaries', 'tasmania_water_bodies',
            'tasmania_roads', 'tasmania_cities'
        ], tas.layers)
        self.assertEqual(tas.styles, [None, None, None, None], tas.styles)

        tas.layers = tas.layers[:-1]
        tas.styles = tas.styles[:-1]

        self.cat.save(tas)

        # this verifies the local state
        self.assertEqual(tas.layers, [
            'tasmania_state_boundaries', 'tasmania_water_bodies',
            'tasmania_roads'
        ], tas.layers)
        self.assertEqual(tas.styles, [None, None, None], tas.styles)

        # force a refresh to check the remote state
        tas.refresh()
        self.assertEqual(tas.layers, [
            'tasmania_state_boundaries', 'tasmania_water_bodies',
            'tasmania_roads'
        ], tas.layers)
        self.assertEqual(tas.styles, [None, None, None], tas.styles)

    def testImageMosaic(self):
        """
            Test case for Issue #110
        """
        # testing the mosaic creation
        name = 'cea_mosaic'
        with open('test/data/mosaic/cea.zip', 'rb') as data:
            self.cat.create_imagemosaic(name, data)

        # get the layer resource back
        self.cat._cache.clear()
        resource = self.cat.get_layer(name).resource

        self.assertIsNotNone(resource)

        # delete granule from mosaic
        coverage = name
        store = self.cat.get_store(name)
        granules = self.cat.list_granules(coverage, store)
        self.assertEqual(1, len(granules['features']))
        granule_id = name + '.1'
        self.cat.mosaic_delete_granule(coverage, store, granule_id)
        granules = self.cat.list_granules(coverage, store)
        self.assertEqual(0, len(granules['features']))
        """
          testing external Image mosaic creation
        """
        name = 'cea_mosaic_external'
        path = 'test/data/mosaic/external'
        self.cat.create_imagemosaic(name, path, workspace='topp')
        self.cat._cache.clear()
        resource = self.cat.get_layer("external").resource
        self.assertIsNotNone(resource)

        # add granule to mosaic
        granule_path = 'test/data/mosaic/granules/cea_20150102.tif'
        self.cat.add_granule(granule_path, name, workspace='topp')
        granules = self.cat.list_granules("external", name, 'topp')
        self.assertEqual(2, len(granules['features']))

        # add external granule to mosaic
        granule_path = os.path.join(
            os.getcwd(), 'test/data/mosaic/granules/cea_20150103.zip')
        self.cat.add_granule(granule_path, name, workspace='topp')
        granules = self.cat.list_granules("external", name, 'topp')
        self.assertEqual(3, len(granules['features']))

        # Delete store
        store = self.cat.get_store(name)
        self.cat.delete(store, purge=True, recurse=True)
        self.cat._cache.clear()

    def testTimeDimension(self):
        sf = self.cat.get_workspace("sf")
        files = shapefile_and_friends(
            os.path.join(gisdata.GOOD_DATA, "time", "boxes_with_end_date"))
        self.cat.create_featurestore("boxes_with_end_date", files, sf)

        get_resource = lambda: self.cat._cache.clear() or self.cat.get_layer(
            'boxes_with_end_date').resource  # noqa: E501

        # configure time as LIST
        resource = get_resource()
        timeInfo = DimensionInfo("time",
                                 "true",
                                 "LIST",
                                 None,
                                 "ISO8601",
                                 None,
                                 attribute="date")
        resource.metadata = {'time': timeInfo}
        self.cat.save(resource)
        # and verify
        resource = get_resource()
        timeInfo = resource.metadata['time']
        self.assertEqual("LIST", timeInfo.presentation)
        self.assertEqual(True, timeInfo.enabled)
        self.assertEqual("date", timeInfo.attribute)
        self.assertEqual("ISO8601", timeInfo.units)

        # disable time dimension
        timeInfo = resource.metadata['time']
        timeInfo.enabled = False
        # since this is an xml property, it won't get written unless we modify it
        resource.metadata = {'time': timeInfo}
        self.cat.save(resource)
        # and verify
        resource = get_resource()
        timeInfo = resource.metadata['time']
        self.assertEqual(False, timeInfo.enabled)

        # configure with interval, end_attribute and enable again
        timeInfo.enabled = True
        timeInfo.presentation = 'DISCRETE_INTERVAL'
        timeInfo.resolution = '3 days'
        timeInfo.end_attribute = 'enddate'
        resource.metadata = {'time': timeInfo}
        self.cat.save(resource)
        # and verify
        resource = get_resource()
        timeInfo = resource.metadata['time']
        self.assertEqual(True, timeInfo.enabled)
        self.assertEqual('DISCRETE_INTERVAL', timeInfo.presentation)
        self.assertEqual('3 days', timeInfo.resolution_str())
        self.assertEqual('enddate', timeInfo.end_attribute)
def publishGeoserver(appdef, progress):
	viewCrs = appdef["Settings"]["App view CRS"]
	usesGeoServer = False
	for applayer in appdef["Layers"]:
		if applayer.method != METHOD_FILE:
			if applayer.layer.type() == applayer.layer.VectorLayer and applayer.layer.providerType().lower() != "wfs":
				usesGeoServer = True
	if not usesGeoServer:
		return
	progress.setText("Publishing to GeoServer")
	progress.setProgress(0)
	geoserverUrl = appdef["Deploy"]["GeoServer url"] + "/rest"
	geoserverPassword = appdef["Deploy"]["GeoServer password"]
	geoserverUsername = appdef["Deploy"]["GeoServer username"]
	workspaceName = appdef["Deploy"]["GeoServer workspace"]
	dsName = "ds_" + workspaceName
	host = appdef["Deploy"]["PostGIS host"]
	port = appdef["Deploy"]["PostGIS port"]
	postgisUsername = appdef["Deploy"]["PostGIS username"]
	postgisPassword = appdef["Deploy"]["PostGIS password"]
	database = appdef["Deploy"]["PostGIS database"]
	schema = appdef["Deploy"]["PostGIS schema"]
	catalog = Catalog(geoserverUrl, geoserverUsername, geoserverPassword)
	workspace = catalog.get_workspace(workspaceName)
	if workspace is None:
		workspace = catalog.create_workspace(workspaceName, workspaceName)
	try:
		store = catalog.get_store(dsName, workspace)
		resources = store.get_resources()
		for resource in resources:
			layers = catalog.get_layers(resource)
			for layer in layers:
				catalog.delete(layer)
			catalog.delete(resource)
		catalog.delete(store)
	except Exception:
		pass
	try:
		store = catalog.get_store(dsName, workspace)
	except FailedRequestError:
		store = None
	for i, applayer in enumerate(appdef["Layers"]):
		layer = applayer.layer
		if applayer.method != METHOD_FILE and applayer.method != METHOD_DIRECT:
			name = safeName(layer.name())
			sld, icons = getGsCompatibleSld(layer)
			if sld is not None:
				catalog.create_style(name, sld, True)
				uploadIcons(icons, geoserverUsername, geoserverPassword, catalog.gs_base_url)
			if layer.type() == layer.VectorLayer:
				if applayer.method == METHOD_WFS_POSTGIS or applayer.method == METHOD_WMS_POSTGIS:
					if store is None:
						store = catalog.create_datastore(dsName, workspace)
						store.connection_parameters.update(
							host=host, port=str(port), database=database, user=postgisUsername, schema=schema,
							passwd=postgisPassword, dbtype="postgis")
						catalog.save(store)
					catalog.publish_featuretype(name, store, layer.crs().authid())
				else:
					path = getDataFromLayer(layer, viewCrs)
					catalog.create_featurestore(name,
													path,
													workspace=workspace,
													overwrite=True)
				gslayer = catalog.get_layer(name)
				r = gslayer.resource
				r.dirty['srs'] = viewCrs
				catalog.save(r)
			elif layer.type() == layer.RasterLayer:
				path = getDataFromLayer(layer, viewCrs)
				catalog.create_coveragestore(name,
				                          path,
				                          workspace=workspace,
				                          overwrite=True)
			if sld is not None:
				publishing = catalog.get_layer(name)
				publishing.default_style = catalog.get_style(name)
				catalog.save(publishing)
		progress.setProgress(int((i+1)*100.0/len(appdef["Layers"])))
Beispiel #37
0
def _register_cascaded_layers(service, owner=None):
    """
    Register layers for a cascading WMS
    """
    if service.type == "WMS" or service.type == "OWS":
        cat = Catalog(settings.OGC_SERVER["default"]["LOCATION"] + "rest", _user, _password)
        # Can we always assume that it is geonode?
        # Should cascading layers have a separate workspace?
        cascade_ws = cat.get_workspace(service.name)
        if cascade_ws is None:
            cascade_ws = cat.create_workspace(service.name, "cascade")
        try:
            store = cat.get_store(service.name, cascade_ws)
        except Exception:
            store = cat.create_wmsstore(service.name, cascade_ws)
            cat.save(store)
        wms = WebMapService(service.base_url)
        layers = list(wms.contents)
        count = 0
        for layer in layers:
            lyr = cat.get_resource(layer, store, cascade_ws)
            if lyr is None:
                if service.type in ["WMS", "OWS"]:
                    resource = cat.create_wmslayer(cascade_ws, store, layer)
                elif service.type == "WFS":
                    resource = cat.create_wfslayer(cascade_ws, store, layer)

                if resource:
                    bbox = resource.latlon_bbox
                    cascaded_layer, created = Layer.objects.get_or_create(
                        typename="%s:%s" % (cascade_ws.name, resource.name),
                        service=service,
                        defaults={
                            "name": resource.name,
                            "workspace": cascade_ws.name,
                            "store": store.name,
                            "storeType": store.resource_type,
                            "title": resource.title or "No title provided",
                            "abstract": resource.abstract or "No abstract provided",
                            "owner": None,
                            "uuid": str(uuid.uuid4()),
                            "bbox_x0": bbox[0],
                            "bbox_x1": bbox[1],
                            "bbox_y0": bbox[2],
                            "bbox_y1": bbox[3],
                        },
                    )

                    if created:
                        cascaded_layer.save()
                        if cascaded_layer is not None and cascaded_layer.bbox is None:
                            cascaded_layer._populate_from_gs(gs_resource=resource)
                        cascaded_layer.set_default_permissions()

                        service_layer, created = ServiceLayer.objects.get_or_create(
                            service=service, typename=cascaded_layer.name
                        )
                        service_layer.layer = cascaded_layer
                        service_layer.title = (cascaded_layer.title,)
                        service_layer.description = (cascaded_layer.abstract,)
                        service_layer.styles = cascaded_layer.styles
                        service_layer.save()

                        count += 1
                    else:
                        logger.error("Resource %s from store %s could not be saved as layer" % (layer, store.name))
        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 == "WCS":
        return HttpResponse("Not Implemented (Yet)", status=501)
    else:
        return HttpResponse("Invalid Service Type", status=400)
Beispiel #38
0
class ModifyingTests(unittest.TestCase):
    def setUp(self):
        self.cat = Catalog("http://localhost:8080/geoserver/rest")

    def testFeatureTypeSave(self):
        # test saving round trip
        rs = self.cat.get_resource("bugsites")
        old_abstract = rs.abstract
        new_abstract = "Not the original abstract"
        enabled = rs.enabled

        # Change abstract on server
        rs.abstract = new_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(new_abstract, rs.abstract)
        self.assertEqual(enabled, rs.enabled)

        # Change keywords on server
        rs.keywords = ["bugsites", "gsconfig"]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(["bugsites", "gsconfig"], rs.keywords)
        self.assertEqual(enabled, rs.enabled)
        
        # Change metadata links on server
        rs.metadata_links = [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(
                        [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")],
                        rs.metadata_links)
        self.assertEqual(enabled, rs.enabled)


        # Restore abstract
        rs.abstract = old_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(old_abstract, rs.abstract)

    def testDataStoreCreate(self):
        ds = self.cat.create_datastore("vector_gsconfig")
        ds.connection_parameters.update(**DBPARAMS)
        self.cat.save(ds)

    def testPublishFeatureType(self):
        # Use the other test and store creation to load vector data into a database
        # @todo maybe load directly to database?
        try:
            self.testDataStoreCreateAndThenAlsoImportData()
        except FailedRequestError:
            pass
        try:
            lyr = self.cat.get_layer('import')
            # Delete the existing layer and resource to allow republishing.
            self.cat.delete(lyr)
            self.cat.delete(lyr.resource)
            ds = self.cat.get_store("gsconfig_import_test")
            # make sure it's gone
            self.assert_(self.cat.get_layer('import') is None)
            self.cat.publish_featuretype("import", ds, native_crs="EPSG:4326")
            # and now it's not
            self.assert_(self.cat.get_layer('import') is not None)
        finally:
            # tear stuff down to allow the other test to pass if we run first
            ds = self.cat.get_store("gsconfig_import_test")
            lyr = self.cat.get_layer('import')
            # Delete the existing layer and resource to allow republishing.
            self.cat.delete(lyr)
            self.cat.delete(lyr.resource)
            self.cat.delete(ds)

    def testDataStoreModify(self):
        ds = self.cat.get_store("sf")
        self.assertFalse("foo" in ds.connection_parameters)
        ds.connection_parameters = ds.connection_parameters
        ds.connection_parameters["foo"] = "bar"
        orig_ws = ds.workspace.name
        self.cat.save(ds)
        ds = self.cat.get_store("sf")
        self.assertTrue("foo" in ds.connection_parameters)
        self.assertEqual("bar", ds.connection_parameters["foo"])
        self.assertEqual(orig_ws, ds.workspace.name)

    @drop_table('import')
    def testDataStoreCreateAndThenAlsoImportData(self):
        ds = self.cat.create_datastore("gsconfig_import_test")
        ds.connection_parameters.update(**DBPARAMS)
        self.cat.save(ds)
        ds = self.cat.get_store("gsconfig_import_test")
        self.cat.add_data_to_store(ds, "import", {
            'shp': 'test/data/states.shp',
            'shx': 'test/data/states.shx',
            'dbf': 'test/data/states.dbf',
            'prj': 'test/data/states.prj'
        })

    def testCoverageStoreCreate(self):
        ds = self.cat.create_coveragestore2("coverage_gsconfig")
        ds.data_url = "file:data/mytiff.tiff"
        self.cat.save(ds)

    def testCoverageStoreModify(self):
        cs = self.cat.get_store("sfdem")
        self.assertEqual("GeoTIFF", cs.type)
        cs.type = "WorldImage"
        self.cat.save(cs)
        cs = self.cat.get_store("sfdem")
        self.assertEqual("WorldImage", cs.type)

        # not sure about order of test runs here, but it might cause problems
        # for other tests if this layer is misconfigured
        cs.type = "GeoTIFF"
        self.cat.save(cs) 

    def testCoverageSave(self):
        # test saving round trip
        rs = self.cat.get_resource("Arc_Sample")
        old_abstract = rs.abstract
        new_abstract = "Not the original abstract"

        # # Change abstract on server
        rs.abstract = new_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(new_abstract, rs.abstract)

        # Restore abstract
        rs.abstract = old_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(old_abstract, rs.abstract)

        # Change metadata links on server
        rs.metadata_links = [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(
            [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")],
            rs.metadata_links)
        self.assertEqual(enabled, rs.enabled)

        srs_before = set(['EPSG:4326'])
        srs_after = set(['EPSG:4326', 'EPSG:3785'])
        formats = set(['ARCGRID', 'ARCGRID-GZIP', 'GEOTIFF', 'PNG', 'GIF', 'TIFF'])
        formats_after = set(["PNG", "GIF", "TIFF"])

        # set and save request_srs_list
        self.assertEquals(set(rs.request_srs_list), srs_before, str(rs.request_srs_list))
        rs.request_srs_list = rs.request_srs_list + ['EPSG:3785']
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEquals(set(rs.request_srs_list), srs_after, str(rs.request_srs_list))

        # set and save response_srs_list
        self.assertEquals(set(rs.response_srs_list), srs_before, str(rs.response_srs_list))
        rs.response_srs_list = rs.response_srs_list + ['EPSG:3785']
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEquals(set(rs.response_srs_list), srs_after, str(rs.response_srs_list))

        # set and save supported_formats
        self.assertEquals(set(rs.supported_formats), formats, str(rs.supported_formats))
        rs.supported_formats = ["PNG", "GIF", "TIFF"]
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEquals(set(rs.supported_formats), formats_after, str(rs.supported_formats))

    def testWmsStoreCreate(self):
        ws = self.cat.create_wmsstore("wmsstore_gsconfig")
        ws.capabilitiesURL = "http://suite.opengeo.org/geoserver/ows?service=wms&version=1.1.1&request=GetCapabilities"
        ws.type = "WMS"
        self.cat.save(ws)
     
    def testWmsLayer(self):
        self.cat.create_workspace("wmstest", "http://example.com/wmstest")
        wmstest = self.cat.get_workspace("wmstest")
        wmsstore = self.cat.create_wmsstore("wmsstore", wmstest)
        wmsstore.capabilitiesURL = "http://suite.opengeo.org/geoserver/ows?service=wms&version=1.1.1&request=GetCapabilities"
        wmsstore.type = "WMS"
        self.cat.save(wmsstore)
        wmsstore = self.cat.get_store("wmsstore")
        self.assertEqual(1, len(self.cat.get_stores(wmstest)))
        available_layers = wmsstore.get_resources(available=True)
        for layer in available_layers:
            new_layer = self.cat.create_wmslayer(wmstest, wmsstore, layer)
        added_layers = wmsstore.get_resources()
        self.assertEqual(len(available_layers), len(added_layers))

    def testFeatureTypeCreate(self):
        shapefile_plus_sidecars = shapefile_and_friends("test/data/states")
        expected = {
            'shp': 'test/data/states.shp',
            'shx': 'test/data/states.shx',
            'dbf': 'test/data/states.dbf',
            'prj': 'test/data/states.prj'
        }

        self.assertEqual(len(expected), len(shapefile_plus_sidecars))
        for k, v in expected.iteritems():
            self.assertEqual(v, shapefile_plus_sidecars[k])
 
        sf = self.cat.get_workspace("sf")
        self.cat.create_featurestore("states_test", shapefile_plus_sidecars, sf)

        self.assert_(self.cat.get_resource("states_test", workspace=sf) is not None)

        self.assertRaises(
            ConflictingDataError, 
            lambda: self.cat.create_featurestore("states_test", shapefile_plus_sidecars, sf)
        )

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_coveragestore("states_raster_test", shapefile_plus_sidecars, sf)
        )

        bogus_shp = {
            'shp': 'test/data/Pk50095.tif',
            'shx': 'test/data/Pk50095.tif',
            'dbf':    'test/data/Pk50095.tfw',
            'prj':    'test/data/Pk50095.prj'
        }

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_featurestore("bogus_shp", bogus_shp, sf)
        )

        lyr = self.cat.get_layer("states_test")
        self.cat.delete(lyr)
        self.assert_(self.cat.get_layer("states_test") is None)


    def testCoverageCreate(self):
        tiffdata = {
            'tiff': 'test/data/Pk50095.tif',
            'tfw':    'test/data/Pk50095.tfw',
            'prj':    'test/data/Pk50095.prj'
        }

        sf = self.cat.get_workspace("sf")
        # TODO: Uploading WorldImage file no longer works???
        # ft = self.cat.create_coveragestore("Pk50095", tiffdata, sf)

        # self.assert_(self.cat.get_resource("Pk50095", workspace=sf) is not None)

        # self.assertRaises(
        #         ConflictingDataError, 
        #         lambda: self.cat.create_coveragestore("Pk50095", tiffdata, sf)
        # )

        self.assertRaises(
            UploadError, 
            lambda: self.cat.create_featurestore("Pk50095_vector", tiffdata, sf)
        )

        bogus_tiff = {
            'tiff': 'test/data/states.shp',
            'tfw': 'test/data/states.shx',
            'prj': 'test/data/states.prj'
        }

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_coveragestore("states_raster", bogus_tiff)
        )

    def testLayerSave(self):
        # test saving round trip
        lyr = self.cat.get_layer("states")
        old_attribution = lyr.attribution
        new_attribution = "Not the original attribution"

        # change attribution on server
        lyr.attribution = new_attribution
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(new_attribution, lyr.attribution)

        # Restore attribution
        lyr.attribution = old_attribution
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(old_attribution, lyr.attribution)

        self.assertEqual(lyr.default_style.name, "population")
     
        old_default_style = lyr.default_style
        lyr.default_style = (s for s in lyr.styles if s.name == "pophatch").next()
        lyr.styles = [old_default_style]
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(lyr.default_style.name, "pophatch")
        self.assertEqual([s.name for s in lyr.styles], ["population"])


    def testStyles(self):
        # upload new style, verify existence
        self.cat.create_style("fred", open("test/fred.sld").read())
        fred = self.cat.get_style("fred")
        self.assert_(fred is not None)
        self.assertEqual("Fred", fred.sld_title)

        # replace style, verify changes
        self.cat.create_style("fred", open("test/ted.sld").read(), overwrite=True)
        fred = self.cat.get_style("fred")
        self.assert_(fred is not None)
        self.assertEqual("Ted", fred.sld_title)

        # delete style, verify non-existence
        self.cat.delete(fred, purge=True)
        self.assert_(self.cat.get_style("fred") is None)

        # attempt creating new style
        self.cat.create_style("fred", open("test/fred.sld").read())
        fred = self.cat.get_style("fred")
        self.assertEqual("Fred", fred.sld_title)

        # verify it can be found via URL and check the name
        f = self.cat.get_style_by_url(fred.href)
        self.assert_(f is not None)
        self.assertEqual(f.name, fred.name)

    def testWorkspaceStyles(self):
        # upload new style, verify existence
        self.cat.create_style("jed", open("test/fred.sld").read(), workspace="topp")

        jed = self.cat.get_style("jed", workspace="blarny")
        self.assert_(jed is None)
        jed = self.cat.get_style("jed", workspace="topp")
        self.assert_(jed is not None)
        self.assertEqual("Fred", jed.sld_title)
        jed = self.cat.get_style("topp:jed")
        self.assert_(jed is not None)
        self.assertEqual("Fred", jed.sld_title)

        # replace style, verify changes
        self.cat.create_style("jed", open("test/ted.sld").read(), overwrite=True, workspace="topp")
        jed = self.cat.get_style("jed", workspace="topp")
        self.assert_(jed is not None)
        self.assertEqual("Ted", jed.sld_title)

        # delete style, verify non-existence
        self.cat.delete(jed, purge=True)
        self.assert_(self.cat.get_style("jed", workspace="topp") is None)

        # attempt creating new style
        self.cat.create_style("jed", open("test/fred.sld").read(), workspace="topp")
        jed = self.cat.get_style("jed", workspace="topp")
        self.assertEqual("Fred", jed.sld_title)

        # verify it can be found via URL and check the full name
        f = self.cat.get_style_by_url(jed.href)
        self.assert_(f is not None)
        self.assertEqual(f.fqn, jed.fqn)

    def testLayerWorkspaceStyles(self):
        # upload new style, verify existence
        self.cat.create_style("ned", open("test/fred.sld").read(), overwrite=True, workspace="topp")
        self.cat.create_style("zed", open("test/ted.sld").read(), overwrite=True, workspace="topp")
        ned = self.cat.get_style("ned", workspace="topp")
        zed = self.cat.get_style("zed", workspace="topp")
        self.assert_(ned is not None)
        self.assert_(zed is not None)

        lyr = self.cat.get_layer("states")
        lyr.default_style = ned
        lyr.styles = [zed]
        self.cat.save(lyr)
        self.assertEqual("topp:ned", lyr.default_style)
        self.assertEqual([zed], lyr.styles)

        lyr.refresh()
        self.assertEqual("topp:ned", lyr.default_style.fqn)
        self.assertEqual([zed.fqn], [s.fqn for s in lyr.styles])

    def testWorkspaceCreate(self):
        ws = self.cat.get_workspace("acme")
        self.assertEqual(None, ws)
        self.cat.create_workspace("acme", "http://example.com/acme")
        ws = self.cat.get_workspace("acme")
        self.assertEqual("acme", ws.name)

    def testWorkspaceDelete(self): 
        self.cat.create_workspace("foo", "http://example.com/foo")
        ws = self.cat.get_workspace("foo")
        self.cat.delete(ws)
        ws = self.cat.get_workspace("foo")
        self.assert_(ws is None)

    def testWorkspaceDefault(self):
        # save orig
        orig = self.cat.get_default_workspace()
        neu = self.cat.create_workspace("neu", "http://example.com/neu")
        try:
            # make sure setting it works
            self.cat.set_default_workspace("neu")
            ws = self.cat.get_default_workspace()
            self.assertEqual('neu', ws.name)
        finally:
            # cleanup and reset to the way things were
            self.cat.delete(neu)
            self.cat.set_default_workspace(orig.name)
            ws = self.cat.get_default_workspace()
            self.assertEqual(orig.name, ws.name)

    def testFeatureTypeDelete(self):
        pass

    def testCoverageDelete(self):
        pass

    def testDataStoreDelete(self):
        states = self.cat.get_store('states_shapefile')
        self.assert_(states.enabled == True)
        states.enabled = False
        self.assert_(states.enabled == False)
        self.cat.save(states)

        states = self.cat.get_store('states_shapefile')
        self.assert_(states.enabled == False)

        states.enabled = True
        self.cat.save(states)

        states = self.cat.get_store('states_shapefile')
        self.assert_(states.enabled == True)

    def testLayerGroupSave(self):
        tas = self.cat.get_layergroup("tasmania")

        self.assertEqual(tas.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities'], tas.layers)
        self.assertEqual(tas.styles, [None, None, None, None], tas.styles)

        tas.layers = tas.layers[:-1]
        tas.styles = tas.styles[:-1]

        self.cat.save(tas)

        # this verifies the local state
        self.assertEqual(tas.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads'], tas.layers)
        self.assertEqual(tas.styles, [None, None, None], tas.styles)

        # force a refresh to check the remote state
        tas.refresh()
        self.assertEqual(tas.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads'], tas.layers)
        self.assertEqual(tas.styles, [None, None, None], tas.styles)
Beispiel #39
0
class Client:
    def __init__(self, geoserver, username, password):
        self.restserver = urlparse.urljoin(geoserver, 'rest/')
        self.wmsserver = urlparse.urljoin(geoserver, 'wms')
        self.username = username
        self.password = password
        self.catalog = Catalog(self.restserver, self.username, self.password)
        self.tempDir = tempfile.mkdtemp()
        self.resource = None
        self.layer = None
        self.layerName = None
        logging.basicConfig(
            format="%(asctime)-15s %(name)-10s %(levelname)-7s : %(message)s",
            level=logging.WARN)
        self.logger = logging.getLogger("gsclient")
        self.logger.setLevel(logging.DEBUG)
        # setup logging for the gsclient
        logging.getLogger('pyclowder').setLevel(logging.DEBUG)
        logging.getLogger('__main__').setLevel(logging.DEBUG)

    ## this method assume that there is 1 store per layer
    def getResourceByStoreName(self, storename, workspace):
        if self.resource != None:
            self.logger.debug("resource instance found; no need to fetch")
            return self.resource
        self.logger.debug("catalog.get_store called")
        store = self.catalog.get_store(storename, workspace)
        self.logger.debug("catalog.get_resources called based on store")
        resources = self.catalog.get_resources(store=store)
        self.logger.debug("fetched resources from server")
        if resources == None:
            return None
        else:
            self.resource = resources[0]
            return self.resource

    def getLayers(self):
        layers = self.catalog.get_layers()
        return layers

    def getLayerByStoreName(self, storename):
        self.logger.debug("getLayerbystore name started")
        layers = self.catalog.get_layers()

        for layer in layers:
            if layer.resource.store.name == storename:
                self.logger.debug("found the layer by store name")
                return layer
        return None

    def getLayerByResource(self, resource):
        if self.layer != None:
            self.logger.debug("layer instance found; no need to fetch")
            return self.layer

        self.logger.debug("get Layer by Resource started...")
        layers = self.catalog.get_layers(resource)
        self.logger.debug("fetched layers from the server")
        if layers == None:
            return None
        else:
            self.layer = layers[0]
            return self.layer

    def mintMetadataWithoutGeoserver(self, workspace, filename, extent):
        self.logger.debug("Creating wms metadata ... ")
        metadata = {}
        wmsLayerName = workspace + ':' + filename
        metadata['WMS Layer Name'] = wmsLayerName
        metadata['WMS Service URL'] = self.wmsserver
        metadata[
            'WMS Layer URL'] = self.wmsserver + '?request=GetMap&layers=' + wmsLayerName + '&bbox=' + extent + '&width=640&height=480&srs=EPSG:3857&format=image%2Fpng'

        self.logger.debug('[DONE]')
        return metadata

    def mintMetadata(self, workspace, storename, extent):
        self.logger.debug("Creating wms metadata ... ")
        metadata = {}
        layername = None
        if self.layerName == None:
            if self.layer == None:
                self.logger.debug("getResourceByStoreName..")
                resource = self.getResourceByStoreName(storename, workspace)
                self.logger.debug("getLayerByResource ...")
                layer = self.getLayerByResource(resource)
                #layername = layer.name
                self.logger.debug("done getting layer name")
                if layer == None:
                    self.logger.debug('No layer found [DONE]')
                    return metadata
                else:
                    layername = layer.name
            else:
                layername = self.layer.name
                self.layerName = self.layer.name
        else:
            layername = self.layerName
        # generate metadata
        wmsLayerName = workspace + ':' + layername
        metadata['WMS Layer Name'] = wmsLayerName
        metadata['WMS Service URL'] = self.wmsserver
        metadata[
            'WMS Layer URL'] = self.wmsserver + '?request=GetMap&layers=' + wmsLayerName + '&bbox=' + extent + '&width=640&height=480&srs=EPSG:3857&format=image%2Fpng'

        self.logger.debug('[DONE]')
        return metadata

    def uploadShapefile(self, geoserver_url, workspace, storename, filename,
                        projection, secret_key, proxy_on):
        self.logger.debug("Uploading shapefile" + filename + "...")

        if (proxy_on.lower() == 'true'):
            self.logger.debug("proxy set to on ....")
            # TODO activate proxy_on method if the proxy in clowder works
            return self.geoserver_manipulation_proxy_off(
                geoserver_url, workspace, storename, filename, projection)
            # return self.geoserver_manipulation_proxy_on(geoserver_url, workspace, storename, filename, projection, secret_key)
        else:
            return self.geoserver_manipulation_proxy_off(
                geoserver_url, workspace, storename, filename, projection)

    def geoserver_manipulation_proxy_off(self, geoserver_url, workspace,
                                         storename, filename, projection):
        self.logger.debug("start geoserver manipulation....")
        # create workspace if not present
        is_workspace = False

        self.logger.debug("checking workspace %s" % workspace)
        response_worksp = requests.get(self.restserver + 'workspaces/' +
                                       workspace,
                                       auth=(self.username, self.password))
        if response_worksp.status_code != 200:
            new_worksp = "<workspace><name>" + workspace + "</name></workspace>"
            response_worksp = requests.post(
                self.restserver + 'workspaces',
                headers={"Content-type": "text/xml"},
                auth=(self.username, self.password),
                data=new_worksp)
            if response_worksp.status_code == 201:
                is_workspace = True
        else:
            is_workspace = True

        if is_workspace:
            url = self.restserver + "workspaces/" + workspace + "/datastores/" + storename + "/file.shp"
            response = None
            self.logger.debug("put file to geosever %s" % url)
            with open(filename, 'rb') as f:
                response = requests.put(
                    url,
                    headers={'content-type': 'application/zip'},
                    auth=(self.username, self.password),
                    data=f)
            self.logger.debug(str(response.status_code) + " " + response.text)

            if response.status_code != 201:
                self.logger.debug("[DONE]")
                return False

            self.set_projection(storename, workspace, projection)

            return True
        else:
            return False

    def geoserver_manipulation_proxy_on(self, geoserver_url, workspace,
                                        storename, filename, projection,
                                        secret_key):
        # create workspace if not present
        is_workspace = False

        # this is a direct method, if the proxy works, this should go through proxy
        last_charactor = geoserver_url[-1]
        if last_charactor == '/':
            geoserver_rest = geoserver_url + 'rest'
        else:
            geoserver_rest = geoserver_url + '/rest'

        response_worksp = requests.get(geoserver_rest + '/workspaces/' +
                                       workspace + '?key=' + secret_key,
                                       auth=(self.username, self.password))
        if response_worksp.status_code != 200:
            new_worksp = "<workspace><name>" + workspace + "</name></workspace>"
            response_worksp = requests.post(
                geoserver_rest + '/workspaces' + '?key=' + secret_key,
                headers={"Content-type": "text/xml"},
                auth=(self.username, self.password),
                data=new_worksp)
            if response_worksp.status_code == 201:
                is_workspace = True
        else:
            is_workspace = True

        if is_workspace:
            url = geoserver_rest + "/workspaces/" + workspace + "/datastores/" + storename + "/file.shp"
            response = None
            with open(filename, 'rb') as f:
                response = requests.put(
                    url + '?key=' + secret_key,
                    headers={'content-type': 'application/zip'},
                    data=f)
            self.logger.debug(str(response.status_code) + " " + response.text)

            if response.status_code != 201:
                self.logger.debug("[DONE]")
                return False

            self.set_projection(storename, workspace, projection)

            return True
        else:
            return False

    def set_projection(self, storename, workspace, projection):
        resource = self.getResourceByStoreName(storename, workspace)

        if resource.projection == None:
            self.logger.debug('Setting projection' + projection)
            resource.projection = projection
            self.catalog.save(resource)
        self.logger.debug("[DONE]")
        self.layerName = storename

    def createThumbnail(self, workspace, storename, extent, width, height):
        self.logger.debug('Creating Thumbnail ...')
        layername = None
        if self.layerName == None:
            if self.layer == None:
                self.logger.debug("getResourceByStoreName..")
                resource = self.getResourceByStoreName(storename, workspace)
                self.logger.debug("getLayerByResource ...")
                layer = self.getLayerByResource(resource)
                self.logger.debug("done getting layer name")
                if layer == None:
                    self.logger.debug('No layer found [DONE]')
                    return metadata
                else:
                    layername = layer.name
            else:
                self.logger.debug("layer instance found: no need to fetch")
                layername = self.layer.name
                self.layerName = self.layer.name
        else:
            self.logger.debug("layerName instance found: no need to fetch")
            layername = self.layerName
            #wmsLayerName = workspace+":"+layer.name
            wmsLayerName = workspace + ":" + layername
        url = self.wmsserver + "?request=GetMap&layers=" + wmsLayerName + "&bbox=" + extent + "&width=" + width + "&height=" + height + "&srs=EPSG:3857&format=image%2Fpng"

        r = requests.get(url, stream=True)
        path = os.path.join(self.tempDir, 'tmp.png')

        if r.status_code == 200:
            tmp = r.headers['content-disposition']
            tmplist = tmp.split(';')
            for t in tmplist:
                if t.strip().find('filename=') != -1:
                    path = os.path.join(self.tempDir, t.strip().split('=')[1])
            with open(path, 'wb') as f:
                for chunk in r.iter_content():
                    f.write(chunk)
            self.logger.debug('[DONE]')
            return path
        else:
            self.logger.debug('can not create thumbnail [DONE]')
            return ''

    def __del__(self):
        # delete the temp dir
        if self.tempDir != None:
            try:
                import shutil
                self.logger.debug("Deleting temp dir " + self.tempDir)
                shutil.rmtree(self.tempDir)
                self.logger.debug("Deleted Temp file")
            except OSError as exc:
                if exc.errno != errno.ENOENT:
                    raise
Beispiel #40
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.rest
    
    try:
        gs_catalog = Catalog(url, _user, _password)
        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,
                        url=wms_url,
                        defaults=dict(
                            extension=ext,
                            name=name,
                            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:
            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')

        links = wcs_links(ogc_server_settings.public_url + 'wcs?', instance.typename.encode('utf-8'),
            bbox=instance.bbox[:-1], crs=instance.bbox[-1], height=height, width=width)
        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',
                            )
                        )


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

    #remove links that belong to and old address

    for link in instance.link_set.all():
        if 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)
Beispiel #41
0
    else:
        return (layer, demo.get_layer(layer).default_style.name)

g = demo.get_layergroup("groupname")
resolved = [resolve(l, s) for (l, s) in zip(g.layers, g.styles)]

# upload all styles to live
for (l, s) in resolved:
    wayne_style = prefix + s
    style_on_server = live.get_style(wayne_style)
    sld = demo.get_style(s).sld_body
    if style_on_server is None:
        live.create_style(wayne_style, sld)
    else:
        style_on_server.update_body(sld)

backup_layernames = {}

# check that all requisite layers exist!
for (l, s) in resolved:
    assert live.get_layer(l) is not None or l in backup_layernames, l

lyrs = [backup_layernames.get(x[0], x[0]) for x in resolved]
stls = [(prefix + x[1]) for x in resolved]
wayne_group = live.get_layergroup(groupname)
if wayne_group is None:
    wayne_group = live.create_layergroup(groupname)
wayne_group.layers = lyrs
wayne_group.styles = stls
live.save(wayne_group)
    def add_to_geoserver(self):
        # Inspired (copied :) ) from https://groups.google.com/forum/#!msg/geonode-users/R-u57r8aECw/AuEpydZayfIJ # TODO : check license

        # We connect to the catalog
        gsUrl = settings.OGC_SERVER['default']['LOCATION'] + "rest"
        gsUser = settings.OGC_SERVER['default']['USER']
        gsPassword = settings.OGC_SERVER['default']['PASSWORD']
        cat = Catalog(gsUrl, gsUser, gsPassword)
        if cat is None:
            raise Exception('unable to instantiate geoserver catalog')

        # We get the workspace
        ws = cat.get_workspace(settings.DEFAULT_WORKSPACE)
        if ws is None:
            raise Exception('workspace %s not found in geoserver' %
                            settings.DEFAULT_WORKSPACE)

        # We get or create the datastore
        store = cat.get_store(self.datastore_name, ws)
        if store is None:
            store = cat.create_datastore(self.datastore_name, ws)
            store.connection_parameters.update(host="postgres",
                                               port="5432",
                                               database="postgres",
                                               user="******",
                                               passwd="postgres",
                                               schema='offline_osm',
                                               dbtype="postgis")
            cat.save(store)
        if store is None:
            raise Exception('datastore %s not found in geoserver' %
                            self.datastore_name)

        # We get or create each layer then register it into geonode
        for layer in Command.layers:
            layername = layer["name"]
            self.stdout.write('Adding {} to geoserver...'.format(layername))

            layer_exists = (not cat.get_layer(layername) is None)

            if not layer_exists or not self.options['no_overwrite']:
                self.stdout.write(
                    ' layer does not exists or no_overwrite unset, we add...')

                ft = cat.publish_featuretype(layername,
                                             store,
                                             'EPSG:4326',
                                             srs='EPSG:4326')
                if ft is None:
                    raise Exception('unable to publish layer %s' % layername)
                ft.title = 'OpenStreetMap Offline - ' + layername.split(
                    '_')[-1]
                ft.abstract = 'This is an automated extract of the OpenStreetMap database. It is available offline. It is intended to be used as a background layer, but the data can also server analysis purposes.'
                cat.save(ft)

                self.stdout.write(
                    ' adding the style for {}...'.format(layername))
                # We get or create the workspace
                style_path = os.path.join(os.path.dirname(__file__), '..',
                                          '..', 'styles', layer["style_name"])
                if not os.path.exists(style_path):
                    self.stdout.write(
                        ' The file {} does not exist. No style will be applied for {}.'
                        .format(style_path, layername))
                else:
                    cat.create_style(layer["style_name"],
                                     open(style_path, 'r').read(),
                                     overwrite=True,
                                     workspace=settings.DEFAULT_WORKSPACE,
                                     raw=True)

                    style = cat.get_style(layer["style_name"], ws)
                    if style is None:
                        raise Exception('style not found (%s)' %
                                        (layer["style_name"]))

                    publishing = cat.get_layer(layername)
                    if publishing is None:
                        raise Exception('layer not found (%s)' % layerName)

                    publishing.default_style = style
                    cat.save(publishing)

                self.stdout.write(
                    ' registering {} into geonode...'.format(layername))
                resource = cat.get_resource(layername, store, ws)
                if resource is None:
                    raise Exception('resource not found (%s)' % layername)

                layer, created = Layer.objects.get_or_create(name=layername)
                layer.workspace = ws.name
                layer.store = store.name
                layer.storeType = store.resource_type
                layer.typename = "%s:%s" % (ws.name.encode('utf-8'),
                                            resource.name.encode('utf-8'))
                layer.title = resource.title
                layer.abstract = resource.abstract
                layer.temporal_extent_start = self.import_timestamp
                layer.temporal_extent_end = self.import_timestamp
                try:
                    layer.save()
                except TypeError as e:
                    # We ignore a specific error in Geonode resourcebase_post_save when settings.SITEURL has no host (relative URL)
                    self.stdout.write(
                        'TODO : report Geonode exception in resourcebase_post_save when settings.SITEURL has no host (relative URL) : '
                        + str(e))
                    pass

                if created:
                    layer.set_default_permissions()
            else:
                self.stdout.write(' layer already exists, we skip.')

        # We get or create the laygroup
        self.stdout.write('Adding layergroup to geoserver...')
        layername = 'offline_osm'
        layergroup_exists = (not cat.get_layergroup(layername) is None)
        if not layer_exists or not self.options['no_overwrite']:
            self.stdout.write(
                ' layer does not exists or no_overwrite unset, we add...')

            layergroup = cat.get_layergroup(
                layername, workspace=settings.DEFAULT_WORKSPACE)
            if layergroup is None:
                layergroup = cat.create_layergroup(
                    layername,
                    layers=layernames,
                    workspace=settings.DEFAULT_WORKSPACE)
                if layergroup is None:
                    raise Exception('unable to publish layer %s' % layername)
            layergroup.title = 'OpenStreetMap Offline'
            layergroup.abstract = 'This is an automated extract of the OpenStreetMap database. It is available offline. It is intended to be used as a background layer, but the data can also server analysis purposes.'
            cat.save(layergroup)
        else:
            self.stdout.write(' layergroup already exists, we skip.')

        # TODO : can we add layergroups to Geonode ?
        self.stdout.write(
            "laygroup won't be added to geonode (not supported yet)")
Beispiel #43
0
	scenario=sys.argv[2]
	nameStore=sys.argv[3]
	cat = Catalog(geoserver_path)
	#pdb.set_trace()
		
	try:
		print name_file,sys.argv[1]
		vk = cat.get_workspace(scenario)
		if vk ==None:
			vk=cat.create_workspace(scenario,scenario)
		vk.enabled=True
		try:
			cv = cat.create_coveragestore(nameStore,sys.argv[1],vk)
			inf=CoverageStore(cat,vk,scenario)
			inf.fetch()
			cat.save(inf)
			f.write("Processed %s"%(name_file))
		except Exception:
			print "Catalogued %s!"%(name_file)
		print nameStore,name_file,scenario
		comman ='curl -i --data "layerName=%s&coverageStore=%s&imageurl=ftp://131.254.204.143:21/../../usr/share/tomcat7/apache-tomcat-7.0.53/webapps/geoserver/data/data/%s/%s/%s.geotiff" http://172.18.242.41:8043/IDV'%(name_file,nameStore,scenario,nameStore,nameStore)
		print comman
		print "Sending to IDV module!"
		#os.system(comman)

	except ConflictingDataError as e:
		print "Exception ",e
	except UploadError as e:
		print "Exception ",e
	except FailedRequestError  as e:
		print "Exception ",e
        return (layer, demo.get_layer(layer).default_style.name)


g = demo.get_layergroup("groupname")
resolved = [resolve(l, s) for (l, s) in zip(g.layers, g.styles)]

# upload all styles to live
for (l, s) in resolved:
    wayne_style = prefix + s
    style_on_server = live.get_style(wayne_style)
    sld = demo.get_style(s).sld_body
    if style_on_server is None:
        live.create_style(wayne_style, sld)
    else:
        style_on_server.update_body(sld)

backup_layernames = {}

# check that all requisite layers exist!
for (l, s) in resolved:
    assert live.get_layer(l) is not None or l in backup_layernames, l

lyrs = [backup_layernames.get(x[0], x[0]) for x in resolved]
stls = [(prefix + x[1]) for x in resolved]
wayne_group = live.get_layergroup(groupname)
if wayne_group is None:
    wayne_group = live.create_layergroup(groupname)
wayne_group.layers = lyrs
wayne_group.styles = stls
live.save(wayne_group)
Beispiel #45
0
class GsConn:
    def __init__(self, host, login, password, debug=False):
        """
        Geoserver connection
        """
        self.host = host
        self.login = login
        self.password = password
        self.debug = debug

        # Connect to server
        self.cat = Catalog("http://%s/geoserver/rest" % host, login, password)
        if self.debug is True:
            print "Connected to geoserver"

    def crate_workspace(self, name, overwrite=False):
        """
        Creates a workspace
        :param name: Workspace name.
        :param overwrite: If True, delete existing workspace.
        :return: None
        """
        workspaces = [workspace.name for workspace in self.cat.get_workspaces()]

        if name in workspaces and overwrite is True:
            # ws2del = self.cat.get_workspace(name)
            # self.cat.delete(ws2del, purge=True, recurse=True)
            return None  # NOTE: If we delete the workspace then all associated layers are lost.
        elif name in workspaces and overwrite is False:
            print "ERROR: Workspace %s already exists (use overwrite=True)." % name

        self.cat.create_workspace(name, "http://%s/%s" % (self.host, name))
        if self.debug is True:
            print "Workspace %s available." % name

        ws = self.cat.get_workspace(name)
        ws.enabled = True

    def create_pg_store(self, name, workspace, host, port, login, password, dbname, schema, overwrite=False):
        """
        Creates datastore.
        :param name: Name of the datastore.
        :param workspace: Name of the workspace to use.
        :param overwrite: If True replace datastore.
        :return: None
        """
        stores = [store.name for store in self.cat.get_stores()]

        if name in stores and overwrite is True:
            # st2del = self.cat.get_store(name)
            # self.cat.delete(st2del, purge=True, recurse=True)
            # self.cat.reload()
            return None  # NOTE: If we delete store, every layers associated with are lost.
        elif name in stores and overwrite is False:
            print "ERROR: Store %s already exists (use overwrite=True)." % name

        ds = self.cat.create_datastore(name, workspace)
        ds.connection_parameters.update(
            host=host, port=port, user=login, passwd=password, dbtype="postgis", database=dbname, schema=schema
        )
        self.cat.save(ds)

        ds = self.cat.get_store(name)
        if ds.enabled is False:
            print "ERROR: Geoserver store %s not enabled" % name

        if self.debug is True:
            print "Datastore %s created." % name

    def publish_pg_layer(self, layer_table, layer_name, store, srid, overwrite=True):
        """
        """
        existing_lyr = self.cat.get_layer("ma_carte:%s" % layer_table)
        if existing_lyr is not None:
            print "Layer ma_carte:%s already exists, deleting it." % layer_table
            self.cat.delete(existing_lyr)
            self.cat.reload()

        ds = self.cat.get_store(store)
        ft = self.cat.publish_featuretype(layer_table, ds, "EPSG:%s" % srid, srs="EPSG:4326")
        ft.projection_policy = "REPROJECT_TO_DECLARED"
        ft.title = layer_name
        self.cat.save(ft)

        if ft.enabled is False:
            print "ERROR: Layer %s %s %s is not enabled."(ft.workspace.name, ft.store.name, ft.title)

        if self.debug is True:
            print "Layer %s>%s>%s published." % (ft.workspace.name, ft.store.name, ft.title)

    def create_style_from_sld(self, style_name, sld_file, workspace, overwrite=True):
        """
        """
        if self.cat.get_style(style_name) is not None:
            print "Style %s already exists, deleting it." % style_name
            style2del = self.cat.get_style(style_name)
            self.cat.delete(style2del)

        self.cat.create_style(
            style_name, open(sld_file).read(), overwrite=overwrite
        )  # FIXME: if ", workspace=workspace" specified can't delete style

        if self.debug is True:
            print "Style %s created in Geoserver" % style_name

    def apply_style_to_layer(self, layer_name, style_name):
        """
        Apply a geoserver styler to a layer
        """
        gs_layer = self.cat.get_layer(layer_name)
        gs_style = self.cat.get_style(style_name)

        # FIXME: Which works better?
        # gs_layer.default_style = gs_style / gs_layer._set_default_style(gs_style)
        # FIXME: Maybe indicate workspace when saving style then name the style as "workspace:style"
        gs_layer._set_default_style(gs_style)
        self.cat.save(gs_layer)

        if self.debug is True:
            print "Style applied to %s" % layer_name
def submitFiles():
    """
    Send the information of the uploaded files to the Open Data Registration Tool as an encoded JSON string in a GET-request
    The info is stored in a list of representations, according to the Open Data Registration Tool API:
    https://github.com/switchonproject/sip-html5-resource-registration/wiki
    """

    threddsAvailable = True
    geoserverAvailable = True

    # Check if Thredds server is online
    threddsAvailable = checkConnection(app.config['THREDDS_SERVER'],
                        "Failed to connect to the THREDDS server at " + app.config['THREDDS_SERVER'] + \
                                ". NetCDF files will not be accessible using web services, only by HTTP download.")

    # Check if GeoServer is online
    geoserverAvailable = checkConnection(app.config['GEOSERVER'],
                        "Failed to connect to the geoserver at " + app.config['GEOSERVER'] + \
                                ". Shapefiles will not be mapped with WMS and can not be downloaded by WFS.")

    datasetname = session['DATASETNAME']
    datasetFoldername = session['DATASETFOLDERNAME']
    generateDOI = session['GENERATEDOI']

    if request.form['submitButton'] == 'previous':
        return redirect('/?datasetname=' + datasetFoldername)

    if request.form['submitButton'] == 'next':

        datasetDir = os.path.join(app.config['BASE_UPLOAD_FOLDER'], datasetFoldername)

        files = [f for f in os.listdir(datasetDir) if
                 os.path.isfile(os.path.join(datasetDir, f)) and f not in app.config['IGNORED_FILES']]

        if len(files) > 0:

            representation = {}
            result = []
            urlRoot = request.url_root.rstrip('/')  # get the url root without the traling '/' (for string concatenation)

            # Store the root url of the dataset as the primary representation if there are more than 1 file
            if len(files) > 1:
                representation['name'] = datasetname
                representation['description'] = "File download"
                representation['type'] = "original data"
                representation['contentlocation'] = '/'.join([urlRoot, 'data', datasetFoldername])
                representation['contenttype'] = "application/octet-stream"
                representation['function'] = "information"
                representation['protocol'] = "WWW:LINK-1.0-http--link"
                result.append(representation)

            # if there is only one file, store the direct link to this file
            if len(files) == 1:
                filename, fileExtension = os.path.splitext(f)

                # region Check if it is a zipped shapefile
                # if it is, ignore it (unless geoserver is unavailable), otherwise the zip file is added twice
                zippedShapefile = False

                if fileExtension == '.zip' and geoserverAvailable:
                    zipFilePath =  os.path.join(datasetDir, f)
                    zipFile = zipfile.ZipFile(zipFilePath, 'r')
                    filesInZip = zipFile.namelist()
                    zipFile.close()

                    for fileInZip in filesInZip:
                        fileInZipExtension = os.path.splitext(fileInZip)[1]
                        if fileInZipExtension == '.shp':
                            zippedShapefile = True
                #endregion

                if fileExtension != '.nc' and zippedShapefile == False:
                    representation['name'] = datasetname
                    representation['description'] = "File download"
                    representation['type'] = "original data"

                    # TODO: improve file recognition
                    if fileExtension == ".zip":
                        representation['contenttype'] = "application/zip"
                    else:
                        representation['contenttype'] = "application/octet-stream"

                    representation['contentlocation'] = '/'.join([urlRoot, 'data', datasetFoldername, f])
                    representation['function'] = "download"
                    representation['protocol'] = "WWW:DOWNLOAD-1.0-http--download"
                    result.append(representation)


            #region THREDDS
            if threddsAvailable:
                if app.config['DEVELOP']:
                    threddsCatalog = '/'.join((app.config['THREDDS_SERVER'], 'netcdftest', 'catalog.xml'))
                else:
                    threddsCatalog = '/'.join((app.config['THREDDS_SERVER'], datasetFoldername, 'catalog.xml'))

                try:
                    opendapUrls = threddsclient.opendap_urls(threddsCatalog)

                    for opendapUrl in opendapUrls:

                        filepath, fileExtension = os.path.splitext(opendapUrl)
                        filename = opendapUrl.split('/')[-1]

                        # check if the file is a netCDF file; if yes, store OPeNDAP service url and html download url
                        if fileExtension == '.nc':
                            representation = {}

                            representation['name'] = filename
                            representation['description'] = "Netcdf file OPeNDAP service"
                            representation['contentlocation'] = opendapUrl
                            representation['contenttype'] = "application/x-netcdf"
                            representation['type'] = "original data"
                            representation['function'] = "service"
                            representation['protocol'] = 'OPeNDAP:OPeNDAP'
                            result.append(representation)

                            representation = {}
                            representation['name'] = filename
                            representation['description'] = "HTML interface OPeNDAP service"
                            representation['contentlocation'] = opendapUrl + ".html"
                            representation['contenttype'] = "application/x-netcdf"
                            representation['type'] = "original data"
                            representation['function'] = "download"
                            representation['protocol'] = 'WWW:DOWNLOAD-1.0-http--download'
                            result.append(representation)

                            representation = {}
                            representation['name'] = filename
                            representation['description'] = "WMS service"
                            representation['contentlocation'] = opendapUrl.replace('dodsC', 'wms') + "?service=WMS&version=1.3.0&request=GetCapabilities"
                            representation['contenttype'] = "application/xml"
                            representation['type'] = "original data"
                            representation['function'] = "service"
                            representation['protocol'] = 'OGC:WMS-1.1.1-http-get-capabilities'
                            result.append(representation)
                except:
                    app.logger.info("URL: " + threddsCatalog + " is not a THREDDS catalog")
            #endregion


            # region GEOSERVER: loop through all files to check for shapefiles
            if geoserverAvailable:
                for file in files:

                    layerName = ''
                    filename, fileExtension = os.path.splitext(file)

                    if fileExtension == '.zip':

                        zipFilePath =  os.path.join(datasetDir, file)
                        zipFile = zipfile.ZipFile(zipFilePath, 'r')
                        filesInZip = zipFile.namelist()

                        for fileInZip in filesInZip:
                            fileInZipName = os.path.split(fileInZip)[1]
                            fileInZipNoExtName, fileInZipExtension = os.path.splitext(fileInZipName)

                            if fileInZipExtension == '.shp':
                                # Layer name is the file without extension
                                layerName = fileInZipNoExtName

                                # Publish .zipped shapefile on geoserver, no subdirectories
                                zipFile.extractall(datasetDir)
                                for root, dirs, files in os.walk(datasetDir):
                                    for name in files:
                                        os.rename(os.path.join(root, name), os.path.join(datasetDir,name))

                                # create workspace
                                r = requests.post(url= app.config['GEOSERVER'] + "/rest/workspaces",
                                                 headers={'Content-type':  'text/xml'},
                                                 data="<workspace><name>" + datasetFoldername + "</name></workspace>",
                                                 auth=HTTPBasicAuth(app.config['GEOSERVER_ADMIN'], app.config['GEOSERVER_PASS']))

                                if r.status_code > 299:    # status code of 201 is success; all else is failure
                                    app.logger.error("Error in creating geoserver workspace for " + datasetFoldername + \
                                                     "; Status code: " + str(r.status_code) + ", Content: " + r.content)
                                    flash("Error in creating workspace on geoserver.")
                                    return redirect(url_for('uploadData'))

                                # for testing purposes.. uploaded file is on local machine and can only publish data that is on the data mount of web app
                                if app.config['DEVELOP']:
                                   shapeFile = "file://D:/sala/Downloads/sld_cookbook_polygon/sld_cookbook_polygon.shp"
                                else:
                                   shapeFile = settings['GEOSERVER_DATA_DIR'] + "/" + datasetFoldername + "/" + fileInZipName

                                # Publish shapefile on the geoserver; the datastore is automatically created and has the same name as the shapefile + ds
                                r = requests.put(url=app.config['GEOSERVER'] + "/rest/workspaces/" + datasetFoldername + "/datastores/" + datasetFoldername + "_ds/external.shp",
                                                 headers={'Content-type': 'text/plain'},
                                                 data='file://'+shapeFile,
                                                 auth=HTTPBasicAuth(app.config['GEOSERVER_ADMIN'], app.config['GEOSERVER_PASS']))

                                if r.status_code > 299:
                                    app.logger.error("Error in publishing shapefile " + datasetFoldername + " on geoserver; Status code: " \
                                                     + str(r.status_code) + ", Content: " + r.content)
                                    flash("Error in publishing shapefile on geoserver.")
                                    return redirect(url_for('uploadData'))

                                representation = {}
                                representation['name'] = layerName
                                representation['description'] = "WMS service"
                                representation['contentlocation'] = app.config['GEOSERVER'] + "/" + datasetFoldername + "/" + \
                                                                    "wms?service=WMS&version=1.1.0&request=GetCapabilities"
                                representation['contenttype'] = "application/xml"
                                representation['type'] = "original data"
                                representation['function'] = "service"
                                representation['protocol'] = 'OGC:WMS-1.1.1-http-get-capabilities'
                                result.append(representation)

                                representation = {}
                                representation['name'] = layerName
                                representation['description'] = "WMS service"
                                representation['contentlocation'] = app.config['GEOSERVER'] + "/" + datasetFoldername + "/" + \
                                                                    "wms?service=WMS&version=1.1.0&request=GetCapabilities"
                                representation['contenttype'] = "application/xml"
                                representation['type'] = "aggregated data"
                                representation['function'] = "service"
                                representation['protocol'] = 'OGC:WMS-1.1.1-http-get-capabilities'

                                #region Get spatial extent from getcapabilities document
                                try:
                                    root = ET.fromstring(requests.get(representation['contentlocation']).content)
                                    latlonElem = root.find('Capability/Layer/Layer/LatLonBoundingBox')
                                    latlonDict = latlonElem.attrib

                                    minx = latlonDict['minx']
                                    miny = latlonDict['miny']
                                    maxx = latlonDict['maxx']
                                    maxy = latlonDict['maxy']

                                    # WKT representation: POLYGON((minx miny, maxx miny, maxx maxy, minx maxy, minx miny))
                                    WKTString = 'POLYGON(({0} {1}, {2} {1}, {2} {3}, {0} {3}, {0} {1}))'.format(minx, miny, maxx, maxy)
                                    representation['wktboundingbox'] = WKTString
                                except:
                                    app.logger.error("Error in deriving WKT bounding box from WMS getcapabilities document")
                                #endregion

                                result.append(representation)

                                representation = {}
                                representation['name'] = fileInZipNoExtName
                                representation['description'] = "WFS service"
                                representation['contentlocation'] = app.config['GEOSERVER'] + "/" + datasetFoldername + "/" + "ows?service=WFS&version=1.0.0&request=GetCapabilities"
                                representation['contenttype'] = "application/xml"
                                representation['type'] = "original data"
                                representation['function'] = "service"
                                representation['protocol'] = "OGC:WFS-1.0.0-http-get-capabilities"
                                result.append(representation)

                                representation = {}
                                representation['name'] = file
                                representation['description'] = "Zipped shapefile"
                                representation['contentlocation'] = '/'.join([urlRoot, 'data', datasetFoldername, file])
                                representation['contenttype'] = "application/zip"
                                representation['type'] = "original data"
                                representation['function'] = "download"
                                representation['protocol'] = "WWW:DOWNLOAD-1.0-http--download"
                                representation['uploadmessage'] = "deriveSpatialIndex:shp"
                                result.append(representation)

                        # Optional sld file (preconditions, shp uploaded, workspace created)
                        for fileInZip in filesInZip:
                            fileInZipName = os.path.split(fileInZip)[1]
                            fileInZipNoExtName, fileInZipExtension = os.path.splitext(fileInZipName)

                            if fileInZipExtension == '.sld':
                                # for testing purposes.. uploaded file is on local machine and can only publish data that is on the data mount of web app
                                if app.config['DEVELOP']:
                                    sldFile = "D:/sala/Downloads/sld_cookbook_polygon/sld_cookbook_polygon.sld"
                                else:
                                    sldFile = settings['GEOSERVER_DATA_DIR'] + "/" + datasetFoldername + "/" + fileInZipName

                                # Connect to geoserver catalogue
                                cat = Catalog(app.config['GEOSERVER'] + "/rest", app.config['GEOSERVER_ADMIN'], password=app.config['GEOSERVER_PASS'])

                                # Add or Overwrite
                                with open(sldFile) as f:
                                    style=cat.create_style(fileInZipNoExtName, f.read(), overwrite=True)
                                # Link it to the layer
                                layer = cat.get_layer(layerName)
                                layer._set_default_style(fileInZipNoExtName)
                                cat.save(layer)

                        # close zip file after looping through all files in the zip file
                        zipFile.close()
            #endregion

            # region
            if generateDOI:
                d = DOI(files, datasetDir, datasetname, logger=app.logger)
                deposition_id = d.runUpload()

            # endregion
            resultString = json.dumps(result)
            text = urllib.quote_plus(resultString.encode('utf-8'))
            if generateDOI:     url = app.config['METADATA_URL'] + text + '&deposition=' + deposition_id
            else:               url = app.config['METADATA_URL'] + text

            # store the representation
            app.logger.info("Representations of the dataset: " + resultString)
            return redirect(url)
        else:
            flash("Please upload at least one file")
            return redirect(url_for('uploadData'))
Beispiel #47
0
#!/usr/bin/env python

from geoserver.catalog import Catalog

cat = Catalog("http://localhost:8080/geoserver/rest", "admin", "geoserver")

native_bbox = \
    ['589434.856', '4914006.338', '609527.21', '4928063.398', 'EPSG:26713']
latlon_bbox = ['-103.877', '44.371', '-103.622', '44.5', 'EPSG:4326']

sf = cat.get_workspace('sf')
for rs in cat.get_resources(workspace=sf):
    rs.native_bbox = native_bbox
    rs.latlon_bbox = latlon_bbox
    cat.save(rs)
def submitFiles():
    """
    Send the information of the uploaded files to the Open Data Registration Tool as an encoded JSON string in a GET-request
    The info is stored in a list of representations, according to the Open Data Registration Tool API:
    https://github.com/switchonproject/sip-html5-resource-registration/wiki
    """

    threddsAvailable = True
    geoserverAvailable = True

    # Check if Thredds server is online
    threddsAvailable = checkConnection(app.config['THREDDS_SERVER'],
                        "Failed to connect to the THREDDS server at " + app.config['THREDDS_SERVER'] + \
                                ". NetCDF files will not be accessible using web services, only by HTTP download.")

    # Check if GeoServer is online
    geoserverAvailable = checkConnection(app.config['GEOSERVER'],
                        "Failed to connect to the geoserver at " + app.config['GEOSERVER'] + \
                                ". Shapefiles will not be mapped with WMS and can not be downloaded by WFS.")

    datasetname = session['DATASETNAME']
    datasetFoldername = session['DATASETFOLDERNAME']
    generateDOI = session['GENERATEDOI']

    if request.form['submitButton'] == 'previous':
        return redirect('/?datasetname=' + datasetFoldername)

    if request.form['submitButton'] == 'next':

        datasetDir = os.path.join(app.config['BASE_UPLOAD_FOLDER'],
                                  datasetFoldername)

        files = [
            f for f in os.listdir(datasetDir)
            if os.path.isfile(os.path.join(datasetDir, f))
            and f not in app.config['IGNORED_FILES']
        ]

        if len(files) > 0:

            representation = {}
            result = []
            urlRoot = request.url_root.rstrip(
                '/'
            )  # get the url root without the traling '/' (for string concatenation)

            # Store the root url of the dataset as the primary representation if there are more than 1 file
            if len(files) > 1:
                representation['name'] = datasetname
                representation['description'] = "File download"
                representation['type'] = "original data"
                representation['contentlocation'] = '/'.join(
                    [urlRoot, 'data', datasetFoldername])
                representation['contenttype'] = "application/octet-stream"
                representation['function'] = "information"
                representation['protocol'] = "WWW:LINK-1.0-http--link"
                result.append(representation)

            # if there is only one file, store the direct link to this file
            if len(files) == 1:
                filename, fileExtension = os.path.splitext(f)

                # region Check if it is a zipped shapefile
                # if it is, ignore it (unless geoserver is unavailable), otherwise the zip file is added twice
                zippedShapefile = False

                if fileExtension == '.zip' and geoserverAvailable:
                    zipFilePath = os.path.join(datasetDir, f)
                    zipFile = zipfile.ZipFile(zipFilePath, 'r')
                    filesInZip = zipFile.namelist()
                    zipFile.close()

                    for fileInZip in filesInZip:
                        fileInZipExtension = os.path.splitext(fileInZip)[1]
                        if fileInZipExtension == '.shp':
                            zippedShapefile = True
                #endregion

                if fileExtension != '.nc' and zippedShapefile == False:
                    representation['name'] = datasetname
                    representation['description'] = "File download"
                    representation['type'] = "original data"

                    # TODO: improve file recognition
                    if fileExtension == ".zip":
                        representation['contenttype'] = "application/zip"
                    else:
                        representation[
                            'contenttype'] = "application/octet-stream"

                    representation['contentlocation'] = '/'.join(
                        [urlRoot, 'data', datasetFoldername, f])
                    representation['function'] = "download"
                    representation[
                        'protocol'] = "WWW:DOWNLOAD-1.0-http--download"
                    result.append(representation)

            #region THREDDS
            if threddsAvailable:
                if app.config['DEVELOP']:
                    threddsCatalog = '/'.join((app.config['THREDDS_SERVER'],
                                               'netcdftest', 'catalog.xml'))
                else:
                    threddsCatalog = '/'.join(
                        (app.config['THREDDS_SERVER'], datasetFoldername,
                         'catalog.xml'))

                try:
                    opendapUrls = threddsclient.opendap_urls(threddsCatalog)

                    for opendapUrl in opendapUrls:

                        filepath, fileExtension = os.path.splitext(opendapUrl)
                        filename = opendapUrl.split('/')[-1]

                        # check if the file is a netCDF file; if yes, store OPeNDAP service url and html download url
                        if fileExtension == '.nc':
                            representation = {}

                            representation['name'] = filename
                            representation[
                                'description'] = "Netcdf file OPeNDAP service"
                            representation['contentlocation'] = opendapUrl
                            representation[
                                'contenttype'] = "application/x-netcdf"
                            representation['type'] = "original data"
                            representation['function'] = "service"
                            representation['protocol'] = 'OPeNDAP:OPeNDAP'
                            result.append(representation)

                            representation = {}
                            representation['name'] = filename
                            representation[
                                'description'] = "HTML interface OPeNDAP service"
                            representation[
                                'contentlocation'] = opendapUrl + ".html"
                            representation[
                                'contenttype'] = "application/x-netcdf"
                            representation['type'] = "original data"
                            representation['function'] = "download"
                            representation[
                                'protocol'] = 'WWW:DOWNLOAD-1.0-http--download'
                            result.append(representation)

                            representation = {}
                            representation['name'] = filename
                            representation['description'] = "WMS service"
                            representation[
                                'contentlocation'] = opendapUrl.replace(
                                    'dodsC', 'wms'
                                ) + "?service=WMS&version=1.3.0&request=GetCapabilities"
                            representation['contenttype'] = "application/xml"
                            representation['type'] = "original data"
                            representation['function'] = "service"
                            representation[
                                'protocol'] = 'OGC:WMS-1.1.1-http-get-capabilities'
                            result.append(representation)
                except:
                    app.logger.info("URL: " + threddsCatalog +
                                    " is not a THREDDS catalog")
            #endregion

            # region GEOSERVER: loop through all files to check for shapefiles
            if geoserverAvailable:
                for file in files:

                    layerName = ''
                    filename, fileExtension = os.path.splitext(file)

                    if fileExtension == '.zip':

                        zipFilePath = os.path.join(datasetDir, file)
                        zipFile = zipfile.ZipFile(zipFilePath, 'r')
                        filesInZip = zipFile.namelist()

                        for fileInZip in filesInZip:
                            fileInZipName = os.path.split(fileInZip)[1]
                            fileInZipNoExtName, fileInZipExtension = os.path.splitext(
                                fileInZipName)

                            if fileInZipExtension == '.shp':
                                # Layer name is the file without extension
                                layerName = fileInZipNoExtName

                                # Publish .zipped shapefile on geoserver, no subdirectories
                                zipFile.extractall(datasetDir)
                                for root, dirs, files in os.walk(datasetDir):
                                    for name in files:
                                        os.rename(
                                            os.path.join(root, name),
                                            os.path.join(datasetDir, name))

                                # create workspace
                                r = requests.post(
                                    url=app.config['GEOSERVER'] +
                                    "/rest/workspaces",
                                    headers={'Content-type': 'text/xml'},
                                    data="<workspace><name>" +
                                    datasetFoldername + "</name></workspace>",
                                    auth=HTTPBasicAuth(
                                        app.config['GEOSERVER_ADMIN'],
                                        app.config['GEOSERVER_PASS']))

                                if r.status_code > 299:  # status code of 201 is success; all else is failure
                                    app.logger.error("Error in creating geoserver workspace for " + datasetFoldername + \
                                                     "; Status code: " + str(r.status_code) + ", Content: " + r.content)
                                    flash(
                                        "Error in creating workspace on geoserver."
                                    )
                                    return redirect(url_for('uploadData'))

                                # for testing purposes.. uploaded file is on local machine and can only publish data that is on the data mount of web app
                                if app.config['DEVELOP']:
                                    shapeFile = "file://D:/sala/Downloads/sld_cookbook_polygon/sld_cookbook_polygon.shp"
                                else:
                                    shapeFile = settings[
                                        'GEOSERVER_DATA_DIR'] + "/" + datasetFoldername + "/" + fileInZipName

                                # Publish shapefile on the geoserver; the datastore is automatically created and has the same name as the shapefile + ds
                                r = requests.put(
                                    url=app.config['GEOSERVER'] +
                                    "/rest/workspaces/" + datasetFoldername +
                                    "/datastores/" + datasetFoldername +
                                    "_ds/external.shp",
                                    headers={'Content-type': 'text/plain'},
                                    data='file://' + shapeFile,
                                    auth=HTTPBasicAuth(
                                        app.config['GEOSERVER_ADMIN'],
                                        app.config['GEOSERVER_PASS']))

                                if r.status_code > 299:
                                    app.logger.error("Error in publishing shapefile " + datasetFoldername + " on geoserver; Status code: " \
                                                     + str(r.status_code) + ", Content: " + r.content)
                                    flash(
                                        "Error in publishing shapefile on geoserver."
                                    )
                                    return redirect(url_for('uploadData'))

                                representation = {}
                                representation['name'] = layerName
                                representation['description'] = "WMS service"
                                representation['contentlocation'] = app.config['GEOSERVER'] + "/" + datasetFoldername + "/" + \
                                                                    "wms?service=WMS&version=1.1.0&request=GetCapabilities"
                                representation[
                                    'contenttype'] = "application/xml"
                                representation['type'] = "original data"
                                representation['function'] = "service"
                                representation[
                                    'protocol'] = 'OGC:WMS-1.1.1-http-get-capabilities'
                                result.append(representation)

                                representation = {}
                                representation['name'] = layerName
                                representation['description'] = "WMS service"
                                representation['contentlocation'] = app.config['GEOSERVER'] + "/" + datasetFoldername + "/" + \
                                                                    "wms?service=WMS&version=1.1.0&request=GetCapabilities"
                                representation[
                                    'contenttype'] = "application/xml"
                                representation['type'] = "aggregated data"
                                representation['function'] = "service"
                                representation[
                                    'protocol'] = 'OGC:WMS-1.1.1-http-get-capabilities'

                                #region Get spatial extent from getcapabilities document
                                try:
                                    root = ET.fromstring(
                                        requests.get(
                                            representation['contentlocation']).
                                        content)
                                    latlonElem = root.find(
                                        'Capability/Layer/Layer/LatLonBoundingBox'
                                    )
                                    latlonDict = latlonElem.attrib

                                    minx = latlonDict['minx']
                                    miny = latlonDict['miny']
                                    maxx = latlonDict['maxx']
                                    maxy = latlonDict['maxy']

                                    # WKT representation: POLYGON((minx miny, maxx miny, maxx maxy, minx maxy, minx miny))
                                    WKTString = 'POLYGON(({0} {1}, {2} {1}, {2} {3}, {0} {3}, {0} {1}))'.format(
                                        minx, miny, maxx, maxy)
                                    representation[
                                        'wktboundingbox'] = WKTString
                                except:
                                    app.logger.error(
                                        "Error in deriving WKT bounding box from WMS getcapabilities document"
                                    )
                                #endregion

                                result.append(representation)

                                representation = {}
                                representation['name'] = fileInZipNoExtName
                                representation['description'] = "WFS service"
                                representation['contentlocation'] = app.config[
                                    'GEOSERVER'] + "/" + datasetFoldername + "/" + "ows?service=WFS&version=1.0.0&request=GetCapabilities"
                                representation[
                                    'contenttype'] = "application/xml"
                                representation['type'] = "original data"
                                representation['function'] = "service"
                                representation[
                                    'protocol'] = "OGC:WFS-1.0.0-http-get-capabilities"
                                result.append(representation)

                                representation = {}
                                representation['name'] = file
                                representation[
                                    'description'] = "Zipped shapefile"
                                representation['contentlocation'] = '/'.join(
                                    [urlRoot, 'data', datasetFoldername, file])
                                representation[
                                    'contenttype'] = "application/zip"
                                representation['type'] = "original data"
                                representation['function'] = "download"
                                representation[
                                    'protocol'] = "WWW:DOWNLOAD-1.0-http--download"
                                representation[
                                    'uploadmessage'] = "deriveSpatialIndex:shp"
                                result.append(representation)

                        # Optional sld file (preconditions, shp uploaded, workspace created)
                        for fileInZip in filesInZip:
                            fileInZipName = os.path.split(fileInZip)[1]
                            fileInZipNoExtName, fileInZipExtension = os.path.splitext(
                                fileInZipName)

                            if fileInZipExtension == '.sld':
                                # for testing purposes.. uploaded file is on local machine and can only publish data that is on the data mount of web app
                                if app.config['DEVELOP']:
                                    sldFile = "D:/sala/Downloads/sld_cookbook_polygon/sld_cookbook_polygon.sld"
                                else:
                                    sldFile = settings[
                                        'GEOSERVER_DATA_DIR'] + "/" + datasetFoldername + "/" + fileInZipName

                                # Connect to geoserver catalogue
                                cat = Catalog(
                                    app.config['GEOSERVER'] + "/rest",
                                    app.config['GEOSERVER_ADMIN'],
                                    password=app.config['GEOSERVER_PASS'])

                                # Add or Overwrite
                                with open(sldFile) as f:
                                    style = cat.create_style(
                                        fileInZipNoExtName,
                                        f.read(),
                                        overwrite=True)
                                # Link it to the layer
                                layer = cat.get_layer(layerName)
                                layer._set_default_style(fileInZipNoExtName)
                                cat.save(layer)

                        # close zip file after looping through all files in the zip file
                        zipFile.close()
            #endregion

            # region
            if generateDOI:
                d = DOI(files, datasetDir, datasetname, logger=app.logger)
                deposition_id = d.runUpload()

            # endregion
            resultString = json.dumps(result)
            text = urllib.quote_plus(resultString.encode('utf-8'))
            if generateDOI:
                url = app.config[
                    'METADATA_URL'] + text + '&deposition=' + deposition_id
            else:
                url = app.config['METADATA_URL'] + text

            # store the representation
            app.logger.info("Representations of the dataset: " + resultString)
            return redirect(url)
        else:
            flash("Please upload at least one file")
            return redirect(url_for('uploadData'))
Beispiel #49
0
class ModifyingTests(unittest.TestCase):
    def setUp(self):
        self.cat = Catalog("http://localhost:8080/geoserver/rest")

    def testFeatureTypeSave(self):
        # test saving round trip
        rs = self.cat.get_resource("bugsites")
        old_abstract = rs.abstract
        new_abstract = "Not the original abstract"
        enabled = rs.enabled

        # Change abstract on server
        rs.abstract = new_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(new_abstract, rs.abstract)
        self.assertEqual(enabled, rs.enabled)

        # Change keywords on server
        rs.keywords = ["bugsites", "gsconfig"]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(["bugsites", "gsconfig"], rs.keywords)
        self.assertEqual(enabled, rs.enabled)
        
        # Change metadata links on server
        rs.metadata_links = [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(
                        [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")],
                        rs.metadata_links)
        self.assertEqual(enabled, rs.enabled)


        # Restore abstract
        rs.abstract = old_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(old_abstract, rs.abstract)

    def testDataStoreCreate(self):
        ds = self.cat.create_datastore("vector_gsconfig")
        ds.connection_parameters.update(
            host="localhost", port="5432", database="db", user="******",
            passwd="password", dbtype="postgis")
        self.cat.save(ds)

    def testDataStoreModify(self):
        ds = self.cat.get_store("sf")
        self.assertFalse("foo" in ds.connection_parameters)
        ds.connection_parameters = ds.connection_parameters
        ds.connection_parameters["foo"] = "bar"
        orig_ws = ds.workspace.name
        self.cat.save(ds)
        ds = self.cat.get_store("sf")
        self.assertTrue("foo" in ds.connection_parameters)
        self.assertEqual("bar", ds.connection_parameters["foo"])
        self.assertEqual(orig_ws, ds.workspace.name)

    def testDataStoreCreateAndThenAlsoImportData(self):
        ds = self.cat.create_datastore("gsconfig_import_test")
        ds.connection_parameters.update(
            host="localhost", port="5432", database="db", user="******",
            passwd="password", dbtype="postgis")
        self.cat.save(ds)
        ds = self.cat.get_store("gsconfig_import_test")
        self.cat.add_data_to_store(ds, "import", {
            'shp': 'test/data/states.shp',
            'shx': 'test/data/states.shx',
            'dbf': 'test/data/states.dbf',
            'prj': 'test/data/states.prj'
        })

    def testCoverageStoreCreate(self):
        ds = self.cat.create_coveragestore2("coverage_gsconfig")
        ds.data_url = "file:data/mytiff.tiff"
        self.cat.save(ds)

    def testCoverageStoreModify(self):
        cs = self.cat.get_store("sfdem")
        self.assertEqual("GeoTIFF", cs.type)
        cs.type = "WorldImage"
        self.cat.save(cs)
        cs = self.cat.get_store("sfdem")
        self.assertEqual("WorldImage", cs.type)

        # not sure about order of test runs here, but it might cause problems
        # for other tests if this layer is misconfigured
        cs.type = "GeoTIFF"
        self.cat.save(cs) 

    def testCoverageSave(self):
        # test saving round trip
        rs = self.cat.get_resource("Arc_Sample")
        old_abstract = rs.abstract
        new_abstract = "Not the original abstract"

        # # Change abstract on server
        rs.abstract = new_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(new_abstract, rs.abstract)

        # Restore abstract
        rs.abstract = old_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(old_abstract, rs.abstract)

        # Change metadata links on server
        rs.metadata_links = [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(
            [("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")],
            rs.metadata_links)
        self.assertEqual(enabled, rs.enabled)

        srs_before = set(['EPSG:4326'])
        srs_after = set(['EPSG:4326', 'EPSG:3785'])
        formats = set(['ARCGRID', 'ARCGRID-GZIP', 'GEOTIFF', 'PNG', 'GIF', 'TIFF'])
        formats_after = set(["PNG", "GIF", "TIFF"])

        # set and save request_srs_list
        self.assertEquals(set(rs.request_srs_list), srs_before, str(rs.request_srs_list))
        rs.request_srs_list = rs.request_srs_list + ['EPSG:3785']
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEquals(set(rs.request_srs_list), srs_after, str(rs.request_srs_list))

        # set and save response_srs_list
        self.assertEquals(set(rs.response_srs_list), srs_before, str(rs.response_srs_list))
        rs.response_srs_list = rs.response_srs_list + ['EPSG:3785']
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEquals(set(rs.response_srs_list), srs_after, str(rs.response_srs_list))

        # set and save supported_formats
        self.assertEquals(set(rs.supported_formats), formats, str(rs.supported_formats))
        rs.supported_formats = ["PNG", "GIF", "TIFF"]
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEquals(set(rs.supported_formats), formats_after, str(rs.supported_formats))


    def testFeatureTypeCreate(self):
        shapefile_plus_sidecars = shapefile_and_friends("test/data/states")
        expected = {
            'shp': 'test/data/states.shp',
            'shx': 'test/data/states.shx',
            'dbf': 'test/data/states.dbf',
            'prj': 'test/data/states.prj'
        }

        self.assertEqual(len(expected), len(shapefile_plus_sidecars))
        for k, v in expected.iteritems():
            self.assertEqual(v, shapefile_plus_sidecars[k])
 
        sf = self.cat.get_workspace("sf")
        self.cat.create_featurestore("states_test", shapefile_plus_sidecars, sf)

        self.assert_(self.cat.get_resource("states_test", workspace=sf) is not None)

        self.assertRaises(
            ConflictingDataError, 
            lambda: self.cat.create_featurestore("states_test", shapefile_plus_sidecars, sf)
        )

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_coveragestore("states_raster_test", shapefile_plus_sidecars, sf)
        )

        bogus_shp = {
            'shp': 'test/data/Pk50095.tif',
            'shx': 'test/data/Pk50095.tif',
            'dbf':    'test/data/Pk50095.tfw',
            'prj':    'test/data/Pk50095.prj'
        }

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_featurestore("bogus_shp", bogus_shp, sf)
        )

        lyr = self.cat.get_layer("states_test")
        self.cat.delete(lyr)
        self.assert_(self.cat.get_layer("states_test") is None)


    def testCoverageCreate(self):
        tiffdata = {
            'tiff': 'test/data/Pk50095.tif',
            'tfw':    'test/data/Pk50095.tfw',
            'prj':    'test/data/Pk50095.prj'
        }

        sf = self.cat.get_workspace("sf")
        # TODO: Uploading WorldImage file no longer works???
        # ft = self.cat.create_coveragestore("Pk50095", tiffdata, sf)

        # self.assert_(self.cat.get_resource("Pk50095", workspace=sf) is not None)

        # self.assertRaises(
        #         ConflictingDataError, 
        #         lambda: self.cat.create_coveragestore("Pk50095", tiffdata, sf)
        # )

        self.assertRaises(
            UploadError, 
            lambda: self.cat.create_featurestore("Pk50095_vector", tiffdata, sf)
        )

        bogus_tiff = {
            'tiff': 'test/data/states.shp',
            'tfw': 'test/data/states.shx',
            'prj': 'test/data/states.prj'
        }

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_coveragestore("states_raster", bogus_tiff)
        )

    def testLayerSave(self):
        # test saving round trip
        lyr = self.cat.get_layer("states")
        old_attribution = lyr.attribution
        new_attribution = "Not the original attribution"

        # change attribution on server
        lyr.attribution = new_attribution
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(new_attribution, lyr.attribution)

        # Restore attribution
        lyr.attribution = old_attribution
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(old_attribution, lyr.attribution)

        self.assertEqual(lyr.default_style.name, "population")
     
        old_default_style = lyr.default_style
        lyr.default_style = (s for s in lyr.styles if s.name == "pophatch").next()
        lyr.styles = [old_default_style]
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(lyr.default_style.name, "pophatch")
        self.assertEqual([s.name for s in lyr.styles], ["population"])


    def testStyles(self):
        # upload new style, verify existence
        self.cat.create_style("fred", open("test/fred.sld").read())
        fred = self.cat.get_style("fred")
        self.assert_(fred is not None)
        self.assertEqual("Fred", fred.sld_title)

        # replace style, verify changes
        self.cat.create_style("fred", open("test/ted.sld").read(), overwrite=True)
        fred = self.cat.get_style("fred")
        self.assert_(fred is not None)
        self.assertEqual("Ted", fred.sld_title)

        # delete style, verify non-existence
        self.cat.delete(fred, purge=True)
        self.assert_(self.cat.get_style("fred") is None)

        # attempt creating new style
        self.cat.create_style("fred", open("test/fred.sld").read())
        fred = self.cat.get_style("fred")
        self.assertEqual("Fred", fred.sld_title)

    def testWorkspaceCreate(self):
        ws = self.cat.get_workspace("acme")
        self.assertEqual(None, ws)
        self.cat.create_workspace("acme", "http://example.com/acme")
        ws = self.cat.get_workspace("acme")
        self.assertEqual("acme", ws.name)

    def testWorkspaceDelete(self): 
        self.cat.create_workspace("foo", "http://example.com/foo")
        ws = self.cat.get_workspace("foo")
        self.cat.delete(ws)
        ws = self.cat.get_workspace("foo")
        self.assert_(ws is None)

    def testFeatureTypeDelete(self):
        pass

    def testCoverageDelete(self):
        pass

    def testDataStoreDelete(self):
        states = self.cat.get_store('states_shapefile')
        self.assert_(states.enabled == True)
        states.enabled = False
        self.assert_(states.enabled == False)
        self.cat.save(states)

        states = self.cat.get_store('states_shapefile')
        self.assert_(states.enabled == False)

        states.enabled = True
        self.cat.save(states)

        states = self.cat.get_store('states_shapefile')
        self.assert_(states.enabled == True)

    def testLayerGroupSave(self):
        tas = self.cat.get_layergroup("tasmania")

        self.assertEqual(tas.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads', 'tasmania_cities'], tas.layers)
        self.assertEqual(tas.styles, [None, None, None, None], tas.styles)

        tas.layers = tas.layers[:-1]
        tas.styles = tas.styles[:-1]

        self.cat.save(tas)

        self.assertEqual(tas.layers, ['tasmania_state_boundaries', 'tasmania_water_bodies', 'tasmania_roads'], tas.layers)
        self.assertEqual(tas.styles, [None, None, None], tas.styles)
Beispiel #50
0
def geoserver_pre_save(instance, sender, **kwargs):
    """Send information to geoserver.

       The attributes sent include:

        * Title
        * Abstract
        * Name
        * Keywords
        * Metadata Links,
        * Point of Contact name and url
    """
    url = ogc_server_settings.rest
    try:
        gs_catalog = Catalog(url, _user, _password)
        gs_resource = gs_catalog.get_resource(instance.name)
    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

    # 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.update_thumbnail(save=False)
Beispiel #51
0
  ws = cat.create_workspace(ws_name, 'http://www.naturalearth.org')

if any(ds.workspace.name == ws.name and ds.name == ds_name for ds in cat.get_stores()):
  print 'datastore already exists...'
  ds = cat.get_store(ds_name, ws_name)
else:
  print 'creating datastore'
  ds = cat.create_datastore(ds_name, ws.name)
  ds.connection_parameters.update(
    host=dbserver,
    port='5432',
    database='ne_tmp',
    user='******',
    password='******',
    dbtype='postgis')
  cat.save(ds)

ds = cat.get_store(ds_name, ws_name)
layers = []
styles = []
threads = []

# add layers
os.chdir('data')
for shp in [ 'ne_10m_land', 'ne_10m_ocean', 'ne_10m_admin_0_boundary_lines_land', 'ne_10m_admin_1_states_provinces_lines_shp', 
             'ne_10m_lakes', 'ne_10m_rivers_lake_centerlines', 'ne_10m_coastline', 'ne_10m_roads', 'ne_10m_urban_areas', 'ne_10m_populated_places' ]:
  if not os.path.isfile(shp + '.shp'):
    continue
  thread = threading.Thread(target=add_layer, args=(shp,))
  thread.name = shp
  thread.start()
Beispiel #52
0
def _register_cascaded_service(url, type, name, username, password, wms=None, owner=None, parent=None):
    """
    Register a service as cascading WMS
    """

    try:
        service = Service.objects.get(base_url=url)
        return_dict = {}
        return_dict["service_id"] = service.pk
        return_dict["msg"] = "This is an existing Service"
        return HttpResponse(json.dumps(return_dict), mimetype="application/json", status=200)
    except:
        # TODO: Handle this error properly
        pass

    if wms is None:
        wms = WebMapService(url)
    # TODO: Make sure we are parsing all service level metadata
    # TODO: Handle for setting ServiceProfiletRole
    service = Service.objects.create(
        base_url=url,
        type=type,
        method="C",
        name=name,
        version=wms.identification.version,
        title=wms.identification.title,
        abstract=wms.identification.abstract,
        online_resource=wms.provider.url,
        owner=owner,
        parent=parent,
    )
    service.keywords = ",".join(wms.identification.keywords)
    service.save()
    service.set_default_permissions()
    if type in ["WMS", "OWS"]:
        # Register the Service with GeoServer to be cascaded
        cat = Catalog(settings.OGC_SERVER["default"]["LOCATION"] + "rest", _user, _password)
        cascade_ws = cat.get_workspace(name)
        if cascade_ws is None:
            cascade_ws = cat.create_workspace(name, "http://geonode.org/" + name)

        # TODO: Make sure there isn't an existing store with that name, and
        # deal with it if there is

        try:
            cascade_store = cat.get_store(name, cascade_ws)
        except:
            cascade_store = cat.create_wmsstore(name, cascade_ws, username, password)
            cascade_store.capabilitiesURL = url
            cascade_store.type = "WMS"
            cat.save(cascade_store)
        available_resources = cascade_store.get_resources(available=True)

    elif type == "WFS":
        # Register the Service with GeoServer to be cascaded
        cat = Catalog(settings.OGC_SERVER["default"]["LOCATION"] + "rest", _user, _password)
        # Can we always assume that it is geonode?
        cascade_ws = cat.get_workspace(settings.CASCADE_WORKSPACE)
        if cascade_ws is None:
            cascade_ws = cat.create_workspace(settings.CASCADE_WORKSPACE, "http://geonode.org/cascade")

        try:
            wfs_ds = cat.get_store(name, cascade_ws)
        except:
            wfs_ds = cat.create_datastore(name, cascade_ws)
            connection_params = {
                "WFSDataStoreFactory:MAXFEATURES": "0",
                "WFSDataStoreFactory:TRY_GZIP": "true",
                "WFSDataStoreFactory:PROTOCOL": "false",
                "WFSDataStoreFactory:LENIENT": "true",
                "WFSDataStoreFactory:TIMEOUT": "3000",
                "WFSDataStoreFactory:BUFFER_SIZE": "10",
                "WFSDataStoreFactory:ENCODING": "UTF-8",
                "WFSDataStoreFactory:WFS_STRATEGY": "nonstrict",
                "WFSDataStoreFactory:GET_CAPABILITIES_URL": url,
            }
            if username and password:
                connection_params["WFSDataStoreFactory:USERNAME"] = username
                connection_params["WFSDataStoreFactory:PASSWORD"] = password

            wfs_ds.connection_parameters = connection_params
            cat.save(wfs_ds)
        available_resources = wfs_ds.get_resources(available=True)

        # Save the Service record
        service, created = Service.objects.get_or_create(type=type, method="C", base_url=url, name=name, owner=owner)
        service.save()
        service.set_default_permissions()
    elif type == "WCS":
        return HttpResponse("Not Implemented (Yet)", status=501)
    else:
        return HttpResponse(
            "Invalid Method / Type combo: " + "Only Cascaded WMS, WFS and WCS supported",
            mimetype="text/plain",
            status=400,
        )

    message = "Service %s registered" % service.name
    return_dict = [
        {
            "status": "ok",
            "msg": message,
            "service_id": service.pk,
            "service_name": service.name,
            "service_title": service.title,
            "available_layers": available_resources,
        }
    ]

    if settings.USE_QUEUE:
        # Create a layer import job
        WebServiceHarvestLayersJob.objects.get_or_create(service=service)
    else:
        _register_cascaded_layers(service)
    return HttpResponse(json.dumps(return_dict), mimetype="application/json", status=200)
Beispiel #53
0
class CatalogTests(unittest.TestCase):
    def setUp(self):
        self.cat = Catalog(GSPARAMS['GSURL'],
                           username=GSPARAMS['GSUSER'],
                           password=GSPARAMS['GSPASSWORD'])

    def testAbout(self):
        about_html = self.cat.about()
        self.assertTrue(
            '<html xmlns="http://www.w3.org/1999/xhtml"' in str(about_html))

    def testGSVersion(self):
        version = self.cat.gsversion()
        pat = re.compile('\d\.\d+(\.[\dx]|-SNAPSHOT)')
        self.assertTrue(pat.match('2.2.x'))
        self.assertTrue(pat.match('2.3.2'))
        self.assertTrue(pat.match('2.3-SNAPSHOT'))
        self.assertTrue(pat.match('2.10.1'))
        self.assertFalse(pat.match('2.3.y'))
        self.assertFalse(pat.match('233'))
        self.assertTrue(pat.match(version))

    def testWorkspaces(self):
        self.assertEqual(7, len(self.cat.get_workspaces()))
        # marking out test since geoserver default workspace is not consistent
        # self.assertEqual("cite", self.cat.get_default_workspace().name)
        self.assertEqual("topp", self.cat.get_workspace("topp").name)
        self.assertEqual("topp", self.cat.get_workspaces("topp")[-1].name)
        self.assertEqual(2,
                         len(self.cat.get_workspaces(names=['topp', 'sde'])))
        self.assertEqual(2, len(self.cat.get_workspaces(names='topp, sde')))

    def testStores(self):
        self.assertEqual(0, len(self.cat.get_stores("nonexistentstore")))
        topp = self.cat.get_workspace("topp")
        sf = self.cat.get_workspace("sf")
        self.assertEqual(9, len(self.cat.get_stores()))
        self.assertEqual(2, len(self.cat.get_stores(workspace=topp)))
        self.assertEqual(2, len(self.cat.get_stores(workspace=sf)))
        self.assertEqual(2, len(self.cat.get_stores(workspace='sf')))
        self.assertEqual(
            2, len(self.cat.get_stores(names='states_shapefile, sfdem')))
        self.assertEqual(
            2, len(self.cat.get_stores(names=['states_shapefile', 'sfdem'])))
        self.assertEqual("sfdem", self.cat.get_stores("sfdem")[-1].name)
        self.assertEqual("states_shapefile",
                         self.cat.get_store("states_shapefile", topp).name)
        self.assertEqual("states_shapefile",
                         self.cat.get_store("states_shapefile").name)
        self.assertEqual("states_shapefile",
                         self.cat.get_store("states_shapefile", "topp").name)
        self.assertEqual("sfdem", self.cat.get_store("sfdem", sf).name)
        self.assertEqual("sfdem", self.cat.get_store("sfdem").name)

    def testResources(self):
        topp = self.cat.get_workspace("topp")
        sf = self.cat.get_workspace("sf")
        states = self.cat.get_store("states_shapefile", topp)
        sfdem = self.cat.get_store("sfdem", sf)
        self.assertEqual(19, len(self.cat.get_resources()))
        self.assertEqual(1, len(self.cat.get_resources(states)))
        self.assertEqual(5, len(self.cat.get_resources(workspace=topp)))
        self.assertEqual(1, len(self.cat.get_resources(sfdem)))
        self.assertEqual(6, len(self.cat.get_resources(workspace=sf)))

        self.assertEqual("states",
                         self.cat.get_resource("states", states).name)
        self.assertEqual("states",
                         self.cat.get_resource("states", workspace=topp).name)
        self.assertEqual("states", self.cat.get_resource("states").name)
        states = self.cat.get_resource("states")

        fields = [
            states.title, states.abstract, states.native_bbox,
            states.latlon_bbox, states.projection, states.projection_policy
        ]

        self.assertFalse(None in fields, str(fields))
        self.assertFalse(len(states.keywords) == 0)
        self.assertFalse(len(states.attributes) == 0)
        self.assertTrue(states.enabled)

        self.assertEqual("sfdem", self.cat.get_resource("sfdem", sfdem).name)
        self.assertEqual("sfdem",
                         self.cat.get_resource("sfdem", workspace=sf).name)
        self.assertEqual("sfdem", self.cat.get_resource("sfdem").name)

    def testResourcesUpdate(self):
        res_dest = self.cat.get_resources()
        count = 0

        for rd in res_dest:
            # only wms layers
            if rd.resource_type != "wmsLayer":
                continue

            # looking for same name
            ro = self.cat.get_resource(rd.name)

            if ro is not None:
                rd.title = ro.title
                rd.abstract = ro.abstract
                rd.keywords = ro.keywords
                rd.projection = ro.projection
                rd.native_bbox = ro.native_bbox
                rd.latlon_bbox = ro.latlon_bbox
                rd.projection_policy = ro.projection_policy
                rd.enabled = ro.enabled
                rd.advertised = ro.advertised
                rd.metadata_links = ro.metadata_links or None

                self.cat.save(rd)
                self.cat.reload()

                # print "Updated layer: " + rd.name
                count += 1

        # print "Total updated layers: " + str(count)

    def testLayers(self):
        expected = set([
            "Arc_Sample", "Pk50095", "Img_Sample", "mosaic", "sfdem",
            "bugsites", "restricted", "streams", "archsites", "roads",
            "tasmania_roads", "tasmania_water_bodies",
            "tasmania_state_boundaries", "tasmania_cities", "states",
            "poly_landmarks", "tiger_roads", "poi", "giant_polygon"
        ])
        actual = set(l.name for l in self.cat.get_layers())
        missing = expected - actual
        extras = actual - expected
        message = "Actual layer list did not match expected! (Extras: %s) (Missing: %s)" % (
            extras, missing)
        self.assertTrue(len(expected ^ actual) == 0, message)

        states = self.cat.get_layer("states")

        self.assertEqual("states", states.name)
        self.assertIsInstance(states.resource, ResourceInfo)
        self.assertEqual(set(s.name for s in states.styles),
                         set(['pophatch', 'polygon']))
        self.assertEqual(states.default_style.name, "population")

    def testLayerGroups(self):
        expected = set(["tasmania", "tiger-ny", "spearfish"])
        actual = set(l.name for l in self.cat.get_layergroups())
        missing = expected - actual
        extras = actual - expected
        message = "Actual layergroup list did not match expected! (Extras: %s) (Missing: %s)" % (
            extras, missing)
        self.assertTrue(len(expected ^ actual) == 0, message)

        tas = self.cat.get_layergroup("tasmania")

        self.assertEqual("tasmania", tas.name)
        self.assertIsInstance(tas, LayerGroup)
        self.assertEqual(tas.layers, [
            'tasmania_state_boundaries', 'tasmania_water_bodies',
            'tasmania_roads', 'tasmania_cities'
        ], tas.layers)
        self.assertEqual(tas.styles, [None, None, None, None], tas.styles)

        # Try to create a new Layer Group into the "topp" workspace
        self.assertIsNotNone(self.cat.get_workspace("topp"))
        tas2 = self.cat.create_layergroup("tasmania_reloaded",
                                          tas.layers,
                                          workspace="topp")
        self.cat.save(tas2)
        self.assertIsNone(self.cat.get_layergroup("tasmania_reloaded"))
        self.assertIsNotNone(
            self.cat.get_layergroup("tasmania_reloaded", "topp"))
        tas2 = self.cat.get_layergroup("tasmania_reloaded", "topp")
        self.assertEqual("tasmania_reloaded", tas2.name)
        self.assertIsInstance(tas2, LayerGroup)
        self.assertEqual(tas2.workspace, "topp", tas2.workspace)
        self.assertEqual(tas2.layers, [
            'tasmania_state_boundaries', 'tasmania_water_bodies',
            'tasmania_roads', 'tasmania_cities'
        ], tas2.layers)
        self.assertEqual(tas2.styles, [None, None, None, None], tas2.styles)

    def testStyles(self):
        self.assertEqual("population", self.cat.get_style("population").name)
        self.assertEqual("popshade.sld",
                         self.cat.get_style("population").filename)
        self.assertEqual("population",
                         self.cat.get_style("population").sld_name)
        self.assertIsNone(self.cat.get_style('non-existing-style'))

    def testEscaping(self):
        # GSConfig is inconsistent about using exceptions vs. returning None
        # when a resource isn't found.
        # But the basic idea is that none of them should throw HTTP errors from
        # misconstructed URLS
        self.cat.get_style("best style ever")
        self.cat.get_workspace("best workspace ever")
        self.assertEqual(
            self.cat.get_store(workspace="best workspace ever",
                               name="best store ever"), None)
        self.cat.get_layer("best layer ever")
        self.cat.get_layergroup("best layergroup ever")

    def testUnicodeUrl(self):
        """
        Tests that the geoserver.support.url function support unicode strings.
        """

        # Test the url function with unicode
        seg = [
            'workspaces', 'test', 'datastores', u'operaci\xf3n_repo',
            'featuretypes.xml'
        ]
        u = url(base=self.cat.service_url, seg=seg)
        self.assertEqual(
            u, self.cat.service_url +
            "/workspaces/test/datastores/operaci%C3%B3n_repo/featuretypes.xml")

        # Test the url function with normal string
        seg = [
            'workspaces', 'test', 'datastores', 'test-repo', 'featuretypes.xml'
        ]
        u = url(base=self.cat.service_url, seg=seg)
        self.assertEqual(
            u, self.cat.service_url +
            "/workspaces/test/datastores/test-repo/featuretypes.xml")
Beispiel #54
0
class ModifyingTests(unittest.TestCase):
    def setUp(self):
        self.cat = Catalog("http://localhost:8080/geoserver/rest")

    def testFeatureTypeSave(self):
        # test saving round trip
        rs = self.cat.get_resource("bugsites")
        old_abstract = rs.abstract
        new_abstract = "Not the original abstract"
        enabled = rs.enabled

        # Change abstract on server
        rs.abstract = new_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(new_abstract, rs.abstract)
        self.assertEqual(enabled, rs.enabled)

        # Change keywords on server
        rs.keywords = ["bugsites", "gsconfig"]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(["bugsites", "gsconfig"], rs.keywords)
        self.assertEqual(enabled, rs.enabled)

        # Change metadata links on server
        rs.metadata_links = [("text/xml", "TC211",
                              "http://example.com/gsconfig.test.metadata")]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual([
            ("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")
        ], rs.metadata_links)
        self.assertEqual(enabled, rs.enabled)

        # Restore abstract
        rs.abstract = old_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("bugsites")
        self.assertEqual(old_abstract, rs.abstract)

    def testDataStoreCreate(self):
        ds = self.cat.create_datastore("vector_gsconfig")
        ds.connection_parameters.update(**DBPARAMS)
        self.cat.save(ds)

    def testPublishFeatureType(self):
        # Use the other test and store creation to load vector data into a database
        # @todo maybe load directly to database?
        try:
            self.testDataStoreCreateAndThenAlsoImportData()
        except FailedRequestError:
            pass
        try:
            lyr = self.cat.get_layer('import')
            # Delete the existing layer and resource to allow republishing.
            self.cat.delete(lyr)
            self.cat.delete(lyr.resource)
            ds = self.cat.get_store("gsconfig_import_test")
            # make sure it's gone
            self.assert_(self.cat.get_layer('import') is None)
            self.cat.publish_featuretype("import", ds, native_crs="EPSG:4326")
            # and now it's not
            self.assert_(self.cat.get_layer('import') is not None)
        finally:
            # tear stuff down to allow the other test to pass if we run first
            ds = self.cat.get_store("gsconfig_import_test")
            lyr = self.cat.get_layer('import')
            # Delete the existing layer and resource to allow republishing.
            self.cat.delete(lyr)
            self.cat.delete(lyr.resource)
            self.cat.delete(ds)

    def testDataStoreModify(self):
        ds = self.cat.get_store("sf")
        self.assertFalse("foo" in ds.connection_parameters)
        ds.connection_parameters = ds.connection_parameters
        ds.connection_parameters["foo"] = "bar"
        orig_ws = ds.workspace.name
        self.cat.save(ds)
        ds = self.cat.get_store("sf")
        self.assertTrue("foo" in ds.connection_parameters)
        self.assertEqual("bar", ds.connection_parameters["foo"])
        self.assertEqual(orig_ws, ds.workspace.name)

    @drop_table('import')
    def testDataStoreCreateAndThenAlsoImportData(self):
        ds = self.cat.create_datastore("gsconfig_import_test")
        ds.connection_parameters.update(**DBPARAMS)
        self.cat.save(ds)
        ds = self.cat.get_store("gsconfig_import_test")
        self.cat.add_data_to_store(
            ds, "import", {
                'shp': 'test/data/states.shp',
                'shx': 'test/data/states.shx',
                'dbf': 'test/data/states.dbf',
                'prj': 'test/data/states.prj'
            })

    def testCoverageStoreCreate(self):
        ds = self.cat.create_coveragestore2("coverage_gsconfig")
        ds.data_url = "file:data/mytiff.tiff"
        self.cat.save(ds)

    def testCoverageStoreModify(self):
        cs = self.cat.get_store("sfdem")
        self.assertEqual("GeoTIFF", cs.type)
        cs.type = "WorldImage"
        self.cat.save(cs)
        cs = self.cat.get_store("sfdem")
        self.assertEqual("WorldImage", cs.type)

        # not sure about order of test runs here, but it might cause problems
        # for other tests if this layer is misconfigured
        cs.type = "GeoTIFF"
        self.cat.save(cs)

    def testCoverageSave(self):
        # test saving round trip
        rs = self.cat.get_resource("Arc_Sample")
        old_abstract = rs.abstract
        new_abstract = "Not the original abstract"

        # # Change abstract on server
        rs.abstract = new_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(new_abstract, rs.abstract)

        # Restore abstract
        rs.abstract = old_abstract
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual(old_abstract, rs.abstract)

        # Change metadata links on server
        rs.metadata_links = [("text/xml", "TC211",
                              "http://example.com/gsconfig.test.metadata")]
        enabled = rs.enabled
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEqual([
            ("text/xml", "TC211", "http://example.com/gsconfig.test.metadata")
        ], rs.metadata_links)
        self.assertEqual(enabled, rs.enabled)

        srs_before = set(['EPSG:4326'])
        srs_after = set(['EPSG:4326', 'EPSG:3785'])
        formats = set(
            ['ARCGRID', 'ARCGRID-GZIP', 'GEOTIFF', 'PNG', 'GIF', 'TIFF'])
        formats_after = set(["PNG", "GIF", "TIFF"])

        # set and save request_srs_list
        self.assertEquals(set(rs.request_srs_list), srs_before,
                          str(rs.request_srs_list))
        rs.request_srs_list = rs.request_srs_list + ['EPSG:3785']
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEquals(set(rs.request_srs_list), srs_after,
                          str(rs.request_srs_list))

        # set and save response_srs_list
        self.assertEquals(set(rs.response_srs_list), srs_before,
                          str(rs.response_srs_list))
        rs.response_srs_list = rs.response_srs_list + ['EPSG:3785']
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEquals(set(rs.response_srs_list), srs_after,
                          str(rs.response_srs_list))

        # set and save supported_formats
        self.assertEquals(set(rs.supported_formats), formats,
                          str(rs.supported_formats))
        rs.supported_formats = ["PNG", "GIF", "TIFF"]
        self.cat.save(rs)
        rs = self.cat.get_resource("Arc_Sample")
        self.assertEquals(set(rs.supported_formats), formats_after,
                          str(rs.supported_formats))

    def testWmsStoreCreate(self):
        ws = self.cat.create_wmsstore("wmsstore_gsconfig")
        ws.capabilitiesURL = "http://suite.opengeo.org/geoserver/ows?service=wms&version=1.1.1&request=GetCapabilities"
        ws.type = "WMS"
        self.cat.save(ws)

    def testWmsLayer(self):
        self.cat.create_workspace("wmstest", "http://example.com/wmstest")
        wmstest = self.cat.get_workspace("wmstest")
        wmsstore = self.cat.create_wmsstore("wmsstore", wmstest)
        wmsstore.capabilitiesURL = "http://suite.opengeo.org/geoserver/ows?service=wms&version=1.1.1&request=GetCapabilities"
        wmsstore.type = "WMS"
        self.cat.save(wmsstore)
        wmsstore = self.cat.get_store("wmsstore")
        self.assertEqual(1, len(self.cat.get_stores(wmstest)))
        available_layers = wmsstore.get_resources(available=True)
        for layer in available_layers:
            # sanitize the layer name - validation will fail on newer geoservers
            name = layer.replace(':', '_')
            new_layer = self.cat.create_wmslayer(wmstest,
                                                 wmsstore,
                                                 name,
                                                 nativeName=layer)
        added_layers = wmsstore.get_resources()
        self.assertEqual(len(available_layers), len(added_layers))

        changed_layer = added_layers[0]
        self.assertEqual(True, changed_layer.advertised)
        self.assertEqual(True, changed_layer.enabled)
        changed_layer.advertised = False
        changed_layer.enabled = False
        self.cat.save(changed_layer)
        self.cat._cache.clear()
        changed_layer = wmsstore.get_resources()[0]
        changed_layer.fetch()
        self.assertEqual(False, changed_layer.advertised)
        self.assertEqual(False, changed_layer.enabled)

    def testFeatureTypeCreate(self):
        shapefile_plus_sidecars = shapefile_and_friends("test/data/states")
        expected = {
            'shp': 'test/data/states.shp',
            'shx': 'test/data/states.shx',
            'dbf': 'test/data/states.dbf',
            'prj': 'test/data/states.prj'
        }

        self.assertEqual(len(expected), len(shapefile_plus_sidecars))
        for k, v in expected.iteritems():
            self.assertEqual(v, shapefile_plus_sidecars[k])

        sf = self.cat.get_workspace("sf")
        self.cat.create_featurestore("states_test", shapefile_plus_sidecars,
                                     sf)

        self.assert_(
            self.cat.get_resource("states_test", workspace=sf) is not None)

        self.assertRaises(
            ConflictingDataError, lambda: self.cat.create_featurestore(
                "states_test", shapefile_plus_sidecars, sf))

        self.assertRaises(
            UploadError, lambda: self.cat.create_coveragestore(
                "states_raster_test", shapefile_plus_sidecars, sf))

        bogus_shp = {
            'shp': 'test/data/Pk50095.tif',
            'shx': 'test/data/Pk50095.tif',
            'dbf': 'test/data/Pk50095.tfw',
            'prj': 'test/data/Pk50095.prj'
        }

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_featurestore("bogus_shp", bogus_shp, sf))

        lyr = self.cat.get_layer("states_test")
        self.cat.delete(lyr)
        self.assert_(self.cat.get_layer("states_test") is None)

    def testCoverageCreate(self):
        tiffdata = {
            'tiff': 'test/data/Pk50095.tif',
            'tfw': 'test/data/Pk50095.tfw',
            'prj': 'test/data/Pk50095.prj'
        }

        sf = self.cat.get_workspace("sf")
        # TODO: Uploading WorldImage file no longer works???
        # ft = self.cat.create_coveragestore("Pk50095", tiffdata, sf)

        # self.assert_(self.cat.get_resource("Pk50095", workspace=sf) is not None)

        # self.assertRaises(
        #         ConflictingDataError,
        #         lambda: self.cat.create_coveragestore("Pk50095", tiffdata, sf)
        # )

        self.assertRaises(
            UploadError, lambda: self.cat.create_featurestore(
                "Pk50095_vector", tiffdata, sf))

        bogus_tiff = {
            'tiff': 'test/data/states.shp',
            'tfw': 'test/data/states.shx',
            'prj': 'test/data/states.prj'
        }

        self.assertRaises(
            UploadError,
            lambda: self.cat.create_coveragestore("states_raster", bogus_tiff))

    def testLayerSave(self):
        # test saving round trip
        lyr = self.cat.get_layer("states")
        old_attribution = lyr.attribution
        new_attribution = "Not the original attribution"

        # change attribution on server
        lyr.attribution = new_attribution
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(new_attribution, lyr.attribution)

        # Restore attribution
        lyr.attribution = old_attribution
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(old_attribution, lyr.attribution)

        self.assertEqual(lyr.default_style.name, "population")

        old_default_style = lyr.default_style
        lyr.default_style = (s for s in lyr.styles
                             if s.name == "pophatch").next()
        lyr.styles = [old_default_style]
        self.cat.save(lyr)
        lyr = self.cat.get_layer("states")
        self.assertEqual(lyr.default_style.name, "pophatch")
        self.assertEqual([s.name for s in lyr.styles], ["population"])

    def testStyles(self):
        # upload new style, verify existence
        self.cat.create_style("fred", open("test/fred.sld").read())
        fred = self.cat.get_style("fred")
        self.assert_(fred is not None)
        self.assertEqual("Fred", fred.sld_title)

        # replace style, verify changes
        self.cat.create_style("fred",
                              open("test/ted.sld").read(),
                              overwrite=True)
        fred = self.cat.get_style("fred")
        self.assert_(fred is not None)
        self.assertEqual("Ted", fred.sld_title)

        # delete style, verify non-existence
        self.cat.delete(fred, purge=True)
        self.assert_(self.cat.get_style("fred") is None)

        # attempt creating new style
        self.cat.create_style("fred", open("test/fred.sld").read())
        fred = self.cat.get_style("fred")
        self.assertEqual("Fred", fred.sld_title)

        # verify it can be found via URL and check the name
        f = self.cat.get_style_by_url(fred.href)
        self.assert_(f is not None)
        self.assertEqual(f.name, fred.name)

    def testWorkspaceStyles(self):
        # upload new style, verify existence
        self.cat.create_style("jed",
                              open("test/fred.sld").read(),
                              workspace="topp")

        jed = self.cat.get_style("jed", workspace="blarny")
        self.assert_(jed is None)
        jed = self.cat.get_style("jed", workspace="topp")
        self.assert_(jed is not None)
        self.assertEqual("Fred", jed.sld_title)
        jed = self.cat.get_style("topp:jed")
        self.assert_(jed is not None)
        self.assertEqual("Fred", jed.sld_title)

        # replace style, verify changes
        self.cat.create_style("jed",
                              open("test/ted.sld").read(),
                              overwrite=True,
                              workspace="topp")
        jed = self.cat.get_style("jed", workspace="topp")
        self.assert_(jed is not None)
        self.assertEqual("Ted", jed.sld_title)

        # delete style, verify non-existence
        self.cat.delete(jed, purge=True)
        self.assert_(self.cat.get_style("jed", workspace="topp") is None)

        # attempt creating new style
        self.cat.create_style("jed",
                              open("test/fred.sld").read(),
                              workspace="topp")
        jed = self.cat.get_style("jed", workspace="topp")
        self.assertEqual("Fred", jed.sld_title)

        # verify it can be found via URL and check the full name
        f = self.cat.get_style_by_url(jed.href)
        self.assert_(f is not None)
        self.assertEqual(f.fqn, jed.fqn)

    def testLayerWorkspaceStyles(self):
        # upload new style, verify existence
        self.cat.create_style("ned",
                              open("test/fred.sld").read(),
                              overwrite=True,
                              workspace="topp")
        self.cat.create_style("zed",
                              open("test/ted.sld").read(),
                              overwrite=True,
                              workspace="topp")
        ned = self.cat.get_style("ned", workspace="topp")
        zed = self.cat.get_style("zed", workspace="topp")
        self.assert_(ned is not None)
        self.assert_(zed is not None)

        lyr = self.cat.get_layer("states")
        lyr.default_style = ned
        lyr.styles = [zed]
        self.cat.save(lyr)
        self.assertEqual("topp:ned", lyr.default_style)
        self.assertEqual([zed], lyr.styles)

        lyr.refresh()
        self.assertEqual("topp:ned", lyr.default_style.fqn)
        self.assertEqual([zed.fqn], [s.fqn for s in lyr.styles])

    def testWorkspaceCreate(self):
        ws = self.cat.get_workspace("acme")
        self.assertEqual(None, ws)
        self.cat.create_workspace("acme", "http://example.com/acme")
        ws = self.cat.get_workspace("acme")
        self.assertEqual("acme", ws.name)

    def testWorkspaceDelete(self):
        self.cat.create_workspace("foo", "http://example.com/foo")
        ws = self.cat.get_workspace("foo")
        self.cat.delete(ws)
        ws = self.cat.get_workspace("foo")
        self.assert_(ws is None)

    def testWorkspaceDefault(self):
        # save orig
        orig = self.cat.get_default_workspace()
        neu = self.cat.create_workspace("neu", "http://example.com/neu")
        try:
            # make sure setting it works
            self.cat.set_default_workspace("neu")
            ws = self.cat.get_default_workspace()
            self.assertEqual('neu', ws.name)
        finally:
            # cleanup and reset to the way things were
            self.cat.delete(neu)
            self.cat.set_default_workspace(orig.name)
            ws = self.cat.get_default_workspace()
            self.assertEqual(orig.name, ws.name)

    def testFeatureTypeDelete(self):
        pass

    def testCoverageDelete(self):
        pass

    def testDataStoreDelete(self):
        states = self.cat.get_store('states_shapefile')
        self.assert_(states.enabled == True)
        states.enabled = False
        self.assert_(states.enabled == False)
        self.cat.save(states)

        states = self.cat.get_store('states_shapefile')
        self.assert_(states.enabled == False)

        states.enabled = True
        self.cat.save(states)

        states = self.cat.get_store('states_shapefile')
        self.assert_(states.enabled == True)

    def testLayerGroupSave(self):
        tas = self.cat.get_layergroup("tasmania")

        self.assertEqual(tas.layers, [
            'tasmania_state_boundaries', 'tasmania_water_bodies',
            'tasmania_roads', 'tasmania_cities'
        ], tas.layers)
        self.assertEqual(tas.styles, [None, None, None, None], tas.styles)

        tas.layers = tas.layers[:-1]
        tas.styles = tas.styles[:-1]

        self.cat.save(tas)

        # this verifies the local state
        self.assertEqual(tas.layers, [
            'tasmania_state_boundaries', 'tasmania_water_bodies',
            'tasmania_roads'
        ], tas.layers)
        self.assertEqual(tas.styles, [None, None, None], tas.styles)

        # force a refresh to check the remote state
        tas.refresh()
        self.assertEqual(tas.layers, [
            'tasmania_state_boundaries', 'tasmania_water_bodies',
            'tasmania_roads'
        ], tas.layers)
        self.assertEqual(tas.styles, [None, None, None], tas.styles)

    def testTimeDimension(self):
        sf = self.cat.get_workspace("sf")
        files = shapefile_and_friends(
            os.path.join(gisdata.GOOD_DATA, "time", "boxes_with_end_date"))
        self.cat.create_featurestore("boxes_with_end_date", files, sf)

        get_resource = lambda: self.cat._cache.clear() or self.cat.get_layer(
            'boxes_with_end_date').resource

        # configure time as LIST
        resource = get_resource()
        timeInfo = DimensionInfo("time",
                                 "true",
                                 "LIST",
                                 None,
                                 "ISO8601",
                                 None,
                                 attribute="date")
        resource.metadata = {'time': timeInfo}
        self.cat.save(resource)
        # and verify
        resource = get_resource()
        timeInfo = resource.metadata['time']
        self.assertEqual("LIST", timeInfo.presentation)
        self.assertEqual(True, timeInfo.enabled)
        self.assertEqual("date", timeInfo.attribute)
        self.assertEqual("ISO8601", timeInfo.units)

        # disable time dimension
        timeInfo = resource.metadata['time']
        timeInfo.enabled = False
        # since this is an xml property, it won't get written unless we modify it
        resource.metadata = {'time': timeInfo}
        self.cat.save(resource)
        # and verify
        resource = get_resource()
        timeInfo = resource.metadata['time']
        self.assertEqual(False, timeInfo.enabled)

        # configure with interval, end_attribute and enable again
        timeInfo.enabled = True
        timeInfo.presentation = 'DISCRETE_INTERVAL'
        timeInfo.resolution = '3 days'
        timeInfo.end_attribute = 'enddate'
        resource.metadata = {'time': timeInfo}
        self.cat.save(resource)
        # and verify
        resource = get_resource()
        timeInfo = resource.metadata['time']
        self.assertEqual(True, timeInfo.enabled)
        self.assertEqual('DISCRETE_INTERVAL', timeInfo.presentation)
        self.assertEqual('3 days', timeInfo.resolution_str())
        self.assertEqual('enddate', timeInfo.end_attribute)

    def testImageMosaic(self):
        # testing the mosaic creation
        name = 'cea_mosaic'
        data = open('test/data/mosaic/cea.zip', 'rb')
        self.cat.create_imagemosaic(name, data)

        # get the layer resource back
        self.cat._cache.clear()
        resource = self.cat.get_layer(name).resource

        self.assert_(resource is not None)

        # delete granule from mosaic
        coverage = name
        store = name
        granule_id = name + '.1'
        self.cat.mosaic_delete_granule(coverage, store, granule_id)
from geoserver.catalog import Catalog

cat = Catalog('http://localhost:8080/geoserver/rest')
ds = cat.create_datastore('riskinfo_lk','geonode')
ds.connection_parameters.update(host='localhost', port='5432', database='riskinfo_lk', user='******', passwd='riskinfo_lk', dbtype='postgis', schema='public')
cat.save(ds)
#!/usr/bin/env python
"""
gsconfig is a python library for manipulating a GeoServer instance via the GeoServer RESTConfig API.

The project is distributed under a MIT License .
"""

__author__ = "David Winslow"
__copyright__ = "Copyright 2012-2015 Boundless, Copyright 2010-2012 OpenPlans"
__license__ = "MIT"

from geoserver.catalog import Catalog

cat = Catalog("http://localhost:8080/geoserver/rest", "admin", "geoserver")
name = 'foo'

ds = cat.create_datastore(name)
ds.connection_parameters.update(host="localhost",
                                port="5432",
                                database="gis",
                                user="******",
                                passwd="",
                                dbtype="postgis")

cat.save(ds)
ds = cat.get_store(name)
components = \
    dict((ext, "myfile." + ext) for ext in ["shp", "prj", "shx", "dbf"])
cat.add_data_to_store(ds, "mylayer", components)
Beispiel #57
0
class CatalogTests(unittest.TestCase):
    def setUp(self):
        self.cat = Catalog(GSPARAMS['GSURL'], username=GSPARAMS['GSUSER'], password=GSPARAMS['GSPASSWORD'])
        self.gs_version = self.cat.get_short_version()

    def testGSVersion(self):
        version = self.cat.get_version()
        pat = re.compile('\d\.\d+')
        self.assertTrue(pat.match('2.2.x'))
        self.assertTrue(pat.match('2.3.2'))
        self.assertTrue(pat.match('2.3-SNAPSHOT'))
        self.assertTrue(pat.match(version))

    def testWorkspaces(self):
        self.assertEqual(7, len(self.cat.get_workspaces()))
        # marking out test since geoserver default workspace is not consistent
        # self.assertEqual("cite", self.cat.get_default_workspace().name)
        self.assertEqual("topp", self.cat.get_workspaces(names="topp")[-1].name)
        self.assertEqual(2, len(self.cat.get_workspaces(names=['topp', 'sde'])))
        self.assertEqual(2, len(self.cat.get_workspaces(names='topp, sde')))
        self.assertEqual("topp", self.cat.get_workspace("topp").name)
        self.assertIsNone(self.cat.get_workspace("blahblah-"))

    def testStores(self):
        self.assertEqual(0, len(self.cat.get_stores(names="nonexistentstore")))
        topp = self.cat.get_workspaces("topp")[0]
        sf = self.cat.get_workspaces("sf")[0]
        self.assertEqual(9, len(self.cat.get_stores()))
        self.assertEqual(2, len(self.cat.get_stores(workspaces=topp)))
        self.assertEqual(2, len(self.cat.get_stores(workspaces=sf)))
        self.assertEqual(2, len(self.cat.get_stores(workspaces='sf')))
        self.assertEqual(2, len(self.cat.get_stores(names='states_shapefile, sfdem')))
        self.assertEqual(2, len(self.cat.get_stores(names=['states_shapefile', 'sfdem'])))
        self.assertEqual("states_shapefile", self.cat.get_stores(names="states_shapefile", workspaces=topp.name)[0].name)
        self.assertEqual("states_shapefile", self.cat.get_stores(names="states_shapefile")[0].name)
        self.assertEqual("sfdem", self.cat.get_stores(names="sfdem", workspaces=sf.name)[0].name)
        self.assertEqual("sfdem", self.cat.get_stores(names="sfdem")[0].name)
        self.assertEqual("sfdem", self.cat.get_store("sfdem").name)
        self.assertIsNone(self.cat.get_store("blah+blah-"))

    def testResources(self):
        topp = self.cat.get_workspaces("topp")[0]
        sf = self.cat.get_workspaces("sf")[0]
        states = self.cat.get_stores(names="states_shapefile", workspaces=topp.name)[0]
        sfdem = self.cat.get_stores(names="sfdem", workspaces=sf.name)[0]
        self.assertEqual(19, len(self.cat.get_resources()))
        self.assertEqual(2, len(self.cat.get_resources(stores=[states.name, sfdem.name])))
        self.assertEqual(11, len(self.cat.get_resources(workspaces=[topp.name, sf.name])))

        self.assertEqual("states", self.cat.get_resources(names="states", stores=states.name)[0].name)
        self.assertEqual("states", self.cat.get_resources(names="states", workspaces=topp.name)[0].name)
        self.assertEqual("states", self.cat.get_resources(names="states")[0].name)
        self.assertEqual("states", self.cat.get_resource("states").name)
        self.assertIsNone(self.cat.get_resource("blah+1blah-2"))

        states = self.cat.get_resources(names="states")[0]

        fields = [
            states.title,
            states.abstract,
            states.native_bbox,
            states.latlon_bbox,
            states.projection,
            states.projection_policy
        ]

        self.assertFalse(None in fields, str(fields))
        self.assertFalse(len(states.keywords) == 0)
        self.assertFalse(len(states.attributes) == 0)
        self.assertTrue(states.enabled)

        self.assertEqual("sfdem", self.cat.get_resources(names="sfdem", stores=sfdem.name)[0].name)
        self.assertEqual("sfdem", self.cat.get_resources(names="sfdem", workspaces=sf.name)[0].name)
        self.assertEqual("sfdem", self.cat.get_resources(names="sfdem")[0].name)

    def testResourcesUpdate(self):
        res_dest = self.cat.get_resources()
        count = 0

        for rd in res_dest:
            # only wms layers
            if rd.resource_type != "wmsLayer":
                continue
            # looking for same name
            ro = self.cat.get_resources(names=rd.name)

            if ro is not None:
                rd.title = ro.title
                rd.abstract = ro.abstract
                rd.keywords = ro.keywords
                rd.projection = ro.projection
                rd.native_bbox = ro.native_bbox
                rd.latlon_bbox = ro.latlon_bbox
                rd.projection_policy = ro.projection_policy
                rd.enabled = ro.enabled
                rd.advertised = ro.advertised
                rd.metadata_links = ro.metadata_links or None

                self.cat.save(rd)
                self.cat.reload()
                count += 1

    def testLayers(self):
        if self.gs_version >= "2.13":
            expected = set([
                'sf:roads',
                'sf:sfdem',
                'nurc:mosaic',
                'tiger:giant_polygon',
                'sf:bugsites',
                'topp:states',
                'sf:streams',
                'tiger:poly_landmarks',
                'tiger:poi',
                'topp:tasmania_water_bodies',
                'tiger:tiger_roads',
                'topp:tasmania_roads',
                'nurc:Pk50095',
                'topp:tasmania_cities',
                'nurc:Img_Sample',
                'sf:restricted',
                'nurc:Arc_Sample',
                'sf:archsites',
                'topp:tasmania_state_boundaries'
            ])
        else:
            expected = set([
                "Arc_Sample",
                "Pk50095",
                "Img_Sample",
                "mosaic",
                "sfdem",
                "bugsites",
                "restricted",
                "streams",
                "archsites",
                "roads",
                "tasmania_roads",
                "tasmania_water_bodies",
                "tasmania_state_boundaries",
                "tasmania_cities",
                "states",
                "poly_landmarks",
                "tiger_roads",
                "poi",
                "giant_polygon"
            ])

        actual = set(l.name for l in self.cat.get_layers())
        missing = expected - actual
        extras = actual - expected
        message = "Actual layer list did not match expected! (Extras: %s) (Missing: %s)" % (extras, missing)
        self.assert_(len(expected ^ actual) == 0, message)

        states = self.cat.get_layer("states")

        self.assert_("states", states.name)
        self.assert_(isinstance(states.resource, ResourceInfo))
        self.assertEqual(set(s.name for s in states.styles), set(['pophatch', 'polygon']))
        self.assertEqual(states.default_style.name, "population")

    def testLayerGroups(self):
        expected = set(["tasmania", "tiger-ny", "spearfish"])
        actual = set(l.name for l in self.cat.get_layergroups(names=["tasmania", "tiger-ny", "spearfish"]))
        missing = expected - actual
        extras = actual - expected
        message = "Actual layergroup list did not match expected! (Extras: %s) (Missing: %s)" % (extras, missing)
        self.assert_(len(expected ^ actual) == 0, message)

        tas = self.cat.get_layergroups(names="tasmania")[0]

        self.assert_("tasmania", tas.name)
        self.assert_(isinstance(tas, LayerGroup))
        if self.gs_version >= "2.13":
            self.assertEqual(tas.layers, [
                'topp:tasmania_state_boundaries',
                'topp:tasmania_water_bodies',
                'topp:tasmania_roads',
                'topp:tasmania_cities'
            ], tas.layers)
        else:
            self.assertEqual(tas.layers, [
                'tasmania_state_boundaries',
                'tasmania_water_bodies',
                'tasmania_roads',
                'tasmania_cities'
            ], tas.layers)
        self.assertEqual(tas.styles, [None, None, None, None], tas.styles)

        # Try to create a new Layer Group into the "topp" workspace
        self.assert_(self.cat.get_workspaces("topp")[0] is not None)
        tas2 = self.cat.create_layergroup("tasmania_reloaded", tas.layers, workspace = "topp")
        self.cat.save(tas2)
        self.assertEqual(1, len(self.cat.get_layergroups(names='tasmania_reloaded', workspaces="topp")))
        tas2 = self.cat.get_layergroups(names='tasmania_reloaded', workspaces="topp")[0]
        self.assert_("tasmania_reloaded", tas2.name)
        self.assert_(isinstance(tas2, LayerGroup))
        self.assertEqual(tas2.workspace, "topp", tas2.workspace)
        if self.gs_version >= "2.13":
            self.assertEqual(tas2.layers, [
                'topp:tasmania_state_boundaries',
                'topp:tasmania_water_bodies',
                'topp:tasmania_roads',
                'topp:tasmania_cities'
            ], tas2.layers)
        else:
            self.assertEqual(tas2.layers, [
                'tasmania_state_boundaries',
                'tasmania_water_bodies',
                'tasmania_roads',
                'tasmania_cities'
            ], tas2.layers)
        self.assertEqual(tas2.styles, [None, None, None, None], tas2.styles)

    def testStyles(self):
        self.assertEqual("population", self.cat.get_styles("population")[0].name)
        self.assertEqual("popshade.sld", self.cat.get_styles("population")[0].filename)
        self.assertEqual("population", self.cat.get_styles("population")[0].sld_name)
        self.assertEqual("population", self.cat.get_style("population").sld_name)
        self.assertIsNone(self.cat.get_style("blah+#5blah-"))
        self.assertEqual(0, len(self.cat.get_styles('non-existing-style')))

    def testEscaping(self):
        # GSConfig is inconsistent about using exceptions vs. returning None
        # when a resource isn't found.
        # But the basic idea is that none of them should throw HTTP errors from
        # misconstructed URLS
        self.cat.get_styles("best style ever")
        self.cat.get_workspaces("best workspace ever")
        self.assertEqual(0, len(self.cat.get_stores(workspaces="best workspace ever", names="best store ever")))
        self.cat.get_layer("best layer ever")
        self.cat.get_layergroups("best layergroup ever")

    def testUnicodeUrl(self):
        """
        Tests that the geoserver.support.url function support unicode strings.
        """

        # Test the url function with unicode
        seg = ['workspaces', 'test', 'datastores', u'operaci\xf3n_repo', 'featuretypes.xml']
        u = build_url(base=self.cat.service_url, seg=seg)
        self.assertEqual(u, self.cat.service_url + "/workspaces/test/datastores/operaci%C3%B3n_repo/featuretypes.xml")

        # Test the url function with normal string
        seg = ['workspaces', 'test', 'datastores', 'test-repo', 'featuretypes.xml']
        u = build_url(base=self.cat.service_url, seg=seg)
        self.assertEqual(u, self.cat.service_url + "/workspaces/test/datastores/test-repo/featuretypes.xml")