
    +'&h5                        d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ ddl
mZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ  G d de          Z ej        ddd           d Zd Zd Z d Z!d Z"d Z#d Z$d Z%d  Z&d! Z'd" Z(d# Z)d$ Z*d% Z+d& Z, e,e           d' Z-dS )(zThis module defines specific functions for GeoPackage dialect.

See GeoPackage specifications here: http://www.geopackage.org/spec/
    N)text)registry)SQLiteDialect_pysqlite)compiles)func)select)	functions)_check_spatial_type)_format_select_args)_spatial_idx_name)setup_create_drop)_SQLITE_FUNCTIONS)get_col_dim)load_spatialite_driver)	Geography)Geometry)_DummyGeometryc                       e Zd ZdZdZdZdZdS )GeoPackageDialectz)Define a specific dialect for GeoPackage.
geopackagegpkgTN)__name__
__module____qualname____doc__namedriversupports_statement_cache     `/var/www/html/reinick/venv/lib/python3.11/site-packages/geoalchemy2/admin/dialects/geopackage.pyr   r      s&        33DF#00r    r   r   z%geoalchemy2.admin.dialects.geopackagec                 t    t          | g|R   |                     d           |                     d           dS )a  Load SpatiaLite extension in GeoPackage connection and set VirtualGpkg and Amphibious modes.

    .. Warning::
        The path to the SpatiaLite module should be set in the `SPATIALITE_LIBRARY_PATH`
        environment variable.

    Args:
        dbapi_conn: The DBAPI connection.
    zSELECT AutoGpkgStart();z"SELECT EnableGpkgAmphibiousMode();N)r   execute
dbapi_connargss     r!   load_geopackage_driverr'   )   sJ     :-----0111;<<<<<r    c                     |                      d                                          d         s|                      d           dS dS )a{  Initialize GeoPackage tables.

    Args:
        dbapi_conn: The DBAPI connection.

    .. Warning::
        No EPSG SRID is loaded in the `gpkg_spatial_ref_sys` table after initialization but
        it is possible to load other EPSG SRIDs afterwards using the
        `gpkgInsertEpsgSRID(srid)`.
        Nevertheless, SRIDs of newly created tables are automatically added.
    z!SELECT CheckGeoPackageMetaData();r   zSELECT gpkgCreateBaseTables();N)r#   fetchoner$   s     r!   init_geopackager*   9   sQ     ABBKKMMaP =;<<<<<= =r    c                 >    t          |            t          | fi | dS )a  Load SpatiaLite extension in GeoPackage and initialize internal tables.

    See :func:`geoalchemy2.admin.dialects.geopackage.load_geopackage_driver` and
    :func:`geoalchemy2.admin.dialects.geopackage.init_geopackage` functions for details about
    arguments.
    N)r'   r*   r%   r&   kwargss      r!   load_spatialite_gpkgr.   J   s.     :&&&J))&)))))r    c                     |                      t          d                              ||                                                    }|d S |\  }}}}}d}	|r|	dz  }	|r|	dz  }	||	||f}
|
S )Na  SELECT
                A.geometry_type_name,
                A.srs_id,
                A.z,
                A.m,
                IFNULL(B.has_index, 0) AS has_index
            FROM gpkg_geometry_columns
            AS A
            LEFT JOIN (
                SELECT table_name, column_name, COUNT(*) AS has_index
                FROM gpkg_extensions
                WHERE LOWER(table_name) = LOWER(:table_name)
                    AND column_name = :column_name
                    AND extension_name = 'gpkg_rtree_index'
            ) AS B
            ON LOWER(A.table_name) = LOWER(B.table_name)
                AND A.column_name = B.column_name
            WHERE LOWER(A.table_name) = LOWER(:table_name)
                AND A.column_name = :column_name;
        
table_namecolumn_nameXYZM)r#   r   
bindparamsr)   )bindr1   col_nameattrsgeometry_typesridhas_zhas_m	has_indexcoord_dimensioncol_attributess              r!   _get_spatialite_attrsrA   U   s    LL	
 	
* *
*
A
A- . hjj/ 
0 }t380M4yO 3 3"OT9DNr    c                     |D ]U}t          j        d|j        j                                      d          }|j        |_        t          |          |_        V| j        d         | _        dS )zGSetup dummy type for new Geometry columns so they can be updated later.z(.+?)[ZMzm]*   )r:   _saved_columnsN)	re	fullmatchtyper:   group_actual_typer   infocolumns)tablegis_colscoltype_strs       r!   _setup_dummy_typerP   {   sf     : :<0FGGMMaPP8!999J/0EMMMr    c                     t          t          t          j        |j        |j                             }|                    d          }|                     |           dS )z)Create spatial index on the given column.T
autocommitN)r   r   r   gpkgAddSpatialIndexr   execution_optionsr#   )r7   rL   rN   stmts       r!   create_spatial_indexrW      sT    &t'?
CH'U'UVVWD!!T!22DLLr    c           
         dD ]C}|                      t          d                    |j        |j        |                               D|                      t          d                              |j        |j                             dS )z#Disable spatial indexes if present.) _node_parent_rowidz#DROP TABLE IF EXISTS rtree_{}_{}{};zDELETE FROM gpkg_extensions
            WHERE LOWER(table_name) = LOWER(:table_name)
                AND column_name = :column_name
                AND extension_name = 'gpkg_rtree_index';r0   N)r#   r   formatr   r6   )r7   rL   rN   is       r!   disable_spatial_indexr_      s    / 	
 	
5<<JH  	
 	
 	
 	
 	LL<	
 	

 *z  
 

 
 
 
 
r    c                    t          |                    d          t                    sdS t          | j        |j        |d                   }|r|\  }}}}ddddd                    ||          }||d         _        ||d         _        ||d         _        t          |          |d         _
        d|d         _        dS dS )	z:Reflect a column of type Geometry with GeoPackage dialect.rG   Nr            )r3   XYZXYMXYZMF)
isinstancegetr   rA   r7   r   r:   	dimensionr;   boolspatial_index_spatial_index_reflected)	inspectorrL   column_infor@   r:   r?   r;   rk   s           r!   reflect_geometry_columnro      s     koof--x88 *9>5:{SYGZ[[N!>L;m 	
 

 #o
/
/ 	 -:F)(7F%#'F ,0,?,?F) 8=F444# "!r    c                 "    t          | g|R i |S )N)r.   r,   s      r!   connectrq      s     
<T<<<V<<<r    c                    t          | |          \  }}}g | j        d<   t          | j                  }|D ]}| j        d         D ]}t	          |j        t          |          r||j                                        v rs| j        	                    |           |j
        t          | j
        |j
                  k    st          |j        dd          s | j        d                             |           t          |          dk    rt          d          t          |          dk    r|d         }|j        j        }	|j        j        d	|j        _        |                    t'          d
                              |	                                                    s6|                    t'          d                              |	                     t-          | |           dS )z6Handle spatial indexes during the before_create event._after_create_indexesrD   rk   FrC   zGOnly one geometry column is allowed for a table stored in a GeoPackage.r   NGEOMETRYz?SELECT COUNT(*) FROM gpkg_spatial_ref_sys WHERE srs_id = :srid;)r;   z SELECT gpkgInsertEpsgSRID(:srid))r   rJ   setindexesr
   rG   r   rK   valuesremover   r   getattrappendlen
ValueErrorr;   r:   r#   r   r6   scalarrP   )
rL   r7   kwdialectrM   regular_colscurrent_indexesidxrN   r;   s
             r!   before_creater      s   &7t&D&D#GX|
 +-EJ&'%-((O D D:./ 	D 	DC"38Xw?? DC3;K]K]K_K_D_D_$$S)))80SXFFFFgHouO OF J67>>sCCC	D 8}}qbccc	X!		qkx}8!)%/CH" ||RSS^^ _  
 
 &((		Y
 LL@AALLRVLWWXXXeX&&&&&r    c                    |j         }| j        D ]A}t          |j        t          |          r"|j        |_        |`t          |          }d|v }d|v }|                    t          d          	                    | j
        |j        j                             |                    t          d          	                    | j
        |j
        |j        j        |j        j        ||                     t          t          t          j        | j
        |j
                             }|                    d          }|                    |           C| j        D ]C}t          |j        t          t$          f|          r|j        j        du rt)          || |           D| j                            d	          D ]2}	| j                            |	           |	                    |
           3dS )z5Handle spatial indexes during the after_create event.r4   r5   a  INSERT INTO gpkg_contents
                    VALUES (
                        :table_name,
                        'features',
                        :table_name,
                        "",
                        strftime('%Y-%m-%dT%H:%M:%fZ', CURRENT_TIMESTAMP),
                        NULL,
                        NULL,
                        NULL,
                        NULL,
                        :srid
                    );)r1   r;   zINSERT INTO gpkg_geometry_columns
                    VALUES (:table_name, :column_name, :geometry_type, :srid, :has_z, :has_m);)r1   r2   r:   r;   r<   r=   TrR   rs   r7   N)r   rK   r
   rG   r   rI   r   r#   r   r6   r   r;   r:   r   r   r   gpkgAddGeometryTriggersrU   r   rk   rW   rJ   poprv   addcreate)
