
    ը	f,                        d Z ddlZddlmZ ddlmZ 	 ddlmZ ddlZej                  e_        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m Z  ddl!m"Z"m#Z# ddl$m%Z%  G d de       Z& G d d      Z' G d de'      Z( G d de'      Z) G d de'      Z*y#   ej                   e
d             Y xY w# e$ r ddlmZ ddlmZ Y w xY w# e$ r	 dd
lmZ Y w xY w)a  !
@brief WMS, WMTS and NASA OnEarth drivers implemented in GRASS using GDAL Python bindings.

List of classes:
 - wms_drv::WMSDrv
 - wms_drv::BaseRequestMgr
 - wms_drv::WMSRequestMgr
 - wms_drv::WMTSRequestMgr
 - wms_drv::OnEarthRequestMgr

(C) 2012 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 Stepan Turek <stepan.turek seznam.cz> (Mentor: Martin Landa)
    N)sleep)gdalzTUnable to load GDAL Python bindings (requires package 'python-gdal' being installed))pifloor)	HTTPError)HTTPException)
ParseError)
ExpatError)GetEpsgGetSRSParamValWMSBase)WMTSCapabilitiesTreeOnEarthCapabilitiesTree)Srsc                       e Zd Zd Zd Zy)WMSDrvc           	         t        j                  t        d             | j                  d   }d| j                  d   v r| j                  dxx   dz  cc<   n| j                  dxx   dz  cc<   | j                  d   s!| j	                  | j                        | _        n| j                  d   | _        | j                  d   dk(  rBt        | j                  | j                  | j                  | j                  | j
                        }n| j                  d   dk(  rBt        | j                  | j                  | j                  | j                  | j                        }nS| j                  d   d	k(  rAt        | j                  | j                  | j                  | j                  | j
                        }j                         }d
}d}d}	 |dk(  r|j                         }sn|d   }|d   }	t        j                  |d       	 | j!                  || j                  d   | j                  d         }
| j1                         }	 t3        |d      }|j5                  
j7                                jA                          d}tC        jD                  |tB        jF                        }|o	 t3        |d      }|j7                         }jA                          "t        j,                  t        d      |z         nt        j,                  t        d             d}|jH                  dk  r!t        j,                  t        d      |z         |jH                  dk(  rB|jK                  d      jM                         #| j1                         }| jO                  ||      }n|}|r| j1                         }tC        jP                  | jR                        }|jU                         }tB        jV                  |vs|tB        jV                     dk(  r+t        j,                  t        d       | jR                  z         |jH                  | _,        |j[                  ||d!   |d"   | jX                  |jK                  d      j\                        }d#}|j_                  dd|	d$   |	d%   |	d$   |	d%         }ja                  |	d&   |	d'   |	d$   |	d%   |       d}d}t        jb                  |       t        jb                  |       '|s|S t        jd                  d(d)tg        | j                  d*         +      }|ji                  d,      }jk                  |       |d-   |d.   z
  tm        |d!         z  }|d/   |d0   z
  tm        |d"         z  }|d.   |d1|d0   d1|g}|jo                  |       d}|S # t"        t$        f$ r}t'        |t(              rI|j*                  dk(  r:t        j,                  t        d      | j                  d   t/        |      fz         n9t        j,                  t        d      | j                  d   t/        |      fz         Y d}~d}~ww xY w# t"        $ r}t'        |t8        j:                        rc|d   dk(  r[|dk  rV|dz  }|dk(  rd}n|dk(  rd}t        j<                  t        d      z         t?        |       Y d}~jA                          t        j,                  t        d      t/        |      z         Y d}~d}~ww xY w# jA                          w xY w# t"        $ r5}t        j,                  t        d      t/        |      z         Y d}~d}~ww xY w# jA                          w xY w)2zh!Downloads data from WMS server using own driver

        @return temp_map with downloaded data
        z#Downloading data from WMS server...url?&capfiledriver
