
    ը	f/                     T   d Z ddlZddlZddlZddlZddlmZ 	 ddlmZ d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      Z G d d      Z G d d      Z G d d      Zd"dZd Zd Zd Zd#dZd Z d Z!d Z"d Z#d Z$d$dZ%d$dZ&d Z'd Z(d  Z)d! Z*y# e
$ r dZ	Y w xY w)%a  
@package animation.utils

@brief Miscellaneous functions and enum classes

Classes:
 - utils::TemporalMode
 - utils::TemporalType
 - utils::Orientation
 - utils::ReplayMode


(C) 2013 by 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 Perasova <kratochanna gmail.com>
    N)	cpu_count)ImageTF)encode)EmptyBitmap)
GExceptionc                       e Zd ZdZdZy)TemporalMode      N)__name__
__module____qualname__TEMPORALNONTEMPORAL     0/usr/lib/grass83/gui/wxpython/animation/utils.pyr	   r	   )   s    HKr   r	   c                       e Zd ZdZdZy)TemporalTyper
   r   N)r   r   r   ABSOLUTERELATIVEr   r   r   r   r   .   s    HHr   r   c                       e Zd ZdZdZy)Orientationr
   r   N)r   r   r   FORWARDBACKWARDr   r   r   r   r   3   s    GHr   r   c                       e Zd ZdZdZdZy)
ReplayModer
   r      N)r   r   r   ONESHOTREVERSEREPEATr   r   r   r   r   8   s    GGFr   r   c                    t        j                  |      }| j                  d      dk\  r5| j                  dd      \  }}|||   v r| S t	        t        d      | z        t        j                         j                         }|D ]&  }||j                         v s| ||   v s| dz   |z   c S  t	        t        d      | z        )zwChecks if space time dataset exists and completes missing mapset.

    Raises GException if dataset doesn't exist.
    @r   r
   z"Space time dataset <%s> not found.)	tgistlist_groupedfindsplitr   _get_tgis_c_library_interfaceavailable_mapsetskeys)
timeseriesetype	trastDict	nameShortmapsetmapsetss         r   validateTimeseriesNamer2   >   s    
 ""5)Isq &,,S!4	6	&))QCDzQRR//1CCEG 1Y^^%%Yv..!C'&001
 Q;<zI
JJr   c                    t        j                  |      }g }| D ]  }|j                  d      dk\  rE|j                  dd      \  }}|||   v r|j	                  |       Et        t        d      |z        d}t        j                  |      D ]#  \  }}||v sd}|j	                  |dz   |z          % |rt        t        d      |z         |S )zChecks if maps exist and completes missing mapset.

    Input is list of map names.
    Raises GException if map doesn't exist.
    r#   r   r
   zMap <%s> not found.FT)	grasslist_groupedr&   r'   appendr   r(   six	iteritems)	namesr-   mapDictnewNamesnamer/   r0   foundmapNamess	            r   validateMapNamesr?   T   s       'GH B99S>Q $

3 2IvGFO+% #8!9D!@AAE$'MM'$: 9 8# EOOD3J$789  #8!9D!@AAB Or   c                     g }t        j                  | |      }|j                  ddd      }g }|r|D ]  }|j                  |d           |S )zhReturns list of maps registered in dataset.
    Can throw ScriptError if the dataset doesn't exist.
    idN
start_time)columnswhereorder)r$   open_old_stdsget_registered_mapsr6   )r,   r-   timeseriesMapssprowsrows         r   getRegisteredMapsrL   o   sa     N			J	.B!!$d,!ODN 	-C!!#d),	-r   c                     dx}}d| v r| j                  d      \  } }d| v r| j                  d      \  } }|r| dz   |z   } | |fS )a=  Checks whether map name contains layer
    and returns map name with mapset (when there was mapset)
    and layer (can be None).

    >>> getNameAndLayer('name:2@mapset')
    ('name@mapset', '2')
    >>> getNameAndLayer('name@mapset')
    ('name@mapset', None)
    >>> getNameAndLayer('name:2')
    ('name', '2')
    Nr#   :)r'   )r<   r0   layers      r   getNameAndLayerrP   ~   sY     FU
