
    ը	f4                        d Z ddlZddlmZmZmZmZmZ 	 ddlm	Z
 dZddlmZ ddlmZmZ  G d d	ej&                        Z G d
 de      Z G d de      Z G d d      Zd ZddZddZd Zd Zd ZddZd Zd Zy# e$ r dZY kw xY w)a  
@package psmap.utils

@brief utilities for wxpsmap (classes, functions)

Classes:
 - utils::Rect2D
 - utils::Rect2DPP
 - utils::Rect2DPS
 - utils::UnitConversion

(C) 2012 by Anna Kratochvilova, and the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.

@author Anna Kratochvilova <kratochanna gmail.com>
    N)ceilfloorsincospi)ImageTF)
RunCommandGErrorc                   <    e Zd ZdZd
dZd Zd Zd Zd Zd Z	d Z
y	)Rect2DzClass representing rectangle with floating point values.

    Overrides wx.Rect2D to unify Rect access methods, which are
    different (e.g. wx.Rect.GetTopLeft() x wx.Rect2D.GetLeftTop()).
    More methods can be added depending on needs.
    c                 L    t         j                  j                  | ||||       y )N)xywh)wxr   __init__)selfr   r   widthheights        ,/usr/lib/grass83/gui/wxpython/psmap/utils.pyr   zRect2D.__init__(   s    
		41Uf=    c                     | j                   S N)r   r   s    r   GetXzRect2D.GetX+       vvr   c                     | j                   S r   )r   r   s    r   GetYzRect2D.GetY.   r   r   c                     | j                   S r   r   r   s    r   GetWidthzRect2D.GetWidth1   s    zzr   c                     || _         y r   r!   )r   r   s     r   SetWidthzRect2D.SetWidth4   s	    
r   c                     | j                   S r   r   r   s    r   	GetHeightzRect2D.GetHeight7   s    {{r   c                     || _         y r   r&   )r   r   s     r   	SetHeightzRect2D.SetHeight:   s	    r   N)r   r   r   r   )__name__
__module____qualname____doc__r   r   r   r"   r$   r'   r)    r   r   r   r       s*    >r   r   c                   X    e Zd ZdZ ej
                          ej
                         fdZy)Rect2DPPzjRectangle specified by 2 points (with floating point values).

    :class:`Rect2D`, :class:`Rect2DPS`
    c                 8   t         j                  | dddd       |d   |d   }}|d   |d   }}| j                  t        ||             | j	                  t        ||             | j                  t        ||             | j                  t        ||             y )Nr   r   r   r   r      )r   r   SetLeftminSetTopSetRightmax	SetBottom)r   topLeftbottomRightx1y1x2y2s          r   r   zRect2DPP.__init__D   s    Qa:WQZBQQBSR[!CBK c"bk"s2r{#r   Nr*   r+   r,   r-   r   Point2Dr   r.   r   r   r0   r0   >   s#    
  *rzz| 	$r   r0   c                   :    e Zd ZdZ ej
                         dfdZy)Rect2DPSzpRectangle specified by point and size (with floating point values).

    :class:`Rect2D`, :class:`Rect2DPP`
    )r   r   c                 P    t         j                  | |d   |d   |d   |d          y )Nr   r3   r2   )r   r   )r   possizes      r   r   zRect2DPS.__init__V   s(    A#a&QQPr   Nr@   r.   r   r   rC   rC   P   s    
 &2::<f Qr   rC   c                   >    e Zd ZdZd
dZd Zd Zd Zd Zd Z	dd	Z
y)UnitConversionzClass for converting unitsNc                    || _         | j                   r.t        j                  | j                         j                         }nd}dt	        d      ddt	        d      ddt	        d      dd	t	        d
      dd| _        dt	        d      ddt	        d      ddt	        d      ddt	        d      ddt	        d      dd| _        |d   t	        d      ddt	        d      ddt	        d      ddt	        d      dd| _        | j                  j                  | j
                         | j                  j                  | j                         y )N)H   rJ   g      ?inch)valtrg      R@pointgRQ@
