2016-07-13 1 views
0

Я работаю с sqlalchemy и geoalchemy и преобразую свои результаты в geojson. с обычным способом, как это:Как конвертировать SDO_GEOMTRY в GeoJSON

print json.dumps([dict(r) for r in connection.execute(query)]) 

это не представляется возможным, потому что cx_Oracle.Objets не сериализации! я могу иметь доступ через отдельные атрибуты, как этот:

result = connection.execute(query) 
result2 = result.fetchone()[0] 
print result2.SDO_ORDINATES 

Вот моя Программа:

#!/usr/bin/env python 
# coding: utf8 
#from __future__ import absolute_import, division, print_function 
from sqlalchemy import create_engine 
from sqlalchemy import Table, MetaData 
from sqlalchemy.sql import and_, select 
from geoalchemy import Geometry, GeometryExtensionColumn 
from geoalchemy import * 
from geoalchemy.oracle import oracle_functions 
from geoalchemy.oracle import OracleComparator 
import cx_Oracle 
import json 
import sdo 

#def main(): 
engine = create_engine('oracle+cx_oracle://TEST_3D:[email protected]:1521/sdetest') 
metadata = MetaData(engine) 

# Loading tables 
building = Table(
    'building', 
    metadata, 
    GeometryExtensionColumn('centroid_geom', Geometry(2, srid= 431467)), 
    autoload=True, 
    autoload_with=engine 
) 
GeometryDDL(building) 

thematic_surface = Table('thematic_surface', metadata, autoload=True) 
surface_geometry = Table('surface_geometry', metadata, autoload=True) 
objectclass = Table('objectclass', metadata, autoload=True) 

connection = engine.connect() 

# define the query 
query = select([(surface_geometry.c.geometry)] #building.c.id, surface_geometry.c.geometry, objectclass.c.classname 
).where(
    and_(
     building.c.grid_id_400 == 4158, 
     building.c.id == thematic_surface.c.building_id, 
     thematic_surface.c.lod2_multi_surface_id == surface_geometry.c.root_id, 
     surface_geometry.c.geometry != None, 
     thematic_surface.c.objectclass_id == objectclass.c.id, 
    ) 
) 
# Execute and print the result of the query 
#print json.dumps([dict(r) for r in connection.execute(query)]) 
result = connection.execute(query) 

Я конвертировать все мои cx_Oracle.Objects в GeoJSON, но как? В Интернете есть функция sdo2geojson, которая отлично работает в sql-разработчике, но, конечно, эта функция не предназначена для python ...

Надеюсь, кто-то может мне помочь ???

ответ

0

Используется (пока еще не выпущенная) версия cx_Oracle, которая поддерживает привязку объектов и других более сложных применений объектов. Используя образец, предоставленный cx_Oracle для демонстрации вставки геометрии, следующий код преобразует созданный таким образом объект в JSON. Функция ObjectRepr(), включенная ниже, должна работать для любого объекта, возвращенного из Oracle. Он просто считывает метаданные объекта и превращает объект в словарь атрибутов или список значений.

import cx_Oracle 
import json 

connection = cx_Oracle.Connection("user/[email protected]") 
typeObj = connection.gettype("SDO_GEOMETRY") 
cursor = connection.cursor() 
cursor.execute(""" 
     select Geometry 
     from TestGeometry 
     where IntCol = 1""") 
obj, = cursor.fetchone() 

def ObjectRepr(obj): 
    if obj.type.iscollection: 
     returnValue = [] 
     for value in obj.aslist(): 
      if isinstance(value, cx_Oracle.Object): 
       value = ObjectRepr(value) 
      returnValue.append(value) 
    else: 
     returnValue = {} 
     for attr in obj.type.attributes: 
      value = getattr(obj, attr.name) 
      if value is None: 
       continue 
      elif isinstance(value, cx_Oracle.Object): 
       value = ObjectRepr(value) 
      returnValue[attr.name] = value 
    return returnValue 

print("JSON:", json.dumps(ObjectRepr(obj))) 
+0

Я получаю это сообщение об ошибке: ** AttributeError: объект 'cx_Oracle.ObjectType' не имеет атрибута 'iscollection' **. Мой результат sql-оператора - cx_Oracle.OBJECT. Что не так? По какой причине вы определили typeObj? Для меня я получаю сообщение об ошибке: ** AttributeError: объект 'cx_Oracle.Connection' не имеет атрибута 'gettype' ** – Moehre

+0

. О функции, которую первая часть (if.obj.type.iscollection) не работает. Вторая часть работает отлично. У меня есть такая структура: ** (Number, cx_Oracle.OBJECT, String), (...), (...), ... ** Как я могу преобразовать эту структуру в GeoJSON следующим образом: {" Номер ": 12," Геометрия ": [3500983.087, 5394211.455, 473.82800000000003, 3500 978,97, 5394211.04, 469.069, 3500979.85, 5394201.47, 468.482, 3500984.777, 53942 02.055, 474.192, 3500983.087, 5394211.455, 473.82800000000003]," Тип: крыша} – Moehre

+0

Вам нужно использовать невыпущенную версию cx_Oracle. Возьмите источник из https://bitbucket.org/anthony_tuininga/cx_oracle и скомпилируйте его. Тогда все должно работать нормально. –