d{zz#f
d{jjoeczF";r   c                    t               t               t               t               d}|r%|D ]  \  }}t        j                  ||      }|j                         }|j	                         d   }|d   j                  |       |d   j                  |       |j                  dd      }|r{g }	|d   j                  t        |             |D ]9  }
|d	k(  r|
j                         }n|
j                         }|	j                  |       ; |d
   j                  t        |	             |d
   j                  d       |d   j                  d       " t        |d         dkD  rt        t        d            t        |d         dkD  rt        t        d            t        |d         dkD  rt        t        d            t        |d
         dkD  rt        t        d            | rt               }| D ]  }|j                  t        |              t        |      dkD  rt        t        d            |r4t        |      d   t        |d         d   k7  rt        t        d            | rt              d   S |rt        |d         d   S y)a8  Checks whether time series (map series and stds) are compatible,
    which means they have equal number of maps ad times (in case of stds).
    This is needed within layer list, not within the entire animation tool.
    Throws GException if these are incompatible.

    :return: number of maps for animation
    )counttemporalTypemapTypemapTimesr   rT   rS   NrB   )rD   rE   rR   absoluterU   r
   z=The number of maps in space-time datasets has to be the same.zPThe temporal type (absolute/relative) of space-time datasets has to be the same.zHThe map type (point/interval) of space-time datasets has to be the same.zHThe temporal extents of maps in space-time datasets have to be the same.zEThe number of maps to animate has to be the same for each map series.z[The number of maps to animate has to be the same as the number of maps in temporal dataset.)setr$   rF   get_map_timeget_initial_valuesaddget_registered_maps_as_objectslenget_absolute_timeget_relative_timer6   tupler   r(   list)mapSeriesListtimeseriesListtimeseriesInfostdsr-   rI   rT   tempTyperJ   timesrK   timerR   	mapSeriess                 r   checkSeriesCompatibilityri      s    5E	N ) 	2KD%##D%0Boo'G,,.q1H9%))'2>*..x8444|4TDw'++CI6 'C:-"446"446LL&' z*..uU|<z*..t4w'++D1)	2, >'"#a'PQ
 	
 >.)*Q.&
 	
 >)$%)&
 	
 >*%&*'
 	
 & 	&IIIc)n%	&u:>4  d5k!n^G5L0Ma0PPJ  E{1~N7+,Q// r   c                 z   |d   t        | d         z  }|d   t        | d         z  }||k  rD|}t        | d   |z  dz         }t        | d   |z  dz         }d}t        |d   |z
  dz  dz         }nC|}t        | d   |z  dz         }t        | d   |z  dz         }d}t        |d   |z
  dz  dz         }|||||dS )aI  Fits source rectangle into destination rectangle
    by scaling and centering.


        >>> ComputeScaledRect(sourceSize = (10, 40), destSize = (100, 50))
        {'height': 50, 'scale': 1.25, 'width': 13, 'x': 44, 'y': 0}


    :param sourceSize: size of source rectangle
    :param destSize: size of destination rectangle
    r   r
   g      ?g       @)widthheightxyscale)floatint)	
sourceSizedestSizeratio1ratio2ro   rk   rl   rm   rn   s	            r   ComputeScaledRectrv      s     a[5A//Fa[5A//FJqME)C/0Z]U*S01!v%,s23JqME)C/0Z]U*S01!u$+c12f11uMMr   c                    t        j                  t        dd            }|j                  |       |j	                  |       \  }}t        |dz   |dz         }|j                  |       |j                  t         j                         |j                  t        j                  |        |j                  t        j                  |        |j                          |j                  | dd       |j                  t         j                         |S )z'Renders text with given font to bitmap.   r   r
   )wxMemoryDCr   SetFontGetTextExtentSelectObjectSetBackgroundModeSOLIDSetTextBackgroundColourSetTextForegroundClearDrawText
NullBitmap)textfontbgcolorfgcolordcwhbmps           r   
RenderTextr     s    	[R(	)BJJtD!DAq
a!eQU
#COOC"G,-G,-HHJKKaOOBMM"Jr   c                     t        j                  d| j                         | j                         f      }|j	                  t        | j                                      |S )zConverts wx.Image to PIL imageRGB)r   newGetWidth	GetHeight	frombytesbytesGetData)imagepilImages     r   WxImageToPilr      sC    yy!15??3D EFHuU]]_-.Or   c                     dj                  |       }|r%|t        t        |j                                     z  }t	        j
                  t        |            j                         S )zCReturns a hash from command given as a list and a region as a dict.r(   joinstrsorteditemshashlibsha1r   	hexdigest)cmdregionr<   s      r   HashCmdr   '  sH    88C=DF6<<>*++<<t%//11r   c                    dj                  | D cg c]  }|D ]  }|  c}}      }|r%|t        t        |j                                     z  }t	        j
                  t        |            j                         S c c}}w )z:Returns a hash from list of commands and regions as dicts.;r   )cmdsr   sublistitemr<   s        r   HashCmdsr   /  sf    88Bg'B$TBTBCDF6<<>*++<<t%//11 Cs   A<
