3

I'm trying to connect to a wfs using GDAL, from reading some of the (fairly sparse) documentation on this i have found that this is possible if GDAL is compiled with the correct drivers (Curl, Xerces).

I have compiled GDAL against both of these and have a working WFS Service to connect to.

From reading the documentation it says this is how the connection should be opened.

GDALDataset  *poDataset;

GDALAllRegister();

poDataset = (GDALDataset *) GDALOpen( pszFilename, GA_ReadOnly );

I have done this and replaced pszFilename with a URL to my WFS which didnt work and gave the error (and i have no idea what file.dat is referring to as all im doing here is entering a URL that should return some XML):

ERROR 4: `/vsimem/http_1/file.dat' not recognised as a supported file format.
ERROR 4: Failed to create temporary file:/tmp/file.dat  

alternatively it says that you could use an XML File that contains the URL like this:

<OGRWFSDataSource>
    <URL>http://path/to/WFS/service[?OPTIONAL_PARAMETER1=VALUE[&amp;OPTIONNAL_PARAMETER2=VALUE]]</URL>
</OGRWFSDataSource>

I have made this XML file and put in my URL for the WFS im trying to connect to and i get this error even though the documentation says that reading the url from XML is supported:

ERROR 4: `:/Resources/WFS.xml' does not exist in the file system,
and is not recognised as a supported dataset name.

Im wondering if anyone knows how to connect to a WFS using GDAL because as far as documentation goes this is about all its says in the way of how to connect and goes into no detail about supported file formats or how to connect to any of these.

Any help would be appreciated (oh and btw my WFS is working because if i type the URL into my web browser i get the XML (or is it GML?) in the web browser for the request i send (a GetCapabilities one))

15
  • does /tmp exist and do you (or the user running the program) have permission to create files on it? GDAL is trying to download the GML to a temp file and then parse it.
    – Ian Turton
    Commented Jul 30, 2013 at 14:27
  • i have no /tmp file in my project directory, i didnt know it was going to save it in a tmp file, but i have full admin rights on my computer so it should be able to create a file where ever it wants to
    – AngryDuck
    Commented Jul 30, 2013 at 14:30
  • i also have no idea where file:/tmp/file.dat is trying to be created. where is file:/??
    – AngryDuck
    Commented Jul 30, 2013 at 14:33
  • does ogrinfo work against your url?
    – Ian Turton
    Commented Jul 30, 2013 at 14:33
  • 2
    it is a command line program see gdal.org/ogrinfo.html - you need to make this work before you proceed into programming :-)
    – Ian Turton
    Commented Jul 30, 2013 at 14:59

1 Answer 1

1

This gets the data from your WFS and then prints it all to console (In C++) it pretty much exactly the example from the docs, but it doesnt make it clear that this was the code to use to link to a WFS. but i assure you after hours of trying this is correct! Anyway the other main problem was the GDAL_DATA errors i was getting, all you have to do is make a system environment variable called GDAL_DATA and point it to your gdal source path (data directory) and that should solve those problems. Anyway heres some code...

.h (and obviously theres the method declarations too):

OGRDataSource *m_dataset;

.cpp:

void ManageGDAL::open()
{
    // Register all of the OGR Drivers (The GDAL Drivers that are used for vector (and therefore WFS) data
    OGRRegisterAll();

    // Initialise OGR Data Source member variable to the WFS on mapserver
    m_dataset = OGRSFDriverRegistrar::Open("http://demo.mapserver.org/cgi-bin/wfs?SERVICE=WFS&VERSION=1.0.0&REQUEST=getFeatures&TYPENAME=cities", FALSE );

    // Display error message and exit program if dataset fails to open correctly
    if( m_dataset == NULL )
    {
        std::cout << "Dataset is empty" << std::endl;
        OGRDataSource::DestroyDataSource( m_dataset );
        exit( 1 );
    }
}

void ManageGDAL::getData()
{
    // Log to console to show amount of WFS layers in the dataset
    std::cout << "THE DATASET CONTAINS THIS MANY LAYERS >>>>> " << m_dataset->GetLayerCount() << std::endl;

    // Declare an object to refer to Layers returned from the WFS
    OGRLayer  *Layer;

    // Initialise the Layer variable to the layer in the dataset called "cities"
    Layer = m_dataset->GetLayerByName( "cities" );

    // Declare variable for reading the features from a WFS layer
    OGRFeature *Feature;

    // Reset Reading (Although not necessary now because it hasnt been read yet, this is good practice before reading WFS data)
    Layer->ResetReading();

    while( (Feature = Layer->GetNextFeature()) != NULL )
    {
        // Variable initialised to contain the definitions of all of the fileds in the WFS Layer
        OGRFeatureDefn *FeatureDefinition = Layer->GetLayerDefn();

        for( int i = 0; i < FeatureDefinition->GetFieldCount(); i++ )
        {
            // Variable initialised to contain field data at the current index of i
            OGRFieldDefn *FieldDefinition = FeatureDefinition->GetFieldDefn(i);

            if(FieldDefinition->GetType() == OFTInteger)
            {
                std::cout << Feature->GetFieldAsInteger(i) << ",";
            }
            else if(FieldDefinition->GetType() == OFTReal)
            {
                std::cout << Feature->GetFieldAsDouble(i) << ",";
            }
            else if( FieldDefinition->GetType() == OFTString )
            {
                std::cout << Feature->GetFieldAsString(i) << ",";
            }
            else
            {
                std::cout << Feature->GetFieldAsString(i) << ",";
            }
        }

        // Variable initialised to contain Geometry point data for the field at the current index of i
        OGRGeometry *Geometry = Feature->GetGeometryRef();

        if(Geometry != NULL && wkbFlatten(Geometry->getGeometryType()) == wkbPoint)
        {
            OGRPoint *Point = (OGRPoint *) Geometry;

            // Maybe need to limit the number of decimal places for X and Y coordinates to 2-3
            std::cout << Point->getX() << "," << Point->getY() << std::endl;
        }
        else
        {
            std::cout << "No Point Geometry" << std::endl;
        }
        OGRFeature::DestroyFeature( Feature );
    }

    OGRDataSource::DestroyDataSource( m_dataset );
    exit(0);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.