WMTS_GRASS	WMS_GRASSOnEarth_GRASSTNr         usernamepasswordi  z3Authorization failed to '%s' when fetching data.
%sz"Unable to fetch data from: '%s'
%swbh         zLServer refused to send data for a tile.
Request will be repeated after %d s.z&Unable to write data into tempfile.
%srbz%Unable to read data from tempfile.
%szWMS server error: %szWMS server unknown errorzBWMS server error: no band(s) received. Is server URL correct? <%s>NOz+Driver %s does not supports Create() methodcolsrowsFsizeXsizeYt_cols_offsett_rows_offsetzg.projwfsrs)flagsepsg
maxxminxminymaxyg        )8grassmessage_params_fetchCapabilitiescap_fileWMTSRequestMgrbboxregionproj_srsWMSRequestMgr	tile_sizeOnEarthRequestMgrGetMapRegionGetNextTiledebug_fetchDataFromServerIOErrorr   
isinstancer   codefatalstr	_tempfileopenwritereadsocketerrorwarningr   closer   OpenGA_ReadOnlyRasterCountGetRasterBandGetRasterColorTable_pct2rgbGetDriverByNamegdal_drv_formatGetMetadataDCAP_CREATEtemp_map_bands_numCreateDataType
ReadRasterWriteRaster
try_removeread_commandr   rstripSetProjectionintSetGeoTransform)self
server_urlreq_mgr
map_regioninittemp_map	fetch_trytile	query_urltile_refwms_datae	temp_tiletemp_tile_opened
sleep_timetile_dataset_infoerror_xml_openederr_strtemp_tile_pct2rgbtile_datasetr   metadatatemp_map_datasettile_to_temp_map
projectionpixel_x_lengthpixel_y_lengthgeo_transforms                               (/usr/lib/grass83/etc/r.in.wms/wms_drv.py	_downloadzWMSDrv._download;   s   
 	a=>?[['
$++e$$KK#%KK#%{{9% 33DKK@DM KK	2DM ;;x L0$TYYT]]DMMG [["k1#TYYT^^T]]G [["o5'TYYT]]DMMG ))+
	 A~ **,  QI AwHKK	1%44t{{:6J8O (I)#'	4#8  &&x}}74 !&&(I $		)T5E5E F (-'+It'<$.335G %**,&KK"8 9G CDKK"< => $ ,,q0\ !! "--2%33A6JJLX %)NN$4!#}}Y8IJ0 >>+--d.B.BC!--/$$H4 0 01T9KKGH../ +7*B*B'#)==v&v&++ ..q1::$    ,66!!!!  (())!!   L $Y'./e h O''Dwt{{5/A'B

  &&t,
&&z2$V,z&/AASvF
 
 %V,z&/AASvF
 

 vv
 	((7w ]+ 
a+#KKPQ;;u-s1v67
 KK?@;;u-s1v67
$  W
 a.1Q43;9q=NI A~%&
"a%'
MMk %% *% !&&( KK"K LsSTv UVV/W2 !&&(  VKK"J KcRSf TUUV %**,sz   >-V <+Y  \ Y%BX==Y	\ A'[;5\ *[;5\ ;\  \ \	]!*]] ]] ]+c                    d}d}t        j                  |      }|!t        j                  t	        d|z               |j                  |      }t        j                  d      t        j                  d      t        j                  d      t        j                  d      dz  g}|j                         }|Tt        t        d|j                                     D ].  }	|j                  |	      }
t        d      D ]  }|
|   ||   |	<    0 t        j                  | j                        }|j!                  ||j"                  |j$                  |      }t        |j$                        D ]p  }|j'                  d||j"                  d      }t        |      D ]B  }||   }t        j(                  ||      }|j                  |dz         j+                  |d|       D r |S )z!Create new dataset with data in dst_filename with bands according to src_filename
        raster color table - modified code from gdal utility pct2rgb

        @return new dataset
           r   zUnable to open %s       r   )r   rS   r5   rI   r7   rV   Numeric
