% Template GRASS newsletter - Article
% Language: Latex
%

% Head
\title{Traitement g\'eospatial sur des serveurs distants via internet
-- PyWPS}
\subtitle{PyWPS et Embrio}
\author{J\'achym  \v{C}epick\'y et Lorenzo Becchi, traduit par Vincent Picavet}

\maketitle

% Abstract
\emph{Le document 05-007r4\footnote{OGC Web Processing Service (WPS):
\url{http://www.opengeospatial.org/standards/requests/28}} de l'OGC  d\'ecrit un
proc\'ed\'e pour mettre \`a disposition des op\'erations g\'eospatiales \`a travers des
r\'esaux en utilisant des Web Services. Cet article pr\'esente une
impl\'ementation -- PyWPS. M\^eme si la cible originelle de PyWPS \'etait de rendre
accessible depuis des applications Web les modules du SIG GRASS, en pratique il
est possible d'utiliser n'importe quel outil en ligne de commande ou qui poss\`ede
une interface avec le langage de programmation Python. Avec l'aide de WPS il est
possible de r\'ealiser des op\'erations couteuses en temps de calcul c\^ot\'e serveur,
ou construire votre propre application de WebSIG tournant dans un navigateur
web. D\'ecrivons maintenant la façon dont PyWPS fonctionne et d\'eterminons s'il
peut r\'epondre \`a vos besoins.}

\section{OGC Web Processing Service}
\label{sec:ogc_wps}
Le standard OGC WPS (Web Processing Service) est relativement jeune et
pas encore aussi connu que son cousin le WMS (Web Map Service). Nous
commencerons donc par en donner un bref aperçu. L'unit\'e de base du WPS est le
\emph{process}, une op\'eration g\'eospatiale, avec des entr\'ees et des sorties de
type d\'efinies. Le client communique avec le serveur \`a l'aide de trois types de
requ\^etes. La requ\^ete peut \^etre envoy\'ee au serveur par HTTP GET avec des
param\`etres donn\'es sous la forme de paires cl\'es-valeurs (Key-Value Pairs, KVP) ou
par HTTP POST, avec des param\`etres donn\'ees dans un fichier XML. Les trois types
de requ\^etes pouvant \^etre envoy\'ees au serveur sont :

\begin{description}
    \item[GetCapabilities] -- Le serveur r\'epond avec du XML, d\'ecrivant le
    serveur, les co\^uts, une description g\'en\'erale et donnant une liste de process,
    pr\^ets \`a \^etre ex\'ecut\'es.

    \item[DescribeProcess] -- Le serveur r\'epond avec du XML, d\'ecrivant en d\'etail
    les types des entr\'ees et des sorties, pour que le client soit capable
    d'\'ecrire la requ\^ete \textit{Execute}.
    
    \item[Execute] -- Le client demande l'ex\'ecution d'une op\'eration g\'eospatiale,
    avec toutes les donn\'ees n\'ecessaires. Le serveur lance le process et informe
    le client (l'utilisateur) de l'avancement.
\end{description}

La suite donne quelques exemples pour illustrer l'utilisation de ces requ\^etes.
Disons que nous voulons faire un calcul de ligne de vue \`a partir de
coordonn\'ees x et y sur un fichier raster, disponible \`a partir d'un
serveur distant. Le nom du process sera \textit{visibility}.

\section{Utilisation basique de l'OGC WPS}
Tout d'abord nous avons besoin de d\'eterminer quelles op\'erations le serveur propose
(voir ce lien 
\footnote{\url{http://pywps.ominiverdi.org/cgi-bin/wps.py?service=WPS&request=GetCapabilities}}).
A partir du XML renvoy\'e, il apparait clairement que le process \emph{visibility}
est disponible sur le serveur, et le r\'esum\'e nous dit qu'il correspond au service
que nous recherchons. Ensuite, nous avons besoin de savoir quel type d'entr\'ee et
de sortie le process n\'ecessite et renvoie. (voir ce lien
\footnote{\url{http://pywps.ominiverdi.org/cgi-bin/wps.py?service=WPS&request=DescribeProcess&version=0.4.0&identifier=visibility}}).

\begin{itemize}
    \item $x$ de type \textit{LiteralValue}
    \item $y$ de type \textit{LiteralValue} 
    \item $maxdist$ -- distance maximale de l'observateur. De type
    \textit{LiteralValue}, valeur minimale 0, maximale 5000 metres. 
    \item $observer$ -- hauteur de l'observateur. De type
    \textit{LiteralValue}, valeur minimale 0, maximale 50 meters.
    
    \item $dem$ -- de type \textit{ComplexValue} -- carte raster de mod\`ele
    num\'erique de terrain, sur laquelle la ligne de vue doit \^etre calcul\'ee.
\end{itemize}

Maintenant nous pouvons \'ecrire la requ\^ete d'ex\'ecution, l'envoyer au serveur et
attendre les r\'esultats de
calcul\footnote{\url{http://pywps.ominiverdi.org/cgi-bin/wps.py?service=WPS&version=0.4.0&request=Execute&identifier=visibility&datainputs=x,602829.1875,y,4925326.875,maxdist=2000,observer=1.2,dem,http://somewhere/?some&service}}.
Le serveur va t\'el\'echarger le mod\`ele num\'erique de terrain, faire le calcul de
ligne de vue et renvoyer le raster de r\'esultat au client.

\section{Introduction \`a PyWPS}

%\includegraphics[width=0.15\columnwidth]{integration/cepicky/pywps}}
PyWPS est un projet relativement jeune, commenc\'e en avril 2006.
Le but premier du projet \'etait de faire la connexion entre UMN-MapServer et le
SIG GRASS de la mani\`ere la plus simple possible, afin de pouvoir cr\'eer une
v\'eritable application WebSIG, capable d'effectuer par exemple de l'interpolation
de donn\'ees raster, ou diverses analyses de mod\`eles num\'eriques de terrain. Avec
le temps, il s'est av\'er\'e que m\^eme si GRASS est un outil puissant, il n'est pas
forc\'ement le meilleur ou le seul choix possible pour toutes les t\^aches.
La conception de PyWPS a chang\'e de telle sorte qu'il puisse \^etre utilis\'e sans
GRASS en arri\`ere plan, mais avec n'importe quel autre outil, ou m\^eme juste avec
Python.
PyWPS est une impl\'ementation du standart WPS de l'OGC comme d\'efini dans le
document OGC 05-007r4. Actuellement, le support de tout le standard n'est pas
complet, mais presque 95\% du standard est impl\'ement\'e et utilisable.

Le projet est construit sur un simple script CGI, afin de rendre la vie des
d\'eveloppeurs de WebSIG la plus simple possible. Il met \`a disposition les
fonctionnalit\'es pour :

\begin{itemize}
    \item Analyser toutes les entr\'ees et cr\'eer toutes les sorties,
    \item R\'ealiser des validations basiques sur les entr\'ees, comme v\'erifier le
    type d'entr\'ees LiteralValue ou la taille maximale de fichier pour une entr\'ee
    de type ComplexValue, etc.
    \item Cr\'eer et supprimer \`a la vol\'ee des fichiers et r\'epertoires temporaires,
    comme des r\'egion et mapsets de GRASS, ou d'autres fichiers cr\'e\'es pour
    pouvoir effectuer le calcul.
    \item Lancer d'autres op\'erations utiles.
\end{itemize}

Le d\'eveloppeur n'a qu'une seule chose \`a faire : d\'efinir les entr\'ees et sorties,
ce qui est simplement un script en Python. Le process est une classe
\emph{Process}, avec une m\'ethode requise nomm\'ee \emph{execute}, dans laquelle le
calcul est effectu\'e. Les donn\'ees d'entr\'ee et de sortie sont d\'efinies d'une
mani\`ere similaire, dans une structure de dictionnaire complexe\footnote{Ceci a
\'et\'e remplac\'e par des appels de m\'ethodes \emph{Add*Input()} dans la version 
\emph{svn} actuelle}:

\begin{small}
\begin{smallverbatim}
{
    'Identifier':'maxdist',
    'Title': 'Maximal distance',
    'Abstract':'Maximal distance of visibility',
    'LiteralData': {
        'values':[ [0.,5000] ],
    },
    'dataType': type(0.0),
},
{
    'Identifier': 'dem',
    'Title': 'Digital elevation mode'
    'Abstract': 'Raster map with elevation model',
    'ComplexValueReference': {
        'Formats':["image/tiff"],
    }
},
\end{smallverbatim}
\end{small}

La m\'ethode \emph{execute()} peut ensuite utiliser par exemple directement des modules de GRASS :

\begin{small}
\begin{smallverbatim}
def execute(self):
    # importation de dem
    os.system("r.in.gdal in=%s out=dem" %\
                    (self.datainputs['dem']))
    # reglage de la region \`a partir du fichier dem
    file os.system("g.region rast=dem")
    # module de ligne de visee
    os.system("r.los input=dem output=output \
               coordinate=%s,%s max_dist=%f \
               obs_elev=%d" % \
               (self.datainputs['x'],
               self.datainputs['y'],
               self.datainputs['maxdist'],
               self.datainputs['observer']))
    # export du raster de sortie
    os.system("r.out.gdal in=output out=out.tif")
    # reglage de la valeur de retour
    self.dataoutputs['output'] = "out.tif"
    return
\end{smallverbatim}
\end{small}

Comme le code source est la meilleure documentation, environ dix exemples de
process sont distribu\'es avec le code source de PyWPS, pour que l'utilisateur
puisse avoir une id\'ee g\'en\'erale de la d\'efinition d'un process.
Il y a aussi une documentation disponible en ligne et hors ligne, qui tente de
d\'ecrire le mieux possible le processus d'installation et la mise en place de vos
propres process.

R\'ecemment, une nouvelle classe a \'et\'e d\'efinie, qui permet une d\'efinition facile
des entr\'ees et sorties de process, ainsi qu'un meilleur support pour les modules
de GRASS.
Toute interface web sera d\'esormais capable de suivre l'avancement des imports
d\'eriv\'es directement du module \texttt{r.in.gdal}. Cette am\'elioration sera
disponible dans la prochaine version de PyWPS.

\subsection{Avanc\'ees du d\'eveloppement}
La premi\`ere version ``stable'' de PyWPS avec cle num\'ero de version 1.0.0 est
sortie en Novembre 2006. Actuellement, l'\'equipe de d\'eveloppement de PyWPS
projette de sortir la version 2.0.0 prochainement, avec de nouvelles
fonctionnalit\'es et quelques corrections de bogues. L'effort g\'en\'eral de
d\'eveloppement est effectu\'e dans trois directions :

\begin{itemize}
    \item Impl\'ementation du standard OGC WPS complet,
    \item S\'ecuriser l'application au maximum afin d'\'eviter la compromission de serveur,
    \item Rendre la vie du d\'eveloppeur de process la plus simple possible.
\end{itemize}

L'\'equipe de d\'eveloppement de PyWPS voudrait \'egalement engager des discussions
avec la communaut\'e g\'eospatiale pour d\'efinir des m\'etadonn\'ees de process. Le
standard OGC WPS d\'efinit les types d'entr\'ee d'un point de vue du process, mais
n'aborde pas le sujet des types d'entr\'ee (et de sortie) d'un point de vue
utilisateur (c'est \`a dire de l'interface). Par exemple, la coordonn\'ee $x$ est de
type \emph{LiteralValue}, mais cela ne d\'efinit pas $x$ comme une coordonn\'ee. Il
serait cependant utile de d\'efinir cette entr\'ee avec un clic de souris sur une
carte, plut\^ot qu'en tapant au clavier dans un champs de texte.
Si vous voulez jeter un oeil de plus pr\`es \`a PyWPS, vous pouvez visiter la page
du projet\footnote{Page du projet PyWPS :
\url{http://pywps.wald.intevation.org}}, o\`u
le code source est disponible, ainsi que des liens vers des
projets utilisant d\'ej\`a PyWPS.

\section{Utiliser ka-Map \& PyWPS pour cr\'eer un WebSIG GRASS}
Ominiverdi\footnote{Site d'Ominiverdi : \url{http://www.ominiverdi.org}} a rejoint
le d\'eveloppement de PyWPS apr\`es la premi\`ere version. Notre premier but \'etait de
cr\'eer un client Web libre (FOSS : Free Open Source Software) pour acc\'eder aux
fonctions de GRASS. PyWPS n'\'etait pas la premi\`ere tentative de cr\'eer une
connexion entre GRASS et le Web, mais aucune autre n'\'etait bas\'ee sur des standards
ouverts, rendant impossible la cr\'eation d'une plateforme partag\'ee. D\`es le d\'epart
nous voulions travailler \`a deux diff\'erents projets : \textbf{Embrio} et \textbf{Wuiw}.

\subsection{Embrio}
Embrio est la premi\`ere impl\'ementation que nous avions \`a l'esprit : utiliser
PyWPS pour faire interagir UMN~MAPSERVER et l'API MapScript avec GRASS.

Un autre but important \'etait un client web riche, et c'est pourquoi nous avons
d\'ecid\'e de baser nos efforts sur ka-Map. Ka-Map utilise Mapscript pour acc\'eder \`a
l'ensemble de puissantes fonctionnalit\'es de UMN~Mapserver et offrir une
exp\'erience de navigation \`a la Google Maps.
La sortie de PyWPS, une fois que le Process retourne une carte, peut \^etre en
GeoTiff, pour une sortie raster, ou en GML pour une sortie vecteur. Les deux
formats sont accessibles nativements par UMN~MapServer et peuvent \^etre
facilement coupl\'es avec d'autres environnements cartographiques. Ainsi, une
requ\^ete au module \textit{Visibility} peut retourner un GeoTiff, qui est gard\'e
par ka-Map et ins\'er\'e dans le vrai syst\`eme de coordonn\'ees de la carte. Ensuite un
style, qui peut \^etre un SLD, est appliqu\'e aux valeurs du raster, et un cache
temporaire est cr\'e\'e \`a la vol\'ee pendant que les tuiles sont renvoy\'ees au client.
Le cache temporaire est li\'e au \textit{sessionId}.

Ce syst\`eme permet \`a diff\'erents modules de s'ex\'ecuter en parall\`ele et de comparer
leurs sorties en utilisant l'interface de ka-Map. Le contr\^ole de la transparence
et de la position du layer peuvent \^etre utiles pour comprendre le resultat
final. La fonction requ\^ete est \'egalement synchronis\'ee si la sortie est
requ\^etable. Le module \textit{Visibility} peut produire l'angle incident avec le
point de visibilit\'e, et la fonction de requ\^ete peut retourner la valeur de chaque pixel
cliqu\'e.\\ 

\begin{figure}[htbp]
   \centering
   %name of your graphic, without the path AND in PNG (screnshots etc)/PDF (drawings) format:
   \includegraphics[width=1\columnwidth]{integration/cepicky/embrio}
   %caption of the figure
   \caption{Copie d'\'ecran de l'interface Embrio la plus r\'ecente.} 
   %label of the figure, which has to correspond to \ref{}:
   \label{fig:label_of_your_image}
\end{figure}


\subsection{Wuiw}
Wuiw est encore aujourd'hui plus un concept qu'une r\'eelle application. Il a pour
objectif de fournir une API Javascript qui connecte le service WPS \`a des sources
de donn\'ees en OWS, et de faire un rendu de la sortie ind\'ependamment d'une
quelconque application de serveur cartographique.

Nous sommes encore en train d'\'evaluer les limites actuelles du brouillon WPS,
qui ne relient pas encore les d\'efinitions des entr\'ees avec la d\'efinition d'un
type complexe. La premi\`ere id\'ee \'etait d'utiliser des informations en m\'etadonn\'ees
pour cr\'eer ce type de relation, mais le risque existe de cr\'eer un dialecte
parall\`ele qui viendrait amoindrir les avantages de l'int\'erop\'erabilit\'e par les
standards.
Nous esp\'erons que le chemin de WPS vers une version 1.0 apportera une solution
adapt\'ee \`a cette limitation.

\section{D\'eveloppements futur}

Il est clair que WPS, PyWPS, Embrio et Wuiw ont tous une histoire courte.
M\^eme si la plupart des choses sont encore \`a faire, le d\'ebut est prometteur.
Concernant Embrio, nous pr\'evoyons d'am\'eliorer l'interaction avec les retours des
scripts de process WPS afin d'afficher une barre de progression. Beaucoup
d'autres modules de GRASS peuvent \^etre d\'evelopp\'es, et nous esp\'erons recevoir de
l'aide de la communaut\'e GRASS pour les r\'ealiser.

Un autre objectif important est d'ajouter plus d'interaction avec les
applications en ligne de commande (CLI : Command Line Interface), comme R,
GDAL/OGR, etc. pour r\'ealiser des g\'eostatistiques, des conversions de format, et
beaucoup, beaucoup d'autres fonctionnalit\'es.

Nous esp\'erons aussi ajouter une ligne de commande en AJAX pour int\'eragir avec
un syst\`eme prot\'eg\'e utilisant WPS.

\section{Licenses}

Il est important de noter que ce projet utilise beaucoup de logiciels avec au
moins deux licences diff\'erentes :

\begin{itemize}
    \item GNU/GPL: GRASS, PyWPS, R
    \item MIT/BSD: UMN MapServer, MapScript, ka-Map, Embrio 
\end{itemize}

\section{R\'ef\'erences}
\begin{itemize}
	\item OGC Web Processing Service \footnote{\url{http://www.opengeospatial.org/standards/requests/28}}
	\item Site web de PyWPS : \footnote{PyWPS Home page:
	\url{http://pywps.wald.intevation.org}}
	\item Derni\`ere d\'emonstration d'embrio: \footnote{ D\'emonstration:\\
\url{http://pywps.ominiverdi.org/demo/embrio/ka-map/htdocs/index\_wps\_qgis.html}}
	\item Site web d'Embrio\footnote{\url{http://pywps.ominiverdi.org/}}
\end{itemize}

\address{J\'achym \v{C}epick\'y\\
  \url{http://les-ejk.cz}\\
  \email{jachym AT les-ejk cz}}

\address{Lorenzo Becchi\\
  \url{http://ominiverdi.org}\\
  \email{lorenzo AT ominiverdi com}}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: main_document.tex
%%% End: 

