Skip to content

Commit

Permalink
Merge 3460f58 into 6cc39b0
Browse files Browse the repository at this point in the history
  • Loading branch information
yvaucher committed Oct 1, 2019
2 parents 6cc39b0 + 3460f58 commit e59a598
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 87 deletions.
113 changes: 59 additions & 54 deletions base_geoengine/fields.py
Expand Up @@ -5,8 +5,10 @@
from operator import attrgetter

from odoo import fields, _
from odoo.tools import sql

from .geo_helper import geo_convertion_helper as convert
from .geo_db import create_geo_column

logger = logging.getLogger(__name__)
try:
Expand Down Expand Up @@ -39,7 +41,6 @@ def column_type(self):
'dim': 2,
'srid': 3857,
'gist_index': True,
'manual': True,
}

def convert_to_column(self, value, record, values=None):
Expand Down Expand Up @@ -95,26 +96,6 @@ def load_geo(cls, wkb):
"""Load geometry into browse record after read was done"""
return wkbloads(wkb, hex=True) if wkb else False

def create_geo_column(self, cr, col_name, table, model):
"""Create a columns of type the geom"""
try:
cr.execute("SELECT AddGeometryColumn( %s, %s, %s, %s, %s)",
(table,
col_name,
self.srid,
self.geo_type,
self.dim))
self._create_index(cr, table, col_name)
except Exception:
cr.rollback()
logger.exception('Cannot create column %s table %s:',
col_name, table)
raise
finally:
cr.commit()

return True

def entry_to_shape(self, value, same_type=False):
"""Transform input into an object"""
shape = convert.value_to_shape(value)
Expand All @@ -125,63 +106,87 @@ def entry_to_shape(self, value, same_type=False):
self.geo_type.lower()))
return shape

def _postgis_index_name(self, table, col_name):
return "%s_%s_gist_index" % (table, col_name)

def _create_index(self, cr, table, col_name):
if self.gist_index:
try:
cr.execute("CREATE INDEX %s ON %s USING GIST ( %s )" %
(self._postgis_index_name(table, col_name),
table,
col_name))
except Exception:
cr.rollback()
logger.exception(
'Cannot create gist index for col %s table %s:',
col_name, table)
raise
finally:
cr.commit()

def update_geo_column(self, cr, col_name, table, model):
def update_geo_db_column(self, model):
"""Update the column type in the database.
"""
cr = model._cr
query = ("""SELECT srid, type, coord_dimension
FROM geometry_columns
WHERE f_table_name = %s
AND f_geometry_column = %s""")
cr.execute(query, (table, col_name))
cr.execute(query, (model._table, self.name))
check_data = cr.fetchone()
if not check_data:
raise TypeError(
"geometry_columns table seems to be corrupted. "
"SRID check is not possible")
"geometry_columns table seems to be corrupted."
" SRID check is not possible")
if check_data[0] != self.srid:
raise TypeError(
"Reprojection of column is not implemented"
"We can not change srid %s to %s" % (
"Reprojection of column is not implemented."
" We can not change srid %s to %s" % (
self.srid, check_data[0]))
if check_data[1] != self.geo_type:
elif check_data[1] != self.geo_type:
raise TypeError(
"Geo type modification is not implemented"
"We can not change type %s to %s" % (
"Geo type modification is not implemented."
" We can not change type %s to %s" % (
check_data[1], self.geo_type))
if check_data[2] != self.dim:
elif check_data[2] != self.dim:
raise TypeError(
"Geo dimention modification is not implemented"
"We can not change dimention %s to %s" % (
"Geo dimention modification is not implemented."
" We can not change dimention %s to %s" % (
check_data[2], self.dim))
if self.gist_index:
cr.execute(
"SELECT indexname FROM pg_indexes WHERE indexname = %s",
(self._postgis_index_name(table, col_name),))
(self._postgis_index_name(model._table, self.name),))
index = cr.fetchone()
if index:
return True
self._create_index(cr, table, col_name)
self._create_index(cr, model._table, self.name)
return True

def update_db_column(self, model, column):
""" Create/update the column corresponding to ``self``.
For creation of geo column
:param model: an instance of the field's model
:param column: the column's configuration (dict)
if it exists, or ``None``
"""
# the column does not exist, create it

if not column:
create_geo_column(
model._cr,
model._table,
self.name,
self.geo_type,
self.srid,
self.dim,
self.string)
return

if column['udt_name'] == self.column_type[0]:
return

self.update_geo_db_column(model)

if column['udt_name'] in self.column_cast_from:
sql.convert_column(
model._cr, model._table, self.name, self.column_type[1])
else:
newname = (self.name + '_moved{}').format
i = 0
while sql.column_exists(
model._cr, model._table, newname(i)
):
i += 1
if column['is_nullable'] == 'NO':
sql.drop_not_null(model._cr, model._table, self.name)
sql.rename_column(model._cr, model._table, self.name, newname(i))
sql.create_column(model._cr, model._table, self.name, self.column_type[1], self.string)


class GeoLine(GeoField):
"""Field for POSTGIS geometry Line type"""
Expand Down
39 changes: 39 additions & 0 deletions base_geoengine/geo_db.py
Expand Up @@ -5,8 +5,10 @@

from odoo import _
from odoo.exceptions import MissingError
from odoo.tools import sql

logger = logging.getLogger('geoengine.sql')
_schema = logging.getLogger('odoo.schema')


def init_postgis(cr):
Expand Down Expand Up @@ -45,3 +47,40 @@ def init_postgis(cr):
"CREATE EXTENSION postgis_topology;\n"
)
)