arrayrangeonesrW   rangeminGetCountGetColorEntryrY   rZ   r^   RasterXSizeRasterYSizeReadAsArraytake
WriteArray)rh   src_filenamedst_filename	out_bandsband_numbersrc_dssrc_bandlookupctientrycgtiff_drivertif_dsiYsrc_dataiBandband_lookupdst_datas                      r   rX   zWMSDrv._pct2rgb  s    	 <(>KK.=>?''4 s#s#s#LL#	
 ))+>3sBKKM23 ,((+q ,A#(8F1IaL,, ++D,@,@A$$&,,f.@.@)

 **+ 	LB++Ar63E3EqIHy) L$Um"<<X>$$UQY/::8QK	L	L     N)__name__
__module____qualname__r   rX    r   r   r   r   :   s    Yv/r   r   c                       e Zd ZdZd Zd Zy)BaseRequestMgrz!!Base class for request managers.c                 ,	   d}i | _         t        t        |d   |d   z
  |d   z  |z               | j                   d<   t        t        |d   |d   z
  |d   z  |z
              | j                   d<   t        t        |d   |d   z
  |d   z  |z               | j                   d	<   t        t        |d   |d
   z
  |d   z  |z
              | j                   d<   d| _        dD ]|  }dD ]u  }| j                   d	   | j                   |   k  s#| j                   |   |d   k  s9| j                   d   | j                   |   k  sY| j                   |   |d   k  sod| _        w ~ | j                  s&t	        j
                  t        d             d| _        y| j                   d   |d   k  rt        |d         | j                   d<   | j                   d   |d   kD  rt        |d         | j                   d<   | j                   d	   |d	   k  rt        |d	         | j                   d	<   | j                   d   |d   kD  rt        |d         | j                   d<   t	        j                  d| j                   d   | j                   d   | j                   d	   | j                   d   fz  d       | j                   d   | j                   d   z
  dz   | j                   d   | j                   d	   z
  dz   z  }	t	        j                  t        d      |	|d   |d   fz         i | _        | j                   d   |d   z  |d   z   | j                  d<   |d   | j                   d	   |d   z  z
  | j                  d<   | j                   d   dz   |d   z  |d   z   | j                  d<   |d   | j                   d   dz   |d   z  z
  | j                  d
<   t        |d   | j                   d   | j                   d   z
  dz   z        | j                  d<   t        |d   | j                   d   | j                   d	   z
  dz   z        | j                  d<   | j                   d   | _
        | j                   d	   | _        |d   |d   |d   |d   z   |d   |d   z
  d| _        |d   |d   d| _        y)zb!Initialize data needed for iteration through tiles. Used by WMTS_GRASS and OnEarth_GRASS drivers.V瞯<r2   xmin_colr1   max_colr4   ymin_rowr3   max_rowF)r   r   )r   r   Tz$Region is out of server data extend.Nz7t_num_bbox: min_col:%d max_col:%d min_row:%d max_row:%d   r   z5Fetching %d tiles with %d x %d pixel size per tile...r&   r'   )r2   r4   r1   r3   )r(   r)   )
t_num_bboxrf   r   
intersectsr5   rQ   r7   rk   rD   r6   i_coli_row
query_bboxrq   )
rh   r<   	tl_corner	tile_spanr@   mat_num_bboxepsiloncolrow	num_tiless
             r   _computeRequestDataz"BaseRequestMgr._computeRequestDataK  s    %(4<)F"33y~EOP&
	" &)4<)F"33y~EOP&
	" &)9V$tF|3y~EOP&
	" &)9V$tF|3y~EOP&
	"
  ) 		+C- +OOI.$//#2FF,Y0GGOOI.$//#2FF,Y0GG&*DO+		+ MM!BCD"DO ??9%i)@A),\)-D)EDOOI&??9%i)@A),\)-D)EDOOI&??9%i)@A),\)-D)EDOOI&??9%i)@A),\)-D)EDOOI&E	*	*	*	*	 		
 __Y/$//)2LLqPOOI&)CCaG
	 	EF)C.)C.9:	
 OOI&37)F:KK 	 f!;y~ MM 	 $(??9#=#AYF
 #
f# f!;a!?9S> QQ 	
 #&cNy)DOOI,FFJL#
 #&cNy)DOOI,FFJL#
 __Y/
__Y/
 f%f%f%	#6f%	#6	
 #,C.9S>Jr   c                 V    |j                  d      dk7  s|j                  d      dk7  ryy)z!Is it geographic projection?z+proj=latlongz+proj=longlatTF)find)rh   projs     r   
_isGeoProjzBaseRequestMgr._isGeoProj  s)    99_%+tyy/IR/Or   N)r   r   r   __doc__r   r   r   r   r   r   r   H  s    +mK^r   r   c                   ,    e Zd ZddZd Zd Zd Zd Zy)r?   Nc                    |d   | _         |d   | _        |d   dz   t        |d         z   }|d   d|d   d|d   d	|d
   d|d   d|d   d|d   z   | _        |d   r| xj                  d|d   z   z  c_        | xj                  d|z   dz   dz   |d   z   z  c_        || _        || _        |d   | _        |d
   | _        |d   dk7  r| xj                  d|d   z   z  c_        t        |d
         }t        |d         }	|| j                  z  | _	        || j                  z  | _
        t        | j                        t        |      z  | j                  d   | j                  d   z
  z  | _        d| _        | j                  dk7  rd| _        | j                  dz   | _	        |	| j                  z  | _        |	| j                  z  | _        t        | j                        t        |	      z  | j                  d   | j                  d   z
  z  | _        d| _        | j                  dk7  rd| _        | j                  dz   | _        t%        | j                        | _        | j                  d   | j                  z   | j&                  d<   d| _        d| _        | j                  | _        || j,                  d
