Code source de geonature.core.imports.checks.sql.geo

from geonature.core.imports.checks.errors import ImportCodeError
from geonature.core.imports.models import BibFields, Entity, TImports
from sqlalchemy.sql.expression import select, update, join
import sqlalchemy as sa
from geoalchemy2.functions import (
    ST_Transform,
    ST_IsValid,
    ST_Centroid,
)
from geonature.utils.env import db

from geonature.core.imports.checks.sql.utils import report_erroneous_rows

from ref_geo.models import LAreas


__all__ = [
    "set_geom_point",
    "convert_geom_columns",
    "check_is_valid_geometry",
    "check_geometry_outside",
]


[docs] def set_geom_point( imprt: TImports, entity: Entity, geom_4326_field: BibFields, geom_point_field: BibFields, ) -> None: """ Set the_geom_point as the centroid of the geometry in the transient table of an import. Parameters ---------- imprt : TImports The import to update. entity : Entity The entity to update. geom_4326_field : BibFields Field containing the geometry in the transient table. geom_point_field : BibFields Field to store the centroid of the geometry in the transient table. Returns ------- None """ transient_table = imprt.destination.get_transient_table() # Set the_geom_point: stmt = ( update(transient_table) .where( transient_table.c.id_import == imprt.id_import, transient_table.c[entity.validity_column] == True, ) .values( { geom_point_field.dest_field: ST_Centroid( transient_table.c[geom_4326_field.dest_field] ), } ) ) db.session.execute(stmt)
[docs] def convert_geom_columns( imprt: TImports, entity: Entity, geom_4326_field: BibFields, geom_local_field: BibFields, ) -> None: """ Convert the geometry from the file SRID to the local SRID in the transient table of an import. Parameters ---------- imprt : TImports The import to update. entity : Entity The entity to update. geom_4326_field : BibFields Field representing the geometry in the transient table in SRID 4326. geom_local_field : BibFields Field representing the geometry in the transient table in the local SRID. """ file_srid = imprt.srid local_srid = db.session.execute(sa.func.Find_SRID("ref_geo", "l_areas", "geom")).scalar() dest_srid = None if file_srid == local_srid: # dataframe check defined geom_local, we must use it to define geom_4326 source_col = geom_local_field.dest_field dest_col = geom_4326_field.dest_field dest_srid = 4326 elif file_srid == 4326: # dataframe check defined geom_4326, we must use it to define geom_local source_col = geom_4326_field.dest_field dest_col = geom_local_field.dest_field dest_srid = local_srid else: # dataframe check has already defined geom_4326 and geom_local pass if dest_srid: transient_table = imprt.destination.get_transient_table() stmt = ( update(transient_table) .where( transient_table.c.id_import == imprt.id_import, transient_table.c[entity.validity_column] == True, transient_table.c[source_col] != None, ) .values( { dest_col: ST_Transform(transient_table.c[source_col], dest_srid), } ) ) db.session.execute(stmt)
[docs] def check_is_valid_geometry( imprt: TImports, entity: Entity, wkt_field: BibFields, geom_field: BibFields, ) -> None: """ Check if the geometry is valid in the transient table of an import. Parameters ---------- imprt : TImports The import to check. entity : Entity The entity to check. wkt_field : BibFields Field containing the source WKT of the geometry. geom_field : BibFields Field containing the geometry from the WKT in `wkt_field` to be validated. """ # It is useless to check valid WKT when created from X/Y transient_table = imprt.destination.get_transient_table() where_clause = sa.and_( transient_table.c[wkt_field.source_field] != None, sa.not_(ST_IsValid(transient_table.c[geom_field.dest_field])), ) report_erroneous_rows( imprt, entity, error_type=ImportCodeError.INVALID_GEOMETRY, error_column="WKT", whereclause=where_clause, )
[docs] def check_geometry_outside( imprt: TImports, entity: Entity, geom_local_field: BibFields, id_area: int, ) -> None: """ For an import, check if one or more geometries in the transient table are outside a defined area. Parameters ---------- imprt : TImports The import to check. entity : Entity The entity to check. geom_local_field : BibFields Field containing the geometry in the local SRID of the area. id_area : int The id of the area to check if the geometry is inside. """ transient_table = imprt.destination.get_transient_table() area = db.session.execute(sa.select(LAreas).where(LAreas.id_area == id_area)).scalar_one() report_erroneous_rows( imprt, entity, error_type=ImportCodeError.GEOMETRY_OUTSIDE, error_column="Champs géométriques", whereclause=sa.and_( transient_table.c[entity.validity_column] == True, transient_table.c[geom_local_field.dest_field].ST_Disjoint(area.geom), ), )