[postgis-users] Writing to PostGIS with OGR

Philippe Wüger wuegerp at ee.ethz.ch
Tue Feb 14 08:38:23 PST 2006


Hello

I'm trying to write to a PostGIS table with OGR, but it doesn't work. I
wrote a class in C++ which would iterate over all points (contained in
(Multi)LineString objects) in a table/layer and set a new z-Coordinate. When
I look at the points after running the program, the z-Coordinates are still
the old value.

Does anyone know what I am doing wrong?

Here's my code:

#include "GISFeatures.h"

using namespace std;

    GISFeatures::GISFeatures()
    {
        OGRRegisterAll();
    }

    GISFeatures::~GISFeatures()
    {
    }

    bool GISFeatures::prepare(string DBname, string tableN)
    {
        tableName = tableN;
        string connectionS = "PG:dbname=" + DBname;
        //string connectionS = "str.shp";
        data = OGRSFDriverRegistrar::Open( connectionS.c_str() , TRUE );

        if( data == NULL )
        {
            cerr << "Opening database \'" << DBname << "\' failed. Query: "
<< connectionS << endl;
            return false;
        }

        cout << "Opened database \'" << DBname << "\'." << endl;

        //string query = "SELECT objectid, the_geom From " + tableName + "
where the_geom && 'BOX(66799 222000, 730000 274000)'::box2d;";
        string query = "SELECT objectid, the_geom From " + tableName + "
where the_geom && 'BOX(682113 247230, 684600 250000)'::box2d;";
        layer = data->ExecuteSQL( query.c_str() , NULL, "" );
        //layer = data->GetLayerByName("str");
        cout << "Executed query: " << query << endl;

        layer->ResetReading();

        return true;
    }

    bool GISFeatures::nextFeature()
    {
        geometryIdx = 0;
        pointIdx = 0;

        // Delete old feature if exists
        if(feature != NULL)
        {
            layer->SetFeature(feature);
            //OGRFeature::DestroyFeature( feature );
        }

        if( (feature = layer->GetNextFeature()) != NULL )
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    bool GISFeatures::nextFeaturePoint()
    {
        geometry = feature->GetGeometryRef();
        if( geometry != NULL && wkbFlatten(geometry->getGeometryType()) ==
wkbMultiLineString )
        {
            OGRGeometryCollection *collection = (OGRGeometryCollection *)
geometry;
            int numGeometries = collection->getNumGeometries();
            OGRGeometry* geometry2;
            while(true)
            {
                if(geometryIdx < numGeometries)
                {
                    geometry2 = collection->getGeometryRef(geometryIdx);
                    if( geometry2 != NULL &&
wkbFlatten(geometry2->getGeometryType()) == wkbLineString )
                    {
                         int numPoints =
((OGRLineString*)geometry2)->getNumPoints();
                         if(pointIdx < numPoints)
                         {
                            lsWithPoint = ((OGRLineString*)geometry2);
                            pointIdx++;
                            return true;
                         }
                         else
                         {
                            geometryIdx++;
                            pointIdx = 0;
                         }
                    }
                    else
                    {
                        geometryIdx++;
                        pointIdx = 0;
                    }
                }
                else
                {
                    //cout << " done with this geometry " << endl;
                    return false;
                }
            }

        }
        else
        {
            cout << "No collection geometry: " <<
geometry->getGeometryName() << endl;
            return false;
        }
        //return false; // Only with shapefile
    }

    double GISFeatures::pointX()
    {
        return lsWithPoint->getX(pointIdx-1);
    }

    double GISFeatures::pointY()
    {
        return lsWithPoint->getY(pointIdx-1);
    }

    double GISFeatures::pointZ()
    {
        return lsWithPoint->getZ(pointIdx-1);
    }

    void GISFeatures::setPointZ(double z)
    {
        cout << "Height of (" << pointX() << ", " << pointY() << ", " <<
pointZ() << ") to " << z;
        lsWithPoint->setPoint(pointIdx-1, pointX(),  pointY(), z);
        cout << " -> (" << pointX() << ", " << pointY() << ", " << pointZ()
<< ")"  << endl;
    }

    void GISFeatures::close()
    {
        if(data->SyncToDisk() != OGRERR_NONE)
        {
            cout << "Error while syncing data to disk." << endl;
        }
        data->ReleaseResultSet(layer);
        OGRDataSource::DestroyDataSource( data );
        cout << "Closed data source" << endl;
    }

main.cpp:

#include <iostream>
#include <sys/time.h>

#include "GISHeightModel.h"
#include "GISFeatures.h";

/*
* Currently supports MultiLineStrings (i. e. streets)
*/


using namespace std;

int main (int argc, char * const argv[]) {

    std::cout << "GIS Add Height Data Start\n";

    // Check for correct amount of arguments
    if(argc != 4)
    {
        printf("Usage: %s <Height-Data> <Database-Name> <Table-Name>\n",
argv[0]);
        exit(1);
    }

    GISFeatures* features = new GISFeatures();
    features->prepare(argv[2], argv[3]);


    GISHeightModel* hm = new GISHeightModel();
    hm->open(argv[1]);
    hm->readFile();

    cout << "Calculating heights." << endl;

    while(features->nextFeature())
    {
        //cout << "F" << endl;
        while(features->nextFeaturePoint())
        {
            //cout << "P" << endl;
            features->setPointZ(hm->getHeight(features->pointX(),
features->pointY()));
        }
    }

    features->close();

    delete hm;
    delete features;

    return 0;
}

Thanks for your help,
Philippe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20060214/50cc1de6/attachment.html>


More information about the postgis-users mailing list