<   |	| j,                  d<   y )!4!Initialize data needed for iteration through tiles.wms_versionr-   	proj_name=r   z#SERVICE=WMS&REQUEST=GetMap&VERSION=z&LAYERS=layersz&WIDTH=r&   z&HEIGHT=r'   z&STYLES=stylesz&TRANSPARENT=transparentbgcolorz	&BGCOLOR=r   zFORMAT=format	urlparams r1   r2   Fr   Tr   r4   r3   N)version	srs_paramr   r   r<   r>   	tile_rows	tile_colsrf   num_tiles_xlast_tile_x_sizefloattile_length_xlast_tile_xnum_tiles_ylast_tile_y_sizetile_length_ylast_tile_ydict	tile_bboxi_xi_yrk   )
rh   r8   r<   r=   r@   r>   r:   r   r&   r'   s
             r   __init__zWMSRequestMgr.__init__  s   m,k"S(>&-+HH%= }%x &!&!x }%

 )HHfY&777HC$J$y06(3CCC	 "6*"6*+"$HHf[111H6&>"6&>"  4>>1 $t~~ 5$..!Dkyy 499V#446 	 !  A%#D#//!3D4>>1 $t~~ 5$..!Dkyy 499V#446 	 !  A%#D#//!3Ddii!%6!2T5G5G!Gv))"&"&r   c                     | j                   S zN!Get size in pixels and bounding box of raster where all tiles will be merged.rk   rh   s    r   rB   zWMSRequestMgr.GetMapRegion	      r   c           
         i }| j                   | j                  k\  ry| j                  |d<   | j                   | j                  dz
  k(  r| j                  r| j                  |d<   | j
                  dk7  rC| j                  dxx   | j                  z  cc<   | j                  dxx   | j                  z  cc<   nE| j                  d   | j                  d<   | j                  d   | j                  z
  | j                  d<   | j                  |d<   | j
                  | j                  dz
  k(  r| j                  r| j                  |d<   | j                  | j                  | j                  | j                  | j                         }| j"                  dz   d	|d
   d|d   d|d   d|d   z   }t%        | j                  | j                   z        |d<   t%        | j                  | j
                  z        |d<   | j
                  | j                  dz
  k\  rbd| _        | xj                   dz  c_         | j                  dxx   | j&                  z  cc<   | j                  d