centimetergffffff9@
millimeter)rK   rN   rO   rP   g
F%u?metersg5B>
kilometersgUUUUUU?feetgeu>milesgg!>nautical miles)rQ   rR   rS   rT   rU   r   pixelmeterdegree)rV   rW   	nautmilesdegrees)	parentr   ClientDCGetPPI_
_unitsPage	_unitsMap_unitsupdate)r   r[   ppis      r   r   zUnitConversion.__init__]   s!   ;;++dkk*113CCqy1!74"&ao>"&ao>	
 %AhK8")<A$AfI6('
;&31=M;NO
 !V1W:6#1W:6!.a8H6IJ%Qx[9
 	4??+4>>*r   c                 \     t         fd j                  j                         D              S )Nc              3   B   K   | ]  }j                   |   d      ywrM   N)r_   .0unitr   s     r   	<genexpr>z3UnitConversion.getPageUnitsNames.<locals>.<genexpr>|   s     Uddood+D1U   )sortedr_   keysr   s   `r   getPageUnitsNamesz UnitConversion.getPageUnitsNames{   s!    Udoo>R>R>TUUUr   c                 \     t         fd j                  j                         D              S )Nc              3   B   K   | ]  }j                   |   d      ywrf   )r`   rg   s     r   rj   z2UnitConversion.getMapUnitsNames.<locals>.<genexpr>   s     STdnnT*40Srk   )rl   r`   rm   r   s   `r   getMapUnitsNameszUnitConversion.getMapUnitsNames~   s!    ST^^=P=P=RSSSr   c                 H    t        | j                  j                               S r   )rl   ra   rm   r   s    r   getAllUnitszUnitConversion.getAllUnits   s    dkk&&())r   c                 t    | j                   j                         D ]  }| j                   |   d   |k(  s|c S  y)zReturns unit by its tr. stringrM   N)ra   rm   )r   nameri   s      r   findUnitzUnitConversion.findUnit   s>    KK$$& 	D{{4 &$.	 r   c                 F    	 | j                   |   d   S # t        $ r Y yw xY w)zReturns tr. string of a unitrM   N)ra   KeyError)r   ri   s     r   findNamezUnitConversion.findName   s-    	;;t$T** 		s    	  c                 d    t        |      | j                  |   d   z  | j                  |   d   z  S )NrL   )floatra   )r   valuefromUnittoUnits       r   convertzUnitConversion.convert   s3    U|dkk(3E::T[[=PQV=WWWr   r   )NN)r*   r+   r,   r-   r   rn   rq   rs   rv   ry   r   r.   r   r   rH   rH   Z   s+    $+<VT*Xr   rH   c                     t        | t        j                        rt        j                  j                         D ]q  \  }}| j                         t        |d   dz        k(  s)| j                         t        |d   dz        k(  sL| j                         t        |d   dz        k(  so|c S  t        | j                               dz   t        | j                               z   dz   t        | j                               z   S t        t        j                  |       d   dz        t        t        j                  |       d   dz        t        t        j                  |       d   dz        f}t        j                  | }|j                         r|S y)z~Converts wx.Colour(r,g,b,a) to string 'r:g:b' or named color,
    or named color/r:g:b string to wx.Colour, depending on inputr      r3      :N)
isinstancer   Colourgrassnamed_colorsitemsRedintGreenBluestrparse_colorIsOk)rgbru   colors      r   
convertRGBr      sF    #ryy! --335 	KD%	SqC00IIK3uQx#~#66HHJ#eAhn"55	 3779~#c#))+&66<s388:NN !!#&q)C/0!!#&q)C/0!!#&q)C/0

 		5!::<Lr   c                 6   t        j                  |      }| d   j                         }| d   j                         }|d   |d   z
  }|d   |d   z
  }	|rv|| d   j	                         z
  }
|| d   j                         z
  }|
|z  |z  }||	z  |z  }|d   |z   }|d   |z
  }t               d   dk(  r||fS t        |      t        |      fS ||d   z
  }|d   |z
  }||z  |z  }
