5

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?

5 Answers 5

18
  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)

7
  • I have the osgeo4w installation. So, I don't need the Fiona to read text attributes? Jan 7, 2014 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, 2014 at 17:17
  • Can you give an example of function please? Jan 7, 2014 at 17:38
  • 1
    I have introduced an example above
    – gene
    Jan 7, 2014 at 18:11
  • Thanks for the examples given. I will try with the PyQGIS. Jan 8, 2014 at 9:42
3

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

8
  • I try with QGIS API but I want to read text attributes. Jan 7, 2014 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, 2014 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. Jan 7, 2014 at 17:05
  • the above mentioned link documentation.qgis.org/2.0/en/docs/pyqgis_developer_cookbook/… is not found anymore and outdated ...!
    – robert tuw
    Feb 11, 2019 at 12:50
  • i did the installation process for my qgis 3.4.3 starting wigh gis.stackexchange.com/questions/273870/… and then followed the steps for fiona and geopandas install from above "installing python3 fiona in osgeo4w". install seemed to be successfully according to the messages on screen. the first test via "import geopandas" from within python 3.7. (osgeo4w shell version) resulted in an fiona error: "ImportError: DLL load failed: module not found")
    – robert tuw
    Feb 11, 2019 at 12:55
1

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.

2
  • I don't remember but I think the osgeo4W installer is 64-bit. Jan 7, 2014 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! Jan 8, 2014 at 9:43
1

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.

0

You can install fiona with the osgeo4w installer. The package is called python3-fiona. To do this choose start "osgeo4w-setup.exe" and choose "Advanced Installation" (and confirm the following steps) and then search under "select packages" for the fiona packages. So it is similar to underdarks solution for matplotlib.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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