[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