VectorDataIOExample.cxxΒΆ
Example source code (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 \ref{sec:VectorDataProjection}, 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.
#include "otbVectorData.h"
#include "otbVectorDataFileReader.h"
#include "otbVectorDataFileWriter.h"
// 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.
#include "itkPreOrderTreeIterator.h"
#include "otbObjectList.h"
#include "otbPolygon.h"
int main(int argc, char* argv[])
{
if (argc != 3)
{
std::cerr << "Usage: " << argv[0];
std::cerr << "inputFile outputFile" << std::endl;
return EXIT_FAILURE;
}
using PixelType = unsigned short;
// We define the types for the vector data structure and the
// corresponding file reader.
using VectorDataType = otb::VectorData<PixelType, 2>;
using VectorDataFileReaderType = otb::VectorDataFileReader<VectorDataType>;
// We can now instantiate the reader and read the data.
VectorDataFileReaderType::Pointer reader = VectorDataFileReaderType::New();
reader->SetFileName(argv[1]);
reader->Update();
// 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 \doxygen{itk}{PreOrderTreeIterator}.
using DataTreeType = VectorDataType::DataTreeType;
using TreeIteratorType = itk::PreOrderTreeIterator<DataTreeType>;
// 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 \doxygen{otb}{ObjectList}.
using PolygonType = otb::Polygon<double>;
using PolygonListType = otb::ObjectList<PolygonType>;
PolygonListType::Pointer polygonList = PolygonListType::New();
// We get the data tree and instantiate an iterator to walk through it.
TreeIteratorType it(reader->GetOutput()->GetDataTree());
it.GoToBegin();
// We check that the current object is a polygon using the
// \code{IsPolygonFeature()} method and get its exterior ring in
// order to store it into the list.
while (!it.IsAtEnd())
{
if (it.Get()->IsPolygonFeature())
{
polygonList->PushBack(it.Get()->GetPolygonExteriorRing());
}
++it;
}
polygonList->PushBack(PolygonType::New());
// 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.
VectorDataType::Pointer outVectorData = VectorDataType::New();
using DataNodeType = VectorDataType::DataNodeType;
// 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.
DataNodeType::Pointer document = DataNodeType::New();
document->SetNodeType(otb::DOCUMENT);
document->SetNodeId("polygon");
DataNodeType::Pointer folder = DataNodeType::New();
folder->SetNodeType(otb::FOLDER);
DataNodeType::Pointer multiPolygon = DataNodeType::New();
multiPolygon->SetNodeType(otb::FEATURE_MULTIPOLYGON);
// We assign these objects to the data tree stored by the vector data object.
DataTreeType::Pointer tree = outVectorData->GetDataTree();
DataNodeType::Pointer root = tree->GetRoot()->Get();
tree->Add(document, root);
tree->Add(folder, document);
tree->Add(multiPolygon, folder);
// We can now iterate through the polygon list and fill the vector
// data structure.
for (PolygonListType::Iterator pit = polygonList->Begin(); pit != polygonList->End(); ++pit)
{
DataNodeType::Pointer newPolygon = DataNodeType::New();
newPolygon->SetPolygonExteriorRing(pit.Get());
tree->Add(newPolygon, multiPolygon);
}
// And finally we write the vector data to a file using a generic
// \doxygen{otb}{VectorDataFileWriter}.
using WriterType = otb::VectorDataFileWriter<VectorDataType>;
WriterType::Pointer writer = WriterType::New();
writer->SetInput(outVectorData);
writer->SetFileName(argv[2]);
writer->Update();
return EXIT_SUCCESS;
// 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.
}