xx   | j&                  z  cc<   ||fS | xj
                  dz  c_        ||fS )[!Get url for tile request from server and information for merging the tile with other tilesNr(   r   r   r3   r4   r)   r   zBBOX=r2   ,r1   r*   r+   )r   r   r   r   r   r   r   r   r<   r   r   r   r   _getQueryBboxr>   r   r   r   rf   r   )rh   rq   r   rp   s       r   rC   zWMSRequestMgr.GetNextTile  s=    88t''' NN88t''!++0@0@ $ 5 5HW 88q=NN6"d&8&88"NN6"d&8&88"%)YYv%6DNN6"%)YYv%69K9K%KDNN6" NN88t''!++0@0@ $ 5 5HW''NNDMM4>>4<<

 HH 6"6"6"6" 	 %((A$B!$'(A$B!88t''!++DHHHMHNN6"d&8&88"NN6"d&8&88" ("" HHMH(""r   c                     |dv s|dk7  r|S t        t        |            j                  dk(  r| j                  |      S |S )z!Creates query bbox (used in request URL)

        Mostly bbox is not modified but if WMS standard is 1.3.0 and
        projection is geographic, the bbox x and y are in most cases flipped.
        )T   S   z1.3.0yx)r   r   	axisorder	_flipBbox)rh   r<   r   r   r   s        r   r   zWMSRequestMgr._getQueryBboxB  sD      Gw$6K	*+55=>>$''r   c                 `    t        |      }i }|d   |d<   |d   |d<   |d   |d<   |d   |d<   |S )z
        Flips bbox values between this keys:
        maxy -> maxx
        maxx -> maxy
        miny -> minx
        minx -> miny
        @return copy of bbox with flipped coordinates
        r1   r4   r2   r3   )r   )rh   r<   	temp_bboxnew_bboxs       r   r   zWMSRequestMgr._flipBboxP  sS     J	$V,$V,$V,$V,r   N)r   r   r   r   rB   rC   r   r   r   r   r   r?   r?     s    E'N3#jr   r?   c                   D    e Zd ZddZd Zd Zd Zd Zd Zd Z	d	 Z
d
 Zy)r;   Nc           	         || _         d| _        d| _        	 t        |      }j                         | _
        |j                         }| j                  ||d   |d         }	|	d   d   }
|	d   d   }|
j                  | j                  j                  d            j                  |d	<   | j!                  |
j#                  | j                  j%                  d
            ||      }| j'                  ||      }| j)                  ||||| j+                  |
             y# t        $ r5}t        j                  t        d      t        |      z         Y d}~0d}~ww xY w)5!Initializes data needed for iteration through tiles.NgמY2?&Unable to parse tile service file.
%s
r   r-   r   r   
Identifiertile_matrix_set
TileMatrix)r>   meters_per_unit
pixel_sizer   r	   r5   rI   r7   rJ   getxmlnshandlerxml_nsgetroot_getMatSetsr   NsOwstext_findTileMatsfindallNsWmts_getMatSizer   _getMatSetSrs)rh   r8   r<   r=   r>   r:   cap_treerP   rootmat_setsmat_setmat_set_linktile_matr   s                 r   r   zWMTSRequestMgr.__init__e  sO    !# "	T ,H5H ..0! ##D&*:F5MJ 1+a.{1~$+LL1B1B<1P$Q$V$V ! %%OODKK..|<=vt

 '',? 	  fdL$2D2DW2M	
1  	TKKDEE
RSS	Ts   D 	E"*EEc                     | j                   S r   r   r   s    r   rB   zWMTSRequestMgr.GetMapRegion  r   r   c                 6   |j                  | j                  j                  d            }|j                  | j                  j                  d            }d}|D ]?  }|j                  | j                  j	                  d            j
                  }||k(  s=|} n |!t        j                  t        d      |z         |j                  | j                  j                  d            }	g }
|j                  | j                  j                  d            }|	D ]  }|j                  | j                  j                  d            j
                  }|D ]  }|j                  | j                  j	                  d            j
                  }||k7  r=| j                  |      }t        |      j                         t        |      j                         k(  s|
j                  ||g         |
s/t        j                  t        d      |d	t        |      z   fz         |
S )
zM!Get matrix sets which are available for chosen layer and have required EPSG.ContentsLayerNr   z-Layer '%s' was not found in capabilities fileTileMatrixSetLinkTileMatrixSetz)Layer '%s' is not available with %s code.zEPSG:)r   r  r  r  r	  r
  r5   rI   r7   r  r   getcoder   upperappendrJ   )rh   r  
layer_namer-   contentsr   ch_layerlayerlayer_idmat_set_linkssuitable_mat_setstileMatrixSetslinkmat_set_link_idr  
mat_set_idmat_set_srss                    r   r  zWMTSRequestMgr._getMatSets  s    99T[[//
;<!!$++"4"4W"=> 	Ezz$++"3"3L"ABGGH:% 		 KKIJZWX ((););<O)PQ!))$++*<*<_*MN! 	>D"ii(:(:?(KLQQO) >$\\$++*;*;L*IJOO
0"009{#++-.2E1L1L1NN%,,gt_=>	> !KK=>wS123
 ! r   c                 j    |j                  | j                  j                  d            j                  S )NSupportedCRS)r   r  r	  r
  )rh   r  s     r   r  zWMTSRequestMgr._getMatSetSrs  s&    ||DKK--n=>CCCr   c                    g }|j                  |d   |d   z
  |d   z  | j                         z  | j                  z         |j                  |d   |d   z
  |d   z  | j                         z  | j                  z         t        |      }d}|D ]l  }t	        |j                  | j                  j                  d            j                        }|r|}	|}
d	}I	|z
  }||z
  }||k  r|d
k  s||kD  sc|d
kD  si|}
|}	n 
S )z4!Find best tile matrix set for requested resolution.r4   r3   r'   r1   r2   r&   TScaleDenominatorFr   )	r  _getMetersPerUnitr  r   r   r   r  r  r
  )rh   	tile_matsr=   r<   
scale_dens	scale_denfirstt_matmat_scale_denbest_scale_den
best_t_mat	best_diffmat_diffs                r   r  zWMTSRequestMgr._findTileMats  s?   
&\DL(Vn$$&' oo	
 	&\DL(Vn$$&' oo	
 
O	 	/E!

4;;--.@ABGGM !."
&2I$y0HH$AH$Q"
!.!	/$ r   c                 @   | j                   r| j                   S | j                  | j                        rg| j                  j                  d      }|D ]%  }d|v st	        |j                  d      d         } n dt
        z  z  }|dz  | _         | j                   S d| j                  v rd| j                  j                  d      }|D ]8  }d|v sdt	        |j                  d      d         z  | _          | j                   S  | j                   S d| _         | j                   S )zQ!Get coefficient which allows converting units of request projection into meters. z+ar   r   r   ih  z	+to_meter)r  r   r>   splitr   r   )rh   proj_paramsparamaequator_perims        r   r/  z WMTSRequestMgr._getMetersPerUnit  s&   ''' ??4==)----c2K$ 5=ekk#.q12A FQJM#03#6D  ### DMM)----c2K$ %'+,uU[[5Ea5H/I+ID(
 ### ### $%D ###r   c                    i }dx|d<   |d<   t        |j                  | j                  j                  d            j                        dz
  |d<   t        |j                  | j                  j                  d            j                        dz
  |d<   |j                  | j                  j                  d	            }||S |j                  | j                  j                  d
            j                  }|j                  | j                  j                  d            }|D ]  }|j                  | j                  j                  d            }|j                  }	|	|k(  s?ddgddgddgddgfD ]c  }