def create_geo_column(
cr, tablename, columnname, geotype, srid, dim, comment=None):
""" Create a geometry column with the given type.
:params: srid: geometry's projection srid
:params: dim: geometry's dimension (2D or 3D)
"""
cr.execute("SELECT AddGeometryColumn( %s, %s, %s, %s, %s)",
(tablename,
columnname,
srid,
geotype,
dim))
if comment:
cr.execute('COMMENT ON COLUMN "{}"."{}" IS %s'.format(
tablename, columnname), (comment,))
_schema.debug(
"Table %r: added geometry column %r of type %s",
tablename, columnname, geotype)


def _postgis_index_name(table, col_name):
return "%s_%s_gist_index" % (table, col_name)


def create_geo_index(cr, columnname, tablename):
""" Create the given index unless it exists. """
indexname = _postgis_index_name(tablename, columnname)
if sql.index_exists(cr, indexname):
return
cr.execute("CREATE INDEX %s ON %s USING GIST ( %s )" %
(indexname,
tablename,
columnname))
_schema.debug("Table %r: created index %r (%s)", tablename, indexname, args)
33 changes: 0 additions & 33 deletions base_geoengine/geo_model.py
Expand Up @@ -19,37 +19,6 @@ class GeoModel(models.AbstractModel):
# Array of ash that define layer and data to use
_georepr = []

@api.model_cr_context
def _auto_init(self):
"""Initialize the columns in dB and Create the GIST index
only create and update supported
We override the base methid because creation of fields in DB is not
actually delegated to the field it self but to the ORM _auto_init
function
"""
cr = self._cr

geo_fields = {}
for f_name, field in self._fields.items():
if field.type.startswith('geo_'):
geo_fields[f_name] = field
res = super()._auto_init()
if self._abstract:
return res

# Create geo columns
column_data = tools.table_columns(cr, self._table)

for f_name, geo_field in geo_fields.items():
if geo_field.compute and not geo_field.store:
continue
fct = geo_field.create_geo_column
if f_name in column_data:
fct = geo_field.update_geo_column
fct(cr, f_name, self._table, self._name)
return res

@api.model
def fields_get(self, allfields=None, attributes=None):
"""Add geo_type definition for geo fields"""
Expand Down Expand Up @@ -110,8 +79,6 @@ def set_field_real_name(in_tuple):
'default_extent': view.default_extent or DEFAULT_EXTENT,
'default_zoom': view.default_zoom,
}
# XXX still the case ?
# TODO find why context in read does not work with webclient
for layer in view.raster_layer_ids:
layer_dict = layer.read()[0]
res['geoengine_layers']['backgrounds'].append(layer_dict)
Expand Down

0 comments on commit e59a598

Please sign in to comment.