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: &#39;CONTENTS_LOSS_AUD&#39; to &#39;CONTENTS_L&#39;</li><li>ERROR 1: No such field: &#39;CONTENTS_LOSS_AUD&#39;    (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>        &quot;&quot;&quot;Save vector data to file<br><br>        Input<br>
            filename: filename with extension .shp or .gml<br>        &quot;&quot;&quot;<br><br>        # Check file format<br>        basename, extension = os.path.splitext(filename)<br><br>        msg = (&#39;Invalid file type for file %s. Only extensions &#39;<br>
               &#39;shp or gml allowed.&#39; % filename)<br>        assert extension == &#39;.shp&#39; or extension == &#39;.gml&#39;, msg<br>        driver = DRIVER_MAP[extension]<br><br>        # FIXME (Ole): Tempory flagging of GML issue (ticket #18)<br>
        if extension == &#39;.gml&#39;:<br>            msg = (&#39;OGR GML driver does not store geospatial reference.&#39;<br>                   &#39;This format is disabled for the time being. See &#39;<br>                   &#39;<a href="https://github.com/AIFDR/riab/issues/18">https://github.com/AIFDR/riab/issues/18</a>&#39;)<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 = &#39;OGR driver %s not available&#39; % driver<br>            raise Exception(msg)<br>
<br>        ds = drv.CreateDataSource(filename)<br>        if ds is None:<br>            msg = &#39;Creation of output file %s failed&#39; % 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 = &#39;Could not create layer %s&#39; % 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) &gt; 0:<br>                try:<br>                    fields = data[0].keys()<br>                except:<br>
                    msg = (&#39;Input parameter &quot;attributes&quot; was specified &#39;<br>                           &#39;but it does not contain dictionaries with &#39;<br>                           &#39;field information as expected. The first&#39;<br>
                           &#39;element is %s&#39; % 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 = (&#39;Unknown type for storing vector &#39;<br>                               &#39;data: %s, %s&#39; % (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 = (&#39;Input parameter &quot;data&quot; was specified &#39;<br>
                       &#39;but appears to be empty&#39;)<br>                raise Exception(msg)<br><br>            # Create attribute fields in layer<br>            store_attributes = True<br>            for name in fields:<br>
                print &#39;Creating&#39;, name<br>                fd = ogr.FieldDefn(name, ogrtypes[name])<br>                # FIXME (Ole): Trying to address issue #16<br>                #              But it doesn&#39;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 = &#39;Could not create field %s&#39; % 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 = &#39;Geometry %s not implemented&#39; % self.geometry_type<br>                raise Exception(msg)<br><br>            feature.SetGeometry(geom)<br>
<br>            G = feature.GetGeometryRef()<br>            if G is None:<br>                msg = &#39;Could not create GeometryRef for file %s&#39; % 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 &lt;type &#39;numpy.ndarray&#39;&gt; 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 = &#39;Failed to create feature %i in file %s&#39; % (i, filename)<br>
                raise Exception(msg)<br><br>            feature.Destroy()<br><br>        # Write keywords if any<br>        write_keywords(self.keywords, basename + &#39;.keywords&#39;)<br><br><br><br><br><div class="gmail_quote">
On Sun, Sep 4, 2011 at 4:16 PM, Even Rouault <span dir="ltr">&lt;<a href="mailto:even.rouault@mines-paris.org">even.rouault@mines-paris.org</a>&gt;</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">&gt; Hi again and sorry for nagging, but do you have any hints as to what this<br>
&gt; error means<br>
&gt;<br>
&gt; &gt;    return _ogr.Feature_SetField(self, *args)<br>
&gt; &gt;<br>
&gt; &gt; NotImplementedError: Wrong number of arguments for overloaded function<br>
&gt; &gt; &#39;Feature_SetField&#39;.<br>
&gt; &gt;<br>
&gt; &gt;   Possible C/C++ prototypes are:<br>
&gt; &gt;     SetField(OGRFeatureShadow *,int,char const *)<br>
&gt; &gt;     SetField(OGRFeatureShadow *,char const *,char const *)<br>
&gt; &gt;     SetField(OGRFeatureShadow *,int,int)<br>
&gt; &gt;     SetField(OGRFeatureShadow *,char const *,int)<br>
&gt; &gt;     SetField(OGRFeatureShadow *,int,double)<br>
&gt; &gt;     SetField(OGRFeatureShadow *,char const *,double)<br>
&gt; &gt;     SetField(OGRFeatureShadow *,int,int,int,int,int,int,int,int)<br>
&gt; &gt;     SetField(OGRFeatureShadow *,char const *,int,int,int,int,int,int,int)<br>
&gt;<br>
&gt; The input to the Python bindings is of the form<br>
&gt; SetField(&#39;STRUCT_DAMAGE_fraction&#39;, 0.346734256639)<br>
&gt;<br>
&gt; i.e. one string argument (char*) followed by a float (double) which I<br>
&gt; thought would be matched by the third last header above. It works fine on<br>
&gt; version 1.6 but not version 1.8.<br>
&gt;<br>
&gt; Can anyone tell me what has changed, what it means and how to work around<br>
&gt; it - please?<br>
&gt;<br>
</div>Ole,<br>
<br>
Unfortunately, I cannot explain your error, but I&#39;m convinced it must be<br>
something particular with your installation. So I&#39;d advise you to test on a<br>
fresh machine and/or clean a bit the packages you&#39;ve installed on the one<br>
where you have problems.<br>
<br>
Below a test I&#39;ve just done to show you that SetField(string, double)<br>
definitely works with GDAL 1.8.0 under normal conditions. I&#39;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 &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.<br>
&gt;&gt;&gt; from osgeo import gdal<br>
&gt;&gt;&gt; from osgeo import ogr<br>
&gt;&gt;&gt; gdal.VersionInfo(&#39;&#39;)<br>
&#39;GDAL 1.8.0, released 2011/01/12&#39;<br>
&gt;&gt;&gt; fielddefn = ogr.FieldDefn(&#39;STRUCT_DAMAGE_fraction&#39;, ogr.OFTReal)<br>
&gt;&gt;&gt; featuredefn = ogr.FeatureDefn()<br>
&gt;&gt;&gt; featuredefn.AddFieldDefn(fielddefn)<br>
&gt;&gt;&gt; feat = ogr.Feature(featuredefn)<br>
&gt;&gt;&gt; feat.SetField(&#39;STRUCT_DAMAGE_fraction&#39;, 0.346734256639)<br>
&gt;&gt;&gt; feat.DumpReadable()<br>
OGRFeature():-1<br>
  STRUCT_DAMAGE_fraction (Real) = 0.346734256639<br>
<br>
<br>
</blockquote></div><br>