||z  |	z  }| d   j	                         |
z   }| d   j                         |z   }||fS )	zConverts paper (inch) coordinates <-> map coordinates.

    :param mapInstr: map frame instruction
    :param x,y: paper coords in inches or mapcoords in map units
    :param paperToMap: specify conversion direction
    envrecter   nsprojll)r   regionr"   r'   r   r   projInfor   )mapInstrr   r   
paperToMapr   r   mapWidthPapermapHeightPaper
mapWidthENmapHeightENdiffXdiffYdiffEWdiffNSr   r   xPaperyPapers                     r   PaperMapCoordinatesr      sg    \\c"FV$--/Mf%//1Nvc{*J+s+KHV$))++HV$))++#m3$~53K& 3K& :f%a4Kq63q6>! VC[q&3'+5&!&&(50&!&&(50v~r   c                    i }	 |dk(  r^|r\d}|dk(  r	 t        j                  dd||      }n|dk(  rt        j                  dd||      }t        j                  |t        	      }nY|d
k(  r7|r5t        j                  dd||      }t        j                  |t        	      }n|dk(  rt        j
                  d      }ny|sy|j                  }	|j                  }
|j                  }|j                  }t        | d      st        |       | _        d
}t               d   dk7  rt	        t               d         }| j                  j                  |d   |d   z
  |z  dd      }| j                  j                  |d   |d   z
  |z  dd      }t!        ||z  ||z        }||z  ||z  kD  r|	|||z  z  |z
  dz  z
  }|
}|||z  z  }|}n|	}|
|||z  z  |z
  dz  z
  }|||z  z  }|}|d   |d   z   dz  }|d   |d   z   dz  }|||ft#        ||||      fS # t         j                  $ r Y w xY w# t         j                  t         j                  f$ r Y w xY w)z^Computes map scale, center and map frame rectangle to fit region
    (scale is not fixed)
    r    rasterzg.regiongu)flagsr   r   vector)r   r   r   )val_typer3   )r   r   r   r   Nr   NNNunitConvr   xyrQ   r   r   rW   rK   r|   r}   r~   r   r   )r   read_commandScriptErrorparse_key_valr{   r   CalledModuleErrorr   r   r   r   hasattrrH   r   r   r   r5   r   )r   	scaleTyper   r   mapmapTyper   currRegionDictresrXrYrWrHtoMmWmHscaler   r   rWNewrHNewcEcNs                          r   
AutoAdjustr      s    N>cC(",,"$sC
 H$((4QTU"00uEN!^$$ZtFPSTC"00uEN!^"\\d3N $
 	B	B	B	B4$&t,
Cz&T!HJx()			c"^C%88C? 
 
B
 
		c"^C%88C? 
 
B
 Rb!E	Bwb"R.2%**b2g"R.2%**b2g 
s 3
3q	8B

s 3
3q	8B2r(F1a666o ((  u667 s4   H, H BH, H)%H, (H))H, ,#IIc                     t        j                  |      }|d   || z  kD  s|d   || z  kD  r&|| z  }|| z  }t        j                  |||      |d<   yy)zIf resolution is too high, lower it

    :param dpi: max DPI
    :param width: map frame width
    :param height: map frame height
    r   colsrows)r   r   r   GRASS_REGIONN)r   r   
region_env)dpir   r   r   r   r   r   s          r   SetResolutionr     sb     \\c"Ff~#vf~'D|s{#..DtMN (Er   c           
         |d   dk(  r|d   }t        | d      st        |       | _        d}t               d   dk7  rt	        t               d         }|d	   j
                  d
