def upload_style(self, style_name, style_file, verbose=False): """Upload style file to geoserver """ # curl -u geoserver -XPOST -H 'Content-type: text/xml' -d # '<style><name>sld_for_Pk50095_geotif_style</name><filename>Pk50095.sld</filename></style>' # localhost:8080/geoserver/rest/styles/ try: curl(self.geoserver_url, self.geoserver_username, self.geoserver_userpass, 'POST', 'text/xml', 'styles', '--data-ascii', '<style><name>%s</name><filename>%s</filename></style>' % (style_name, style_file), verbose=verbose) except Exception, e: if str(e).find('already exists') > 0: # Style already exists, no worries pass else: # Reraise msg = 'Could not create style %s: %s' % (style_name, e) raise Exception(msg)
def create_workspace(self, name, verbose=False): """Create new workspace on the geoserver Generate and execute curl commands of the form curl -u admin:geoserver -v -X POST -H "Content-type: text/xml" \ "http://localhost:8080/geoserver/rest/workspaces" --data-ascii \ "<workspace><name>aifdr</name></workspace>" """ try: curl(self.geoserver_url, self.geoserver_username, self.geoserver_userpass, 'POST', 'text/xml', 'workspaces', '--data-ascii', '<workspace><name>%s</name></workspace>' % name, verbose=verbose) except Exception, e: if str(e).find('already exists') > 0: # Workspace already exists, no worries pass else: # Reraise msg = 'Could not create workspace %s: %s' % (name, e) raise Exception(msg)
def set_default_style(self, style_name, layer_name, verbose=False): """Set given style as default for specified layer""" curl(self.geoserver_url, self.geoserver_username, self.geoserver_userpass, 'PUT', 'text/xml', 'layers/%s' % (layer_name), '--data-ascii', '<layer><defaultStyle><name>%s</name></defaultStyle><enabled>true</enabled></layer>' % style_name, verbose=verbose)
def get_workspace(self, name, verbose=False): """Get workspace info from the geoserver """ # FIXME(Ole): Unfortunate name as it doesn't return anything out = curl(self.geoserver_url, self.geoserver_username, self.geoserver_userpass, 'GET', 'text/xml', 'workspaces/%s' % name, '', '', verbose=verbose) succes = False for line in out: if line.startswith('Workspace'): if line.split()[1][1:-1] == name: succes = True break if not succes: msg = 'Could not find workspace %s in geoserver %s' % (name, self.geoserver_url) raise Exception(msg)
def delete_layer(self, layer_name, workspace, verbose=False): """Delete layer on server This is done through REST in three steps with commands like this: curl -u admin:geoserver -v -X DELETE "http://localhost:8080/geoserver/rest/layers/shakemap_padang_20090930" curl -u admin:geoserver -v -X DELETE "http://localhost:8080/geoserver/rest/workspaces/hazard/coveragestores/shakemap_padang_20090930/coverages/shakemap_padang_20090930" curl -u admin:geoserver -v -X DELETE "http://localhost:8080/geoserver/rest/workspaces/hazard/coveragestores/shakemap_padang_20090930" In newer versions of GeoServer it can done like this: curl -u admin:geoserver -v -X DELETE "http://localhost:8080/geoserver/rest/workspaces/hazard/coveragestores/shakemap_padang_20090930?recurse=true" """ if not layer_name: msg = 'Valid layer name was not provided for deletion. I got "%s"' % str(layer_name) raise Exception(msg) # Delete layer curl(self.geoserver_url, self.geoserver_username, self.geoserver_userpass, 'DELETE', '', 'layers/%s' % layer_name, '', '', verbose=verbose) # Delete associated coverages curl(self.geoserver_url, self.geoserver_username, self.geoserver_userpass, 'DELETE', '', 'workspaces/%s/coveragestores/%s/coverages/%s' % (workspace, layer_name, layer_name), '', '', verbose=verbose) # Delete associated coverage store curl(self.geoserver_url, self.geoserver_username, self.geoserver_userpass, 'DELETE', '', 'workspaces/%s/coveragestores/%s' % (workspace, layer_name), '', '', verbose=verbose)
def upload_vector_layer(self, filename, workspace, verbose=False): """Upload vector file to named layer Valid file types are Zipped shapefile with extension *.zip Or it can be the name of the main shapefiel (*.shp) in which case it will be zipped up before upload. Uploads are done using curl commands of the form curl -u admin:geoserver -v -X PUT -H "Content-type: application/zip" "http://localhost:8080/geoserver/rest/workspaces/futnuh/datastores/volcanoes/file.shp" --data-binary @volcanoes.zip """ subdir = os.path.split(filename)[0] local_filename = os.path.split(filename)[1] layername, extension = os.path.splitext(local_filename) upload_filename = layername + '.zip' style_filename = layername + '.sld' # Locally stored provided_style_filename = os.path.join(subdir, style_filename) # In case it accompanies the file msg = 'Vector data must have extension zip or shp' assert extension in ['.zip', '.shp'], msg if extension == '.shp': projection_filename = os.path.join(subdir, layername) + '.prj' try: fid = open(projection_filename) except: msg = 'Could not open projection file %s' % projection_filename raise Exception(msg) else: fid.close() # Zip shapefile and auxiliary files cmd = 'cd %s; zip %s %s*' % (subdir, upload_filename, layername) run(cmd, stdout='zip.stdout', stderr='zip.stderr', verbose=verbose) # Move to cwd # FIXME (Ole): For some reason geoserver won't accept the zip file unless # located in CWD. # FIXME (Ole): If zip file already exists with different owner, this # will silently wait for a newline. Annoying. cmd = 'mv %s/%s .' % (subdir, upload_filename) run(cmd, stdout='mvzip.stdout', stderr='mvzip.stderr', verbose=verbose) else: # Already zipped - FIXME: Need to test if it is indeed a zipped shape file pass # Upload vector data to Geoserver curl(self.geoserver_url, self.geoserver_username, self.geoserver_userpass, 'PUT', 'application/zip', 'workspaces/%s/datastores/%s/file.shp' % (workspace, layername), '--data-binary', '@%s' % upload_filename, verbose=verbose) # Take care of styling if os.path.isfile(provided_style_filename): # Use provided style file # Copy provide file to local directory because the REST interface # spits the dummy with pathnames. cmd = 'cp %s %s' % (provided_style_filename, os.getcwd()) run(cmd, verbose=False) else: # Automatically create new style file for vector file (FIXME: Not yet implemented) #self.create_vector_sld(upload_filename) return '%s:%s' % (workspace, layername) # Upload style file to Geoserver self.upload_style(layername, style_filename, verbose=verbose) # Make it the default for this layer self.set_default_style(layername, layername, verbose=verbose) return '%s:%s' % (workspace, layername)
def upload_coverage(self, filename, workspace, verbose=False): """Upload raster file to named layer Valid file types are ASCII with appropriate projection file: *.asc (*.txt) & *.prj GEOTIFF file: *.tif If style file (sld) is present it will be used. Otherwise an autogenerated sld will be made for ASCII rasters. Geotiffs will rely on their native styling. (FIXME: Rethink semantics of all this) Uploads are done using curl commands of the form curl -u admin:geoserver -v -X PUT -H "Content-type: image/tif" "http://localhost:8080/geoserver/rest/workspaces/futnuh/coveragestores/population_padang_1/file.geotiff" --data-binary "@data/population_padang_1.tif """ # Form derived variables pathname, extension = os.path.splitext(filename) layername = os.path.split(pathname)[-1] msg = 'Coverage must have extension asc, txt or tif' assert extension in ['.asc', '.txt', '.tif'], msg # Check to see if the dataset has a coordinate system # FIXME: Do this for vector layers also dataset = osgeo.gdal.Open(filename, osgeo.gdal.GA_ReadOnly) msg = filename+' has no Coordinate/Spatial Reference System (CRS)' assert dataset.GetProjectionRef().startswith('GEOGCS') or dataset.GetProjectionRef().startswith('PROJCS'), msg # Style file in case it accompanies the file provided_style_filename = pathname + '.sld' # Locally stored upload_filename = layername + '.tif' style_filename = layername + '.sld' if extension == '.tif': generate_sld = False cmd = 'cp %s %s' % (filename, os.getcwd()) # upload_filename) run(cmd, verbose=False) else: # Convert to Geotiff generate_sld = True cmd = 'gdal_translate -ot Float64 -of GTiff -co "PROFILE=GEOTIFF" %s %s' % (filename, upload_filename) if verbose: run(cmd, verbose=verbose) else: run(cmd, stdout='upload_raster.stdout', stderr='upload_raster.stderr', verbose=verbose) # Upload raster data to Geoserver curl(self.geoserver_url, self.geoserver_username, self.geoserver_userpass, 'PUT', 'image/tif', 'workspaces/%s/coveragestores/%s/file.geotiff' % (workspace, layername), '--data-binary', '@%s' % upload_filename, verbose=verbose) # Take care of styling if os.path.isfile(provided_style_filename): # Use provided style file # Copy provide file to local directory because the REST interface # spits the dummy with pathnames. cmd = 'cp %s %s' % (provided_style_filename, os.getcwd()) run(cmd, verbose=False) else: # Automatically create new style file for raster file self.create_raster_sld(upload_filename, quantiles=False, verbose=verbose) if generate_sld: # Upload style file to Geoserver self.upload_style(layername, style_filename, verbose=verbose) # Make it the default for this layer self.set_default_style(layername, layername, verbose=verbose) return '%s:%s' % (workspace, layername)
if str(e).find('already exists') > 0: # Style already exists, no worries pass else: # Reraise msg = 'Could not create style %s: %s' % (style_name, e) raise Exception(msg) # curl -u geoserver -XPUT -H 'Content-type: application/vnd.ogc.sld+xml' -d @sld_for_Pk50095_geotif.sld # localhost:8080/geoserver/rest/styles/sld_for_Pk50095_geotif_style curl(self.geoserver_url, self.geoserver_username, self.geoserver_userpass, 'PUT', 'application/vnd.ogc.sld+xml', 'styles/%s' % (style_name), '--data-binary', '@%s' % style_file, verbose=verbose) def set_default_style(self, style_name, layer_name, verbose=False): """Set given style as default for specified layer""" curl(self.geoserver_url, self.geoserver_username, self.geoserver_userpass, 'PUT', 'text/xml',