I´m developing a plugin in Python and I need to read the shapefile attributes, so I found the Fiona API and dbfpy also but I don't understand how to install these packages because I install the QGIS through osgeo4W. How do I do that?

  1. Why would you want install Fiona if you can use PyQGIS to read the shapefile attributes ?
  2. Fiona is for reading geometries and attributes of a shapefile file (as PyShp), therefore you don't need dbfpy (look at Python Script examples for geoprocessing shapefiles without using arcpy).
  3. Fiona is a Python module so you must install it as any Python module in the site-packages folder of your Python installation as SaultDon says.
  4. but as Fiona needs to compile C++ code (from GDAL/OGR) to install, you cannot use pip or easy-install on Windows (no compiler).You can try to install the "ready to use" version of Christoph Gohlke but it is linked to his version of GDAL)
  5. this procedure works with the standalone version of QGIS.

Examples of reading attributes of a shapefile:

With Fiona:

import fiona
features = fiona.open("strati.shp")
features.schema
{'geometry': 'Point', 'properties': OrderedDict([(u'PENDAGE', 'int:2'), (u'DIRECTION', 'int:3'), (u'TYPE', 'str:10')])}
for feat in features:
     print feat['properties']

OrderedDict([(u'PENDAGE', 30), (u'DIRECTION', 120), (u'TYPE', u'incl')])
OrderedDict([(u'PENDAGE', 45), (u'DIRECTION', 145), (u'TYPE', u'incl')])
OrderedDict([(u'PENDAGE', 78), (u'DIRECTION', 148), (u'TYPE', u'incl')])

With PyShp:

import shapefile
reader = shapefile.Reader("strati.shp") 
fields = reader.fields[1:]
print fields
[['PENDAGE', 'N', 2, 0], ['DIRECTION', 'N', 3, 0], ['TYPE', 'C', 10, 0]]
field_names = [field[0] for field in fields]
schema = dict((d[0],d[1:]) for d in reader.fields[1:])
print schema
{'DIRECTION': ['N', 3, 0], 'PENDAGE': ['N', 2, 0], 'TYPE': ['C', 10, 0]}
for feat in reader.shapeRecords():
    print dict(zip(field_names, sr.record))  

{'DIRECTION': 148, 'PENDAGE': 78, 'TYPE': 'incl'}
{'DIRECTION': 148, 'PENDAGE': 78, 'TYPE': 'incl'}
{'DIRECTION': 148, 'PENDAGE': 78, 'TYPE': 'incl'}

with PyQGIS in the Python console:

layer = qgis.utils.iface.activeLayer()  
fields = layer.pendingFields()  
field_names = [field.name() for field in fields]  
field_types = [field.typeName() for field in fields]
field_precision = [field.precision() for field in fields]
print field_precision
[0,0,0]
print dict(zip(field_names,field_types))
{u'DIRECTION': u'Integer', u'PENDAGE': u'Integer', u'TYPE': u'String'}
schema = dict((field_names[i], {field_types[i]:field_precision[i] if  field_precision[i] > 0 else field_types[i]:'' }) for i in range(len(field_names)))
print schema
{u'DIRECTION': {u'Integer': ''}, u'PENDAGE': {u'Integer': ''}, u'TYPE': {u'String': ''}}
for feat in layer.getFeatures():  
    print dict(zip(field_names, feat.attributes()))

{u'DIRECTION': 120, u'PENDAGE': 30, u'TYPE': u'incl'}
{u'DIRECTION': 145, u'PENDAGE': 45, u'TYPE': u'incl'}
{u'DIRECTION': 148, u'PENDAGE': 78, u'TYPE': u'incl'} 

With dbfpy:

from dbfpy import dbf
db = dbf.Dbf("strati.dbf")
print db.fieldNames
['PENDAGE', 'DIRECTION', 'TYPE']
print db.fieldDefs
[PENDAGE    N   2   0, DIRECTION  N   3   0, TYPE       C  10   0]  
schema = dict(zip(db.fieldNames,db.fieldDefs))
print schema
{'DIRECTION': DIRECTION  N   3   0, 'PENDAGE': PENDAGE    N   2   0, 'TYPE': TYPE       C  10   0} 
for feat in db:
    print dict(zip(db.fieldNames, feat.asList()))  

{'DIRECTION': 120, 'PENDAGE': 30, 'TYPE': 'incl'}
{'DIRECTION': 145, 'PENDAGE': 45, 'TYPE': 'incl'}
{'DIRECTION': 148, 'PENDAGE': 78, 'TYPE': 'incl'}