z  |d	   j                  d
z  f}| j                  j                  |d   dd      |z  |z  | j                  j                  |d   dd      |z  |z  f}|d   d   }|d   d   }| j                  j                  d      }	|	r|	j                  }
nd}
|
rkt        j                  t        ||d   z         t        ||d   z
        t        ||d   z         t        ||d   z
        | j                  |
   d   |      |d<   yt        j                  t        ||d   z         t        ||d   z
        t        ||d   z         t        ||d   z
        |      |d<   yy)z^Computes and sets region from current scale, map center
    coordinates and map rectangle
    r      r   r   r3   r   r   rQ   r   r   r   rK   rW   r   centerr   N)r   r   r   r   rastr   r   )r   r   r   r   r   )r   rH   r   r   r{   r   r   r   instructionFindInstructionByTypeidr   r   r   r   )r   mapDictr   r   fromMrectHalfInchrectHalfMetercenterEcenterNr   rasterIds              r   ComputeSetRegionr   +  s   
 {q  tZ(*40DM:f%(*X./E--176?3I3IA3MNMM!!"1ow "   	
 MM!!"1ow "   	
 (#A&(#A&!!77AyyHH"'"2"2wq!112-"223wq!112-"223%%h/9#C #("2"2wq!112-"223wq!112-"223#CU !r   c                  r    t        dddt        j                        } | j                  d      dk7  r| S ddd	S )
zQReturn region projection and map units information,
    taken from render.py
    zg.projgT)r   readparseru   xy_location_unprojectedr   r   )r   units)r	   r   r   get)	proj_infos    r   r   r   c  sM     !!	I == $== 	 R(r   c                    d}|sd}	 t        t        t        t        j                  dd|z   d| |      j                         j                  d      d   j                  d	                  }t        |d   |d   |d   |d   z
  |d   |d   z
        S # t        j                  t        f$ r t        t        d
             Y yw xY w)zRun ps.map -b to get information about map bounding box

    :param filename: psmap input file
    :param env: environment with GRASS_REGION defined
    :param portrait: page orientationr   rzps.mapbT)r   quietinputr   =r3   ,zUnable to run `ps.map -b`)messageNr   r   r   )listr   r{   r   r   stripsplitr   
IndexErrorr
   r^   r   )filenamer   portraitorientbbs        r   GetMapBoundsr   u  s     F""C&LHRU sA	
 s

 "Q%A11r!ur!u}== z* q456s   A#B .CCc                     | d} t        j                  | d      }|j                  d      rt        j                  |       d   }|S y)z/Returns type of raster map (CELL, FCELL, DCELL)Nr   cell)ru   elementfiledatatype)r   	find_filer   raster_info)r   r   
rasterTypes      r   getRasterTyper    sF    
{??V4Dxx&&s+J7
r   c                 8   |dz  t         z  }t        |      }t        |      }||z  }| |z  }||z  }| |z  }	dx}
}d|cxk  rdk  rn n|
}|
|z   |	z   }||z
  }||z   }nhd|cxk  rdk  rn n|
|z   }|
|	z   }||z
  |z   }|}nEd|cxk  rdk  rn n|
|	z   |z   }|
}||z   }||z
  }n"d|cxk  rdk  rn n|
|	z   }|
|z   }|}||z   |z
  }t        t	        t              t              z               }t        t	        t              t              z               }||fS )zCompute bounding box or rotated rectangle

    :param w: rectangle width
    :param h: rectangle height
    :param angle: angle (0, 360) in degrees
    g     f@r   Z      i  ih  )r   r   r   r   r   abs)r   r   angleangleRadctsthctwcthstwstr   r   y_miny_maxx_minx_maxr   r   s                     r   BBoxAfterRotationr    sU    u}r!H	XB	XB
b&C
b&C
b&C
b&CIA5BC#CC	e	s	CCC#	u		C#CC	u		CCC#SZ#e*,-.Ec%j3u:-./F&=r   )TNr   )T) r-   r   mathr   r   r   r   r   PILr   PILImagehavePILImageImportErrorgrass.scriptscriptr   	core.gcmdr	   r
   r   r0   rC   rH   r   r   r   r   r   r   r   r  r  r.   r   r   <module>r     s   " 
 * *%L  (RYY <$v $$Qv Q9X 9Xx6"JD7NN5p$>6	(G  Ls   B   B
	B
