
 XI                 @   sM  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 m Z d d l m Z m Z m Z d Z  Gd d   d e  Z! Gd d   d e!  Z" Gd d   d e e  Z# d S)    N)settings)BaseSpatialOperations)SpatialOperator)
GDALRaster)Geometry)Distance)ImproperlyConfigured)DatabaseOperations)ProgrammingError)six)cached_property   )PostGISAdapter)PostGISGeometryColumnsPostGISSpatialRefSys)from_pgrasterget_pgraster_sridto_pgrasterZ	bilateralc                   sF   e  Z d  Z d d   f d d  Z   f d d   Z d d   Z   S)PostGISOperatorFc                s,   | |  _  | |  _ t t |   j |   d  S)N)	geographyrastersuperr   __init__)selfr   r   kwargs)	__class__ _/home/ubuntu/projects/ifolica/build/django/django/contrib/gis/db/backends/postgis/operations.pyr      s    		zPostGISOperator.__init__c                sl   | j  j j r; |  j r; t d |  j p. |  j f   n  |  j | |  } t t |   j	 | | | |  S)Nz>PostGIS geography does not support the "%s" function/operator.)
lhsoutput_fieldr   
ValueErrorfuncopcheck_rasterr   r   as_sql)r   
connectionlookuptemplate_paramsargs)r   r   r   r$   $   s
    zPostGISOperator.as_sqlc             C   s  t  | j t t f  r; | j d } | j d d k } n | j } d } | j j j d k } t  | t  } | j d  k	 r | r |  j	 s t
 d   n  d | d | j f | d <n  | j d  k	 r| r|  j	 s t
 d   n  d | d	 | j f | d	 <n  |  j s| rM| r/d
 | d | d <n  | rd
 | d	 | d	 <qnV |  j t k r| r~| r~d
 | d | d <q| r| rd
 | d	 | d	 <qn  | S)Nr   r   spheroidFRASTERzFBand indices are not allowed for this operator, it works on bbox only.z%s, %sr   rhszST_Polygon(%s))
isinstancer+   tuplelistr   field	geom_typer   Zband_lhsr!   r    Zband_rhsr   	BILATERAL)r   r&   r'   Zrhs_valr)   Zlhs_is_rasterZrhs_is_rasterr   r   r   r#   ,   s4    			zPostGISOperator.check_raster)__name__
__module____qualname__r   r$   r#   r   r   )r   r   r      s   r   c                   s(   e  Z d  Z d Z   f d d   Z   S)PostGISDistanceOperatorz+%(func)s(%(lhs)s, %(rhs)s) %(op)s %(value)sc                s   | j  j j r | j  j j |  r |  j | |  } |  j } t | j  d k r | j d	 d k r | j i |  j	 d 6d d 6 d } | j
 d | j  j j  n | j i |  j	 d 6d d 6 | | | f St t |   j | | | |  S)
