Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'm writing a shapefile using OGR in python, creating fields on-the-fly from a python data source. Creation of a new field requires an OGR data type, is there a mapping between OGR and python data types?

For example, this would be the norm:

new_field = ogr.FieldDefn('MYFLD', ogr.OFTInteger)

Ideally:

ogr_datatype = get_ogr_data_type(python_data)
new_field = ogr.FieldDefn('MYFLD', ogr_datatype)

Currently my conversions are hard coded (e.g. int = ogr.OFTInteger), but this is a bit of a pain and relies on me coding all possible data types.

Thanks.

share|improve this question
add comment

4 Answers

You'll have to create a dictionary of Python types to OGR "types" because they're just ints. It's a bit of a pain I grant you, but OGR (and the SWIG-generated bindings) have no notion of a language's types whether it's in C or Python.

Something like this should work:

OGRTypes = {int: ogr.OFTInteger, str: ogr.OFTString, ...}

...

new_field = ogr.FieldDefn('MYFLD', OGRTypes[type(python_data)])
share|improve this answer
    
Thanks - I suspected this would be the case! –  thom Jan 16 '12 at 9:46
add comment

For what it's worth, I've got a Python package that contains such a mapping. See https://github.com/Toblerity/Fiona/blob/master/src/fiona/ogrext.pyx#L18. Copied here:

# Mapping of OGR integer field types to Fiona field type names.
#
# Only ints, floats, and unicode strings are supported. On the web, dates and
# times are represented as strings (see RFC 3339). 
FIELD_TYPES = [
    'int',          # OFTInteger, Simple 32bit integer
    None,           # OFTIntegerList, List of 32bit integers
    'float',       # OFTReal, Double Precision floating point
    None,           # OFTRealList, List of doubles
    'str',          # OFTString, String of ASCII chars
    None,           # OFTStringList, Array of strings
    None,           # OFTWideString, deprecated
    None,           # OFTWideStringList, deprecated
    None,           # OFTBinary, Raw Binary data
    None,           # OFTDate, Date
    None,           # OFTTime, Time
    None,           # OFTDateTime, Date and Time
    ]

# Mapping of Fiona field type names to Python types.
FIELD_TYPES_MAP = {
    'int':      IntType,
    'float':    FloatType,
    'str':      UnicodeType,
    }

My mapping is incomplete because I don't run into many OFT*List fields in the wild. You'd want to map these to Python arrays, I suppose (OFTIntegerList -> array('i') for example) since Python's lists aren't typed. OFTDate/Time fields are the devil and mapping these to Python DateTime doesn't make the situation any better because the datetime module API is awful. In my project, I'm going to map dates and times to ISO 8601 strings like "2012-01-02T20:59:38Z". Raw binary data would be mapped to a non-unicode Python string (which becomes the bytes type in Python 3).

share|improve this answer
    
Was going to mention fiona and then I scroll down and see you have already posted :) –  Nathan W Jan 12 '12 at 11:35
add comment

If you're goal is simply shapefile editing in Python check out PyShp:

http://code.google.com/p/pyshp/

It's pure python so you only use python data types. I also have examples of common geometry and attribute operations on GeospatialPython.com

share|improve this answer
add comment

I think the geodjango ogr wrapper is the best wrapper I've ever used. It provides a very intuitive way to describe geo features. You could find more information about it in geodjango website.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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