[Gdal-dev] importFromWkt() problem

Mateusz Loskot mateusz at loskot.net
Sun Sep 3 10:34:03 EDT 2006


Petteri Packalen wrote:
> 
> Unfortunately this is not the problem, WKT strings are in correct
> format. geo_trans is a global variable which is filled within
> ConvertWktByJhs154ToEuref(). Note that example 2 works perfectly.

Petteri,

I'm inclined to state that OGR works perfectly and the problem
is somewhere in your code.
However, it's very hard to point out where is the problem.
Your latest snipped may be correct as you assembled it from various
files of your code, but your original "big" application may work
incorrectly.

Also, semantically, there is no difference between using:
poPoly->importFromWkt( &geo_trans );
and using
OGRErr err = OGRGeometryFactory::createFromWkt(&pszWkt, ref, &new_geom);

The latter is just a short of the former - user does not need to
allocate geometry, the factory will do it.

I checked "mass generation" of shapes using techniques from the 1st
example from your initial post, the one that's not working
for you - poPoly->importFromWkt...

I generate 1 billion of features and it works perfectly, without
any segmentation faults, illegal memory access or memory leaks
(see below).

////////////////////////////////////////////////////////////////////////////////
// importwkt.cpp - test of non-factory-based importFromWkt()
// Compile:
// g++ -g -Wall -Wno-long-long -pedantic importwkt.cpp
//     -o importwkt -lgdal -lgeos_c -lgeos
//
#include <ogr_geometry.h>
#include <ogrsf_frmts.h>
#include <cassert>
#include <cstdio>  // printf(), sprintf()
#include <cstdlib> // srand(), rand()
#include <ctime>   // time()

int main(int argc, char* argv[])
{
    // No specific options, just run with some dummy argument(s)
    // ./importwkt blabla
    // to run in verbose mode or without any arguments to run in
    // dotted mode + summary:
    // ./importwkt
    //
    bool verbose = false;
    if (argc != 1)
    {
        verbose = true;
    }

    // CHANGE nFeaturesMax TO TEST VARIOUS CASES
    const std::size_t nFeaturesMax = 1000000; // max number of features

    const char *pszDriverName = "ESRI Shapefile";
    OGRSFDriver *poDriver = NULL;
    OGRErr rc = OGRERR_NONE;

    OGRRegisterAll();

    // Driver
    poDriver =
OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName);
    assert(NULL != poDriver);

    // Data source
    OGRDataSource *poDS = poDriver->CreateDataSource("testimpwkt.shp",
NULL);
    assert(NULL != poDS && "Can not create shapefile!");

    // Layer
    OGRLayer *poLayer = poDS->CreateLayer("testimpwkt", NULL,
wkbPolygon, NULL);
    assert(NULL != poLayer && "Can not create layer!");

    // Field
    const std::size_t fieldSize = 40;
    OGRFieldDefn oField("Name", OFTString);
    oField.SetWidth(fieldSize - 1);
    rc = poLayer->CreateField( &oField );
    assert(OGRERR_NONE == rc && "Can not create field!");

    // Generate nFeaturesMax number of features
    std::srand(std::time(NULL)); // we will try to generate random
coordinates
    const int coordMax = 1000; // max coord value
    const int coordMin = 10;   // min coord value

    // WKT buffer
    const std::size_t wktSize = 100; // max WKT length
    char wkt[wktSize] = { 0 };

    std::size_t nCount = 0;
    while (nCount < nFeaturesMax)
    {
        std::size_t ret = 0;

        // Feature
        OGRFeature *poFeature = new OGRFeature(poLayer->GetLayerDefn());

        // Attribute
        char name[fieldSize]= { 0 };
        ret = sprintf(name, "Feature %d", nCount);;
        assert(fieldSize >= ret);
        poFeature->SetField( "Name", name );

        // Geometry

        // Just to make coords less tedious ;-)
        int coord = (std::rand() % (coordMax - coordMin + 1)) + coordMin;

        // let's be a bit more defensive
        // NOTE: it can be safely commented
        memset(wkt, 0, wktSize);

        ret = sprintf(wkt, "POLYGON ((0 0 %u, %u 0 5, %u %u 5, 0 %u 5))",
                      coord, coord, coord, coord, coord);
        assert(wktSize >= ret);

        OGRPolygon* poPoly = new OGRPolygon();

        char* ptr = wkt;
        poPoly->importFromWkt(&ptr);
        poFeature->SetGeometryDirectly( poPoly ); // transfer geom
ownership to the feature

        // Create Feature
        rc = poLayer->CreateFeature(poFeature);
        assert(OGRERR_NONE == rc && "Can not create feature!");

        // Control output
        if (verbose)
            printf("%s: Geometry: %s\n", name, poPoly->getGeometryName());
        else
            printf(".");

        delete poFeature; // also frees geometry
        ++nCount;
    }

    printf("\nSuccessfully saved %d features\n", nCount);

    // Close data source
    OGRDataSource::DestroyDataSource( poDS );
}
////////////////////////////////////////////////////////////////////////////////

Last lines of output:

........................................
Successfully saved 1000000 features
mloskot:~/dev/gdal/test$ ls -lh testimpwkt.*
-rw-r--r-- 1 mloskot mloskot  39M 2006-09-03 16:18 testimpwkt.dbf
-rw-r--r-- 1 mloskot mloskot 115M 2006-09-03 16:18 testimpwkt.shp
-rw-r--r-- 1 mloskot mloskot 7.7M 2006-09-03 16:18 testimpwkt.shx



Now, what valgrind says about it (see LEAK SUMMARY):

...
Feature 9995: Geometry: POLYGON
Feature 9996: Geometry: POLYGON
Feature 9997: Geometry: POLYGON
Feature 9998: Geometry: POLYGON
Feature 9999: Geometry: POLYGON
==6766==
==6766== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 75 from 1)
==6766== malloc/free: in use at exit: 3,723 bytes in 43 blocks.
==6766== malloc/free: 230,162 allocs, 230,119 frees, 10,970,713 bytes
allocated.
==6766== For counts of detected errors, rerun with: -v
==6766== searching for pointers to 43 not-freed blocks.
==6766== checked 2,427,092 bytes.
==6766==
==6766== LEAK SUMMARY:
==6766==    definitely lost: 0 bytes in 0 blocks.
==6766==      possibly lost: 0 bytes in 0 blocks.
==6766==    still reachable: 3,723 bytes in 43 blocks.
==6766==         suppressed: 0 bytes in 0 blocks.
==6766== Reachable blocks (those to which a pointer was found) are not
shown.
==6766== To see them, rerun with: --show-reachable=yes



I'm sorry, but I'm completely out of concepts what is going wrong
with your code.
The only possibility I see to run and check your code with
input datasets you're using.

Are you running your code on Windows with DLLs?
If you are, then may be you're dealing with "passing objects across DLL
boundaries" issue.


Cheers
-- 
Mateusz Loskot
http://mateusz.loskot.net



More information about the Gdal-dev mailing list