Dear Even<br><br>Thank you so much for going through the trouble of reproducing this issue. You have help a lot, but I need one more hint regarding the apparent change in how field names get truncated (Normalized/laundered).<br>
<br>To summarise:<br><ul><li>I followed your suggestions and rebuilt from scratch. </li><li>Your Python example worked perfectly</li><li>However my code still produced the error in SetField (NotImplementedError: Wrong number of arguments for overloaded function)</li>
<li>It turned out the reason was that I was passing a singleton numpy.ndarray element into it. Casting that to a float fixed the problem in ogr 1.8</li><li>However, I still get the following warning and associated errors of the form<br>
</li><ul><li>Warning 6: Normalized/laundered field name: 'CONTENTS_LOSS_AUD' to 'CONTENTS_L'</li><li>ERROR 1: No such field: 'CONTENTS_LOSS_AUD' (not surprisingly, if it was truncated :-))<br></li>
</ul></ul><br>The warning comes from a call to lyr.CreateField(fd) and the error happens when calling SetField with the full length string.<br>I have included the routine I wrote to store our layers as reference below, but my questions are<br>
<br><ul><li>What are the official ogr steps required to store a vector layer (represented as e.g. a list of x, y values and associated feature attributes (name, value))? In particular, is CreateField perhaps obsoleted by something else?<br>
</li><li>Is the truncation to 10 characters hard and fast or driver dependent - and how should one deal with this truncation? Your example (which does not use CreateField) would suggest names can be longer than 10 characters.</li>
<li>Where can i find some documentation of the OGR Python bindings?</li></ul><br>I am sorry that my questions are so fundamental, but I am still new to this library.<br>Cheers and many thanks<br>Ole Nielsen<br><br><br><br>
<br>------------ The code that works for version 1.6 but not 1.8 --------------------------------<br><br> def write_to_file(self, filename):<br> """Save vector data to file<br><br> Input<br>
filename: filename with extension .shp or .gml<br> """<br><br> # Check file format<br> basename, extension = os.path.splitext(filename)<br><br> msg = ('Invalid file type for file %s. Only extensions '<br>
'shp or gml allowed.' % filename)<br> assert extension == '.shp' or extension == '.gml', msg<br> driver = DRIVER_MAP[extension]<br><br> # FIXME (Ole): Tempory flagging of GML issue (ticket #18)<br>
if extension == '.gml':<br> msg = ('OGR GML driver does not store geospatial reference.'<br> 'This format is disabled for the time being. See '<br> '<a href="https://github.com/AIFDR/riab/issues/18">https://github.com/AIFDR/riab/issues/18</a>')<br>
raise Exception(msg)<br><br> # Derive layername from filename (excluding preceding dirs)<br> layername = os.path.split(basename)[-1]<br><br> # Get vector data<br> geometry = self.get_geometry()<br>
data = self.get_data()<br> N = len(geometry)<br><br> # Clear any previous file of this name (ogr does not overwrite)<br> try:<br> os.remove(filename)<br> except:<br> pass<br>
<br> # Create new file with one layer<br> drv = ogr.GetDriverByName(driver)<br> if drv is None:<br> msg = 'OGR driver %s not available' % driver<br> raise Exception(msg)<br>
<br> ds = drv.CreateDataSource(filename)<br> if ds is None:<br> msg = 'Creation of output file %s failed' % filename<br> raise Exception(msg)<br><br> lyr = ds.CreateLayer(layername,<br>
self.projection.spatial_reference,<br> self.geometry_type)<br> if lyr is None:<br> msg = 'Could not create layer %s' % layername<br> raise Exception(msg)<br>
<br> # Define attributes if any<br> store_attributes = False<br> if data is not None:<br> if len(data) > 0:<br> try:<br> fields = data[0].keys()<br> except:<br>
msg = ('Input parameter "attributes" was specified '<br> 'but it does not contain dictionaries with '<br> 'field information as expected. The first'<br>
'element is %s' % data[0])<br> raise Exception(msg)<br> else:<br> # Establish OGR types for each element<br> ogrtypes = {}<br>
for name in fields:<br> att = data[0][name]<br> py_type = type(att)<br> msg = ('Unknown type for storing vector '<br> 'data: %s, %s' % (name, str(py_type)[1:-1]))<br>
assert py_type in TYPE_MAP, msg<br> ogrtypes[name] = TYPE_MAP[py_type]<br><br> else:<br> msg = ('Input parameter "data" was specified '<br>
'but appears to be empty')<br> raise Exception(msg)<br><br> # Create attribute fields in layer<br> store_attributes = True<br> for name in fields:<br>
print 'Creating', name<br> fd = ogr.FieldDefn(name, ogrtypes[name])<br> # FIXME (Ole): Trying to address issue #16<br> # But it doesn't work and<br>
# somehow changes the values of MMI in test<br> #width = max(128, len(name))<br> #print name, width<br> #fd.SetWidth(width)<br><br> if lyr.CreateField(fd) != 0:<br>
msg = 'Could not create field %s' % name<br> raise Exception(msg)<br><br> # Store geometry<br> geom = ogr.Geometry(self.geometry_type)<br> layer_def = lyr.GetLayerDefn()<br>
for i in range(N):<br> # Create new feature instance<br> feature = ogr.Feature(layer_def)<br><br> # Store geometry and check<br> if self.geometry_type == ogr.wkbPoint:<br>
x = float(geometry[i][0])<br> y = float(geometry[i][1])<br> geom.SetPoint_2D(0, x, y)<br> elif self.geometry_type == ogr.wkbPolygon:<br> wkt = array2wkt(geometry[i])<br>
geom = ogr.CreateGeometryFromWkt(wkt)<br> else:<br> msg = 'Geometry %s not implemented' % self.geometry_type<br> raise Exception(msg)<br><br> feature.SetGeometry(geom)<br>
<br> G = feature.GetGeometryRef()<br> if G is None:<br> msg = 'Could not create GeometryRef for file %s' % filename<br> raise Exception(msg)<br><br> # Store attributes<br>
if store_attributes:<br> for name in fields:<br> val = data[i][name]<br> if type(val) == numpy.ndarray:<br> # A singleton of type <type 'numpy.ndarray'> works for gdal version 1.6<br>
# but fails for version 1.8 in SetField with error:<br> # NotImplementedError: Wrong number of arguments for overloaded function<br> val = float(val)<br>
<br> feature.SetField(name, val)<br><br> # Save this feature<br> if lyr.CreateFeature(feature) != 0:<br> msg = 'Failed to create feature %i in file %s' % (i, filename)<br>
raise Exception(msg)<br><br> feature.Destroy()<br><br> # Write keywords if any<br> write_keywords(self.keywords, basename + '.keywords')<br><br><br><br><br><div class="gmail_quote">
On Sun, Sep 4, 2011 at 4:16 PM, Even Rouault <span dir="ltr"><<a href="mailto:even.rouault@mines-paris.org">even.rouault@mines-paris.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Le dimanche 04 septembre 2011 05:54:34, Ole Nielsen a écrit :<br>
<div class="im">> Hi again and sorry for nagging, but do you have any hints as to what this<br>
> error means<br>
><br>
> > return _ogr.Feature_SetField(self, *args)<br>
> ><br>
> > NotImplementedError: Wrong number of arguments for overloaded function<br>
> > 'Feature_SetField'.<br>
> ><br>
> > Possible C/C++ prototypes are:<br>
> > SetField(OGRFeatureShadow *,int,char const *)<br>
> > SetField(OGRFeatureShadow *,char const *,char const *)<br>
> > SetField(OGRFeatureShadow *,int,int)<br>
> > SetField(OGRFeatureShadow *,char const *,int)<br>
> > SetField(OGRFeatureShadow *,int,double)<br>
> > SetField(OGRFeatureShadow *,char const *,double)<br>
> > SetField(OGRFeatureShadow *,int,int,int,int,int,int,int,int)<br>
> > SetField(OGRFeatureShadow *,char const *,int,int,int,int,int,int,int)<br>
><br>
> The input to the Python bindings is of the form<br>
> SetField('STRUCT_DAMAGE_fraction', 0.346734256639)<br>
><br>
> i.e. one string argument (char*) followed by a float (double) which I<br>
> thought would be matched by the third last header above. It works fine on<br>
> version 1.6 but not version 1.8.<br>
><br>
> Can anyone tell me what has changed, what it means and how to work around<br>
> it - please?<br>
><br>
</div>Ole,<br>
<br>
Unfortunately, I cannot explain your error, but I'm convinced it must be<br>
something particular with your installation. So I'd advise you to test on a<br>
fresh machine and/or clean a bit the packages you've installed on the one<br>
where you have problems.<br>
<br>
Below a test I've just done to show you that SetField(string, double)<br>
definitely works with GDAL 1.8.0 under normal conditions. I've installed Ubuntu<br>
11.04 amd64 in a virtual machine, installed first python-gdal (1.6), then added<br>
ubuntugis-unstable PPA, installed qgis (1.7) :<br>
<br>
even@even-virtual-machine:~$ dpkg -l | grep gdal<br>
<div class="im">ii gdal-bin 1.8.0-2~natty2<br>
Geospatial Data Abstraction Library - Utility programs<br>
</div>ii libgdal1-1.6.0 1.6.3-4build4<br>
Geospatial Data Abstraction Library<br>
ii libgdal1-1.8.0 1.8.0-2~natty2<br>
<div class="im">Geospatial Data Abstraction Library<br>
ii python-gdal 1.8.0-2~natty2<br>
Python bindings to the Geospatial Data Abstraction Library<br>
<br>
</div>even@even-virtual-machine:~$ python<br>
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)<br>
[GCC 4.5.2] on linux2<br>
Type "help", "copyright", "credits" or "license" for more information.<br>
>>> from osgeo import gdal<br>
>>> from osgeo import ogr<br>
>>> gdal.VersionInfo('')<br>
'GDAL 1.8.0, released 2011/01/12'<br>
>>> fielddefn = ogr.FieldDefn('STRUCT_DAMAGE_fraction', ogr.OFTReal)<br>
>>> featuredefn = ogr.FeatureDefn()<br>
>>> featuredefn.AddFieldDefn(fielddefn)<br>
>>> feat = ogr.Feature(featuredefn)<br>
>>> feat.SetField('STRUCT_DAMAGE_fraction', 0.346734256639)<br>
>>> feat.DumpReadable()<br>
OGRFeature():-1<br>
STRUCT_DAMAGE_fraction (Real) = 0.346734256639<br>
<br>
<br>
</blockquote></div><br>