So you don't need dbfpy or other dbf Python module (PyPI:dbf)

  • I have the osgeo4w installation. So, I don't need the Fiona to read text attributes? – Bárbara Duarte Jan 7 '14 at 17:06
  • 1
    @BárbaraDuarte Not necessarily, fiona is simply an option =) Folks here are saying that the QGIS API can read text attributes. There's a nice example in the link from underdark – SaultDon Jan 7 '14 at 17:17
  • Can you give an example of function please? – Bárbara Duarte Jan 7 '14 at 17:38
  • 1
    I have introduced an example above – gene Jan 7 '14 at 18:11
  • Thanks for the examples given. I will try with the PyQGIS. – Bárbara Duarte Jan 8 '14 at 9:42

Update: Installing Python3 Fiona in OSGeo4W

  1. OSGeo4W installer: install python3-pip
  2. Environment variables: add GDAL_VERSION = 2.3.2 (or whichever version your OSGeo4W installation currently features)
  3. OSGeo4W shell: call C:\OSGeo4W64\bin\py3_env.bat
  4. OSGeo4W shell: pip3 install geopandas (this will error at fiona)
  5. From https://www.lfd.uci.edu/~gohlke/pythonlibs/#fiona: download Fiona-1.7.13-cp37-cp37m-win_amd64.whl
  6. OSGeo4W shell: pip3 install <path-to-download>\Fiona-1.7.13-cp37-cp37m-win_amd64.whl
  7. OSGeo4W shell: pip3 install geopandas

Old answer: You can access the attributes using QGIS API. You don't need Fiona to do that.

http://documentation.qgis.org/2.0/en/docs/pyqgis_developer_cookbook/vector.html

  • I try with QGIS API but I want to read text attributes. – Bárbara Duarte Jan 7 '14 at 16:42
  • 1
    @BárbaraDuarte You wrote "I need to read the shapefile attributes". What do you mean with "read text attributes"? – underdark Jan 7 '14 at 16:43
  • I want to obtain a list of text attributes. The idea is read each text attribute and assign a number to that attribute. – Bárbara Duarte Jan 7 '14 at 17:05

Are you running the 32-bit or 64-bit OSGeo4W installer?

You can try installing setuptools too and then from the OSGeo4W terminal try executing easy_install fiona and easy_install dbfpy.

There is a bug report for the 64bit installer because setuptools is broken for that one.


I found that you can always download the ez_setup.py script and then from the OSGeo4W terminal run it using python ez_setup.py - this will install easy_setup and it works on OSGeo4W 64-bit.

I've installed dbfpy using easy_install dbfpy but Fiona is complaining about missing gdal-config. Troubleshooting that right now and it looks like it can be fixed by setting the needed paths in Fiona's setup.cfg file.

  • I don't remember but I think the osgeo4W installer is 64-bit. – Bárbara Duarte Jan 7 '14 at 17:12
  • Thanks for the explanation. I will try with the PyQGIS but its important to me to know how to install external packages. Thank you! – Bárbara Duarte Jan 8 '14 at 9:43

I had the same issue. Here is what I found works. My mistake was that I tried to install using my independently installed Python rather than Python in QGIS.

  1. Right click on OSGeo4W Shell icon and click on "Run as administrator". There seems to be another way (https://stackoverflow.com/questions/28528020/why-am-i-getting-windowserror-error-5-access-is-denied), but it only gave me access to the independent Python.

  2. Install pip by following the pip install section in this: https://github.com/BurntSushi/nfldb/wiki/Python-&-pip-Windows-installation

  3. Download Fiona from http://www.lfd.uci.edu/~gohlke/pythonlibs/ (in my case, Fiona‑1.7.2‑cp27‑cp27m‑win_amd64.whl)

  4. Run python -m pip install [path to the whl file downloaded in step 3]

  5. To check, go to the Python directory (e.g., C:\Program Files\QGIS 2.14\apps\Python27) and type pip freeze. Fiona should appear.

I was having a lot of trouble installing Fiona but this simple method worked for me. I have arcgis 10.1 32bit python 2.7

I downloaded this link http://trac.osgeo.org/osgeo4w/wiki

and clicked on advanced install and sent it to my arcgis10.1 python install in program files and GDAL/Fiona installed correctly. I was pleasantly surprised with how simple that was

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.