rL   r7   r~   r   rN   ri   r<   r=   rV   r   s
             r!   after_creater      s   lG} , ,sx7;; *	'CH #C((I9$E9$ELL  *$z     ( LLb  *$z #"%("8   	   .t/KEJX[X`/a/abbcD))T)::DLL} 3 3  8Y*?II	3&$.. uc222z~~566  #


 r    c                    t          | |          \  }}}|D ]}t          || |           |                    t          d                              | j        |j                             |                    t          d                              | j        |j                             |                    t          d                              | j                             dS )z4Handle spatial indexes during the before_drop event.zDELETE FROM gpkg_extensions
                WHERE LOWER(table_name) = LOWER(:table_name)
                    AND column_name = :column_name;r0   zDELETE FROM gpkg_geometry_columns
                WHERE LOWER(table_name) = LOWER(:table_name)
                    AND column_name = :column_name;zWDELETE FROM gpkg_contents
                WHERE LOWER(table_name) = LOWER(:table_name);)r1   N)r   r_   r#   r   r6   r   )rL   r7   r~   r   rM   r   rN   s          r!   before_dropr   (  s   &7t&D&D#GX| !
 !
 	dE3/// 	7  j :H   		
 		
 		
 	7  j :H   		
 		
 		
 	A  jEJj//		
 	
 	
 	