N   r   r)   r"   ZST_Distance_Spheroidr!   z0%(func)s(%(lhs)s, %(rhs)s, %%s) %(op)s %(value)sZST_Distance_Spherer,   )r   r   r   geodeticr#   sql_templatelenr+   updater"   insert	_spheroidr   r6   r$   )r   r%   r&   r'   Z
sql_paramsr9   )r   r   r   r$   Y   s    %	(zPostGISDistanceOperator.as_sql)r3   r4   r5   r9   r$   r   r   )r   r   r6   V   s   r6   c                   s  e  Z d  Z d Z d Z d Z d Z e j d  Z	 e
 Z i e d d d d  d 6e d d	 d
 d d d  d 6e d d d d  d 6e d d d e  d 6e d d d e  d 6e d d  d 6e d d  d 6e d d  d 6e d d  d 6e d d  d 6e d d  d 6e d d d e  d 6e d d d e  d  6e d! d" d e  d# 6e d! d$ d e  d% 6e d! d& d
 d d e  d' 6e d! d( d
 d d e  d) 6e d! d*  d+ 6e d! d, d e  d- 6e d! d.  d/ 6e d! d0 d
 d d e  d1 6e d! d2  d3 6e d! d4 d e  d5 6e d! d6  d7 6e d! d8 d e  d9 6e d! d: d e  d; 6e d! d< d
 d d e  d= 6e d! d> d d? d
 d  d@ 6e d! d> d dA d
 d  dB 6e d! d> d dC d
 d  dD 6e d! d> d dE d
 d  dF 6Z e   Z i dG dH 6dI dJ 6dK dL 6Z   f dM dN   Z e dO dP    Z dQ dR   Z dS dT   Z dU dV   Z dW dX   Z d dY dZ  Z d[ d\   Z d] d^   Z d_ d`   Z da db   Z dc dd   Z de df   Z  dg dh   Z! di dj   Z" dk dl   Z# dm dn   Z$ do dp   Z% dq dr   Z& ds dt   Z' du dv   Z(   S)wPostGISOperationspostgisTZST_z/^(?P<major>\d)\.(?P<minor1>\d)\.(?P<minor2>\d+)r"   ~r   Z
bbcontainsz&&r   Z
bboverlaps@Z	containedz&<Zoverlaps_leftz&>Zoverlaps_rightz&<|Zoverlaps_belowz|&>Zoverlaps_abovez<<leftz>>rightz<<|Zstrictly_belowz|>>Zstrictly_abovez~=Zsame_asexactr!   ZST_ContainscontainsZST_ContainsProperlyZcontains_properlyZST_CoveredByZ	coveredbyZ	ST_CoversZcoversZ
ST_CrossesZcrossesZST_DisjointZdisjointZ	ST_EqualsequalsZST_IntersectsZ
intersectsZ
ST_IsValidisvalidZST_OverlapsZoverlapsZ	ST_RelateZrelateZ
ST_TouchesZtouchesZ	ST_WithinZwithinZ
ST_DWithindwithinZST_Distance>Zdistance_gtz>=Zdistance_gte<Zdistance_ltz<=Zdistance_lteZST_MinimumBoundingCircleZBoundingCircleZST_Mem_SizeZMemSizeZ
ST_NPointsZ	NumPointsc                s  t  t |   j |  |  j } | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _	 | d |  _
 | d |  _ | d	 |  _ | d
 |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _ | d |  _  | d |  _! | d |  _" | d  |  _# | d! |  _$ | d" |  _% | d# |  _& | d$ |  _' | d% |  _( | d& |  _) | d& |  _* d  S)'NZAreaZMinimumBoundingCircleZCentroidZCollectZ
Differencer   distance_spheredistance_spheroidZEnvelopeZExtentZ3DExtentZForceRHRZGeoHashZ	AsGeoJsonZAsGMLZIntersectionZIsValidZAsKMLZLengthZ3DLengthlength_spheroidZMakeLineZ	MakeValidmem_sizeZNumGeometriesZnpointsZ	PerimeterZ3DPerimeterZPointOnSurfaceZ
PolygonizeZReverseZScaleZ
SnapToGridZAsSVGZSymDifferenceZ	TransformZ	TranslateUnion)+r   r>   r   geom_func_prefixareaZbounding_circleZcentroidZcollect
differenceZdistancerK   rL   ZenvelopeZextentextent3dZ	force_rhrZgeohashZgeojsonZgmlintersectionrG   ZkmllengthZlength3drM   ZmakelineZ	makevalidrN   Znum_geomZ
num_pointsZ	perimeterZperimeter3dZpoint_on_surfaceZ
polygonizereverseZscaleZsnap_to_gridsvgZsym_difference	transform	translateunionZunionagg)r   r%   prefix)r   r   r   r      sR    	zPostGISOperations.__init__c             C   s{   t  t d  r t j } n\ |  j d  y |  j   } Wn, t k
 rf t d |  j j d   Yn X| 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 2.0. Was the database created from a spatial database template?NAMEr   N)	hasattrr   r\   _get_postgis_funcpostgis_version_tupler
   r   r%   Zsettings_dict)r   r]   Zvtupr   r   r   spatial_version   s    	z!PostGISOperations.spatial_versionc       	      C   su   | d k r d S| d d  j  d  \ } } t t | j     \ } } t t | j     \ } } | | | | f S)z
        Returns 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   r   ,r,   )splitmapfloat)	r   Zboxsridllurxminyminxmaxymaxr   r   r   convert_extent   s    z PostGISOperations.convert_extentc             C   s   | d k r d S| d d  j  d  \ } } t t | j     \ } } } t t | j     \ } }	 }
 | | | | |	 |
 f S)z
        Returns 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   r   rd   r,   )re   rf   rg   )r   Zbox3drh   ri   rj   rk   rl   Zzminrm   rn   Zzmaxr   r   r   convert_extent3d   s    z"PostGISOperations.convert_extent3dc             C   s!   | r t  | d | j Sd Sd S)zI
        Converts the geometry returned from PostGIS aggregates.
        rh   N)r   rh   )r   hexZ	geo_fieldr   r   r   convert_geom   s    zPostGISOperations.convert_geomc             C   s   | j  d k r d S| j d k r2 | j  d } n	 | j  } | j rs | j d k rb t d   n  d | | j f Sd | | j f Sd	 S)
zM
        Return the database field type for the given spatial field.
        r*   r   r7   Zi  z=PostGIS only supports geography columns with an SRID of 4326.zgeography(%s,%d)zgeometry(%s,%d)N)r1   Zdimr   rh   NotImplementedError)r   fr1   r   r   r   geo_db_type	  s    		zPostGISOperations.geo_db_typec             C   s  | d } | j  |  j  } | j } t | t  r | rF | j } q | rs | d k rg t d   n  | j } q t | t j | j	 |  j    } n | } | g }	 | r	t
 |  d k r	| d }
 | r	| r	| d k r	|
 d k r	|	 j d | j  q	n  |	 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   rH   zNOnly numeric values of degree units are allowed on geographic DWithin queries.r   r)   )r8   r%   r   r-   r   mr    getattrZunit_attnameZ
units_namer:   r<   r=   )r   rv   Zdist_valZlookup_typeZhandle_spheroidvaluer8   r   Z
dist_paramparamsoptionr   r   r   get_distance  s$    
	'	
%zPostGISOperations.get_distancec             C   s   | d k r d } n9 | j  d k rE t | t j  rE t |  } n	 | j } | d k si | | j k rr d } nP | j  d k r t | t j  r d |  j | j f } n d |  j | j f } t | d  r | j |  \ } } | | } n  | 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.
        Nr*   z%sz%s((%%s)::raster, %s)z%s(%%s, %s)r$   )	r1   r-   r   string_typesr   rh   rX   r_   compile)r   rv   rz   compilerZ
value_sridplaceholderZsql_r   r   r   get_geom_placeholderH  s    	!		!z&PostGISOperations.get_geom_placeholderc          
   C   s;   |  j  j   & } | j d |  | j   d SWd QXd S)zZ
        Helper routine for calling PostGIS functions and returning their result.
        zSELECT %s()r   N)r%   Ztemporary_connectionexecuteZfetchone)r   r!   cursorr   r   r   r`   h  s    z#PostGISOperations._get_postgis_funcc             C   s   |  j  d  S)z:Returns the version of the GEOS library used with PostGIS.postgis_geos_version)r`   )r   r   r   r   r   q  s    z&PostGISOperations.postgis_geos_versionc             C   s   |  j  d  S)zGReturns the version number of the PostGIS library used with PostgreSQL.postgis_lib_version)r`   )r   r   r   r   r   u  s    z%PostGISOperations.postgis_lib_versionc             C   s   |  j  d  S)z<Returns the version of the PROJ.4 library used with PostGIS.postgis_proj_version)r`   )r   r   r   r   r   y  s    z&PostGISOperations.postgis_proj_versionc             C   s   |  j  d  S)z8Returns PostGIS version number and compile-time options.postgis_version)r`   )r   r   r   r   r   }  s    z!PostGISOperations.postgis_versionc             C   s   |  j  d  S)z8Returns PostGIS version number and compile-time options.postgis_full_version)r`   )r   r   r   r   r     s    z&PostGISOperations.postgis_full_versionc             C   s   |  j    } |  j j |  } | rf t | j d   } t | j d   } t | j d   } n t d |   | | | | f S)zj
        Returns the PostGIS version as a tuple (version string, major,
        minor, subminor).
        majorminor1minor2z*Could not parse PostGIS version string: %s)r   version_regexmatchintgroup	Exception)r   r]   rx   r   r   r   r   r   r   ra     s    z'PostGISOperations.postgis_version_tuplec             C   sw   t  j d  } |  j   } | j |  } | rg t t t | j d  | j d  | j d  g   St d   d S)z
        Return the version of PROJ.4 used by PostGIS as a tuple of the
        major, minor, and subminor release numbers.
        z(\d+)\.(\d+)\.(\d+)r      r7   z0Could not determine PROJ.4 version from PostGIS.N)	rer   r   searchr.   rf   r   r   r   )r   Z
proj_regexZproj_ver_strrx   r   r   r   proj_version_tuple  s    7z$PostGISOperations.proj_version_tuplec             C   s"   | d k r |  j  S|  j | Sd  S)NZExtent3D)rS   rP   )r   Zagg_namer   r   r   spatial_aggregate_name  s    z(PostGISOperations.spatial_aggregate_namec             C   s   t  S)N)r   )r   r   r   r   geometry_columns  s    z"PostGISOperations.geometry_columnsc             C   s   t  S)N)r   )r   r   r   r   spatial_ref_sys  s    z!PostGISOperations.spatial_ref_sysc             C   s
   t  |  S)N)r   )r   rz   r   r   r   parse_raster  s    zPostGISOperations.parse_rasterc             C   s
   t  |  S)N)r   )r   rz   r   r   r   deconstruct_raster  s    z$PostGISOperations.deconstruct_raster))r3   r4   r5   namer?   r   rP   r   r   r   r   ZAdapterr   r2   r6   Zgis_operatorssetZunsupported_functionsZfunction_namesr   r   rb   ro   rq   rs   rw   r}   r   r`   r   r   r   r   r   ra   r   r   r   r   r   r   r   r   )r   r   r>   i   s   	
-	* 	r>   )$r   Zdjango.confr   Z.django.contrib.gis.db.backends.base.operationsr   Z$django.contrib.gis.db.backends.utilsr   Zdjango.contrib.gis.gdalr   Z#django.contrib.gis.geometry.backendr   Zdjango.contrib.gis.measurer   Zdjango.core.exceptionsr   Z(django.db.backends.postgresql.operationsr	   Zdjango.db.utilsr
   Zdjango.utilsr   Zdjango.utils.functionalr   adapterr   modelsr   r   Zpgrasterr   r   r   r2   r   r6   r>   r   r   r   r   <module>   s$   >