As we have seen in the previous chapter, OTB has a great capability to read and process images. However, images are not the only type of data we will need to manipulate. Images are characterized by a regular sampling grid. For some data, such as Digital Elevation Models (DEM) or Lidar, this is too restrictive and we need other representations.
Vector data are also used to represent cartographic objects, segmentation results, etc: basically, everything which can be seen as points, lines or polygons. OTB provides functionnalities for accessing this kind of data.
The source code for this example can be found in the file
Examples/IO/DEMToImageGenerator.cxx.
The following example illustrates the use of the otb::DEMToImageGenerator class. The aim of this class is to generate an image from the srtm data (precising the start extraction latitude and longitude point). Each pixel is a geographic point and its intensity is the altitude of the point. If srtm doesn’t have altitude information for a point, the altitude value is set at -32768 (value of the srtm norm).
Let’s look at the minimal code required to use this algorithm. First, the following header defining the otb::DEMToImageGenerator class must be included.
The image type is now defined using pixel type and dimension. The output image is defined as an otb::Image.
The DEMToImageGenerator is defined using the image pixel type as a template parameter. After that, the object can be instancied.
Input parameter types are defined to set the value in the DEMToImageGenerator.
The path to the DEM folder is given to the filter.
The origin (Longitude/Latitude) of the output image in the DEM is given to the filter.
The size (in Pixel) of the output image is given to the filter.
The spacing (step between to consecutive pixel) is given to the filter. By default, this spacing is set at 0.001.
The output image name is given to the writer and the filter output is linked to the writer input.
The invocation of the Update() method on the writer triggers the execution of the pipeline. It is recommended to place update calls in a try/catch block in case errors occur and exceptions are thrown.
Let’s now run this example using as input the SRTM data contained in DEM_srtm folder. Figure 7.1 shows the obtained DEM. Invalid data values – hidden areas due to SAR shadowing – are set to zero.
More examples about representing DEM are presented in section 24.2.4.
The source code for this example can be found in the file
Examples/IO/LidarReaderExample.cxx.
This example describes how to read a lidar data file and to display the basic information about it. Here, OTB make use of libLAS.
The first step toward the use of these filters is to include the proper header files.
We need now to declare the data types that we will be using and instanciate the reader (which is a otb::PointSetFileReader).
We can already display some interesting information such as the data extension and the number of points:
We can also loop on the point to see each point with its coordinates and value. Be careful here, data set can have hundred of thousands of points:
The source code for this example can be found in the file
Examples/IO/LidarToImageExample.cxx.
This example describes how to convert a point set obtained from lidar data to an image file. A lidar produces a point set which is irregular in terms of spatial sampling. To be able to generate an image, an interpolation is required.
The interpolation is done using the itk::BSplineScatteredDataPointSetToImageFilter which uses BSplines. The method is fully described in [135] and [87].
The first step toward the use of these filters is to include the proper header files.
Here a note is important. The itk::BSplineScatteredDataPointSetToImageFilter is on the review directory of ITK, which means that it won’t be compiled by default. If you want to use it, you have to set: ITK_USE_REVIEW to ON in the ccmake of OTB.
Then, we declare the type of the data that we are going to use. As lidar decribes the altitude of the point (often to centimeter accuracy), it is required to use a real type to represent it.
Lidar data are read into a point set using the otb::PointSetFileReader. Its usage is very similar to the otb::ImageFileReader:
We can now prepare the parameters to pass to the interpolation filter: you have to be aware that the origin of the image is on the upper left corner and thus corresponds to the minimun easting but the maximum northing.
All these parameters are passed to the interpolation filter:
The result of this filter is an image in which every pixel is a vector (with only one element). For now, the otb writer does not know how to process that (hopefully soon!). So we have to manually copy the element in a standard image:
Everything is ready so we can just write the image:
Figure 7.2 shows the output images with two sets of parameters
The source code for this example can be found in the file
Examples/IO/VectorDataIOExample.cxx.
Unfortunately, many vector data formats do not share the models for the data they represent. However, in some cases, when simple data is stored, it can be decomposed in simple objects as for instance polylines, polygons and points. This is the case for the Shapefile and the KML (Keyhole Markup Language) formats, for instance.
Even though specific reader/writer for Shapefile and the Google KML are available in OTB, we designed a generic approach for the IO of this kind of data.
The reader/writer for VectorData in OTB is able to access a variety of vector file formats (all OGR supported formats)
In section 11.5, you will find more information on how projections work for the vector data and how you can export the results obtained with OTB to the real world.
This example illustrates the use of OTB’s vector data IO framework.
We will start by including the header files for the classes describing the vector data and the corresponding reader and writer.
We will also need to include the header files for the classes which model the individual objects that we get from the vector data structure.
We define the types for the vector data structure and the corresponding file reader.
We can now instantiate the reader and read the data.
The vector data obtained from the reader will provide a tree of nodes containing the actual objects of the scene. This tree will be accessed using an itk::PreOrderTreeIterator.
In this example we will only read polygon objects from the input file before writing them to the output file. We define the type for the polygon object as well as an iterator to the vertices. The polygons obtained will be stored in an otb::ObjectList.
We get the data tree and instantiate an iterator to walk through it.
We check that the current object is a polygon using the IsPolygonFeature() method and get its exterior ring in order to store it into the list.
Before writing the polygons to the output file, we have to build the vector data structure. This structure will be built up of nodes. We define the types needed for that.
We fill the data structure with the nodes. The root node is a document which is composed of folders. A list of polygons can be seen as a multi polygon object.
We assign these objects to the data tree stored by the vector data object.
We can now iterate through the polygon list and fill the vector data structure.
And finally we write the vector data to a file using a generic otb::VectorDataFileWriter.
This example can convert an ESRI Shapefile to a MapInfo File but you can also access with the same OTB source code to a PostgreSQL datasource, using a connection string as : PG:”dbname=’databasename’ host=’addr’ port=’5432’ user=’x’ password=’y’” Starting with GDAL 1.6.0, the set of tables to be scanned can be overridden by specifying tables=schema.table.