9!
 !
r    c                 D    | j                             d          | _        dS )z3Handle spatial indexes during the after_drop event.rD   N)rJ   r   rK   )rL   r7   r~   s      r!   
after_dropr   P  s    JNN#344EMMMr    c                 j    fd} t          t          t          |           d          |           d S )Nc                 R    d                      |j        | j        fi |          S )Nz{}({}))r]   processclauses)elementcompilerr~   fns      r!   _compile_gpkgz%_compiles_gpkg.<locals>._compile_gpkgV  s/    r#38#3GO#J#Jr#J#JKKKr    r   )r   ry   r	   )clsr   r   s    ` r!   _compiles_gpkgr   U  sM    L L L L L 4HWY$$l33MBBBBBr    c                 Z    |                                  D ]\  }}t          ||           dS )a3  Register compilation mappings for the given functions.

    Args:
        mapping: Should have the following form::

                {
                    "function_name_1": "gpkg_function_name_1",
                    "function_name_2": "gpkg_function_name_2",
                    ...
                }
    N)itemsr   )mappingr   r   s      r!   register_gpkg_mappingr   \  s<     ==??    RsB   r    c                 J    |                      t          d                     dS )a  Create the `spatial_ref_sys` view from the `gpkg_spatial_ref_sys` table.

    .. Note::

        This is usually only needed to use the `ST_Transform` function on GeoPackage data
        because this function, when used with SpatiaLite, requires the `spatial_ref_sys` table.
    zCREATE VIEW spatial_ref_sys AS
            SELECT
                srs_id AS srid,
                organization AS auth_name,
                organization_coordsys_id AS auth_srid,
                definition AS srtext
            FROM gpkg_spatial_ref_sys;N)r#   r   r   s    r!   create_spatial_ref_sys_viewr   o  s6     	LL*	
 	

 
 
 
 
r    ).r   rE   
sqlalchemyr   sqlalchemy.dialectsr   #sqlalchemy.dialects.sqlite.pysqliter   sqlalchemy.ext.compilerr   sqlalchemy.sqlr   r   geoalchemy2r	   !geoalchemy2.admin.dialects.commonr
   r   r   r   !geoalchemy2.admin.dialects.sqliter   r   r   geoalchemy2.typesr   r   r   r   registerr'   r*   r.   rA   rP   rW   r_   ro   rq   r   r   r   r   r   r   r   r   r    r!   <module>r      s   
 
			       ( ( ( ( ( ( F F F F F F , , , , , ,       ! ! ! ! ! ! ! ! ! ! ! ! A A A A A A A A A A A A ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 9 9 9 9 9 9 D D D D D D ' ' ' ' ' ' & & & & & & , , , , , ,1 1 1 1 1. 1 1 1  &ACV W W W= = = = = ="* * *# # #L1 1 1    2= = =4= = ="' "' "'J= = =@%
 %
 %
P5 5 5
C C C        ' ( ( (    r    