Mapeando entre os tipos de dados OGR e Python?

8

Estou escrevendo um shapefile usando OGR em python, criando campos dinamicamente a partir de uma fonte de dados python. A criação de um novo campo requer um tipo de dados OGR, existe um mapeamento entre os tipos de dados OGR e python?

Por exemplo, esta seria a norma:

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

Idealmente:

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

Atualmente, minhas conversões são codificadas (por exemplo, int = ogr.OFTInteger), mas isso é um pouco trabalhoso e depende de eu codificar todos os tipos de dados possíveis.

Tomas
fonte
Eu acho que o wrapper geodjango ogr é o melhor wrapper que eu já usei. Ele fornece uma maneira muito intuitiva de descrever os recursos geográficos. Você pode encontrar mais informações sobre isso no site geodjango .
xiao 31/01

Respostas:

9

Você precisará criar um dicionário de tipos Python para "tipos" de OGR, porque eles são apenas ints. É um pouco doloroso que eu conceda, mas o OGR (e as ligações geradas pelo SWIG) não têm noção dos tipos de uma linguagem, seja em C ou Python.

Algo assim deve funcionar:

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

...

new_field = ogr.FieldDefn('MYFLD', OGRTypes[type(python_data)])
MerseyViking
fonte
7

Quanto vale a pena, eu tenho um pacote Python que contém esse mapeamento. Consulte https://github.com/Toblerity/Fiona/blob/master/src/fiona/ogrext.pyx#L18 . Copiado aqui:

# 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,
    }

Meu mapeamento está incompleto porque não encontro muitos campos OFT * List em estado selvagem. Você gostaria de mapeá-los para matrizes Python, suponho (OFTIntegerList -> array ('i') por exemplo), já que as listas do Python não são digitadas. Os campos OFTDate / Time são o diabo e o mapeamento para o Python DateTime não melhora a situação porque a API do módulo datetime é péssima. No meu projeto, vou mapear datas e horas para as sequências ISO 8601 como "2012-01-02T20: 59: 38Z". Os dados binários brutos seriam mapeados para uma sequência Python não unicode (que se torna o tipo de bytes no Python 3).

sgillies
fonte
Iria mencionar fiona e então eu role para baixo e veja que você já postou :) #
W Nathan Nathan
1

Se seu objetivo é simplesmente editar o shapefile no Python, confira o PyShp:

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

É python puro, então você usa apenas tipos de dados python. Também tenho exemplos de operações comuns de geometria e atributos em GeospatialPython.com

GeospatialPython.com
fonte