|j                  | j                  j                  |
d               }t        |j                        ||
d   <   |
d   dv sS||
d      dz
  ||
d   <   e  |S  |S )zW!Get rows and cols extend of data available on server for chosen layer and tile matrix.r   r   r   MatrixWidthr   r   MatrixHeightr   TileMatrixSetLimitsr   TileMatrixLimitsr  
MinTileRow
MaxTileRow
MinTileCol
MaxTileCol)r   r   )rf   r   r  r  r
  r	  r  )rh   r  r  r   tile_mat_set_limitstile_mat_idtile_mat_limitslimitlimit_tile_matlimit_idr   i_tags               r   r  zWMTSRequestMgr._getMatSize  s    <==Y,y"9dkk00?@EEFJ 	Y dkk00@AFFG!K 	Y
 +//[[ 56
 &mmDKK$5$5l$CDII-55KK12
 % 	E"ZZ(:(:<(HIN%**H;&----	 DA "JJt{{'9'9!A$'?@E),UZZL1&t55-9!A$-?!-CQqT*D '	& r   c                    t        |j                  | j                  j                  d            j                        }|| j
                  z  | j                         z  }|j                  | j                  j                  d            j                  j                  d      }i }	t        |d         |	d<   t        |d         |	d<   t        |      }
|
j                         dk(  r5|
j                  d	v r't        j                  d
       |	d   |	d   c|	d<   |	d<   nt        j                  d       i }i | _        t        |j                  | j                  j                  d            j                        | j                  d<   || j                  d   z  |d<   t        |j                  | j                  j                  d            j                        | j                  d<   || j                  d   z  |d<   |d   d|d   d|d   d|d   d|d   d|j                  | j                  j                  d            j                  
z   | _        t"        j%                  | ||	|| j                  |       y)r   r.  TopLeftCornerr;  r   r2   r   r4   z	EPSG:4326)uriurnswitchz	no switch	TileWidthr   
TileHeightr   r   z1SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=r   z&STYLE=r   z&FORMAT=r   z&TILEMATRIXSET=r  z&TILEMATRIX=r   N)r   r   r  r  r
  r  r/  r<  r   r  encodingr5   rQ   r@   rf   r	  r   r   r   )rh   r  r8   r<   r   r*  r2  
pixel_spantl_strr   sr   s               r   r   z"WMTSRequestMgr._computeRequestData0  s   (--(:(:;M(NOTTU	043I3I3KK
t{{11/BCHHNNsS	!&),	&!&),	& 

 99;+%!***FMM(#&!&! 3Yv	& 1
 MM+&	!(--0B0B;0O"P"U"UVs#dnnS&99	#!(--0B0B<0P"Q"V"VWs#dnnS&99	#%= x x x ()dkk//=>CC

 	**$	9dnnl	
r   c                    | j                   r| j                  | j                  d   kD  ry| j                  dt	        | j                        t	        | j
                        fz  z   }t	        | j                  d   | j                  | j                  d   z
  z        | j                  d<   t	        | j                  d   | j
                  | j                  d   z
  z        | j                  d	<   | j
                  | j                  d
   k\  r*| j                  d   | _        | xj                  dz  c_        n| xj
                  dz  c_        || j                  fS )z\!Get url for tile request from server and information for merging the tile with other tiles.r   Nz&TILECOL=%i&TILEROW=%ir   r   r*   r   r   r+   r   r   )r   r   r   r   rf   r   r@   rq   )rh   rp   s     r   rC   zWMTSRequestMgr.GetNextTiled  s   $**ty/I"IHH7

