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)
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
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
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)
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()
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()
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)
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
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)
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
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
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
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)
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
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)
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)
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()
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
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
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))
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)
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)
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)
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)
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"])))
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)
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)
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
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)
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)")
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)
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'))
#!/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'))
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)
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)
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()
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)
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")
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)
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")