
    Dvg@                     P   d dl Z d dlmZ d dlmZ d dlmZ d dlmZ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mZ d dlmZ d dlmZ d dlmZmZ d dlmZ d dl m!Z! ddl"m#Z# ddl$m%Z%m&Z& ddl'm(Z( dZ) G d de          Z* G d de          Z+ G d dee          Z,dS )    N)settings)BaseSpatialOperations)SpatialOperator)GeometryFieldRasterField)
GDALRaster)GEOSGeometryBase)wkb_r)Distance)ImproperlyConfigured)NotSupportedErrorProgrammingError)DatabaseOperations)is_psycopg3)FuncValue)cached_property)get_version_tuple   )PostGISAdapter)PostGISGeometryColumnsPostGISSpatialRefSysfrom_pgraster	bilateralc                   6     e Zd Zd fd	Z fdZd Zd Z xZS )PostGISOperatorFc                 V    || _         || _         t                      j        di | d S )N )	geographyrastersuper__init__)selfr    r!   kwargs	__class__s       n/var/www/pixelcanvas.ch/venv/lib/python3.11/site-packages/django/contrib/gis/db/backends/postgis/operations.pyr#   zPostGISOperator.__init__   s8     #
 ""6"""""    c                     |                      ||          }|                     ||          } t                      j        |||g|R  S N)check_rastercheck_geographyr"   as_sql)r$   
connectionlookuptemplate_paramsargsr&   s        r'   r-   zPostGISOperator.as_sql(   sO    ++FODD..vGGuww~j&/IDIIIIr(   c                 "   |j         o|j         d         dk    }|j        j        j        dk    }t	          |j        t                    }|j        -|r+| j        st          d          |d         d|j        |d<   |j
        -|r+| j        st          d          |d         d|j
        |d<   | j        r|r!|rd|d         z  |d<   |rd|d         z  |d<   n5| j        t          k    r%|r|sd|d         z  |d<   n|r|sd|d         z  |d<   |S )	NspheroidRASTERzFBand indices are not allowed for this operator, it works on bbox only.lhsz, rhszST_Polygon(%s))
rhs_paramsr6   field	geom_type
isinstancer7   r   band_lhsfunc
ValueErrorband_rhsr!   	BILATERAL)r$   r/   r0   r4   lhs_is_rasterrhs_is_rasters         r'   r+   zPostGISOperator.check_raster-   s   $L):2)>*)L 
(2h>"6:z:: ?&=&9    
  &&&&OE"
 ?&=&9    
  &&&&OE" { 	Sh 	S S)9OE<R)R& S)9OE<R)R&[I%%  S] S)9OE<R)R&& S} S)9OE<R)R&r(   c                 V    |j         j        j        r| j        s|dxx         dz  cc<   |S )z9Convert geography fields to geometry types, if necessary.r6   z
::geometry)r6   output_fieldr    )r$   r/   r0   s      r'   r,   zPostGISOperator.check_geography\   s=    :", 	3T^ 	3E"""l2"""r(   )FF)__name__
__module____qualname__r#   r-   r+   r,   __classcell__r&   s   @r'   r   r      sz        
# 
# 
# 
# 
# 
#J J J J J
- - -^      r(   r   c                   8     e Zd Zd Z fdZed             Z xZS )
ST_Polygonc                    t                                          |           | j        d         }t          |t                    r?|j        s:t	          |j        t          |j        j                            | j        d<   d S d S d S )Nr   srid)rD   )	r"   r#   source_expressionsr;   r   _output_field_or_nonevaluer   rN   )r$   exprr&   s     r'   r#   zST_Polygon.__init__f   s    &q)dE"" 	4+E 	).
$*/)J)J)J* * *D#A&&&	 	 	 	r(   c                 L    t          | j        d         j        j                  S )Nr   rM   )r   rO   r9   rN   r$   s    r'   rD   zST_Polygon.output_fieldn   s!    $"9!"<"B"GHHHHr(   )rE   rF   rG   functionr#   r   rD   rH   rI   s   @r'   rK   rK   c   s_        H     I I _I I I I Ir(   rK   c                       e Zd ZdZdZdZeZedz   Zedz   Z	edz   Z
edz   Zedz   Zed	z   Zed
z   Zi d edd          d eddd          d edd          d ede          d ede          d ed          d ed          d ed          d ed          d  ed!          d" ed#          d$ ed%e          d& ed%e          d' ed(e)          d* ed+e)          d, ed-de.          d/ ed0de.           ed12           ed3e)           ed42           ed5de.           ed6e)           ed72           ed8e)           ed9e)           ed:de.          d;	Z e            Zerd<nd=Zd>Zed?             Zed@             ZdA ZdB ZdC ZdD ZdE ZdF ZdG Z dH Z!dI Z"dJ Z#dK Z$dL Z%dM Z&dN Z'dO Z(dP Z)dQ Z* fdRZ+e,dS             Z-dT Z.dU Z/ xZ0S )VPostGISOperationspostgisTST_CollectExtent3DExtent3DLengthMakeLine3DPerimeterUnion
bbcontains~)opr!   
bboverlapsz&&)rc   r    r!   	contained@overlaps_leftz&<overlaps_rightz&>overlaps_belowz&<|)rc   overlaps_abovez|&>leftz<<rightz>>strictly_belowz<<|strictly_abovez|>>same_asz~=exactcontainsST_Contains)r=   r!   contains_properlyST_ContainsProperly	coveredbyST_CoveredBy)r=   r    r!   covers	ST_Covers
ST_Crosses)r=   ST_Disjoint	ST_EqualsST_IntersectsST_Overlaps	ST_Relate
ST_Touches	ST_Within
ST_DWithin)	crossesdisjointequals
intersectsoverlapsrelatetoucheswithindwithin%sz	%s::byteaNc                     ddddddd}|S )NST_AsBinary	ST_AsTextST_MinimumBoundingCircleST_GeomFromWKBST_GeomFromText
ST_NPoints)AsWKBAsWKTBoundingCircleFromWKBFromWKT	NumPointsr   )r$   function_namess     r'   r   z PostGISOperations.function_names   s*     # 8'(%
 
 r(   c                    t          t          d          rt          j        }ne|                     d           	 |                                 }n0# t
          $ r# t          d| j        j        d         z            w xY w|dd         }|S )z-Determine the version of the PostGIS library.POSTGIS_VERSIONversionzCannot determine PostGIS version for database "%s" using command "SELECT postgis_lib_version()". GeoDjango requires at least PostGIS version 3.0. Was the database created from a spatial database template?NAMEr   N)	hasattrr   r   _get_postgis_funcpostgis_version_tupler   r   r.   settings_dict)r$   r   vtups      r'   spatial_versionz!PostGISOperations.spatial_version   s     8.// 	.GG
 ""9---	1133#   *  #'/"?"G	H   122hGs   A -A;c                     |dS |dd                              d          \  }}t          t          |                                           \  }}t          t          |                                           \  }}||||fS )z
        Return a 4-tuple extent for the `Extent` aggregate by converting
        the bounding box text returned by PostGIS (`box` argument), for
        example: "BOX(-90.0 30.0, -85.0 40.0)".
        N   r3   ,splitmapfloat)r$   boxllurxminyminxmaxymaxs           r'   convert_extentz PostGISOperations.convert_extent   sp     ;4QrT%%B

++
d

++
ddD$''r(   c                    |dS |dd                              d          \  }}t          t          |                                           \  }}}t          t          |                                           \  }}}	||||||	fS )z
        Return a 6-tuple extent for the `Extent3D` aggregate by converting
        the 3d bounding-box text returned by PostGIS (`box3d` argument), for
        example: "BOX3D(-90.0 30.0 1, -85.0 40.0 2)".
        N   r3   r   r   )
r$   box3dr   r   r   r   zminr   r   zmaxs
             r'   convert_extent3dz"PostGISOperations.convert_extent3d   s|     =4qt""3''Bubhhjj11dDubhhjj11dDdD$d33r(   c                     |j         dk    rdS |j        dk    r|j         dz   }n|j         }|j        r&|j        dk    rt	          d          d||j        fz  S d||j        fz  S )	zM
        Return the database field type for the given spatial field.
        r5   r!      Zi  z=PostGIS only supports geography columns with an SRID of 4326.zgeography(%s,%d)zgeometry(%s,%d))r:   dimr    rN   r   )r$   fr:   s      r'   geo_db_typezPostGISOperations.geo_db_type   s     ;(""8 5A::c)III; 	;v~~'S   &AF(;;;$	16':::r(   c                 P   |d         }|                     | j                  }|j        }t          |t                    rd|r|j        }n\|r|dk    rt          d          |j        }n=t          |t	          j        |	                    | j                                      }n|}|gS )a  
        Retrieve the distance parameters for the given geometry field,
        distance lookup value, and the distance lookup type.

        This is the most complex implementation of the spatial backends due to
        what is supported on geodetic geometry columns vs. what's available on
        projected geometry columns.  In addition, it has to take into account
        the geography column type.
        r   r   zNOnly numeric values of degree units are allowed on geographic DWithin queries.)
geodeticr.   r    r;   r   mr>   getattrunit_attname
units_name)r$   r   dist_vallookup_typerQ   r   r    
dist_params           r'   get_distancezPostGISOperations.get_distance  s      ::do..K	eX&& 	 "W

 
)++$A   #W

$80do1N1NOO 


 J|r(   c                     |                      d          }t          |d          r'|j        j        |j        k    rd}n|d|j        d}|S |d}n|j        }|||j        k    rd}n|d|j        d}|S )z
        Provide a proper substitution value for Geometries or rasters that are
        not in the SRID of the field. Specifically, this routine will
        substitute in the ST_Transform() function call.
        	Transformr-   r   z(%s, )N)spatial_function_namer   r9   rN   )r$   r   rQ   compilertransform_funcplaceholder
value_srids          r'   get_geom_placeholderz&PostGISOperations.get_geom_placeholder+  s     33K@@5(## 	{16))"/=~~qvvvF =JJJ qv!5!5KK+9>>1666BKr(   c                     | j                                         5 }|                    d|z             |                                d         cddd           S # 1 swxY w Y   dS )zZ
        Helper routine for calling PostGIS functions and returning their result.
        zSELECT %s()r   N)r.   temporary_connectionexecutefetchone)r$   r=   cursors      r'   r   z#PostGISOperations._get_postgis_funcH  s    
 _1133 	(vNN=4/000??$$Q'	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	( 	(s   2AA Ac                 ,    |                      d          S )z9Return the version of the GEOS library used with PostGIS.postgis_geos_versionr   rT   s    r'   r   z&PostGISOperations.postgis_geos_versionQ      %%&<===r(   c                 ,    |                      d          S )zFReturn the version number of the PostGIS library used with PostgreSQL.postgis_lib_versionr   rT   s    r'   r   z%PostGISOperations.postgis_lib_versionU  s    %%&;<<<r(   c                 ,    |                      d          S )z9Return the version of the PROJ library used with PostGIS.postgis_proj_versionr   rT   s    r'   r   z&PostGISOperations.postgis_proj_versionY  r   r(   c                 ,    |                      d          S )7Return PostGIS version number and compile-time options.postgis_versionr   rT   s    r'   r   z!PostGISOperations.postgis_version]  s    %%&7888r(   c                 ,    |                      d          S )r   postgis_full_versionr   rT   s    r'   r   z&PostGISOperations.postgis_full_versiona  r   r(   c                 P    |                                  }|ft          |          z   S )zi
        Return the PostGIS version as a tuple (version string, major,
        minor, subminor).
        )r   r   )r$   r   s     r'   r   z'PostGISOperations.postgis_version_tuplee  s+    
 **,,z-g6666r(   c                    t          j        d          }|                                 }|                    |          }|r4t	          t          t          |                                                    S t          d          )z
        Return the version of PROJ used by PostGIS as a tuple of the
        major, minor, and subminor release numbers.
        z(\d+)\.(\d+)\.(\d+)z.Could not determine PROJ version from PostGIS.)	recompiler   searchtupler   intgroups	Exception)r$   
proj_regexproj_ver_strr   s       r'   proj_version_tuplez$PostGISOperations.proj_version_tuplem  sp    
 Z 677
0022l++ 	NS!((**--...LMMMr(   c                 0    |dk    r| j         S | j        |z   S )NExtent3D)extent3dgeom_func_prefix)r$   agg_names     r'   spatial_aggregate_namez(PostGISOperations.spatial_aggregate_namez  s#    z!!= (833r(   c                     t           S r*   )r   rT   s    r'   geometry_columnsz"PostGISOperations.geometry_columns  s    %%r(   c                     t           S r*   )r   rT   s    r'   spatial_ref_sysz!PostGISOperations.spatial_ref_sys  s    ##r(   c                      t          |          S )z@Convert a PostGIS HEX String into a dict readable by GDALRaster.r   )r$   rQ   s     r'   parse_rasterzPostGISOperations.parse_raster  s    U###r(   c                      t                      j        |                     |          |                     |          fi |S r*   )r"   distance_expr_for_lookup_normalize_distance_lookup_arg)r$   r6   r7   r%   r&   s       r'   r   z*PostGISOperations.distance_expr_for_lookup  sO    /uww///44//44
 
 
 
 	
r(   c                     t          | d          r| j        j        dk    nt          | t                    }|rt          |           n| S )Nr9   r5   )r   r9   r:   r;   r   rK   )arg	is_rasters     r'   r   z0PostGISOperations._normalize_distance_lookup_arg  sN     sG$$-CI8++C,, 	
 #,4z#4r(   c                 T    t                      j        |j        j        fd}|S )Nc                     t          | t                    r|                     d          } | d nt           |                     S )Nascii)r;   strencoder	   )rQ   
expressionr.   
geom_classreads      r'   	converterz;PostGISOperations.get_geometry_converter.<locals>.converter  sG    %%% .W-- =44.>ttE{{J.W.WWr(   )r
   r	  rD   r  )r$   r  r
  r  r	  s      @@r'   get_geometry_converterz(PostGISOperations.get_geometry_converter  sF    ww|,7
	X 	X 	X 	X 	X 	X
 r(   c                     dS )Nsq_mr   )r$   r9   s     r'   get_area_att_for_fieldz(PostGISOperations.get_area_att_for_field  s    vr(   )1rE   rF   rG   namerX   r   r   Adaptercollectextentr   length3dmakelineperimeter3dunionaggr   r@   gis_operatorssetunsupported_functionsr   selectselect_extentr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   staticmethodr   r  r  rH   rI   s   @r'   rW   rW   s   s       DGG*G(F*,H*,H*,H"]2K')H!ooT:::!oodKKK! 	__D999! 	DCCC	!
 	//T)DDD! 	//U333! 	//U333! 	4(((! 	D)))! 	//U333! 	//U333! 	??d9===! 	D;;;! 	OOyIII! 	__&y
 
 
!$ 	__4	
 
 
%!* 	//{d9UUU+!, #?555#OyIII!/{333%o D
 
 
 $OyIII!/{333"?YGGG!/{9EEE"?YWWWA! ! !MF  CEE 1TTkFM	 	 _	   _:( ( (4 4 4; ; ;.# # #J  :( ( (> > >= = => > >9 9 9> > >7 7 7N N N4 4 4& & &$ $ $$ $ $
 
 
 
 
 5 5 \5	 	 	      r(   rW   )-r   django.confr   .django.contrib.gis.db.backends.base.operationsr   $django.contrib.gis.db.backends.utilsr   django.contrib.gis.db.modelsr   r   django.contrib.gis.gdalr    django.contrib.gis.geos.geometryr	   %django.contrib.gis.geos.prototypes.ior
   django.contrib.gis.measurer   django.core.exceptionsr   	django.dbr   r   (django.db.backends.postgresql.operationsr   )django.db.backends.postgresql.psycopg_anyr   django.db.modelsr   r   django.utils.functionalr   django.utils.versionr   adapterr   modelsr   r   pgrasterr   r@   r   rK   rW   r   r(   r'   <module>r/     s   				             P P P P P P @ @ @ @ @ @ C C C C C C C C . . . . . . = = = = = = 7 7 7 7 7 7 / / / / / / 7 7 7 7 7 7 9 9 9 9 9 9 9 9 G G G G G G A A A A A A ( ( ( ( ( ( ( ( 3 3 3 3 3 3 2 2 2 2 2 2 # # # # # # @ @ @ @ @ @ @ @ # # # # # # 	E E E E Eo E E EPI I I I I I I I t t t t t-/A t t t t tr(   