O

O;
  
 
	
 *-NN34::	0J#JK*
o& *-NN34::	0J#JK*
o& ::333DJJJ!OJJJ!OJ$--''r   r   )r   r   r   r   rB   r  r  r  r/  r  r   rC   r   r   r   r;   r;   d  s5    (
T%!ND&P$:,\2
h(r   r;   c                   >    e Zd Zd Zd Zd Zd
dZd Zd Zd Z	d	 Z
y)rA   c                    	 t        |      | _        | j                  j                         }| j                  ||||      \  }| _	        }	| _
        || _        |d   |d   z   | j                  d<   | j                  ||	| j                  | j                         y# t        $ r4}t        j                  t        d      t        |      z         Y d}~d}~ww xY w)r   r   Nr   r   )r   r  r	   r5   rI   r7   rJ   r  _parseTileServicer   r@   r   r   )
rh   r8   r<   r=   r>   tile_servicerP   r  r   t_patt_bboxs
             r   r   zOnEarthRequestMgr.__init__  s    	T 4LADM }}$$& <@;Q;Q$<
8T^[$. Umc!f,  {DNNDNNS  	TKKDEE
RSS	Ts   B 	C *CCc                     | j                   S r   r   r   s    r   rB   zOnEarthRequestMgr.GetMapRegion  r   r   c                 D   |j                  d      }| j                  |      }|s!t        j                  t	        d      dz         d}|D ])  }|j                  d      }	|	j
                  |d   k(  s'|} n |$t        j                  t	        d      |d   z         |j                  d      }
| j                  |
||      }|j
                  j                  d	      }|d
   r| j                  |d
   |      }n|d   }|D ]	  }d|vs|} | j                  j                  |      \  }}}}i }t        |d   |d   z
        |d<   t        |d   |d   z
        |d<   |j                  d      }i }dD ]  }t        |j                  |            ||<   ! i }||d<   ||d<   ||||fS )z !Get data from tile service fileTiledPatternsz;Unable to parse tile service file. 
 No tag '%s' was found.
TiledGroupNNamer   z3Tiled group '%s' was not found in tile service fileTilePatternr0   r   r   ztime=${r   r   r   r   r   LatLonBoundingBox)r2   r3   r1   r4   )r   _getAllTiledGroupr5   rI   r7   r
  r  _parseTilePatternr<  _insTimeToTilePatternUrlr  gettilepatternurldataabsr   get)rh   r  r<   r=   r8   tiled_patternstile_groups	req_groupgroupnamegroup_t_patts	best_patturlsr   ut_bboxwidthheightr   tile_pattern_bboxra  r[  r@   s                          r   r_  z#OnEarthRequestMgr._parseTileService  s   ?3,,^<KKPQ
 	  	E::f%DyyF8,,!			 KKGH"#
 "))-8**=$G	~~##D)+//{0CTJCq'C A%C &*]]%H%H%M"VUF	VAY23	#VAY23	#%NN+>?1 	=A"#4#8#8#;<KN	= 		#	#I{I55r   Nc                     |sg }||j                  d      z  }|j                  d      }|D ]  }| j                  ||        |S )z!Get all 'TileGroup' elementsre  TiledGroups)r  ri  )rh   parenttiled_groups
new_groupsrr  s        r   ri  z#OnEarthRequestMgr._getAllTiledGroup  sP    L|44^^M2
 	8E""5,7	8r   c                    i }|d   |d   z
  |d   z  |d<   |d   |d   z
  |d   z  |d<   |d   |d   k  rd}nd}i }d	}|D ]  }| j                   j                  |j                  j                  d
      d         \  }	}
}}t	        |
d   |
d   z
        |z  |d<   t	        |
