Creating raster footprints

A common way to catalog raster datasets that consist of a large number of files is by creating a vector dataset with polygon footprints of the extent of each raster file. The vector footprint files can be easily loaded in QGIS or served over the Web. This recipe demonstrates a method to create a footprint vector from a directory full of raster files. We will build this program as a Processing Toolbox script, which is easier to build than a QGIS plugin and provides both a GUI and a clean programming API.

Getting ready

Download the sample raster image scenes from https://geospatialpython.googlecode.com/svn/scenes.zip. Unzip the scenes directory into a directory named rasters in your qgis_data directory.

For this recipe, we will create a new Processing Toolbox script using the following steps:

  1. In the QGIS Processing Toolbox, expand the Scripts tree menu.
  2. Next, expand the Tools tree menu.
  3. Finally, double-click on the Create new script item to bring up the processing script editor.

How to do it...

First, we will use the Processing Toolbox header naming conventions ,which will simultaneously define our GUI and the input and output variables. Then, we'll create the logic, which processes a raster directory and calculates the image extents, and finally we'll create the vector file. To do this, we need to perform the following steps:

  1. First, we define our input variables using comments to tell the Processing Toolbox to add these to the GUI when the script is invoked by a user. The first item defines the script's group menu to place our script in the toolbox, the second item defines the directory containing the rasters, and the third item is the output name of our shapefile. The script must start with these comments. Each item also declares a type allowed by the Processing Toolbox API. The names of the variables in these comments become available to the script:
    ##Vector=group
    ##Input_Raster_Directory=folder
    ##Output_Footprints_Vector=output vector
    
  2. Next, we import the Python libraries we will need, using the following commands:
    import os
    from qgis.core import *
    
  3. Now, we get a list of files in the raster directory. The following script makes no attempt to filter the files by type. If there are other types of data in the directory that are not raster files, they will be included as well:
    files = os.listdir(Input_Raster_Directory)
    
  4. Then, we declare a couple of variables, which will hold our raster extents and the coordinate reference string, as shown here:
    footprints = []
    crs = ""
    
  5. Now, we loop through the rasters, load them as a raster layer to grab their extents, store them as point data in Python dictionaries, and add them to our list of footprints for temporary storage. If the raster can't be processed, a warning is issued using the Processing Toolbox progress object:
    for f in files:
        try:
            fn = os.path.join(Input_Raster_Directory, f)
            lyr = QgsRasterLayer(fn, "Input Raster")
            crs = lyr.crs()
            e = lyr.extent()
            ulx = e.xMinimum()
            uly = e.yMaximum()
            lrx = e.xMaximum()
            lry = e.yMinimum()
            ul = (ulx, uly)
            ur = (lrx, uly)
            lr = (lrx, lry)
            ll = (ulx, lry)
            fp = {}
            points = []
            points.append(QgsPoint(*ul))
            points.append(QgsPoint(*ur))
            points.append(QgsPoint(*lr)) 
            points.append(QgsPoint(*ll))   
            points.append(QgsPoint(*ul))
            fp["points"] = points
            fp["raster"] = fn
            footprints.append(fp)
        except:
            progress.setInfo("Warning: The file %s does not appear to be a 
    valid raster file." % f)
    
  6. Using the following code, we will create a memory vector layer to build the footprint vector before writing it to a shapefile:
    vectorLyr =  QgsVectorLayer("Polygon?crs=%s&field=raster:string(100)" 
    % crs, "Footprints" , "memory")
    vpr = vectorLyr.dataProvider()
    
  7. Now, we'll turn our list of extents into features:
    features = []
    for fp in footprints:
        poly = QgsGeometry.fromPolygon([fp["points"]])
        f = QgsFeature()
        f.setGeometry(poly)
        f.setAttributes([fp["raster"]])
        features.append(f)
    vpr.addFeatures(features)
    vectorLyr.updateExtents()
    
  8. We'll then set up the file driver and the CRS for the shapefile:
    driver = "Esri Shapefile"
    epsg = crs.postgisSrid()
    srs = "EPSG:%s" % epsg
    
  9. Finally, we'll write the selected output file, specifying the layer we are saving to disk; the name of the output file; the file encoding, which might change depending on the input; the coordinate reference system; and the driver for the output file type, which in this case is a shapefile:
    error = QgsVectorFileWriter.writeAsVectorFormat (vectorLyr, Output_Footprints_Vector, "utf-8", srs, driver)
    if error == QgsVectorFileWriter.NoError:
        pass
    else:
        progress.setInfo("Unable to output footprints.")
    

How it works...

It is important to remember that a Processing Toolbox script can be run in several different contexts: as a GUI process such as a plugin, as a programmatic script from the Python console, a Python plugin, or the Graphical Modeler framework. Therefore, it is important to follow the documented Processing Toolbox API so that it can work as expected in all of these contexts. This includes defining clear inputs and outputs and using the progress object. The progress object is the proper way to provide feedback to the user for both progress bars and messages. Although the API allows you to define outputs that let the user select different OGR and GDAL outputs, only shapefiles and GeoTiffs seem to be supported currently.

There's more...

The Graphical Modeler tool within the Processing Toolbox lets you visually chain different processing algorithms together to create complex workflows. Another interesting plugin is the Processing Workflows plugin, which not only allows you to chain algorithms together but also provides a nice tabbed interface with instructions for the end user to help beginners through complicated geospatial workflows.

The following screenshot shows the raster footprints over an OpenStreetMap basemap:

There's more...
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset