U
    Ha,                     @   s  d dl mZ d dlmZ d dlmZ d dlmZmZm	Z	 d dl
mZ d dlmZ G dd de	ZG d	d
 d
eZejG dd deZejG dd deZejG dd deZejG dd deZejG dd deZejG dd deZejG dd deZejG dd deZejG dd deZeed ejG dd deZejG d d! d!eZejG d"d# d#eZejG d$d% d%eZejG d&d' d'eZejG d(d) d)eZejG d*d+ d+eZ ejG d,d- d-eZ!ejG d.d/ d/eZ"ejG d0d1 d1eZ#ejG d2d3 d3eZ$ejG d4d5 d5eZ%ejG d6d7 d7eZ&ejG d8d9 d9eZ'ejG d:d; d;eZ(G d<d= d=eZ)ejG d>d? d?e)Z*G d@dA dAe)Z+ejG dBdC dCe+Z,ejG dDdE dEe+Z-ejG dFdG dGe+Z.ejG dHdI dIe+Z/dJS )K    )BaseSpatialField)Distance)NotSupportedError)
ExpressionLookup	Transform)Query)_lazy_re_compilec                   @   s   e Zd Zdd ZdS )RasterBandTransformc                 C   s   | | jS N)compilelhs)selfcompiler
connection r   H/tmp/pip-unpacked-wheel-3jxiddxt/django/contrib/gis/db/models/lookups.pyas_sql
   s    zRasterBandTransform.as_sqlN__name__
__module____qualname__r   r   r   r   r   r
   	   s   r
   c                       sf   e Zd ZdZdZdZdZdZ fddZdd Z	dddZ
d	d
 Z fddZdd Zdd Z  ZS )	GISLookupNFc                    s>   t |ttfr|n|g^}| _t || i | _|   d S r   )
isinstancelisttuple
rhs_paramssuper__init__template_paramsprocess_rhs_params)r   r   rhs	__class__r   r   r      s    zGISLookup.__init__c                 C   sf   | j rJt| j | jdkrdndkr,|   qbt| j dkrbtd| j nt| jtrb| jdd d S )Nrelate      zTuple too long for lookup %s.T)only_lhs)r   lenlookup_nameprocess_band_indices
ValueErrorr   r   r
   r   r   r   r   r       s    
zGISLookup.process_rhs_paramsc                 C   sP   |rd| _ | jjd | _dS t| jtr8| jjd | _nd| _| j^| _ | _dS )z
        Extract the lhs band index from the band transform class and the rhs
        band index from the input tuple.
        r&   N)band_rhsr   Z
band_indexband_lhsr   r
   r   )r   r'   r   r   r   r*   %   s    zGISLookup.process_band_indicesc                 C   s   d|j |gfS )N%s)opsZAdapter)r   valuer   r   r   r   get_db_prep_lookup8   s    zGISLookup.get_db_prep_lookupc                    sj   t | jtrt ||S t | jtr6| j|j| _t ||\}}|j	| j
j| j|}|| |fS r   )r   r!   r   r   process_rhsr   resolve_expressionqueryr0   Zget_geom_placeholderr   output_field)r   r   r   r!   r   placeholderr"   r   r   r3   <   s    zGISLookup.process_rhsc                 C   s   |j j| j S r   )r0   gis_operatorsr)   )r   r   r!   r   r   r   
get_rhs_opF   s    zGISLookup.get_rhs_opc           
      C   sV   |  ||\}}| ||\}}||}||dd| j}| ||}	|	|| ||S )Nr/   )r   r!   r1   )Zprocess_lhsr3   r   r9   r   )
r   r   r   Zlhs_sqlZ
lhs_paramsrhs_sqlr   Z
sql_paramsr   Zrhs_opr   r   r   r   L   s    zGISLookup.as_sql)F)r   r   r   sql_templateZtransform_funcdistancer-   r.   r   r    r*   r2   r3   r9   r   __classcell__r   r   r"   r   r      s   


r   c                   @   s   e Zd ZdZdZdS )OverlapsLeftLookupzy
    The overlaps_left operator returns true if A's bounding box overlaps or is to the
    left of B's bounding box.
    Zoverlaps_leftNr   r   r   __doc__r)   r   r   r   r   r>   Z   s   r>   c                   @   s   e Zd ZdZdZdS )OverlapsRightLookupz}
    The 'overlaps_right' operator returns true if A's bounding box overlaps or is to the
    right of B's bounding box.
    Zoverlaps_rightNr?   r   r   r   r   rA   c   s   rA   c                   @   s   e Zd ZdZdZdS )OverlapsBelowLookupzs
    The 'overlaps_below' operator returns true if A's bounding box overlaps or is below
    B's bounding box.
    Zoverlaps_belowNr?   r   r   r   r   rB   l   s   rB   c                   @   s   e Zd ZdZdZdS )OverlapsAboveLookupzs
    The 'overlaps_above' operator returns true if A's bounding box overlaps or is above
    B's bounding box.
    Zoverlaps_aboveNr?   r   r   r   r   rC   u   s   rC   c                   @   s   e Zd ZdZdZdS )
LeftLookupzo
    The 'left' operator returns true if A's bounding box is strictly to the left
    of B's bounding box.
    leftNr?   r   r   r   r   rD   ~   s   rD   c                   @   s   e Zd ZdZdZdS )RightLookupzq
    The 'right' operator returns true if A's bounding box is strictly to the right
    of B's bounding box.
    rightNr?   r   r   r   r   rF      s   rF   c                   @   s   e Zd ZdZdZdS )StrictlyBelowLookupzp
    The 'strictly_below' operator returns true if A's bounding box is strictly below B's
    bounding box.
    Zstrictly_belowNr?   r   r   r   r   rH      s   rH   c                   @   s   e Zd ZdZdZdS )StrictlyAboveLookupzp
    The 'strictly_above' operator returns true if A's bounding box is strictly above B's
    bounding box.
    Zstrictly_aboveNr?   r   r   r   r   rI      s   rI   c                   @   s   e Zd ZdZdZdS )SameAsLookupz
    The "~=" operator is the "same as" operator. It tests actual geometric
    equality of two features. So if A and B are the same feature,
    vertex-by-vertex, the operator returns true.
    Zsame_asNr?   r   r   r   r   rJ      s   rJ   exactc                   @   s   e Zd ZdZdZdS )BBContainsLookupzq
    The 'bbcontains' operator returns true if A's bounding box completely contains
    by B's bounding box.
    Z
bbcontainsNr?   r   r   r   r   rL      s   rL   c                   @   s   e Zd ZdZdZdS )BBOverlapsLookupz_
    The 'bboverlaps' operator returns true if A's bounding box overlaps B's bounding box.
    Z
bboverlapsNr?   r   r   r   r   rM      s   rM   c                   @   s   e Zd ZdZdZdS )ContainedLookupzt
    The 'contained' operator returns true if A's bounding box is completely contained
    by B's bounding box.
    Z	containedNr?   r   r   r   r   rN      s   rN   c                   @   s   e Zd ZdZdS )ContainsLookupcontainsNr   r   r   r)   r   r   r   r   rO      s   rO   c                   @   s   e Zd ZdZdS )ContainsProperlyLookupZcontains_properlyNrQ   r   r   r   r   rR      s   rR   c                   @   s   e Zd ZdZdS )CoveredByLookupZ	coveredbyNrQ   r   r   r   r   rS      s   rS   c                   @   s   e Zd ZdZdS )CoversLookupZcoversNrQ   r   r   r   r   rT      s   rT   c                   @   s   e Zd ZdZdS )CrossesLookupZcrossesNrQ   r   r   r   r   rU      s   rU   c                   @   s   e Zd ZdZdS )DisjointLookupZdisjointNrQ   r   r   r   r   rV      s   rV   c                   @   s   e Zd ZdZdS )EqualsLookupequalsNrQ   r   r   r   r   rW      s   rW   c                   @   s   e Zd ZdZdS )IntersectsLookupZ
intersectsNrQ   r   r   r   r   rY      s   rY   c                   @   s   e Zd ZdZdS )OverlapsLookupoverlapsNrQ   r   r   r   r   rZ      s   rZ   c                       s,   e Zd ZdZdZedZ fddZ  ZS )RelateLookupr$   z%(func)s(%(lhs)s, %(rhs)s, %%s)z^[012TF\*]{9}$c                    sp   | j d }|jj| j }t|dr.|| n"t|trD| j	|sPt
d| t ||\}}|||g fS )Nr   check_relate_argumentz)Invalid intersection matrix pattern "%s".)r   r0   r8   r)   hasattrr]   r   strpattern_regexmatchr+   r   r3   )r   r   r   patternZ
backend_opsqlparamsr"   r   r   r3      s    

zRelateLookup.process_rhs)	r   r   r   r)   r;   r	   r`   r3   r=   r   r   r"   r   r\      s   r\   c                   @   s   e Zd ZdZdS )TouchesLookupZtouchesNrQ   r   r   r   r   re     s   re   c                   @   s   e Zd ZdZdS )WithinLookupZwithinNrQ   r   r   r   r   rf     s   rf   c                   @   s$   e Zd ZdZdZdd Zdd ZdS )DistanceLookupBaseTz+%(func)s(%(lhs)s, %(rhs)s) %(op)s %(value)sc                 C   sx   dt | j  krdks,n td| j n$t | jdkrP| jd dkrPtdt | jdkrt| jd dkrt|   d S )Nr&      z22, 3, or 4-element tuple required for '%s' lookup.r%   spheroidzHFor 4-element tuples the last argument must be the 'spheroid' directive.)r(   r   r+   r)   r*   r,   r   r   r   r      s    z%DistanceLookupBase.process_rhs_paramsc                 C   sB   | j d }t|dr&|||jS d|j| jj| j | j	fS )Nr   r4   r/   )
r   r^   r   r4   r5   r0   Zget_distancer   r6   r)   r   r   r   Z
dist_paramr   r   r   process_distance$  s
    
z#DistanceLookupBase.process_distanceN)r   r   r   r<   r;   r    rk   r   r   r   r   rg     s   
rg   c                       s0   e Zd ZdZdZ fddZ fddZ  ZS )DWithinLookupZdwithinz%%(func)s(%(lhs)s, %(rhs)s, %(value)s)c                    s<   | j d }|jjs.t|dr.t|ts.tdt ||S )Nr   r4   zXThis backend does not support expressions for specifying distance in the dwithin lookup.)	r   featuresZsupports_dwithin_distance_exprr^   r   r   r   r   rk   rj   r"   r   r   rk   2  s    
zDWithinLookup.process_distancec                    s8   |  ||\}}|| jd< t ||\}}||| fS )Nr1   )rk   r   r   r3   )r   r   r   dist_sqldist_paramsr:   rd   r"   r   r   r3   ?  s    
zDWithinLookup.process_rhs)r   r   r   r)   r;   rk   r3   r=   r   r   r"   r   rl   -  s   rl   c                   @   s   e Zd Zdd ZdS )DistanceLookupFromFunctionc           	      C   sv   t | jdkr| jd dkpd }|jj| j| j|d}|||j\}}| 	||\}}d|| j
|d || fS )Nr%   ri   )ri   z%(func)s %(op)s %(dist)s)funcopdist)r(   r   r0   Zdistance_expr_for_lookupr   r!   r   r4   r5   rk   rs   )	r   r   r   ri   Zdistance_exprrc   rd   rn   ro   r   r   r   r   G  s     z!DistanceLookupFromFunction.as_sqlNr   r   r   r   r   rp   F  s   rp   c                   @   s   e Zd ZdZdZdS )DistanceGTLookupZdistance_gt>Nr   r   r   r)   rs   r   r   r   r   ru   R  s   ru   c                   @   s   e Zd ZdZdZdS )DistanceGTELookupZdistance_gtez>=Nrw   r   r   r   r   rx   X  s   rx   c                   @   s   e Zd ZdZdZdS )DistanceLTLookupZdistance_lt<Nrw   r   r   r   r   ry   ^  s   ry   c                   @   s   e Zd ZdZdZdS )DistanceLTELookupZdistance_ltez<=Nrw   r   r   r   r   r{   d  s   r{   N)0Z#django.contrib.gis.db.models.fieldsr   Zdjango.contrib.gis.measurer   Z	django.dbr   Zdjango.db.modelsr   r   r   Zdjango.db.models.sql.queryr   Zdjango.utils.regex_helperr	   r
   r   Zregister_lookupr>   rA   rB   rC   rD   rF   rH   rI   rJ   rL   rM   rN   rO   rR   rS   rT   rU   rV   rW   rY   rZ   r\   re   rf   rg   rl   rp   ru   rx   ry   r{   r   r   r   r   <module>   s   L	