d   |
d   z
        |z  |d<   |||   }|}}||   z
  }||   ||   z
  }||k  r|dk  s||kD  s|dkD  s||   }|} |S )z1!Find best tile pattern for requested resolution.r4   r3   r'   r   r1   r2   r&   r   Nr0   r   r   r   r   )r  rl  r
  r<  rm  )rh   rt  r<   r=   rescomp_rest_resru  patternr   rx  ry  rz  best_resr8  	tile_diffs                   r   rj  z#OnEarthRequestMgr._parseTilePattern  sW   L4</6&>ACL4</6&>ACs8c#hHH	$ 	$G)-)L)L""4(+*&C VAY23e;E#JVAY23f<E#J  ?#	 3x=0Ih#h-7II%)a-I%)a- ?#	)	$, r   c                 f   d}g }|j                  d      }|D ]  }	 |j                  d      \  }}dk7  r|j                  |       /d}	|D ]f  }| j                  ||      }
|
s||
d   t        |dz         z   |
d	    }|dd
 dk(  s;|t        |      d	z
     dk(  sP|d|
d    |z   ||
d	   d z   }d}	 n |	rt        j                  t	        d      |dfz          |r!t        j                  t	        d      dz         |S # t        $ r& t        j                  t	        d      |dfz         Y w xY w)z!Time can be variable in some urls in OnEarth TMS.
        Insert requested time from 'urlparams' into the variable if any url of urls contains the variable.
        Nr   r   zcWrong form of parameter '%s' in '%s'. 
                                  The parameter was ignored.r   timeFr   r   r   z${}Tz;Parameter '%s' in '%s' is not variable in tile pattern url.zM%s driver supports only '%s' parameter in '%s'. Other parameters are ignored.)zOnEarth GRASSr  r   )r<  
ValueErrorr5   rQ   r7   r  geturlparamidxslen)rh   
url_paramsrv  r   not_sup_paramsurl_params_listr>  kvhas_time_var
url_p_idxsurl_p_values               r   rk  z*OnEarthRequestMgr._insTimeToTilePatternUrl  s    $**3/$ !	E	{{3'1 F{%%a( L 
!11#q9
!!*Q-#a#g,">AOr?d*{3{;Ka;O/PTW/Wo
1.6Z]_9MMC#'L
  ST+&'=!	F MMc 99 
Q  = k*	+s   D,D0/D0c                     d}i }dx|d<   |d<   t        |d   |d   z
  |d   z  |z         |d<   t        |d	   |d
   z
  |d   z  |z         |d<   t        j                  | ||| j                  | j                  |       y)r   r   r   r   r   r4   r3   r   r   r1   r2   r   r   N)r   r   r   r   r@   )rh   r<   ra  r   r@   r   r   s          r   r   z%OnEarthRequestMgr._computeRequestData1  s    <==Y,y"9"' ;v#66)C.H7R#
Y #( ;v#66)C.H7R#
Y 	**$T^^T^^\	
r   c                    | j                   | j                  d   kD  ry| j                  d   | j                   z  }| j                  d   | j                  z  }| j                  d   dz   dt        | j                  d   |z         d	t        | j                  d
   |z
        d	t        | j                  d   |z         d	t        | j                  d   |z
        z   | j                  d   z   }t        | j                  d   | j                   | j                  d   z
  z        | j                  d<   t        | j                  d   | j                  | j                  d   z
  z        | j                  d<   | j                  | j                  d   k\  r*| j                  d   | _        | xj                   dz  c_         n| xj                  dz  c_        || j                  fS )r   r   Nr   r   r   r   zbbox=r2   r   r3   r1   r4   r   r   r*   r   r+   r   )
r   r   r   r   r   r   r   rf   r@   rq   )rh   x_offsety_offsetrp   s       r   rC   zOnEarthRequestMgr.GetNextTileB  s   ::	22>>#&3>>#&3 HHQK doof-89doof-89doof-89doof-89 hhqk	 	 *-NN34::	0J#JK*
o& *-NN34::	0J#JK*
o& ::333DJJJ!OJJJ!OJ$--''r   r   )r   r   r   r   rB   r_  ri  rj  rk  r   rC   r   r   r   rA   rA   ~  s.    T(26h
#J3j
""(r   rA   )+r   rO   grass.scriptscriptr5   r  r   osgeor   rI   r7   numpyr   aranger   mathr   r   urllib2r   httplibr   ImportErrorurllib.errorhttp.clientxml.etree.ElementTreer	   xml.parsers.expatr
   wms_baser   r   r   wms_cap_parsersr   r   r-   r   r   r   r?   r;   rA   r   r   r   <module>r     s   $    ^^  *!%;0 6 5 I KW K\v vr`N `FW(^ W(tf( f(IEKK	b	
  *&)*  ;:;s.   B B9 C B69CCCC