diff --git a/bower.json b/bower.json index 32e68382..f0eac513 100644 --- a/bower.json +++ b/bower.json @@ -19,6 +19,8 @@ "openlayers": "git@github.com:openlayers/openlayers.git#release-2.13", "extjs": "http://cdn.sencha.com/ext/gpl/ext-3.4.1.1-gpl.zip", "handlebars": "~3.0.0", - "r.js": "git@github.com:jrburke/r.js.git#2.1.18" + "r.js": "git@github.com:jrburke/r.js.git#2.1.18", + "html2canvas": "0.5.0-beta4", + "es6-promise": "~3.1.2" } } diff --git a/config/config.exempleSimple.php b/config/config.exempleSimple.php index ad4cc693..005b04a1 100644 --- a/config/config.exempleSimple.php +++ b/config/config.exempleSimple.php @@ -43,9 +43,10 @@ 'navigateur' => array( 'OutilRapporterBogue' => array('lien' => 'http://geoegl.msp.gouv.qc.ca/mantis/login_page.php'), 'OutilAjoutWMS' => array('urlPreenregistre' => "http://geoegl.msp.gouv.qc.ca/cgi-wms/inspq_icu.fcgi," - . "http://geoegl.msp.gouv.qc.ca/cgi-wms/gouvouvertqc.fcgi"), + . "http://geoegl.msp.gouv.qc.ca/cgi-wms/igo_gouvouvert.fcgi"), 'OutilZoomPreselection' => array('service' => '[zoomPreSelection]'), // [] -> Fait référence à servicesExternes->zoomPreSelection 'OutilAide' => array ('lien' => "guides/guide.pdf"), + 'PanneauInfo' => array('urlServiceElevation' => 'http://geogratis.gc.ca/services/elevation/cdsm/altitude'), 'WMS' => array( 'infoFormat' => "application/vnd.ogc.gml" ) @@ -56,7 +57,8 @@ //Les urls externes utilisés dans l'application doivent correspondre à un regex pour être permis 'regex' => array( "#".preg_quote("http://geoegl.msp.gouv.qc.ca/cgi-wms/inspq_icu.fcgi")."#", - "#".preg_quote("http://geoegl.msp.gouv.qc.ca/cgi-wms/gouvouvertqc.fcgi")."#" + "#".preg_quote("http://geoegl.msp.gouv.qc.ca/cgi-wms/igo_gouvouvert.fcgi")."#" + "#".preg_quote("http://geogratis.gc.ca/services/elevation/cdsm/altitude")."#" ) ), // les configurations permettent d'appeler un fichier xml en mode rest et d'associer une clé avec un lien vers un fichier diff --git a/doc/xml/DocumentationXML.markdown b/doc/xml/DocumentationXML.markdown index 086e8d05..ea906dc6 100644 --- a/doc/xml/DocumentationXML.markdown +++ b/doc/xml/DocumentationXML.markdown @@ -254,13 +254,15 @@ l'échelle et la projection de la carte. |Nom |Description |Obligatoire |Valeurs possibles|Valeur défaut| |---------------|-----------------------|---------------|-----------------|-------------| -|id | | | |*info-panneau*| -|titre | | | |*Informations additionnelles*| -|position | | | |*sud*| -|dimension |Hauteur du panneau. | | |*75*| -|minDimension |Hauteur minimale du panneau.| | |*75*| -|maxDimension |Hauteur maximale du panneau.| | |*400*| -|ouvert | | | |*false*| +|id | |Non| |*info-panneau*| +|titre | |Non| |*Informations additionnelles*| +|position | |Non| |*sud*| +|dimension |Hauteur du panneau. |Non| |*75*| +|minDimension |Hauteur minimale du panneau.|Non| |*75*| +|maxDimension |Hauteur maximale du panneau.|Non| |*400*| +|ouvert | |Non| |*false*| +|projection |Afficher dans la liste les projections comme code EPSG ou leurs nom commun|Non|code, nom|*code*| +|elevation |Afficher l'altitude à une position dans la carte. (Ajout dans le config.php est nécessaire pour identifié le service api d'élévation)|Non|Booléen |*false*| *Exemples* @@ -268,7 +270,7 @@ l'échelle et la projection de la carte. + ouvert="false" projection="nom" elevation="true" /> ``` @@ -401,12 +403,15 @@ couches disponibles à l’affichage sur la carte. |Nom |Description |Obligatoire |Valeurs possibles|Valeur défaut| |---------------|-----------------------|---------------|-----------------|-------------| -|idResultatTable|Identifiant du PanneauTable ou du PanneauOnglet. Ce panneau sera utilisé pour afficher les occurences.|Non|Chaîne alphanumérique|| +|idResultatTable|Identifiant du PanneauTable ou du PanneauOnglet. Ce panneau sera utilisé pour afficher les occurences.|Non|Chaîne alphanumérique| | +|retirerCheckboxPremNiveau| Permet de retirer les checkbox de premier niveau dans l'arborescence | non | true | false | +|identifierSousSelection| Permet de griser les répertoires parents lorsqu'une couche est sélectionnée | non | true| false +|identifierGetInfo| Permet d'ajout l'icône du getInfo à gauche de la couche lorsque celle-ci est cochée et qu'elle contient un getInfo | Non | true | false | *Exemple* ```xml - + ``` *Aperçu* @@ -826,7 +831,7 @@ OutilZoomPreselection et OutilZoomRectangle*. |id |Identifiant de l'outil. Est utilisé pour accéder à celui-ci. Doit être unique.|Non|Chaîne alphanumérique|*outil*| |classe |Nom de la classe qui implémente l'outil. |Non |Les classes prédéfinies sont : *OutilAide*, *OutilAjoutWMS*, *OutilAnalyseSpatiale*, *OutilDeplacement*, *OutilDessin*, *OutilHistoriqueNavigation*, *OutilInfo*, *OutilMesure*, *OutilDeplacerCentre*, *OutilPartagerCarte*, *OutilReporterBug*, *OutilZoomEtendueMaximale*, *OutilZoomPreselection*, *OutilZoomRectangle* ou Classe personnalisée (voir attribut urlModule)|*Outil*| |urlModule|Url du fichier Javascript contenant la classe définissant un panneau personnalisé.|Seulement pour les panneaux personnalisés|URL|| -|icone|Icône de l'outil. Est affiché sur le bouton dans la barre d'outils.|Non|URL ou Classe CSS prédéfinie : *aide*, *apropos*, *back*, *bug*, *deletefeature*, *drawpoint*, *drawline*, *drawpolygon*, *gentillyboom*, *getinfo*, *measrCircle*, *measrlinear*, *measrpolgn*, *modifyfeature*, *moveto*, *next*, *pan*, *print*, *zoomfull*, *zoomin*, *zoomout*, *zoom-hydro*, *zoom-mrc*, *zoom-mun*, *zoom-reg-adm*|titre|Titre de l'outil. Est affiché à droite du bouton dans la barre d'outils.|Non|Chaîne alphanumérique|| +|icone|Icône de l'outil. Est affiché sur le bouton dans la barre d'outils.|Non|URL ou Classe CSS prédéfinie : *aide*, *apropos*, *back*, *bug*, *deletefeature*, *drawpoint*, *drawline*, *drawpolygon*, *getinfo*, *measrCircle*, *measrlinear*, *measrpolgn*, *modifyfeature*, *moveto*, *next*, *pan*, *print*, *zoomfull*, *zoomin*, *zoomout*, *zoom-hydro*, *zoom-mrc*, *zoom-mun*, *zoom-reg-adm*|titre|Titre de l'outil. Est affiché à droite du bouton dans la barre d'outils.|Non|Chaîne alphanumérique|| |infobulle|Infobulle de l'outil. Est affiché lorsque le curseur de la souris est placée sur le bouton dans la barre d'outils.|Non|Chaîne alphanumérique|| |visible|Indique si le bouton est visible ou non dans la barre d'outils lors de l'affichage initial du navigateur.|Non|Booléen|*true*| |actif|Indique si le bouton est actif ou non (grisé) dans la barre d'outils lors de l'affichage initial du navigateur.|Non|Booléen|*true*| @@ -994,6 +999,18 @@ infobulle="Dessin/Annotations" visible="true" actif="true"/> ![](media/image21.png) + +outilExportCSV +----------- + + +Permet d'exporter les données d'un panneauTable en fichier csv. Inclus dans le panneauTable. + +*Attributs ou valeurs spécifiques* + +Aucune + + outilExportGPX ----------- @@ -1305,6 +1322,11 @@ partir d'une liste. |type |Type de l'outil. Sert à déterminer le type de région à afficher dans la liste.|Oui|*region-adm / mrc / mun / hydro*|| |icone | | | |*zoom-reg-adm (si type = region-adm)*, *zoom-mrc (si type = mrc)*, *zoom-mun (si type = mun)*, *zoom-hydro (si type = hydro)*| |titre | | | |*Par région administrative (si type = region-adm)*, *Par MRC (si type = mrc)*, *Par municipalité (si type = mun)*, *Par hydrographie (si type = hydro)*| +|etiquette| attribut à utiliser pour afficher dans l'étiquette |Non| string |res_nm_reg mrs_nm_reg mus_nm_mun | +|texteForm| Texte à afficher dans le formulaire| Non | string | | +|fieldLabel | Titre du combobox à afficher | Non | String | | +|requestParametre| Nom du service d'obtention des données | Non | string | +|service | url du service | Non | String| | *Exemple*s ```xml @@ -1315,6 +1337,19 @@ municipalité" infobulle="Zoom municipalité" visible="true" actif="true"/> ``` +```xml + + +``` +*Personnalisé: +```xml + +``` + *Aperçu* ![](media/image29.png) @@ -1474,7 +1509,8 @@ Marqueurs, OSM, TMS, Vecteur, WMS*. |ordreAffichage| Ordre d'affichage de la couche | Non | Nombre entier | *Valeurs par défaut d’OpenLayers*| |droit | Indique les droits de la couche (Copyrights) | Non | Chaîne alphanumérique | | |metadonnee| Lien vers les métadonnées | Non | URL | | -|ordreArborescence| Ordre d'affichage de la couche dans le groupe de l'arborescence (1 étant le haut du groupe)| Non| Nombre entier|| +|ordreArborescence| Ordre d'affichage de la couche dans le groupe de l'arborescence (1 étant le haut du groupe)| Non| Nombre entier| +|estInterrogeable|Indique si le getInfo doit être fait sur cette couche | Non | Booléen | true | blanc ----- @@ -1642,7 +1678,8 @@ Permet la définition d'une couche provenant d’un service de carte (WMS). |infoEncodage | Indique l'encodage voulu dans la fenêtre de résultats pour l' *OutilInfo* sur la couche | Non| Chaîne alphanumérique| *UTF-8*| |infoGabarit | Indique l'emplacement du script [Handlebars](https://github.com/wycats/handlebars.js#differences-between-handlebarsjs-and-mustache) avec l'extension *.html* qui sera apliqué dans la fenêtre de résultats sur l' *OutilInfo* après le clique sur la couche dans la carte ([exemple](https://github.com/bosthy/igo/blob/dev/interfaces/navigateur/public/template/handlebars.exemple.html),[ exemple simple](https://github.com/bosthy/igo/blob/dev/interfaces/navigateur/public/template/handlebars.exempleSimple.html)) | Non| URL| |infoUrl | Indique un url qui sera remplacer par l'url GetFeaturInfo de l' *OutilInfo* | Non| URL| | -|infoAction | Indique l'emplacement du script qui reçevra le résultats json du GetFeatureInfo de l' *OutilInfo* après le clique sur la couche dans la carte l'affichage sera géré par le script| Non| URL| | +|infoAction | Indique l'emplacement du script qui reçevra le résultats json du GetFeatureInfo de l' *OutilInfo* après le clique sur la couche dans la carte l'affichage sera géré par le script| Non| URL| | +|afficherMessageErreurUtilisateur| Permettre d'afficher un message générique à l'utilisateur quand la couche est en erreur. | Non | "True" | | *Exemples* ```xml diff --git a/doc/xml/media/image4.png b/doc/xml/media/image4.png index 3c286a8f..ace57048 100644 Binary files a/doc/xml/media/image4.png and b/doc/xml/media/image4.png differ diff --git a/interfaces/navigateur/api/index.php b/interfaces/navigateur/api/index.php index a19bd76e..16f38cd2 100644 --- a/interfaces/navigateur/api/index.php +++ b/interfaces/navigateur/api/index.php @@ -14,10 +14,16 @@ $di->get('chargeurModules')->chargerApis($app); /** - * + * * @param string $configuration */ - $app->get('/configuration/{configuration}', function($configuration) use($di, $app) { + $app->get('/configuration/{configuration}', 'configuration'); + + + function configuration($configuration){ + + global $di; + global $app; $config = $di->getConfig(); $debug = $config->application->debug; @@ -37,7 +43,7 @@ } if(!file_exists ($xmlPath) && !curl_url_exists($xmlPath)){ - return envoyerResponse(404, "Not Found", "La configuration '{$configuration}' n'existe pas!"); + return envoyerResponse(404, "Not Found", "La configuration '{$configuration}' n'existe pas!"); } if($encoding === "json"){ @@ -63,18 +69,18 @@ $avertissements = array(); foreach($result as $couche){ $coucheId = $couche->attributes()->idbd->__toString(); - - $igoVueCouche = is_numeric($coucheId) - ? IgoVueCouche::findFirst("id={$coucheId}") - : IgoVueCouche::findFirst("mf_layer_name='{$coucheId}'"); - + + $igoVueCouche = is_numeric($coucheId) + ? IgoVueCouche::findFirst("id={$coucheId}") + : IgoVueCouche::findFirst("mf_layer_name='{$coucheId}'"); + if(!$igoVueCouche){ - - $avertissements[] = is_numeric($coucheId) + + $avertissements[] = is_numeric($coucheId) ? "La couche avec id : '{$coucheId}' n'existe pas!" : "La couche avec mf_layer_name : '{$coucheId}' n'existe pas!"; - + $dom = dom_import_simplexml($couche); $dom->parentNode->removeChild($dom); continue; @@ -94,7 +100,7 @@ $config->mapserver['couchesCacheDir'] . $igoVueCouche->mf_layer_name . '.map'; $protocole = 'WMS'; - + //Ne pas exposer la connexion unset($igoVueCouche->connexion); }else{ @@ -115,22 +121,22 @@ if(!$couche->attributes()->$key){ $couche->addAttribute($key, $value); } - } + } }else{ if ($debug){ $avertissements[] = "Vous n'avez pas les droits sur la couche {$igoVueCouche->mf_layer_meta_title} (id : {$igoVueCouche->id})"; - } + } $dom = dom_import_simplexml($couche); - $dom->parentNode->removeChild($dom); + $dom->parentNode->removeChild($dom); } } - + if(count($avertissements)){ foreach($avertissements as $value){ $element->addChild('avertissements', $value); } } - + $variableXml = array(); if(isset($config->variableXml)){ $variableXml = $config->variableXml; @@ -138,34 +144,55 @@ $json = json_encode($element); $json = preg_replace_callback( - "/\"{{(\w+?)}}\"/", + "/\"{{(\w+?)}}\"/", function($m) use ($variableXml) { if(!isset($variableXml[$m[1]])){ return ""; } - return json_encode($variableXml[$m[1]]); + return json_encode($variableXml[$m[1]]); }, $json ); $json = preg_replace_callback( - "/{{(\w+?)}}/", + "/{{(\w+?)}}/", function($m) use ($variableXml) { if(!isset($variableXml[$m[1]])){ return ""; } - return json_encode($variableXml[$m[1]]); + return json_encode($variableXml[$m[1]]); }, $json ); - echo $json; - + echo $json; + }else{ return envoyerResponse(404, "Not Found", "L'élément racine du fichier de configuration doit se nommer 'navigateur' !"); - } - }else{ + } + }else{ return envoyerResponse(404, "Not Found", "L'encodage '{$encoding}' n'est pas supporté!"); } - }); + }; + + $app->map('/proxy/html2canvas',"redirigerRequetesHtml2Canvas")->via(array('GET','OPTIONS')); + + function redirigerRequetesHtml2Canvas() { + global $app; + + if(!utilisateurActuelEstAuthentifie()) { + return envoyerResponse(401, "", "Non-Autorisees"); + } + + $cheminServices = '../../../services'; + $cheminProxy = $cheminServices . '/proxy/html2canvasproxy.php'; + + if(file_exists($cheminProxy)) { + ob_end_clean(); + ob_start(); + include $cheminProxy; + $contenu = ob_get_contents(); + die($contenu); + } + }; /** * @@ -176,7 +203,7 @@ function obtenirContexte($contexteId){ global $app; $igoContexte = IgoContexte::findFirst("id={$contexteId}"); if(!$igoContexte){ - return envoyerResponse(404, "Not Found", "Le contexte '{$contexteId}' n'existe pas!"); + return envoyerResponse(404, "Not Found", "Le contexte '{$contexteId}' n'existe pas!"); } return $igoContexte; } @@ -190,11 +217,11 @@ function obtenirContexteParCode($contexteCode){ global $app; $igoContexte = IgoContexte::findFirst("code='{$contexteCode}'"); if(!$igoContexte){ - return envoyerResponse(404, "Not Found", "Le contexte '{$contexteCode}' n'existe pas!"); + return envoyerResponse(404, "Not Found", "Le contexte '{$contexteCode}' n'existe pas!"); } return $igoContexte; } - + /** * * @return ??? @@ -218,7 +245,7 @@ function envoyerResponse($statusCode, $titre, $msgErreur){ $app->response->setContentType('application/json', 'UTF-8'); $app->response->setContent(json_encode($error)); - return $app->response->send(); + return $app->response->send(); } /** @@ -229,7 +256,7 @@ function obtenirAuthentificationModule(){ global $app; // Construire un tableau associatif de permissions avec le id de la couche ou groupe de couche comme clef. $authentificationModule = $app->getDI()->get("authentificationModule"); - + if($authentificationModule == null){ return null; } @@ -238,7 +265,7 @@ function obtenirAuthentificationModule(){ return envoyerResponse(401, "Unauthorized", "Vous n'êtes pas authentifié!"); } return $authentificationModule; - } + } /** * Indique si l'utilisateur courant est authentifié @@ -252,7 +279,7 @@ function utilisateurActuelEstAuthentifie(){ return false; } return $session->get("info_utilisateur")->estAuthentifie; - } + } /** * Indique si l'utilisateur courant est anonyme @@ -299,13 +326,13 @@ function obtenirUtilisateurProfilsInQuery() { $profiLActif = utilisateurActuelProfilActif(); $profils = utilisateurActuelProfils(); - if(!is_null($profiLActif)) { + if(!is_null($profiLActif)) { $nomProfilAnonyme = $app->session->get('nomProfilAnonyme'); if($nomProfilAnonyme === null){ $config = $app->getDI()->get("config"); if(isset($config->application->authentification)){ - $nomProfilAnonyme = $config->application->authentification->nomProfilAnonyme; - } + $nomProfilAnonyme = $config->application->authentification->profilAnonyme->nom; + } } if(isset($nomProfilAnonyme)){ @@ -315,8 +342,8 @@ function obtenirUtilisateurProfilsInQuery() { if(isset($tAP[0]) && isset($tAP[0]['id'])){ $anonymeId = $tAP[0]['id']; if($anonymeId !== $profiLActif){ - return (string) '0,' . $anonymeId . ',' . $profiLActif; - } + return (string) '0,' . $anonymeId . ',' . $profiLActif; + } } } } @@ -332,19 +359,19 @@ function obtenirUtilisateurProfilsInQuery() { return (string) '0'; } - + /** * * @return */ function obtenirPermission($couche_id){ global $app; - + if(is_null($app->getDI()->getConfig()->database)) { return null; } - - $conditions = "profil_id in (" . obtenirUtilisateurProfilsInQuery() . ") AND (couche_id = ?1)"; + + $conditions = "profil_id in (" . obtenirUtilisateurProfilsInQuery() . ") AND (couche_id = ?1)"; $parameters = array(1 => $couche_id); $permission = IgoVuePermissionsPourCouches::findFirst(array( $conditions, @@ -355,13 +382,13 @@ function obtenirPermission($couche_id){ return $permission; } - + /** * * @param string $coucheId * @return */ - function obtenirGroupeCouche($coucheId){ + function obtenirGroupeCouche($coucheId){ $igoGroupeCouches = IgoGroupeCouche::find("couche_id={$coucheId}"); $in = array(); @@ -369,15 +396,21 @@ function obtenirGroupeCouche($coucheId){ $in[] = $igoGroupeCouche->groupe_id; } return implode(',', $in); - } - + } + /** * * @param int $coucheId * @return */ - $app->get('/couche/{coucheId}', function($coucheId) use($di, $app){ - + $app->get('/couche/{coucheId}', 'couche'); + + + function couche ($coucheId){ + + global $di; + global $app; + $config = $di->getConfig(); $authentificationModule = obtenirAuthentificationModule(); $arrayCoucheId = explode(",", $coucheId); @@ -399,20 +432,20 @@ function obtenirGroupeCouche($coucheId){ if($couche->connexion_type == 'POSTGIS' || $couche->connexion_type == null){ - $couche->mf_map_meta_onlineresource = + $couche->mf_map_meta_onlineresource = $config->mapserver['host']. $config->mapserver['mapserver_path'] . $config->mapserver['executable']. $config->mapserver['mapfileCacheDir'] . $config->mapserver['couchesCacheDir'] . $couche->mf_layer_name . '.map'; - $couche->protocole = 'WMS'; - + $couche->protocole = 'WMS'; + //Ne pas exposer la connexion unset($couche->connexion); - + }else{ - + $couche->mf_map_meta_onlineresource = $couche->connexion; $couche->protocole = $couche->connexion_type; $couche->nom = $couche->mf_layer_name; @@ -431,7 +464,7 @@ function obtenirGroupeCouche($coucheId){ } } - + if(count($avertissements)){ $reponse = array('couches'=>$couches, 'avertissements'=>$avertissements); }else{ @@ -440,77 +473,40 @@ function obtenirGroupeCouche($coucheId){ $app->response->setContentType('application/json; charset=UTF-8')->sendHeaders(); echo json_encode($reponse); - }); - + }; + /** * * @param ??? $contexteCode */ - $app->get('/contexteCode/{contexteCode}', function($contexteCode) use($app, $di){ + $app->get('/contexteCode/{contexteCode}', 'contexteCode'); + + function contexteCode($contexteCode){ + + global $app; + global $di; + $contexte = obtenirContexteParCode($contexteCode); obtenirInfoContexte($contexte, $app, $di); - }); + }; /** * * @param int $contexteId */ - $app->get('/contexte/{contexteId:[0-9]+}', function($contexteId) use($app, $di){ - $contexte = obtenirContexte($contexteId); - obtenirInfoContexte($contexte, $app, $di); - }); + $app->get('/contexte/{contexteId:[0-9]+}', 'contexte'); + function contexte($contexteId) { - /** - * Obtenir Chaine de connexion au site securise - * @param ??? $service - * @param ??? $restService - * @return ??? $auth - */ - - function obtenirChaineConnexion($service, $restService){ + global $di; global $app; - //Services - $igoController = new IgoController(); - $permisUrl = $igoController->obtenirPermisUrl($service, $restService); - - if($permisUrl === false){ - http_response_code(403); - die("Vous n'avez pas les droits pour ce service."); - } - - //Decrypter la chaine de connexion - if (!empty($permisUrl['connexion']) || !empty($permisUrl['user'])) { - $auth = array(); - if(!empty($permisUrl['user'])) { - $auth['user'] = $permisUrl['user']; - } - if(!empty($permisUrl['pass'])) { - $auth['pass'] = $permisUrl['pass']; - } - if(!empty($permisUrl['methode'])) { - $auth['method'] = $permisUrl['methode']; - } + $contexte = obtenirContexte($contexteId); + obtenirInfoContexte($contexte, $app, $di); + }; + + - if(!empty($permisUrl['connexion'])){ - $crypt = $app->getDI()->get("crypt"); - $chaine = explode(",", $crypt->decryptBase64(urldecode($permisUrl['connexion']))); - $auth['user'] = ltrim(trim($chaine[0]), " user:"); - $auth['pass'] = ltrim(trim($chaine[1]), " pass:"); - if (empty($auth['pass'])) { - header('Content-Type: text/html; charset=utf-8'); - http_response_code(401); - die("Votre clé n'est pas décryptée correctement."); - } - } - - } - - $auth['url'] = $permisUrl['url']; - return $auth; - } - /** @@ -531,12 +527,12 @@ function obtenirInfoContexte($contexte, $app, $di){ } else { $order = "layer_a_order, mf_layer_meta_group_title, mf_layer_meta_title"; } - + $contexteId = $contexte->id; $contexteCouches = IgoVueContexteCoucheNavigateur::find(array( - "conditions"=>"contexte_id=$contexteId", + "conditions"=>"contexte_id=$contexteId", "order"=>$order - )); + )); $authentificationModule = obtenirAuthentificationModule(); $array = array(); @@ -583,7 +579,7 @@ function obtenirInfoContexte($contexte, $app, $di){ if($test==1&&isset($matches[1]))$couche->wms_timeextent = $matches[1]; } }else{ - if ($debug){ + if ($debug){ $avertissements[] = "Vous n'avez pas les droits sur la couche '{$couche->mf_layer_meta_title}' (id : {$couche->couche_id})"; } } @@ -591,9 +587,9 @@ function obtenirInfoContexte($contexte, $app, $di){ } $contexte->couches = $array; - + if(count($avertissements)){ - $contexte->avertissements = array('avertissements'=>$avertissements); + $contexte->avertissements = array('avertissements'=>$avertissements); } $app->response->setContentType('application/json; charset=UTF-8')->sendHeaders(); @@ -622,7 +618,7 @@ function wms_proxy($contexteId){ $data = array(); foreach($datain as $key => $value){ $data[strtoupper($key)] = $value; - } + } $service = $filter->sanitize($data["SERVICE"], array("string", "upper")); $request = $filter->sanitize($data["REQUEST"], array("string", "upper")); }else{ @@ -630,7 +626,7 @@ function wms_proxy($contexteId){ error_log("not a get or a post?"); return; } - + if($service === "WMS"){ $config = $app->getDI()->get("config"); @@ -642,7 +638,7 @@ function wms_proxy($contexteId){ $method = $httprequest->getMethod(); $data = $httprequest->get(); - $data["MAP"] = $igoContexte->getMapfilePath(); + $data["MAP"] = $igoContexte->getMapfilePath(); $response = null; switch($request){ case "GETCAPABILITIES": @@ -655,7 +651,7 @@ function wms_proxy($contexteId){ case "GETLEGENDGRAPHIC": $authentificationModule = obtenirAuthentificationModule(); if($authentificationModule === null){ - $response = proxy_request($mapserverPath, $data , $method); + $response = proxy_request($mapserverPath, $data , $method); }else{ if(isset($data["LAYERS"])){ $couches = explode(",", $data["LAYERS"]); @@ -686,7 +682,7 @@ function wms_proxy($contexteId){ die("Forbidden"); } } - $response = proxy_request($mapserverPath, $data , $method); + $response = proxy_request($mapserverPath, $data , $method); } break; default: @@ -703,7 +699,7 @@ function wms_proxy($contexteId){ die("Seul les services WMS sont pris en charge par ce proxy."); } } - + /** * * @param string @@ -761,7 +757,7 @@ function proxy_request($url, $data, $method) { // receive the results of the request $result .= fgets($fp, 128); } - }else{ + }else{ return array( 'status' => 'err', 'error' => "$errstr ($errno)" @@ -786,7 +782,7 @@ function proxy_request($url, $data, $method) { } $app->map('/service[/]?{service}',"proxyNavigateur")->via(array('GET','POST')); - + /** * * @param @@ -805,7 +801,7 @@ function ObtenirAdresseIP($serveur){ $ip = $tabIPs[0]; return $ip; } - + /** * * @return @@ -830,7 +826,7 @@ function proxyNavigateur($service) { if($files!=null) { $options['files'] = $files; } - + $restService = true; if($service == null){ $restService = false; @@ -842,7 +838,7 @@ function proxyNavigateur($service) { unset($paramsGet['_url']); unset($paramsPost['_client_IP']); unset($paramsGet['_client_IP']); - + //Session $session = $app->getDI()->getSession(); if(!$session->has("info_utilisateur")){ @@ -850,15 +846,15 @@ function proxyNavigateur($service) { http_response_code(401); die("Vous devez être connecté pour utiliser ce service"); } - - $auth = obtenirChaineConnexion ($service, $restService); - $url = $auth['url']; + + $igoController = new IgoController(); + $auth = $igoController->obtenirChaineConnexion($service, $restService); $authtmp['auth'] = $auth; $options = array_merge($options, $authtmp); - + $url = $options['auth']['url']; - + if(isset($url) && is_string($url) && $url !== ""){ if(substr($url, 0, 1) === "/"){ $url = "http://localhost".$url; @@ -952,8 +948,8 @@ function proxyNavigateur($service) { $url = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '=', $url); } proxyRequestNavigateur($url, $paramsPost, $method, $options); - }; - + }; + /** * * @param string $url @@ -962,17 +958,18 @@ function proxyNavigateur($service) { * @param * @return */ - function proxyRequestNavigateur($url, $data, $method, $options) { + function proxyRequestNavigateur($url, $data, $method, $options) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); - if(isset($GLOBALS['HTTP_RAW_POST_DATA'])){ + $rawData = file_get_contents('php://input'); + if(isset($rawData)){ curl_setopt($ch, CURLOPT_POST, 1 ); - curl_setopt($ch, CURLOPT_POSTFIELDS, $GLOBALS['HTTP_RAW_POST_DATA'] ); + curl_setopt($ch, CURLOPT_POSTFIELDS, $rawData ); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/plain')); } else if ($method === 'POST') { if(isset($options['files'])){ @@ -1004,95 +1001,31 @@ function proxyRequestNavigateur($url, $data, $method, $options) { curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); - curl_setopt($ch, CURLOPT_POSTFIELDS, $GLOBALS['HTTP_RAW_POST_DATA']); + curl_setopt($ch, CURLOPT_POSTFIELDS, $rawData); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:' . $_SERVER['CONTENT_TYPE'], 'SOAPAction:' . $_SERVER['HTTP_SOAPACTION'])); } - if (!empty($options['auth'])) { - $auth = $options['auth']; - if (isset($auth['method']) && isset($auth['user']) && isset($auth['pass'])) { - //On obtient le payload (objectif chercher dans le payload les url securisees) - $postdata = file_get_contents ("php://input"); - - //Seul le post xml de zoo est modifié - if (!empty ($postdata) && strpos ($postdata, 'wps:Execute') !== false) { - $doc = new DOMDocument(); - $doc->loadXML ($postdata); - $domList = $doc->getElementsByTagNameNS ('*', '*'); - //on navigue dans tout le payload - for ($i = 0; $i < $domList->length; $i++) { - if ($domList->item ($i)->tagName === 'wps:Reference') { - $xmlurl = $domList->item ($i)->getAttribute ('xlink:href'); - $partsxml = parse_url ($xmlurl); - //les credentials a ajouter dans le xml on verifié s il y en as - if (isset ($xmlurl) && $partsxml['scheme'] === 'https') { - if ($xmlurl !== $url ) { - //les credentials des urls qu on as pas - $authxml = obtenirChaineConnexion ($partsxml['scheme'] . '://' . $partsxml['host'] . $partsxml['path'], $restService=false); - if (isset ($authxml['user']) && isset ($authxml['pass'])) { - $urlxml = $partsxml['scheme'] . '://' . $authxml['user'] . ':' . $authxml['pass'] . '@' . $partsxml['host'] . $partsxml['path'] . '?' . $partsxml['query']; - } - $xmlpost = str_replace ($xmlurl, $urlxml, $postdata); - $postdata = $xmlpost; - } - //les credentials de zoo on possede deja dans le xml est modifié - if ($xmlurl === $url) { - $urlxml = $partsxml['scheme'] . '://' . $auth['user'] . ':' . $auth['pass'] . '@' . $partsxml['host'] . $partsxml['path']; - $xmlpost = str_replace ($xmlurl, $urlxml, $postdata); - $postdata = $xmlpost; - } - } - } - } - - curl_setopt ($ch, CURLOPT_POST, 1); - curl_setopt ($ch, CURLOPT_POSTFIELDS, $postdata); - - } - - //Necessaire pour le SSL sinon on voit pas les couches dans - //la list des couche disponible analyse spatial - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); - - - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); - - switch ($auth['method']) { - case "BASIC": - curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); - break; - case "NTLM": - curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM); - break; - case "GSSNEGOTIATE": - curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_GSSNEGOTIATE); - break; - case "DIGEST": - curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); - break; - default: - curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - break; - } - curl_setopt($ch, CURLOPT_USERPWD, $auth['user'] . ':' . $auth['pass']); - } + if(isset($_COOKIE['sessionIGO']) && $_SERVER['HTTP_HOST'] === parse_url($url)['host']) { + $strCookie = "sessionIGO=" . $_COOKIE['sessionIGO']; + session_write_close(); + curl_setopt( $ch, CURLOPT_COOKIE, $strCookie ); } + $igoController = new IgoController(); + $ch = $igoController->proxyChaineConnexion($ch, $url, $method, $options); + $result = curl_exec ($ch); $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); $http_status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); - + curl_close ($ch); $contentsTypesAVerifier = array( - "application/xml", - "application/vnd.ogc.wms_xml", - "application/vnd.ogc.gml", + "application/xml", + "application/vnd.ogc.wms_xml", + "application/vnd.ogc.gml", "text/xml; subtype=gml/3.1.1" ); @@ -1105,7 +1038,7 @@ function proxyRequestNavigateur($url, $data, $method, $options) { } if(isset($options['encodage'])){ - $contentType = $contentType . "; charset=" . $options['encodage']; + $contentType = $contentType . "; charset=" . $options['encodage']; } header('Content-type: ' . $contentType); diff --git a/interfaces/navigateur/app/controllers/IgoController.php b/interfaces/navigateur/app/controllers/IgoController.php index ae35e3f8..73ee4fb1 100644 --- a/interfaces/navigateur/app/controllers/IgoController.php +++ b/interfaces/navigateur/app/controllers/IgoController.php @@ -9,15 +9,15 @@ public function indexAction() { public function configurationAction($configuration) { $this->definirVariablesCommunes(); - $this->traiterXml($configuration); + $this->traiterXml($configuration); } public function contexteAction($code) { $this->definirVariablesCommunes(); $this->traiterXml('defaut'); - + if(!is_numeric($code)){ - $type = "code"; + $type = "code"; $contexte = IgoContexte::findFirst("$type='$code'"); } else { $type = "id"; @@ -33,17 +33,17 @@ public function contexteAction($code) { } } - public function coucheAction($id) { + public function coucheAction($id) { $this->definirVariablesCommunes(); $this->traiterXml('defaut'); - + $filterArray = function ($value){ if(is_numeric($value)){ return $value; } }; - - $arrayCoucheId = array_filter(explode(",",$id), $filterArray); + + $arrayCoucheId = array_filter(explode(",",$id), $filterArray); $couches = array(); foreach ($arrayCoucheId as $key => $value) { @@ -64,7 +64,7 @@ public function coucheAction($id) { } $this->ajouterModules(); } - + public function groupeAction($id) { $this->definirVariablesCommunes(); $this->traiterXml('defaut'); @@ -74,9 +74,9 @@ public function groupeAction($id) { return $value; } }; - - $arrayGroupeCoucheId = array_filter(explode(",",$id), $filterArray); - + + $arrayGroupeCoucheId = array_filter(explode(",",$id), $filterArray); + $couches = array(); foreach ($arrayGroupeCoucheId as $key => $value) { $couche = IgoGroupeCouche::find("groupe_id=$value"); @@ -106,8 +106,9 @@ public function groupeAction($id) { } $this->ajouterModules(); } - + private function traiterXml($nomXml){ + if(isset($this->getDi()->getConfig()->configurations[$nomXml])){ $xmlPath = $this->getDi()->getConfig()->configurations[$nomXml]; } else { @@ -116,10 +117,10 @@ private function traiterXml($nomXml){ if(file_exists($xmlPath)){ $externe = false; - $element = simplexml_load_file($xmlPath); + $element = simplexml_load_file($xmlPath); } else { //url externe $externe = true; - $element = simplexml_load_string(curl_file_get_contents($xmlPath)); + $element = simplexml_load_string(curl_file_get_contents($xmlPath)); } $elAttributes = $element->attributes(); if(isset($_GET['mode'])){ @@ -139,41 +140,41 @@ private function traiterXml($nomXml){ curl_setopt($curl, CURLOPT_NOBODY, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_FILETIME, true); - curl_exec($curl); + curl_exec($curl); $timestamp = curl_getinfo($curl, CURLINFO_FILETIME); $filemtime = $timestamp; } $this->view->setVar("configuration", $nomXml . "?v={$filemtime}"); - + $contexteArrayId = array(); $contexteArrayCode = array(); $this->view->setVar("couche", "null"); - + if(isset($element->contexte)){ $contexte = null; for($i = 0; $i < count($element->contexte); $i++) { if(isset($element->contexte[$i]->attributes()->id)) { $contexteId = $element->contexte[$i]->attributes()->id; - $contexte = IgoContexte::findFirst("id=$contexteId"); + $contexte = IgoContexte::findFirst("id=$contexteId"); if($contexte){ - $contexteArrayId[] = $element->contexte[$i]->attributes()->id . "?v=" . md5($contexte->date_modif); + $contexteArrayId[] = $element->contexte[$i]->attributes()->id . "?v=" . md5($contexte->date_modif); }else{ $this->view->setVar("avertissement", "Le contexte avec le id:$contexteId n'existe pas"); } } else if (isset($element->contexte[$i]->attributes()->code)) { $contexteCode = $element->contexte[$i]->attributes()->code; - $contexte = IgoContexte::findFirst("code='$contexteCode'"); + $contexte = IgoContexte::findFirst("code='$contexteCode'"); if($contexte){ - $contexteArrayCode[] = $element->contexte[$i]->attributes()->code . "?v=" . md5($contexte->date_modif); + $contexteArrayCode[] = $element->contexte[$i]->attributes()->code . "?v=" . md5($contexte->date_modif); }else{ $this->view->setVar("avertissement", "Le contexte '$contexteCode' n'existe pas"); } - } + } } } $this->view->setVar("contexteCode", $contexteArrayCode); $this->view->setVar("contexteId", $contexteArrayId); - + if(isset($elAttributes->aliasUri)){ $this->config->uri->librairies = $elAttributes->aliasUri . 'librairie/'; $this->config->uri->services = $elAttributes->aliasUri . 'services/'; @@ -183,6 +184,7 @@ private function traiterXml($nomXml){ $this->config->uri->navigateur = $elAttributes->aliasUri . 'public/'; $this->config->application->baseUri = $this->config->uri->navigateur; } else if(isset($elAttributes->baseUri)){ + if(isset($elAttributes->libUri)){ $this->config->uri->librairies = $elAttributes->baseUri . $elAttributes->libUri; } @@ -193,11 +195,12 @@ private function traiterXml($nomXml){ $this->config->uri->api = $elAttributes->baseUri . $elAttributes->apiUri; } if(isset($elAttributes->modulesUri)){ - $this->config->uri->modules = $elAttributes->modulesUri; - } + $this->config->uri->modules = (string) $elAttributes->modulesUri; + } - $this->config->uri->navigateur = $elAttributes->baseUri; + $this->config->uri->navigateur = (string) $elAttributes->baseUri; $this->config->application->baseUri = $this->config->uri->navigateur; + } if(isset($elAttributes->mapserver)){ @@ -213,15 +216,19 @@ private function traiterXml($nomXml){ if(isset($element->serveur)){ if(isset($element->serveur->authentification)) { $configServeurXml['authentification'] = array(); - foreach ($element->serveur->authentification->attributes() as $key=>$attr) { - $configServeurXml['authentification'][$key] = (String) $attr; + foreach ($element->serveur->authentification->children() as $key=>$attr) { + $child = array(); + foreach ($attr->attributes() as $cle => $valeur) { + $child[$cle] = (String) $valeur; + } + $configServeurXml['authentification'][$key] = $child; } } } } $application->getDI()->getSession()->set('configXml', $configServeurXml); - - $this->ajouterModules(); + + $this->ajouterModules(); } private function definirVariablesCommunes(){ @@ -245,10 +252,10 @@ private function definirVariablesCommunes(){ $idProfil = $application->getDI()->getSession()->get("info_utilisateur")->profilActif; if(isset($application->getDI()->getSession()->get("info_utilisateur")->profils)){ $count = count($application->getDI()->getSession()->get("info_utilisateur")->profils); - if(isset($idProfil)){ + if(isset($idProfil)){ foreach($application->getDI()->getSession()->get("info_utilisateur")->profils as $value){ if($value['id']== $idProfil){ - $libelleProfil = $value['libelle']; + $libelleProfil = $value['libelle']; break; } } @@ -288,7 +295,7 @@ private function definirVariablesCommunes(){ $fonctionCallback = "function(e){ var coucheWMS = new Igo.Couches.WMS( { - url:'{$url}', + url:'{$url}', nom:'{$layers}', fond:false, active:{$active}, @@ -302,11 +309,11 @@ private function definirVariablesCommunes(){ } else { $this->view->setVar("callbackInitIGO", 'null'); } - } + } /** * Ajoute tous les scripts Javascript requis pour chacun des modules. - * + * * @return void */ private function ajouterModules() { @@ -322,7 +329,7 @@ private function ajouterModules() { $configXml = $this->getDi()->getView()->configXml; $modulesFonctions = $chargeurModules->obtenirFonctions(); foreach ($modulesFonctions as $fct) { - include($fct); + include($fct); } } @@ -330,12 +337,15 @@ private function ajouterModules() { * vérifie si URL ou nom du service est permis selon config.php. */ public function verifierPermis($szUrl, $restService=false){ - return obtenirPermisUrl($szUrl, $restService) !== false; + return $this->obtenirPermisUrl($szUrl, $restService) !== false; } public function obtenirPermisUrl($szUrl, $restService=false){ - //vérifier URL + //vérifier URL //Services + + $szUrl = $this->removeDblBackSlash($szUrl); + $url = ""; $serviceRep = array( @@ -344,7 +354,7 @@ public function obtenirPermisUrl($szUrl, $restService=false){ ); $session = $this->getDI()->getSession(); - + if($session->has("info_utilisateur") && isset($this->config['permissions'])) { //utilisateur if(($session->info_utilisateur->identifiant) && isset($this->config->permissions[$session->info_utilisateur->identifiant]) && isset($this->config->permissions[$session->info_utilisateur->identifiant]->servicesExternes)){ @@ -362,7 +372,7 @@ public function obtenirPermisUrl($szUrl, $restService=false){ if(isset($profil) && isset($this->config->permissions[$profil]) && isset($this->config->permissions[$profil]->servicesExternes)){ $serviceExtProfil = $this->config->permissions[$profil]->servicesExternes; $serviceRep = self::verifieDomaineFunc($serviceRep, $szUrl, $serviceExtProfil, $restService); - if($serviceRep["test"] !== false){ + if($serviceRep["test"] !== false){ $test = true; if ($serviceRep["url"] !== false) { break; @@ -371,7 +381,7 @@ public function obtenirPermisUrl($szUrl, $restService=false){ } } } - + $serviceRep["test"] = $test; } } else if (!$session->has("info_utilisateur")) { @@ -380,7 +390,9 @@ public function obtenirPermisUrl($szUrl, $restService=false){ //general if (($serviceRep["test"] === false || $serviceRep["url"] === true) && isset($this->config['servicesExternes'])) { + $servicesExternes = $this->config['servicesExternes']; + $serviceRep = self::verifieDomaineFunc($serviceRep, $szUrl, $servicesExternes, $restService); } @@ -397,18 +409,175 @@ public function obtenirPermisUrl($szUrl, $restService=false){ } } else { if(is_object($serviceRep["url"])){ - $szUrl = (array) $serviceRep["url"]; + $szUrl = (array) $serviceRep["url"]; if(!isset($szUrl['url'])){ $szUrl['url'] = $szUrl[0]; - } + } } else { - $szUrl = array("url" => $serviceRep["url"]); + $szUrl = array("url" => $serviceRep["url"]); } } return $szUrl; + + } + + + + /** + * Obtenir Chaine de connexion au site securise + * @param ??? $service + * @param ??? $restService + * @return ??? $auth + */ + + public function obtenirChaineConnexion($service, $restService=false){ + global $app; + + $permisUrl = self::obtenirPermisUrl($service, $restService); + + if($permisUrl === false){ + http_response_code(403); + die("Vous n'avez pas les droits pour ce service."); + } + + //Decrypter la chaine de connexion + if (!empty($permisUrl['connexion']) || !empty($permisUrl['user'])) { + $auth = array(); + if(!empty($permisUrl['user'])) { + $auth['user'] = $permisUrl['user']; + } + if(!empty($permisUrl['pass'])) { + $auth['pass'] = $permisUrl['pass']; + } + if(!empty($permisUrl['methode'])) { + $auth['method'] = $permisUrl['methode']; + } + if(!empty($permisUrl['cainfo'])) { + $auth['cainfo'] = $permisUrl['cainfo']; + } + if(!empty($permisUrl['verifypeer'])) { + $auth['verifypeer'] = $permisUrl['verifypeer']; + } + + if(!empty($permisUrl['connexion'])){ + $crypt = $this->getDI()->get("crypt"); + $chaine = explode(",", $crypt->decryptBase64(urldecode($permisUrl['connexion']))); + $auth['user'] = ltrim(trim($chaine[0]), " user:"); + $auth['pass'] = ltrim(trim($chaine[1]), " pass:"); + if (empty($auth['pass'])) { + header('Content-Type: text/html; charset=utf-8'); + http_response_code(401); + die("Votre clé n'est pas décryptée correctement."); + } + } + + } + + $auth['url'] = $permisUrl['url']; + return $auth; } + + /** + * Obtenir Chaine de connexion au site securise pour proxy + * @param ??? $ch + * @param ??? $url + * @param ??? $method + * @param ??? $url + * @return ??? $ch + */ + public function proxyChaineConnexion ($ch, $url, $method, $options) { + + if (!empty ($options['auth'])) { + $auth = $options['auth']; + if (isset ($auth['user']) && isset ($auth['pass'])) { + //On obtient le payload (objectif chercher dans le payload les url securisees) + $postdata = file_get_contents ("php://input"); + //Seul le post xml de zoo est modifié + if (!empty ($postdata) && strpos ($postdata, 'wps:Execute') !== false) { + $doc = new DOMDocument(); + $doc->loadXML ($postdata); + $domList = $doc->getElementsByTagNameNS ('*', '*'); + //on navigue dans tout le payload + for ($i = 0; $i < $domList->length; $i++) { + if ($domList->item ($i)->tagName === 'wps:Reference') { + $xmlurl = $domList->item ($i)->getAttribute ('xlink:href'); + $partsxml = parse_url ($xmlurl); + //les credentials a ajouter dans le xml on verifié s il y en as + if (isset ($xmlurl) && $partsxml['scheme'] === 'https') { + if ($xmlurl !== $url) { + //les credentials des urls qu on as pas + $authxml = $this->obtenirChaineConnexion ($partsxml['scheme'] . '://' . $partsxml['host'] . $partsxml['path'], $restService = false); + if (isset ($authxml['user']) && isset ($authxml['pass']) && isset($partsxml['host']) && isset($partsxml['path']) && isset ( $partsxml['query'])) { + $urlxml = $partsxml['scheme'] . '://' . $authxml['user'] . ':' . $authxml['pass'] . '@' . $partsxml['host'] . $partsxml['path'] . '?' . $partsxml['query']; + } else if (isset ($authxml['user']) && isset ($authxml['pass']) && isset($partsxml['host']) && isset($partsxml['path'])) { + $urlxml = $partsxml['scheme'] . '://' . $authxml['user'] . ':' . $authxml['pass'] . '@' . $partsxml['host'] . $partsxml['path'] ; + } + $xmlpost = str_replace ($xmlurl, $urlxml, $postdata); + $postdata = $xmlpost; + } + //les credentials de zoo on possede deja dans le xml est modifié + if ($xmlurl === $url) { + $urlxml = $partsxml['scheme'] . '://' . $auth['user'] . ':' . $auth['pass'] . '@' . $partsxml['host'] . $partsxml['path']; + $xmlpost = str_replace ($xmlurl, $urlxml, $postdata); + $postdata = $xmlpost; + } + } + } + } + + curl_setopt ($ch, CURLOPT_POST, 1); + curl_setopt ($ch, CURLOPT_POSTFIELDS, $postdata); + } + + //Necessaire pour le SSL sinon on voit pas les couches dans + //la list des couche disponible analyse spatial + + //curl_setopt ($ch, CURLOPT_VERBOSE, 1); + //curl_setopt ($ch, CURLOPT_CERTINFO, 1); + + if (isset ($auth['cainfo'])) { + curl_setopt ($ch, CURLOPT_CAINFO, $auth['cainfo']); + } + + //Verify peer pour le SSL 1 par défaut, 0 si dans config 'verifypeer' => 'Off' (pas de vérification) + if (isset ($auth['verifypeer']) && $auth['verifypeer'] == 'Off') { + curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); + } else { + curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 1); + } + + curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 2); + + curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, $method); + + switch ($auth['method']) { + case "BASIC": + curl_setopt ($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + break; + case "NTLM": + curl_setopt ($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM); + break; + case "GSSNEGOTIATE": + curl_setopt ($ch, CURLOPT_HTTPAUTH, CURLAUTH_GSSNEGOTIATE); + break; + case "DIGEST": + curl_setopt ($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + break; + default: + curl_setopt ($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + break; + } + + curl_setopt ($ch, CURLOPT_USERPWD, $auth['user'] . ':' . $auth['pass']); + } + } + + return $ch; + } private function verifieDomaineRegexFunc($service, $arrayRegex) { foreach ($arrayRegex as $regex) { if ($regex[0] === '#' || $regex[0] === '/') { @@ -430,7 +599,7 @@ private function verifieDomaineRegexFunc($service, $arrayRegex) { return false; } - + private function verifieDomaineFunc($serviceRep, $service, $arrayServicesExternes, $restService){ if(isset($arrayServicesExternes[$service])){ if($restService == false){return $serviceRep;} @@ -453,4 +622,25 @@ private function verifieDomaineFunc($serviceRep, $service, $arrayServicesExterne return $serviceRep; } + + /** + * Obtenir une url sans double backslash. Permet ainsi de résoudre + * correctement les regex pour les urls permis. + * @param ??? $url url à vérifier + * @return ??? $resultat url sans double backslash + */ + private function removeDblBackSlash($url){ + + $resultat = preg_replace('/(?removeDblBackSlash($resultat); + } + + if($resultat === null){ + $resultat = $url; + } + + return $resultat; + } } diff --git a/interfaces/navigateur/app/library/Utils.php b/interfaces/navigateur/app/library/Utils.php index b16c96b4..41d67d09 100644 --- a/interfaces/navigateur/app/library/Utils.php +++ b/interfaces/navigateur/app/library/Utils.php @@ -357,4 +357,14 @@ static function curl_file_get_contents($url,$connectout=5,$timeout=10){ return $contenu; } + /** + * Remplace les lettres avec accent par leur équivalent sans accent, dans une chaine de caractères. + * + * @link http://stackoverflow.com/questions/27680624/compare-two-string-and-ignore-but-not-replace-accents-php + * @param string $string La chaine de caractères. + * @return string La chaine de caractères avec les accents enlevés. + */ + static function enleverAccents($chaine) { + return strtolower(trim(preg_replace('~[^0-9a-z]+~i', '-', preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($chaine, ENT_QUOTES, 'UTF-8'))), ' ')); + } } diff --git a/interfaces/navigateur/app/plugins/SecurityPlugin.php b/interfaces/navigateur/app/plugins/SecurityPlugin.php index 78f4ea51..66dcc946 100644 --- a/interfaces/navigateur/app/plugins/SecurityPlugin.php +++ b/interfaces/navigateur/app/plugins/SecurityPlugin.php @@ -12,13 +12,13 @@ class SecurityPlugin extends Plugin { public function beforeExecuteRoute(Phalcon\Events\Event $event, Phalcon\Mvc\Dispatcher $dispatcher){ - $authentificationModule = $this->getDI()->get("authentificationModule"); + $authentificationModule = $this->getDI()->get("authentificationModule"); if($authentificationModule == null){ return; } $controller = $dispatcher->getControllerName(); - $action = $dispatcher->getActionName(); + $action = $dispatcher->getActionName(); $config = $this->getDI()->get("config"); if($controller === "connexion" || $controller === "error"){ @@ -27,8 +27,10 @@ public function beforeExecuteRoute(Phalcon\Events\Event $event, Phalcon\Mvc\Disp }else if($controller === "igo" && ($action === "configuration" || $action === "index")){ $user = $this->session->get("info_utilisateur"); $authObligatoire = isset($_GET['force-auth']) ? $_GET['force-auth'] : false; - $configuration = $this->obtenirConfiguration($action, $dispatcher); + + $authRequise = ($authObligatoire || $this->estAuthentificationRequise($configuration))? true:false; + if(isset($this->getDi()->getConfig()->configurations[$configuration])){ $file = $this->getDi()->getConfig()->configurations[$configuration]; } else { @@ -37,39 +39,39 @@ public function beforeExecuteRoute(Phalcon\Events\Event $event, Phalcon\Mvc\Disp if((!file_exists($file) && !curl_url_exists($file))){ return $this->forwardToErrorPage(); } - if(($authObligatoire || $this->estAuthentificationRequise($configuration)) && !$this->estAuthentifie() && (!$this->estAnonyme() || ($this->estAnonyme() && (!isset($user->persistant) || $user->persistant == false)))){ + if(($authObligatoire || $authRequise) && !$this->estAuthentifie() && (!$this->estAnonyme() || ($this->estAnonyme() && (!isset($user->persistant) || $user->persistant == false)))){ return $this->forwardToLoginPage(); - } else if($this->estAuthentificationRequise($configuration) && $this->estRoleSelectionneRequis() && !$this->estRoleSelectionne()){ + } else if($authRequise && $this->estRoleSelectionneRequis() && !$this->estRoleSelectionne()){ return $this->forwardToRolePage(); - } else if (!$this->estAuthentificationRequise($configuration) && !$this->estAuthentifie()){ + } else if (!$authRequise && !$this->estAuthentifie()){ $authentificationModule = $this->getDI()->get("authentificationModule"); if(!$this->session->has("info_utilisateur")) { $this->session->set("info_utilisateur", new SessionController()); } - $configuration = $this->getDI()->get("config"); - if($configuration->offsetExists("database")) { + $configurationSysteme = $this->getDI()->get("config"); + if($configurationSysteme->offsetExists("database")) { if($this->estRoleSelectionneRequis()){ - $profilAnonyme = IgoProfil::findFirst("nom = '{$configuration->application->authentification->nomProfilAnonyme}'"); + $profilAnonyme = IgoProfil::findFirst("nom = '{$configurationSysteme->application->authentification->profilAnonyme->nom}'"); if($profilAnonyme){ $this->session->get("info_utilisateur")->profils = array($profilAnonyme->toArray()); $this->session->get("info_utilisateur")->profilActif = $this->session->get("info_utilisateur")->profils[0]['id']; } - } else if(isset($configuration->application->authentification->nomProfilAnonyme)){ - $this->session->get("info_utilisateur")->profils = IgoProfil::find("nom = '{$configuration->application->authentification->nomProfilAnonyme}'")->toArray(); - } + } else if(isset($configurationSysteme->application->authentification->profilAnonyme->nom)){ + $this->session->get("info_utilisateur")->profils = IgoProfil::find("nom = '{$configurationSysteme->application->authentification->profilAnonyme->nom}'")->toArray(); + } } $this->session->get("info_utilisateur")->estAnonyme = true; } else if($this->estRoleSelectionneRequis() && !$this->estRoleSelectionne()){ return $this->forwardToRolePage(); } - - if($this->estAnonyme() && isset($config->application->authentification->permettreAccesAnonyme) && !$config->application->authentification->permettreAccesAnonyme){ + + if($this->estAnonyme() && $authObligatoire){ return $this->forwardToUnauthorizedPage(); } if($this->estAnonyme()){ $this->session->get("info_utilisateur")->persistant = false; } - }else if ($controller == "igo" && ($action == "contexte" || $action == "couche" || $action == "groupe")){ + }else if ($controller == "igo" && ($action == "contexte" || $action == "couche" || $action == "groupe")){ if($this->estAnonyme()){ $user = $this->session->get("info_utilisateur"); if(isset($user->persistant) && $user->persistant === true){ @@ -77,18 +79,18 @@ public function beforeExecuteRoute(Phalcon\Events\Event $event, Phalcon\Mvc\Disp } else { $this->session->destroy(); $authentificationModule->deconnexion(); - } - } - if(!$this->estAnonyme() && !$this->estAuthentifie()){ + } + } + if(!$this->estAnonyme() && !$this->estAuthentifie()){ return $this->forwardToLoginPage(); }else if($this->estRoleSelectionneRequis() && !$this->estRoleSelectionne()){ return $this->forwardToRolePage(); }if($this->estAnonyme() && isset($config->application->authentification->permettreAccesAnonyme) && !$config->application->authentification->permettreAccesAnonyme){ return $this->forwardToUnauthorizedPage(); - } - } + } + } } - + private function forwardToLoginPage(){ $this->dispatcher->forward(array( "controller" => "connexion", @@ -97,7 +99,7 @@ private function forwardToLoginPage(){ )); return; } - + private function forwardToErrorPage(){ $this->dispatcher->forward(array( "controller" => "error", @@ -105,82 +107,87 @@ private function forwardToErrorPage(){ )); return; } - + private function forwardToUnauthorizedPage(){ $this->dispatcher->forward(array( "controller" => "error", "action" => "error403" )); return; - } + } private function forwardToRolePage(){ $this->dispatcher->forward(array( "controller" => "connexion", "action" => "role" )); return; - } - + } + private function estAuthentificationRequise($configuration){ + if(!isset($this->getDi()->getConfig()->application->authentification) || $this->getDi()->getConfig()->application->authentification == false){ - return false; + $authentification = false; } + if(isset($this->getDi()->getConfig()->configurations[$configuration])){ $xmlPath = $this->getDi()->getConfig()->configurations[$configuration]; } else { $xmlPath = $this->getDi()->getConfig()->configurationsDir . $configuration . '.xml'; } if(file_exists($xmlPath)){ - $element = simplexml_load_file($xmlPath); - if(isset($element->serveur) && isset($element->serveur->authentification) && isset($element->serveur->authentification->attributes()->nomProfilAnonyme)){ - $this->getDi()->getConfig()->application->authentification->nomProfilAnonyme = (String) $element->serveur->authentification->attributes()->nomProfilAnonyme; - $this->session->set('nomProfilAnonyme', $this->getDi()->getConfig()->application->authentification->nomProfilAnonyme); - } + $element = simplexml_load_file($xmlPath); + if(isset($element->serveur) && isset($element->serveur->authentification) && isset($element->serveur->authentification->children()->profilAnonyme->attributes()->nom)){ + $this->getDi()->getConfig()->application->authentification->profilAnonyme->nom = (String) $element->serveur->authentification->children()->profilAnonyme->attributes()->nom; + $this->session->set('nomProfilAnonyme', $this->getDi()->getConfig()->application->authentification->profilAnonyme->nom); + } } else { //url externe - $element = simplexml_load_string(curl_file_get_contents($xmlPath)); - } + $element = simplexml_load_string(curl_file_get_contents($xmlPath)); + } + if(isset($element->attributes()->authentification)){ $authentification = $element->attributes()->authentification; } else{ $authentification = "true"; // Est-ce qu'on devrait forcer l'authentification par defaut? En attendant de décider, on le force par défaut. - } - // Si la configuration demande que l'utilisateur soit authentifié et qu'il ne l'est pas encore, le rediriger vers la fenetre de connexion - if($authentification == "true"){ + } + // Si la configuration demande que l'utilisateur soit authentifié et qu'il ne l'est pas encore, le rediriger vers la fenetre de connexion + if($authentification == "true"){ return true; }else{ return false; } + + } - + private function estAuthentifie(){ if($this->session->has("info_utilisateur")) { return $this->session->get("info_utilisateur")->estAuthentifie; } return false; } - + private function estAnonyme(){ if($this->session->has("info_utilisateur")) { return $this->session->get("info_utilisateur")->estAnonyme; } return false; } - + private function estRoleSelectionneRequis(){ if(isset($this->getDi()->getConfig()->application->authentification->activerSelectionRole)){ return $this->getDi()->getConfig()->application->authentification->activerSelectionRole; } return false; } - + private function estRoleSelectionne(){ if($this->session->has("info_utilisateur")) { return !is_null($this->session->get("info_utilisateur")->profilActif); } return false; } - + private function obtenirConfiguration($action, $dispatcher){ if($action === "index"){ $configuration = "defaut"; @@ -189,5 +196,5 @@ private function obtenirConfiguration($action, $dispatcher){ } return $configuration; } - -} \ No newline at end of file + +} diff --git a/interfaces/navigateur/app/views/partials/librairies_css.volt b/interfaces/navigateur/app/views/partials/librairies_css.volt index 1d04cc90..1c095db4 100644 --- a/interfaces/navigateur/app/views/partials/librairies_css.volt +++ b/interfaces/navigateur/app/views/partials/librairies_css.volt @@ -1,2 +1,3 @@ {{ view.ajouterCss("extjs/resources/css/ext-all.css", true, true) }} {{ view.ajouterCss("css/igo.css", false) }} +{{ view.ajouterCss("css/print.css", false) }} diff --git a/interfaces/navigateur/app/views/partials/requireConfig.volt b/interfaces/navigateur/app/views/partials/requireConfig.volt index 3ab357bf..277af540 100644 --- a/interfaces/navigateur/app/views/partials/requireConfig.volt +++ b/interfaces/navigateur/app/views/partials/requireConfig.volt @@ -38,6 +38,9 @@ options.requireConfigFct = function(version, debug){ hbars : "libs/require/src/hbars", handlebars: '{{this.config.uri.librairies}}/handlebars/handlebars', jquery: debug ? "{{this.config.uri.librairies}}/jquery/jquery" : "{{this.config.uri.librairies}}/jquery/jquery.min", + html2canvas: "{{this.config.uri.librairies}}/html2canvas/dist/html2canvas", + html2canvassvg: "{{this.config.uri.librairies}}/html2canvas/dist/html2canvas.svg", + es6promise: "{{this.config.uri.librairies}}/es6-promise/es6-promise.min", proj4js: 'libs/proj/Proj4js', epsgDef: 'libs/proj/epsgDef', build: "js/main-build" diff --git a/interfaces/navigateur/build/configRequire.js b/interfaces/navigateur/build/configRequire.js index ed06fa2d..b2cc1e9b 100644 --- a/interfaces/navigateur/build/configRequire.js +++ b/interfaces/navigateur/build/configRequire.js @@ -72,6 +72,7 @@ require.config({ outilZoomEtendueMaximale: 'js/app/outil/outilZoomEtendueMaximale', outilZoomPreselection: 'js/app/outil/outilZoomPreselection', outilZoomRectangle: 'js/app/outil/outilZoomRectangle', + outilExportCSV: 'js/app/outil/outilExportCSV', panneau: 'js/app/panneau/panneau', panneauAccordeon: 'js/app/panneau/panneauAccordeon', panneauCarte: 'js/app/panneau/panneauCarte', @@ -97,6 +98,10 @@ require.config({ fileUploadField: 'empty:', getInfo: 'empty:', handlebars: 'empty:', - IGODatePicker: 'empty:' + IGODatePicker: 'empty:', + fixOpenLayersRequire: 'empty:', + html2canvas: 'empty:', + html2canvassvg: 'empty:', + es6promise: 'empty:' } }); \ No newline at end of file diff --git a/interfaces/navigateur/public/css/igo.css b/interfaces/navigateur/public/css/igo.css index 2a315c32..66ac6dd6 100644 --- a/interfaces/navigateur/public/css/igo.css +++ b/interfaces/navigateur/public/css/igo.css @@ -60,9 +60,6 @@ img.olTileImage { .apropos { background-image:url(../images/toolbar/onebit_25.png) !important; } -.gentillyboom { - background-image:url(../images/toolbar/hazard_radioactive2.png) !important; -} .getinfo { background-image:url(../images/toolbar/info.png) !important; } @@ -125,13 +122,16 @@ ul.list { font-size: 11px; padding: 0 0 0 16px; } -#currentMousePositionComponent, + +#currentMousePositionElevation, #currentScaleComponent, #currentProjectionComponent, -#currentTimeComponent{ +#currentTimeComponent, +#currentMousePositionComponent{ float: left; } - + + div.southPanel{ padding: 0px 0px 0px 0px; } @@ -438,4 +438,4 @@ div.olControlMousePosition { #occurencesResultatsWindow .x-panel-body { overflow: auto; -} \ No newline at end of file +} diff --git a/interfaces/navigateur/public/css/print.css b/interfaces/navigateur/public/css/print.css new file mode 100644 index 00000000..209050e3 --- /dev/null +++ b/interfaces/navigateur/public/css/print.css @@ -0,0 +1,95 @@ +@media print { + + #menu-panneau3, + #resultatRechercheTable, + .x-panel, + .x-toolbar, + .x-slider, + .x-layout-split, + .x-layout-collapsed, + .x-unselectable, + .x-tip, + .x-panel-tbar, + .x-window, + .x-shadow, + .olControlNoSelect, + .ext-el-mask + { + display: none !important; + } + + #carte-panneau1, + #mapComponent, + #printLayer, + .x-panel-bwrap + { + display: block !important; + } + + #carte-panneau1, + #mapComponent { + left: 0 !important; + background-color: white !important; + /*top: -100px !important;*/ + /*left: -100px !important;*/ + /* width: 1000px !important;*/ + /*height: 1200px !important;*/ + } + + #printLayer { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + background-color: none !important; + } + + #printLayer .centerH { + text-align: center; + } + + #printLayer .printTitle { + width: 100%; + margin: auto; + text-align: center; + padding: 5px; + font-size: 18px; + text-shadow: #fff 0px 0px 2px; + font-weight: bold; + } + + #printLayer .printLegend { + position: absolute; + right: 0; + top: 0; + background-color: white; + max-width: 30%; + } + + #printLayer .printDescription { + position: absolute; + bottom: 0; + font-size: 12px; + background-color: white; + max-width: 30%; + } + + #printLayer .printInfo { + position: absolute; + bottom: 0; + text-align: center; + width: 100%; + } + + #printLayer .printInfo div { + font-size: 12px; + background-color: white; + text-align: center; + display: inline; + } + .x-border-layout-ct { + background-color: white !important; + border: none !important; + } +} diff --git a/interfaces/navigateur/public/images/quebec/gouv_qc_logo.png b/interfaces/navigateur/public/images/quebec/gouv_qc_logo.png new file mode 100644 index 00000000..7938f4bf Binary files /dev/null and b/interfaces/navigateur/public/images/quebec/gouv_qc_logo.png differ diff --git a/interfaces/navigateur/public/images/toolbar/export-csv.png b/interfaces/navigateur/public/images/toolbar/export-csv.png new file mode 100644 index 00000000..8b82dd29 Binary files /dev/null and b/interfaces/navigateur/public/images/toolbar/export-csv.png differ diff --git a/interfaces/navigateur/public/index.php b/interfaces/navigateur/public/index.php index 2e54d564..9c1ce825 100644 --- a/interfaces/navigateur/public/index.php +++ b/interfaces/navigateur/public/index.php @@ -4,17 +4,21 @@ error_reporting(E_ALL); try { - + $config = include __DIR__ . "/../app/config/config.php"; include __DIR__ . "/../app/config/loader.php"; include __DIR__ . "/../app/config/services.php"; $application = new \Phalcon\Mvc\Application($di); - + + //TODO + //faire un module pour la retro-compatibilité, pour ce genre de code. + if(isset($config->application->authentification->nomProfilAnonyme)){ + $config->application->authentification->profilAnonyme = array('nom'=>$config->application->authentification->nomProfilAnonyme); + } + $application->registerModules($di->get('chargeurModules')->obtenirDefinitionModules()); echo $application->handle()->getContent(); } catch (\Exception $e) { - echo $e->getMessage(); + echo $e->getMessage(); } - - diff --git a/interfaces/navigateur/public/js/app/analyseur/analyseurConfig.js b/interfaces/navigateur/public/js/app/analyseur/analyseurConfig.js index 116ffcc3..9d6169f2 100644 --- a/interfaces/navigateur/public/js/app/analyseur/analyseurConfig.js +++ b/interfaces/navigateur/public/js/app/analyseur/analyseurConfig.js @@ -1,16 +1,16 @@ -/** +/** * Module pour l'objet {@link AnalyseurConfig}. * @module analyseurConfig - * @requires aide - * @requires navigateur - * @requires carte - * @requires contexte + * @requires aide + * @requires navigateur + * @requires carte + * @requires contexte * @author Marc-André Barbeau, MSP * @version 1.0 */ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], function(Aide, Navigateur, Carte, Contexte, Evenement, Serveur) { - /** + /** * Création de l'object AnalyseurConfig. * @constructor * @name AnalyseurConfig @@ -18,9 +18,9 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func * @alias analyseurConfig:AnalyseurConfig * @requires analyseurConfig * @param {object} options Liste des options possibles - * @param {object | string} [options.configuration='defaut'] La - * configuration dans le format json en paramètre ou appelle l'api - * ([api]/configuration/[options.configuration]) pour obtenir + * @param {object | string} [options.configuration='defaut'] La + * configuration dans le format json en paramètre ou appelle l'api + * ([api]/configuration/[options.configuration]) pour obtenir * le json ou le xml. (voir la documentation du XML) * @param {string} [options.configuration] todo: à complèter * @param {function} [options.callback] Function appelée lorsque l'initialisation @@ -38,9 +38,9 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func }; - /** - * Initialisation de l'object AnalyseurConfig. - * @method + /** + * Initialisation de l'object AnalyseurConfig. + * @method * @private * @name AnalyseurConfig#_init */ @@ -48,11 +48,11 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func this.options = $.extend({}, this.defautOptions, this.options); }; - /** + /** * Sert à charger le navigateur selon la configuration donnée lors de la création de {@link AnalyseurConfig}. - * Si la configuration est un string, appelle l'api ([api]/configuration/[options.configuration]) pour obtenir + * Si la configuration est un string, appelle l'api ([api]/configuration/[options.configuration]) pour obtenir * le json ou le xml. - * @method + * @method * @name AnalyseurConfig#charger * @returns {Navigateur} Le navigateur construit: @link Navigateur */ @@ -79,10 +79,10 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func return this.igo; }; - /** - * Fonction appelée si l'api retourne un erreur lors de l'obtention de la configuration. + /** + * Fonction appelée si l'api retourne un erreur lors de l'obtention de la configuration. * Affiche les erreurs obtenues. - * @method + * @method * @private * @name AnalyseurConfig#_chargementError */ @@ -93,10 +93,10 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func Aide.afficherMessage("Erreur chargement de la configuration XML", message, null, 'ERROR'); }; - /** - * Fonction appelée si la configuration est obtenue. + /** + * Fonction appelée si la configuration est obtenue. * @param {object} config La configuration en format json ou xml - * @method + * @method * @private * @name AnalyseurConfig#_chargementConfigSuccess */ @@ -194,18 +194,18 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func } that.igo.nav.carte.gestionCouches.enleverToutesLesCouches(); - that._analyserCouches(groupeCouches); + that._analyserCouches(groupeCouches); }); } } - - /** + + /** * Convertie la configuration xml en json. * @param {object} xml Configuration dans le format xml. - * @method + * @method * @private * @name AnalyseurConfig#_chargementConfigSuccess - * @returns {object} Configuration dans le format json + * @returns {object} Configuration dans le format json */ AnalyseurConfig.prototype._xml2Json = function(xml) { var obj = {}; @@ -246,12 +246,12 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func return obj; }; - /** + /** * Obtenir les modules requis pour le json en paramètre * @param {object} json Partie de la configuration à analyser * @param {tableau} [modulesReq = []] Tableau des modules requis * @param {entier} [niveauForage = 1] Nombre de niveau du json à analyser - * @method + * @method * @private * @name AnalyseurConfig#_analyserRequire * @returns {array} Tableau des modules requis @@ -304,12 +304,12 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func return modulesReq; }; - /** + /** * Analyser la section "panneaux" de la config * @param {object} json Partie de la configuration concernant les panneaux * @param {Panneau|Navigateur} [panneauOccurence = Navigateur] Parent des panneaux * @method - * @private + * @private * @name AnalyseurConfig#_analyserRequire */ AnalyseurConfig.prototype._analyserPanneaux = function(json, panneauOccurence) { @@ -368,17 +368,22 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func }); }; - /** + /** * Charger le contexte enregistré - * @method + * @method * @private * @name AnalyseurConfig#_analyserContexte */ AnalyseurConfig.prototype._analyserContexte = function() { if (this.fin.panneaux && this.fin.couches && this.fin.actions) { - var contexte = new Contexte(); - contexte.charger(); - this._fin(); + if(!window.arboLoading) { + var contexte = new Contexte(); + contexte.charger(); + this._fin(); + } else { + var that = this; + setTimeout(function(){that._analyserContexte()}, 500); + } } }; @@ -396,12 +401,12 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func } this._analyserAvertissements(); }; - - /** + + /** * Analyser la section "outils" de la config * @param {object} json Partie de la configuration concernant les outils * @param {BarreOutil|OutilMenu} [outilOccurence] Parent des outils - * @method + * @method * @private * @name AnalyseurConfig#_analyserOutils */ @@ -423,7 +428,7 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func } else { arrayGroupeOutils = [json]; } - + arrayGroupeOutils = $.isArray(arrayGroupeOutils) ? arrayGroupeOutils : [arrayGroupeOutils]; $.each(arrayGroupeOutils, function(key, groupeOutils) { var listOutils = []; @@ -456,7 +461,7 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func } if(options.actionScope){ options.actionScope = that._pathShortToLong(options.actionScope); - } + } var outilOccurence = new Igo.Outils[classe](options); listOutils.push(outilOccurence); @@ -476,10 +481,10 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func }); }; - /** + /** * Analyser la section "couches" de la config * @param {object} json Partie de la configuration concernant les couches - * @method + * @method * @private * @name AnalyseurConfig#_analyserCouches */ @@ -508,14 +513,14 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func if (!couches || !couches.couche) { return true; }; - + var couchesOptions = couches["@attributes"] || couches["attributs"]; var propriete = $.isArray(couches.couche) ? couches.couche : [couches.couche]; $.each(propriete, function(key, couche) { var options = couche["@attributes"] || couche["attributs"]; if(options.infoAction){ options.infoAction = that._pathShortToLong(options.infoAction); - } + } options.droit = options.droit || couche.droit; options = $.extend({}, couchesOptions, options); var classe = options.protocole; @@ -528,21 +533,21 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func } }); }); - + if (listCouches.length === 0 || !listCouches[0].estFond() || listCouches[0].obtenirTypeClasse()==='Google') { that._ajouterCoucheBlanc(listCouches); return true; } - + that.listCouchesApresContexte = listCouchesApresContexte; that._analyserCouchesSuccess(listCouches); }); }; - /** + /** * Appeler lorsque l'analyse des couches est terminée * @param {tableau} listCouches Tableau de {@link Couche} à ajouter à la carte - * @method + * @method * @private * @name AnalyseurConfig#_analyserCouches */ @@ -555,10 +560,10 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func } }; - /** + /** * Ajouter la couche 'Blanc' lorsque la carte n'a pas de couche de fond. * @param {tableau} listCouches Tableau de {@link Couche} à ajouter à la carte - * @method + * @method * @private * @name AnalyseurConfig#_ajouterCoucheBlanc */ @@ -567,11 +572,11 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func this._analyserCouchesSuccess(listCouches); }; - /** + /** * Sert à charger le contexte de la BD. Utilise le contexte.attributes.id ou le contexte.attributes.code du json * Si id, appelle l'api ([api]/contexte/[contexte.attributes.id]) pour obtenir les couches de la bd. * Si code, appelle l'api ([api]/contexteCode/[contexte.attributes.code]) pour obtenir les couches de la bd. - * @method + * @method * @private * @name AnalyseurConfig#_analyserContexteBD */ @@ -605,7 +610,7 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func } else if(this.options.contexteId) { contexteId = this.options.contexteId; } - + var contexteUrl; if (contexteId && contexteId !== "null") { contexteUrl = Aide.obtenirConfig('uri.api')+"contexte/" + contexteId; @@ -613,7 +618,11 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func contexteUrl = Aide.obtenirConfig('uri.api')+"contexteCode/" + contexteCode; } else { this.fin.couches = true; - this._analyserContexte(); + setTimeout(function () { + that.igo.nav.carte.gestionCouches.ajouterCouches(that.listCouchesApresContexte); + that._analyserContexte(); + }, 1); + return true; } @@ -629,10 +638,10 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func }); }; - /** - * Fonction appelée si l'api retourne un erreur lors de l'obtention des couches du contexte. + /** + * Fonction appelée si l'api retourne un erreur lors de l'obtention des couches du contexte. * Affiche les erreurs obtenues. - * @method + * @method * @private * @name AnalyseurConfig#_analyserContexteBDError */ @@ -645,10 +654,10 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func this._analyserContexte(); }; - /** + /** * Analyser les couches reçues de la BD * @param {object} data Json des couche à ajouter à la carte - * @method + * @method * @private * @name AnalyseurConfig#_analyserContexteBDSuccess */ @@ -660,6 +669,10 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func if(layernamePermis){ layernamePermis = layernamePermis.split(','); } + var layerActif = Aide.obtenirParametreURL("layeractif"); + if(layerActif){ + layerActif = layerActif.split(','); + } $.each(couches, function(key, couche) { var layername = couche.mf_layer_name || couche.mf_layer_meta_name; if(layernamePermis){ @@ -667,6 +680,10 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func return true; } couche.est_active = true; + } else if (layerActif){ + if(layerActif.indexOf(layername) !== -1){ + couche.est_active = true; + } } var options = { id: couche.couche_id, @@ -697,7 +714,7 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func if(Aide.obtenirConfig("uri.mapserver")){ if(Aide.obtenirConfig("uri.mapserver") !== true){ options.url = Aide.obtenirConfig("uri.mapserver") + options.url; - } + } } else { options.url = Aide.obtenirConfig("uri.api") + "wms/" + data.id; } @@ -761,10 +778,10 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func return objet; } - /** + /** * Analyser la section "declencheurs" de la config * @param {object} json Partie de la configuration concernant les déclencheurs - * @method + * @method * @private * @name AnalyseurConfig#_analyserDeclencheurs */ @@ -788,10 +805,10 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func }); }; - /** + /** * Analyser la section "actions" de la config * @param {object} json Partie de la configuration concernant les actions - * @method + * @method * @private * @name AnalyseurConfig#_analyserActions */ @@ -813,7 +830,7 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func if (aJSExt !== -1) { source = source.substr(0, aJSExt); } - + var paths = {}; paths[id] = source; require.ajouterConfig({ @@ -829,11 +846,11 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func }; - /** + /** * Sert à charger une couche de la bd selon son ID * Appelle l'api ([api]/couche/[coucheId]) pour obtenir les informations sur la couche * @param {string} coucheId Le ID de la couche - * @method + * @method * @name AnalyseurConfig#_analyserCoucheBD */ AnalyseurConfig.prototype._analyserCoucheBD = function(coucheId) { @@ -846,12 +863,12 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func dataType: 'json' }); }; - - /** + + /** * Sert à analyser les avertissements subvenus lors du chargement de la config * Affiche la liste des avertissements à l'utilisateur * @param {tableau} avertissements Tableau d'avertissements (string) à afficher. - * @method + * @method * @name AnalyseurConfig#_analyserAvertissements */ AnalyseurConfig.prototype._analyserAvertissements = function(avertissements){ @@ -865,7 +882,7 @@ define(['aide', 'navigateur', 'carte', 'contexte', 'evenement', 'serveur'], func Aide.afficherMessageConsole(avertissement); }); - + } }; diff --git a/interfaces/navigateur/public/js/app/carte.js b/interfaces/navigateur/public/js/app/carte.js index 611b0ac1..ee5aad52 100644 --- a/interfaces/navigateur/public/js/app/carte.js +++ b/interfaces/navigateur/public/js/app/carte.js @@ -8,8 +8,7 @@ * @author Marc-André Barbeau, MSP * @version 1.0 */ - -define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', 'contexteMenuCarte', 'libs/extension/OpenLayers/DrawFeatureEx', 'libs/extension/OpenLayers/CircleToMeasure', 'libs/extension/OpenLayers/MeasureCircle', 'libs/extension/OpenLayers/resetLayersZIndex'], function(Point, Occurence, Limites, GestionCouches, Evenement, Aide, ContexteMenuCarte) { +define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', 'contexteMenuCarte', 'html2canvas', 'html2canvassvg', 'es6promise', 'libs/extension/OpenLayers/fixOpenLayers'], function(Point, Occurence, Limites, GestionCouches, Evenement, Aide, ContexteMenuCarte, html2canvas, html2canvassvg) { /** * Création de l'object Carte. * @constructor @@ -24,6 +23,7 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', * @property {Dictionnaire} options Options de la carte. */ function Carte(options) { + this.isReady = false; this.gestionCouches = new GestionCouches(this); this.options = options || {}; this._init(); @@ -111,7 +111,7 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', //this.gestionCouches.ajouterCouche(new Blanc({visible:true, active:true})); //Controles - this._carteOL.addControl(new OpenLayers.Control.Attribution()); + this._carteOL.addControl(new OpenLayers.Control.Attribution({separator: ', '})); this._carteOL.addControl(new OpenLayers.Control.PanPanel()); this._carteOL.addControl(new OpenLayers.Control.ZoomPanel()); this._carteOL.addControl(new OpenLayers.Control.Navigation({ @@ -149,7 +149,7 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', return false; } - if(occurence.obtenirInteraction('survol') === false){ + if(occurence.obtenirInteraction('survol') === false){ return false; } that.gestionCouches.ajouterOccurenceSurvol(occurence); @@ -174,7 +174,7 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', return false; } - if(occurence.obtenirInteraction('survol') === false){ + if(occurence.obtenirInteraction('survol') === false){ return false; } @@ -197,7 +197,7 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', return false; } - if(occurence.obtenirInteraction('cliquable') === false){ + if(occurence.obtenirInteraction('cliquable') === false){ return false; } @@ -208,12 +208,12 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', if(lastOccSurvol.id === occurence.id){ dessus = true; } - } + } couche.declencher({ type: "occurenceClique", occurence: occurence, dessus: dessus - }); + }); }, moveend: function() { that.declencher({ @@ -229,7 +229,7 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', that.declencher({ type: "quitterSurvolCarte" }); - clearInterval(that._timerEvenementPauseSurvol); + clearTimeout(that._timerEvenementPauseSurvol); }, mousemove: function(e) { that.coordSouris = e.xy; @@ -242,9 +242,9 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', x: lonlat.lon, y: lonlat.lat }); - clearInterval(that._timerEvenementPauseSurvol); - that._timerEvenementPauseSurvol = setInterval(function() { - clearInterval(that._timerEvenementPauseSurvol); + clearTimeout(that._timerEvenementPauseSurvol); + that._timerEvenementPauseSurvol = setTimeout(function() { + clearTimeout(that._timerEvenementPauseSurvol); that.declencher({ type: "pauseSurvolCarte", x: that._carteOL.getLonLatFromViewPortPx(that.coordSouris).lon, @@ -283,6 +283,69 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', }; }; + /** + * Permet d'exporter un canvas de la carte + * @method + * @name Carte#exporterCanvas + * @return {Canvas} Une version canvas de la carte + */ + Carte.prototype.exporterCanvas = function() { + var deferred = jQuery.Deferred(); + var options = { + useCORS: true, + allowTaint: false, + proxy: Aide.obtenirConfig('uri.api') + '/proxy/html2canvas' + }; + + // Correctif pour support Internet Explorer et RequireJS + html2canvas.svg = html2canvassvg; + window.html2canvas = html2canvas; + + html2canvas(this._carteOL.div, options).then(function(canvas) { + deferred.resolve(canvas); + }) + + return deferred.promise(); + }; + + /** + * Permet d'exporter une image de la carte au format PNG. + * @method + * @name Carte#exporterImage + * @param {function} callbackPreprocesseurCanvas + * Callback de modification du canvas avant la convertion en image. + * @return {Image} Une version image PNG de la carte + */ + Carte.prototype.exporterImage = function(callbackPreprocesseurCanvas) { + var deferred = jQuery.Deferred(); + + this.exporterCanvas().then(function(canvas) { + var image = new Image(); + + try { + if(callbackPreprocesseurCanvas) { + canvas = callbackPreprocesseurCanvas(canvas); + } + + image.src = canvas.toDataURL("image/png"); + } catch(e) { + deferred.reject(e); + } + + image.onload = function () { + deferred.resolve(image); + } + image.onerror = function(error) { + deferred.reject(error); + }; + + }).fail(function(erreur) { + deferred.reject(erreur); + }); + + return deferred.promise(); + }; + /** * Obtenir la projection de la carte. (Format EPSG) * @method @@ -430,7 +493,20 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', return this._carteOL.resolution; }; - Carte.prototype.obtenirEchelle = function() { + Carte.prototype.obtenirEchelle = function(approximative) { + if (approximative) { + var scale = this._carteOL.getScale(); + scale = Math.round(scale); + if (scale < 10000) { + return scale; + } + scale = Math.round(scale/1000); + if (scale < 1000) { + return scale + 'K'; + } + scale = Math.round(scale/1000); + return scale + 'M'; + } return this._carteOL.getScale(); }; @@ -668,17 +744,17 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', cacherVertex(); that._.curseur = 'move'; if(occurence){ - couche.declencher({ type: "debutDeplacementOccurence", occurence: occurence }); + couche.declencher({ type: "debutDeplacementOccurence", occurence: occurence }); } - }, + }, onDrag: function(feature){ cacherVertex(); var occurence = couche.obtenirOccurenceParId(feature.id); if(occurence){ occurence.majGeometrie(feature.geometry, {lancerDeclencheur: false}); - couche.declencher({ type: "deplacementOccurence", occurence: occurence }); + couche.declencher({ type: "deplacementOccurence", occurence: occurence }); } - }, + }, onComplete: function(feature){ if(that.controleEdition){ that.controleEdition.resetVertices(); @@ -688,9 +764,9 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', if(occurence){ occurence.majGeometrie(feature.geometry); $olMapViewport.removeClass('olControlDragFeatureOver'); - couche.declencher({ type: "finDeplacementOccurence", occurence: occurence }); + couche.declencher({ type: "finDeplacementOccurence", occurence: occurence }); } - }, + }, onEnter: function(feature){ var occurence = couche.obtenirOccurenceParId(feature.id); if(occurence && occurence.obtenirInteraction('editable') === false){ @@ -717,19 +793,27 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', this._._carteOL.addControl(this.controleDrag); this.controleDrag.activate(); } + this.controleDrag.coucheIgo = couche; if (this.snap) { this.activerSnap(couche); } } - Carte.Controles.prototype.desactiverDeplacementVecteur = function(couche) { + Carte.Controles.prototype.desactiverDeplacementVecteur = function() { if (this.controleDrag) { + var couche = this.controleDrag.coucheIgo; this.desactiverSnap(); this.controleDrag.deactivate(); this._._carteOL.removeControl(this.controleDrag); this.controleDrag.destroy(); this.controleDrag = undefined; + if (couche) { + couche.definirOrdreAffichage(couche._layer.z_index_default); + couche.declencher({ + type: 'controleDeplacementVecteurDesactiver' + }); + } } } @@ -753,24 +837,24 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', var modeEdit = 0; if(options.editVertex !== false){ modeEdit = OpenLayers.Control.ModifyFeature.RESHAPE ; - } + } if(options.rotation){ modeEdit += OpenLayers.Control.ModifyFeature.ROTATE ; - } + } if(options.editDimension){ modeEdit += OpenLayers.Control.ModifyFeature.RESIZE ; - } + } if(modeEdit){ this.controleEdition = new OpenLayers.Control.ModifyFeature(couche._layer, { mode: modeEdit }); - this._._carteOL.addControl(this.controleEdition); + this._._carteOL.addControl(this.controleEdition); this.controleEdition.optionsIgo = options; this.controleEdition.coucheIgo = couche; } } - + if(this.controleEdition){ this.controleEdition.activate(); @@ -789,7 +873,7 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', couche.declencher({ type: 'controleEditionActiver' }); - + if (this.snap) { this.activerSnap(couche); } @@ -801,7 +885,7 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', if (this.vertex) { this.dragVertex(this.vertex, pixel); } - + if(this.feature){ var occ = new Occurence(this.feature.geometry); couche.declencher({ @@ -832,6 +916,7 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', this._editionEvents.oModifificationTerminee = undefined; this.activerOccurenceEvenement(); if (couche) { + couche.definirOrdreAffichage(couche._layer.z_index_default); couche.deselectionnerTout(); couche.declencher({ type: 'controleEditionDesactiver' @@ -889,7 +974,7 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', } - if(occurence.obtenirInteraction('editable') === false){ + if(occurence.obtenirInteraction('editable') === false){ if(occurence.obtenirTypeGeometrie() === 'Point'){ //la carte n'est plus focus pour un déplacement that.controleEdition.handlers.drag.dragend(e) @@ -898,7 +983,7 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', } occurence._resetVertex = function(){if(that.controleEdition){that.controleEdition.resetVertices()}}; - + occurence._controle = that.controleEdition; that._editionEvents.oModifificationTerminee = that._editionEvents.oModifification; that._editionEvents.oModifification = occurence; @@ -939,7 +1024,7 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', this._editionEvents.fnVecteurOccurenceSelectionnee = function(e) { //e.options.scope._desactiverEventsEdition(); - if (couche.obtenirOccurencesSelectionnees().length > 1) { + if (couche.obtenirOccurencesSelectionnees().length > 1) { couche.deselectionnerTout({exceptions: [e.occurence]}); } if(e.occurence){ @@ -963,6 +1048,10 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', //todo: créer si pas de couche? avertissement? couche = couche === "active" ? this._.gestionCouches.coucheVecteurActive : couche; + if(couche && typeof couche.activer==='function'){ + couche.activer(true); + } + if (options.releverBoutonOutil !== false) { var boutonActif = Ext.ButtonToggleMgr.getPressed('carte'); if (boutonActif) { @@ -1086,6 +1175,7 @@ define(['point', 'occurence', 'limites', 'gestionCouches', 'evenement', 'aide', } this._._carteOL.addControl(this.controleDessin); + this.controleDessin.coucheIgo = couche; } Aide.obtenirNavigateur().evenements.ajouterDeclencheur('controleCarteActiver', function(e) { diff --git a/interfaces/navigateur/public/js/app/contexteMenu/contexteMenuArborescence.js b/interfaces/navigateur/public/js/app/contexteMenu/contexteMenuArborescence.js index f642bc3b..ac84e0d5 100644 --- a/interfaces/navigateur/public/js/app/contexteMenu/contexteMenuArborescence.js +++ b/interfaces/navigateur/public/js/app/contexteMenu/contexteMenuArborescence.js @@ -174,85 +174,16 @@ define(['contexteMenu', 'aide', 'fonctions', 'panneauTable', 'dateTimeIntervalPi if (args.couche.options.wms_timeextent) { // This is a layer from the MSP map file. In which case we read the msp metadata. // Create the DatePicker - var timeExtentArray = args.couche.options.wms_timeextent.split("/"); - var startDate = Fonctions.createDateFromIsoString(timeExtentArray[0]); - var endDate=null; - var allowIntervals=null; - var defautPrecision; - if(timeExtentArray.length>1){ - endDate = Fonctions.createDateFromIsoString(timeExtentArray[1]); - allowIntervals = true; - if(timeExtentArray[2]){ - switch (timeExtentArray[2][timeExtentArray[2].length-1]){ - case 'S': - defautPrecision = 'seconde'; - break; - case 'M': - defautPrecision = 'minute'; - break; - case 'H': - defautPrecision = 'heure'; - break; - case 'D': - defautPrecision = 'jour'; - break; - case 'M': - defautPrecision = 'mois'; - break; - case 'Y': - defautPrecision = 'annee'; - break; - } - } - } else{ - endDate = null; - allowIntervals = false; - } - - if(args.couche.options.wms_timeAllowIntervals){ - allowIntervals = Aide.toBoolean(args.couche.options.wms_timeAllowIntervals); - } - - if(!defautPrecision){ - var strArray = timeExtentArray[0].split("-"); - var heureArray; - switch(strArray.length){ - case 1: - defautPrecision = 'annee'; - break; - case 2: - defautPrecision = 'mois'; - break; - case 3: - defautPrecision = 'jour'; - if(strArray[2].split("T")[1]){ - heureArray = strArray[2].split("T")[1].split(':'); - } - break; - } - if(heureArray){ - switch(heureArray.length){ - case 1: - defautPrecision = 'heure'; - break; - case 2: - defautPrecision = 'minute'; - break; - case 3: - defautPrecision = 'seconde'; - break; - } - } - } - + var periode = Fonctions.obtenirPeriodeTemps(args.couche.options.wms_timeextent); + var datePicker = new DateTimeIntervalPicker({ id : 'datePicker', layer : args.couche._layer, - allowIntervals : allowIntervals, - minStartDate : startDate, - maxEndDate : endDate, + allowIntervals : periode.allowIntervals, + minStartDate : periode.min, + maxEndDate : periode.max, mapServerTimeString : args.couche.options.wms_timedefault, - precision : args.couche.options.wms_timeprecision || defautPrecision + precision : args.couche.options.wms_timeprecision || periode.precision }); return { diff --git a/interfaces/navigateur/public/js/app/contexteMenu/contexteMenuCarte.js b/interfaces/navigateur/public/js/app/contexteMenu/contexteMenuCarte.js index b8b64231..3fb992d3 100644 --- a/interfaces/navigateur/public/js/app/contexteMenu/contexteMenuCarte.js +++ b/interfaces/navigateur/public/js/app/contexteMenu/contexteMenuCarte.js @@ -264,10 +264,12 @@ define(['contexteMenu', 'point', 'polygone', 'occurence', 'aide', 'analyseurGML' }; ContexteMenuCarte.prototype.initSelectionSubmenu = function(args){ + var that=args.scope; if(args.occurencesSelectionnees.length !== 0){ var type = ""; var memeType = true; + var typePolygone = true; $.each(args.occurencesSelectionnees, function(index, occurence){ if(type === ""){ type=occurence.type; @@ -277,6 +279,11 @@ define(['contexteMenu', 'point', 'polygone', 'occurence', 'aide', 'analyseurGML' memeType = false; } } + + if(type !== 'MultiPolygone' && type !== 'Polygone') { + typePolygone = false; + } + }); var subSelection = { @@ -300,12 +307,42 @@ define(['contexteMenu', 'point', 'polygone', 'occurence', 'aide', 'analyseurGML' } }); + if(memeType){ + if(typePolygone === true) + { + subSelection.menu.items.push('-'); + subSelection.menu.items.push({ + id: 'selectionPerimetre', + text: "Périmètre", + handler: function(){ + var perimetre = 0; + $.each(args.occurencesSelectionnees, function(index, occurence){ + perimetre += occurence.obtenirPerimetre(); + }); + Aide.afficherMessage('Périmètre', perimetre + ' ' + that.options.carte._carteOL.getUnits()); + } + }); + subSelection.menu.items.push({ + id: 'selectionSuperficie', + text: 'Superficie', + handler: function(){ + var superficie = 0; + $.each(args.occurencesSelectionnees, function(index, occurence){ + superficie += occurence.obtenirSuperficie(); + }); + Aide.afficherMessage('Superficie', superficie + ' ' + that.options.carte._carteOL.getUnits() + "²"); + } + }); + } + var submenuCopieVers = args.scope.initSubMenuCopieVers("-1", args.occurencesSelectionnees, type); if(submenuCopieVers){ + subSelection.menu.items.push('-'); subSelection.menu.items.push(submenuCopieVers); } + } if(args.occurencesSelectionnees.length === 1 && args.occurencesSelectionnees[0]._obtenirGeometrie() === undefined ){ diff --git a/interfaces/navigateur/public/js/app/couche/gestionCouches.js b/interfaces/navigateur/public/js/app/couche/gestionCouches.js index d5db8e55..c5fee7b9 100644 --- a/interfaces/navigateur/public/js/app/couche/gestionCouches.js +++ b/interfaces/navigateur/public/js/app/couche/gestionCouches.js @@ -74,13 +74,7 @@ define(['evenement', 'couche', 'blanc', 'limites', 'aide'], function(Evenement, opt = opt || {}; if (couche._getLayer()) { this.listeCouches.push(couche); - if(couche.obtenirTypeClasse() === "WMS"){ - setTimeout(function() { - that._ajouterCoucheCallbackEnd(couche, opt); - }, 1) - } else { - this._ajouterCoucheCallbackEnd(couche, opt); - } + this._ajouterCoucheCallbackEnd(couche, opt); }; }; @@ -154,6 +148,23 @@ define(['evenement', 'couche', 'blanc', 'limites', 'aide'], function(Evenement, return couches; }; + /** + * Obtenir la liste des couches ayant le nom donné en paramètre. + * @method + * @name GestionCouches#obtenirCouchesParNom + * @param {String} nom Nom recherché + * @returns {Tableau} Tableau de {@link Couche} + */ + GestionCouches.prototype.obtenirCouchesParNom = function(nom) { + var couches = []; + $.each(this.listeCouches, function(index, value){ + if(value.obtenirNom() === nom){ + couches.push(value); + } + }); + return couches; + }; + /** * Obtenir la liste des couches avec l'aide d'un regex * @method @@ -165,6 +176,7 @@ define(['evenement', 'couche', 'blanc', 'limites', 'aide'], function(Evenement, opt = opt || {}; var testerTitre = opt.testerTitre !== false ? true : false; var testerGroupe = opt.testerGroupe !== false ? true : false; + var testerNom = opt.testerNom !== false ? true : false; if(typeof regex === "string"){ var ignorerCase = opt.ignorerCase !== false ? 'i' : ''; @@ -185,7 +197,7 @@ define(['evenement', 'couche', 'blanc', 'limites', 'aide'], function(Evenement, var couches = []; $.each(this.listeCouches, function(index, value){ - if((testerTitre && regex.test(value.obtenirTitre())) || (testerGroupe && regex.test(value.obtenirGroupe()))){ + if((testerTitre && regex.test(value.obtenirTitre())) || (testerGroupe && regex.test(value.obtenirGroupe())) || (testerNom && regex.test(value.obtenirNom()))){ couches.push(value); } }); @@ -426,9 +438,28 @@ define(['evenement', 'couche', 'blanc', 'limites', 'aide'], function(Evenement, if(!couche.estFond() && couche.estActive()){ couche.desactiver(); + couche.gererStyleParentEnfantSelect(); } }); }; + + /** + * Désélectionner toutes les couches WMTS qui ne sont pas des fonds de carte + * @method + * @name GestionCouches#deselectionnerCouchesWMTS + * + */ + GestionCouches.prototype.deselectionnerCouchesWMTS = function(){ + + var tabCouches = this.obtenirCouchesParType("WMTS"); + + $.each(tabCouches, function(index, couche){ + + if(!couche.estFond() && couche.estActive()){ + couche.desactiver(); + } + }); + }; /** * Création de l'object GestionCouches.Controles diff --git a/interfaces/navigateur/public/js/app/couche/protocole/OSM.js b/interfaces/navigateur/public/js/app/couche/protocole/OSM.js index 22dacee4..a04f6f08 100644 --- a/interfaces/navigateur/public/js/app/couche/protocole/OSM.js +++ b/interfaces/navigateur/public/js/app/couche/protocole/OSM.js @@ -53,7 +53,7 @@ define(['couche'], function(Couche) { window.location.protocol+"//c.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png"]; break; case "humanitaire": - var HOTAttribution = '
© Contributions OpenStreetMap Humanitaire
'; + var HOTAttribution = '© Contributions OpenStreetMap Humanitaire'; var get_my_url = function(bounds) { var res = this.map.getResolution(); var x = Math.round ((bounds.left - this.maxExtent.left) / (res * this.tileSize.w)); diff --git a/interfaces/navigateur/public/js/app/couche/protocole/WMS.js b/interfaces/navigateur/public/js/app/couche/protocole/WMS.js index 4d1d95c1..992897a2 100644 --- a/interfaces/navigateur/public/js/app/couche/protocole/WMS.js +++ b/interfaces/navigateur/public/js/app/couche/protocole/WMS.js @@ -1,13 +1,13 @@ -/** +/** * Module pour l'objet {@link Couche.WMS}. * @module wms - * @requires couche + * @requires couche * @author Marc-André Barbeau, MSP * @version 1.0 */ define(['couche', 'aide', 'browserDetect'], function(Couche, Aide, BrowserDetect) { - /** + /** * Création de l'object Couche.WMS. * Pour la liste complète des paramètres, voir {@link Couche} * @constructor @@ -27,11 +27,11 @@ define(['couche', 'aide', 'browserDetect'], function(Couche, Aide, BrowserDetect if(!this.options.layerOL){ if (!this.options.url) { throw new Error("Igo.WMS a besoin d'un url"); - } - + } + if (!this.options.nom && !this.options.mode) { throw new Error("Igo.WMS a besoin d'un nom"); - } + } } if(this.options.nom){ @@ -43,42 +43,42 @@ define(['couche', 'aide', 'browserDetect'], function(Couche, Aide, BrowserDetect if(Aide.toBoolean(this.options.utiliserProxy)){ this.options.url=Aide.utiliserProxy(this.options.url, true); } - + this.defautOptions.version = "1.1.1"; - + this._optionsOL = { queryable: true, singleTile: !Aide.toBoolean(this.options.multiTuile) }; - + if(!this.options.mode){ this._init(); } }; - + WMS.prototype = new Couche(); WMS.prototype.constructor = WMS; - - /** + + /** * Initialisation de l'object WMS. * Appelé lors de la création. - * @method + * @method * @private * @name Couche.WMS#_init */ - WMS.prototype._init = function(target, callback, optCalback){ + WMS.prototype._init = function(target, callback, optCallback){ if (!this.options.layerOL){ Couche.prototype._init.call(this); - + var transparence = this.options.transparence || true; - + if(this.options.format === "jpeg" || this.options.format === "jpg"){ transparence = false; } - + var parametreWMS = { layers: this.options.nom, - transparent: transparence, + transparent: transparence, version: this.options.version }; if (this.options.mapdir){ @@ -88,7 +88,7 @@ define(['couche', 'aide', 'browserDetect'], function(Couche, Aide, BrowserDetect this._layer = new OpenLayers.Layer.WMS( this.options.titre||this.options.nom, this.options.url, - parametreWMS, + parametreWMS, this._optionsOL ); @@ -110,59 +110,70 @@ define(['couche', 'aide', 'browserDetect'], function(Couche, Aide, BrowserDetect this._layer.mergeNewParams(this.options.extraParams); } } - + if(this.options.mode){ Couche.prototype._ajoutCallback.call(this, target, callback, optCallback); } } else { this._layer = this.options.layerOL; + this.options.url = this._layer.url; + this.options.nom = this._layer.params.LAYERS.toString(); + this.options.titre = this._layer.name; + this.options.version = this._layer.params.VERSION; } - + this._layer.events.register('loadend',this,this._validerChargement); }; - /** + /** * Appelé lors de l'ajout de la couche à la carte si le mode GetCapabilities est activé. - * @method + * @method * @private * @name Couche.WMS#_getCapabilities */ - WMS.prototype._getCapabilities = function(target, callback, optCalback){ + WMS.prototype._getCapabilities = function(target, callback, optCallback){ var tjrsProxy = this.options.encodage ? true : false; + var that=this; + window.arboLoading = true; $.ajax({ - url: Aide.utiliserProxy(this.options.url, tjrsProxy),//this.options.url.split('?')[0], + url: Aide.utiliserProxy(that.options.url, tjrsProxy),//this.options.url.split('?')[0], data: { SERVICE: "WMS", - VERSION: this.options.version || this.defautOptions.version, + VERSION: that.options.version || that.defautOptions.version, REQUEST: "GetCapabilities", - _encodage: this.options.encodage //"wms_encoding" "ISO-8859-1" + _encodage: that.options.encodage, //"wms_encoding" "ISO-8859-1" + t: +new Date }, - //crossDomain: true, //utilisation du proxy - async:false, - context:this, + async:true, + context:that, dataType:'xml', dataFilter: function(response, type){ return jQuery.trim(response); }, success:function(response) { - this._getCapabilitiesSuccess(response, target, callback, optCalback); + that._getCapabilitiesSuccess(response, target, callback, optCallback); }, - error:function(e){this._getCapabilitiesError(e, target, callback, optCalback);} + error:function(e){that._getCapabilitiesError(e, target, callback, optCallback);} }); }; - - WMS.prototype._getCapabilitiesSuccess = function(response, target, callback, optCalback){ - var that=this; - if(!response){ - this._getCapabilitiesError(); + WMS.prototype._getCapabilitiesSuccess = function(response, target, callback, optCallback){ + var that=this; + if(!response || (response.getElementsByTagName && response.getElementsByTagName("BODY").length)){ + var errorMessage; + if(response){ + errorMessage = { + responseText: response.getElementsByTagName("BODY")[0].textContent + } + } + this._getCapabilitiesError(errorMessage); return false; } var xml=new OpenLayers.Format.WMSCapabilities().read(response); var iCL=0; var xmlOptions = {}; var capabilityLayers, arrayLayers, len; - //InfoFormat absent dans le fichier contexte alors on le prend + //InfoFormat absent dans le fichier contexte alors on le prend //dans le getCapabilities pour le nouveau GetInfo if(!this.options.infoFormat && xml.capability.request.getfeatureinfo !== undefined ){ var arrayInfoFormat = xml.capability.request.getfeatureinfo.formats; @@ -181,10 +192,10 @@ define(['couche', 'aide', 'browserDetect'], function(Couche, Aide, BrowserDetect len = arrayLayers.length; capabilityLayers=xml.capability.layers; } - $.each(capabilityLayers, function(key,value){ + $.each(capabilityLayers, function(key,value){ if((!that.options.nom) || jQuery.inArray(value.name, arrayLayers)>=0){ - iCL++; - if(!that.options._merge){ + iCL++; + if(!that.options._merge){ var parcourirLayerXML = function(value, groupe, groupeNiveauBase){ var layers=value; @@ -195,7 +206,7 @@ define(['couche', 'aide', 'browserDetect'], function(Couche, Aide, BrowserDetect groupe = groupe ? groupe+'/' : ""; groupe += value.title; } - + layers = value.nestedLayers; $.each(layers, function(key2, value2){ parcourirLayerXML(value2, groupe, groupeNiveauBase); @@ -203,15 +214,28 @@ define(['couche', 'aide', 'browserDetect'], function(Couche, Aide, BrowserDetect } else { xmlOptions = { titre: value.title, - droit: value.attribution ? value.attribution.href : undefined, echelleMin: value.minScale, - echelleMax: value.maxScale + echelleMax: value.maxScale, + aGetInfo: value.queryable }; + if(value.attribution){ + xmlOptions.droitTitre = value.attribution.title; + xmlOptions.droitLien = value.attribution.href; + if(value.attribution.logo){ + xmlOptions.droitLogo = value.attribution.logo.href; + xmlOptions.droitLogoLargeur = value.attribution.logo.width; + xmlOptions.droitLogoHauteur = value.attribution.logo.height; + } + } + if(value.dataURL && value.dataURL.format === 'igo'){ //"wms_dataurl_format" "igo" var idMeta = value.dataURL.href; var igoClassMeta = idMeta; xmlOptions.metadonnee = igoClassMeta; //"wms_dataurl_href" "/path/to/metdata3.xml" ou numéro de la metadata + } else if (value.dataURL && value.dataURL.format === 'text/html'){ + xmlOptions.metadonneeLien = value.dataURL.href; + xmlOptions.metadonnee = true; } $.extend(xmlOptions, that.options); @@ -234,7 +258,7 @@ define(['couche', 'aide', 'browserDetect'], function(Couche, Aide, BrowserDetect xmlOptions.wms_timedefault = value.dimensions.time.default; } target.ajouterCouche(new WMS(xmlOptions)); - } + } }; parcourirLayerXML(value, that.options.groupe, that.options.groupeNiveauBase); @@ -245,11 +269,20 @@ define(['couche', 'aide', 'browserDetect'], function(Couche, Aide, BrowserDetect } else if (iCL===1){ xmlOptions = { titre: value.title, - droit: value.attribution ? value.attribution.href : undefined, echelleMin: value.minScale, echelleMax: value.maxScale, - groupe: "Couches WMS ajoutées" + aGetInfo: value.queryable, + groupe: "Couches WMS ajoutées" }; + if(value.attribution){ + xmlOptions.droitTitre = value.attribution.title; + xmlOptions.droitLien = value.attribution.href; + if(value.attribution.logo){ + xmlOptions.droitLogo = value.attribution.logo.href; + xmlOptions.droitLogoLargeur = value.attribution.logo.width; + xmlOptions.droitLogoHauteur = value.attribution.logo.height; + } + } if (len===1){ return false; }; @@ -265,20 +298,25 @@ define(['couche', 'aide', 'browserDetect'], function(Couche, Aide, BrowserDetect } } }); + + window.arboLoading = false; if(iCL===0){ Aide.afficherMessageConsole("Couche(s) introuvable(s): " + this.options.nom); return false; } if(len===1 && that.options._merge){ this.options=$.extend(xmlOptions, this.options); - this._init(target, callback, optCalback); + this._init(target, callback, optCallback); } } - WMS.prototype._getCapabilitiesError = function(response, target, callback, optCalback){ + WMS.prototype._getCapabilitiesError = function(response, target, callback, optCallback){ + window.arboLoading = false; response = response || {}; - if(response.status != 200){ - Aide.afficherMessageConsole('Erreur WMS: GetCapabilities:
Le GetCapabilities pour \''+this.options.url+'\' a échoué.
'+response.responseText); + if(response.status != 200){ + var message = 'Erreur WMS: GetCapabilities:
Le GetCapabilities pour \''+this.options.url+'\' a échoué.
'+response.responseText; + console.log(message); + Aide.afficherMessageConsole(message); return false; } if(BrowserDetect.browser == "Explorer"){ @@ -287,15 +325,15 @@ define(['couche', 'aide', 'browserDetect'], function(Couche, Aide, BrowserDetect xmlDoc.validateOnParse = false; xmlDoc.resolveExternals = false; var parsed=xmlDoc.loadXML(response.responseText); - + if(!parsed) { var myErr = xmlDoc.parseError; Aide.afficherMessage('Erreur WMS: GetCapabilities', 'Le GetCapabilities pour \''+this.options.url+'\' a échoué.
'+myErr.reason, 'OK', 'ERREUR'); } else { - this._getCapabilitiesSuccess(xmlDoc, target, callback, optCalback); + this._getCapabilitiesSuccess(xmlDoc, target, callback, optCallback); } return false; - } + } Aide.afficherMessage('Erreur WMS: GetCapabilities', 'Le GetCapabilities pour \''+this.options.url+'\' a échoué.', 'OK', 'ERREUR'); } @@ -306,8 +344,10 @@ define(['couche', 'aide', 'browserDetect'], function(Couche, Aide, BrowserDetect Couche.prototype._ajoutCallback.call(this, target, callback, optCallback); } }; - + WMS.prototype._validerChargement = function(e, a){ + var that = this; + if(e.object.div.innerHTML.indexOf("olImageLoadError")>-1){ $.ajax({ url: Aide.utiliserProxy(decodeURIComponent($('