c                 b    t         j                  j                  | t        ||      dz   |z         S )z<Returns file path created as a hash from command and region..)ospathr   r   )dirnamer   r   	extensions       r   GetFileFromCmdr   7  s(    77<<f!5!;i!GHHr   c                 b    t         j                  j                  | t        ||      dz   |z         S )zFReturns file path created as a hash from list of commands and regions.r   )r   r   r   r   )r   r   r   r   s       r   GetFileFromCmdsr   <  s(    77<<$!7#!=	!IJJr   c           	         d}| D ]2  }|j                   st        |d      st        |j                        } n g }| D ]  }|j                   st        |d      rt	        |j
                        D ]  \  }}|j                  d      s|j
                  dd }g }|j                  D ]b  }t        |      \  }	}
dj                  |	      ||<   |
r'	 |j                  d      }dj                  |
	      ||<   |j                  |dd        d |j                  |        |j                  |j
                  g|z          t        t        |       S # t        $ r$ |j                  dj                  |
	             Y w xY w)
zGoes thru layerList and create matrix of commands
    for the composition of map series.:

    :return: matrix of cmds for composition
    r   mapszmap=Nz
map={name})r<   rO   zlayer={layer})rO   )activehasattrr\   r   	enumerater   
startswithrP   formatindex
ValueErrorr6   r`   zip)	layerListrR   rO   cmdsForCompositionipartr   r   map_mapNamemapLayeridxs               r   layerListToCmdsMatrixr   A  s    E <<GE62

OE	
  ;||5&!$UYY/ 44??6*))A,CD %

 
,,;D,A)!-!4!4'!4!BA#S&)ii&8+:+A+A+A+QC CF+
, '--d34" %%uyykE&9:+;. '()) $. S #

?+A+A+A+Q RSs   &E*E<	;E<	c                     g }d}d}|D ]C  }|.||k7  r|}|dz  }|j                  t        | |   ||                3|j                  d       E |t        |       dz
  k(  sJ |S )zEApplies information from temporal sampling
    to the command matrix. Nr
   )r6   r   r\   )	cmdMatrixsampledSeriesregions	namesListjlastNamer<   s          r   sampleCmdMatrixAndCreateNamesr   h  s     I
AH #4QXilGAJ?@T"# I""""r   c                  6    	 t               S # t        $ r Y yw xY w)zMReturns number of available cpus.
    If fails, default (4) is returned.
       )r   NotImplementedErrorr   r   r   getCpuCountr   z  s!    { s   	 	c                    || z
  t        |dz
        z  }g }| |k  r"| |k  rM|j                  |        | |z  } | |k  rn0|| k  r"|| k  r&|j                  |        | |z  } || k  rn	| g|dz
  z  }|j                  |       |S )a,  Interpolates values between start and end.

    :param start: start value (float)
    :param end: end value (float)
    :param count: total number of values including start and end

    >>> interpolate(0, 10, 5)
    [0, 2.5, 5.0, 7.5, 10]
    >>> interpolate(10, 0, 5)
    [10, 7.5, 5.0, 2.5, 0]
    r
   )rp   r6   )startendrR   stepvaluess        r   interpolater     s     %K5++DFs{ckMM% TME ck 
uEkMM% TME Ek EAI&
MM#Mr   )strds)NN)ppm)+__doc__r   ry   r   r7   multiprocessingr   PILr   hasPILImportErrorgrass.temporaltemporalr$   grass.scriptscriptr4   grass.script.utilsr   gui_core.wrapr   	core.gcmdr   r	   r   r   r   r2   r?   rL   rP   ri   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>r      s   & 
 	  
 %F   % %   
 
 
 K,6,Z0zN<"22I
K
$*N$M  Fs   B B'&B'