source: spip-zone/_plugins_/hydraulic/trunk/formulaires/courbe_remous.php @ 103452

Last change on this file since 103452 was 103452, checked in by dorch@…, 4 years ago

Courbe de remous : Ajout de la détection et représentation du ressaut hydraulique

File size: 14.1 KB
Line 
1<?php
2/**
3 *      @file formulaires/courbe_remous.php
4 *      Fonctions du formulaire CVT pour les courbes de remous
5 */
6
7/*      Copyright 2009-2012 Dorch <dorch@dorch.fr>, Médéric Dulondel
8 *
9 *      This program is free software; you can redistribute it and/or modify
10 *      it under the terms of the GNU General Public License as published by
11 *      the Free Software Foundation; either version 2 of the License, or
12 *      (at your option) any later version.
13 *
14 *      This program is distributed in the hope that it will be useful,
15 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *      GNU General Public License for more details.
18 *
19 *      You should have received a copy of the GNU General Public License
20 *      along with this program; if not, write to the Free Software
21 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 *      MA 02110-1301, USA.
23 */
24
25
26/* Tableau des champs à afficher dans le formulaire.
27 * On travaille avec les libelles non traduits pour pouvoir gérer
28 * le multilinguisme.
29 */
30function mes_saisies() {
31
32        // On récupère les champs communs à tous les formulaires à savoir les champs de section.
33        include_spip('hyd_inc/section');
34        $fieldset_champs = mes_saisies_section(true);
35
36        $fieldset_champs['Cond_lim']    = array(
37                'condition_limite',
38                array(
39                        'rQ'     =>array('debit_amont',2,'op'),
40                        'rYaval' =>array('h_aval_imposee',0.4,'pn'),
41                        'rYamont'=>array('h_amont_imposee',0.15,'pn')
42                )
43        );
44
45        $fieldset_champs['Param_calc']  = array(
46                'param_calcul',
47                array(
48                        'rDx'    =>array('pas_discret',5,'op'),
49                        'rPrec'  =>array('precision_calc',0.001,'op')
50                )
51        );
52        return $fieldset_champs;
53}
54
55
56// Définition des champs à lire dans le formulaire
57function getChamps() {
58
59        $tSaisie = mes_saisies();
60        $sTypeSection = _request('crTypeSection');
61        $tData = array();
62
63        foreach($tSaisie as $IdFS=>$FieldSet) {
64                // Si ce n'est pas une section ou la section définie...
65                if((substr($IdFS,0,1) != 'F') || ($IdFS == $sTypeSection)){
66                        // ... alors on parcourt notre deuxième tableau en ajoutant les champs nécessaires.
67                        foreach($FieldSet[1] as $Cle=>$Champ) {
68                                $tData[$IdFS.'_'.$Cle] = _request($IdFS.'_'.$Cle); // Valeur dans le formulaire
69                                $tCtrl[$IdFS.'_'.$Cle] = $Champ[2]; // Codes de vérification
70                        }
71                }
72        }
73        return array($tData,$tCtrl);
74}
75
76
77function formulaires_courbe_remous_charger_dist() {
78        // On charge les saisies et les champs qui nécessitent un accès par les fonctions
79        $tSaisie_section = mes_saisies();
80        $valeurs = array(
81                'crTypeSection' => 'FT',
82                'mes_saisies' => $tSaisie_section
83        );
84
85        // On charge tous les champs avec leur valeur
86        foreach($tSaisie_section as $CleFD=>$FieldSet) {
87                foreach($FieldSet[1] as $Cle=>$Champ) {
88                        $valeurs[$CleFD.'_'.$Cle] = $Champ[1];
89                }
90        }
91    $valeurs['choix_resolution'] = _request('choix_resolution');
92
93        return $valeurs;
94}
95
96function formulaires_courbe_remous_verifier_dist() {
97        $erreurs = array();
98        list($tData,$tCtrl) = getChamps();
99        include_spip('hyd_inc/formulaire');
100        return hyd_formulaires_verifier($tData,$tCtrl);
101}
102
103function formulaires_courbe_remous_traiter_dist() {
104        global $spip_lang;
105        include_spip('hyd_inc/section.class');
106        include_spip('hyd_inc/cache');
107        include_spip('hyd_inc/log.class');
108        include_spip('hyd_inc/courbe_remous');
109        include_spip('hyd_inc/graph.class');
110
111        $datas = array();
112        $echo = '';
113        $tSaisie = mes_saisies();
114        $tChUtil = array();
115        $crTypeSection = _request('crTypeSection');
116
117        // On récupère tous les champs utiles, à savoir les champs fixes, et les champs appartenant à la section choisie
118        foreach($tSaisie as $IdFS=>$FieldSet) {
119                if((substr($IdFS,0,1) != 'F') || ($IdFS == $crTypeSection)){
120                        foreach($FieldSet[1] as $Cle=>$Champ) {
121                                $tChUtil[] = $IdFS.'_'.$Cle;
122                        }
123                }
124        }
125
126        //On récupère tous les champs utiles dans le tableau datas
127        foreach($tChUtil as $champ) {
128                if (_request($champ)){
129                        $datas[$champ] = _request($champ);
130                }
131
132                $datas[$champ] = str_replace(',','.',$datas[$champ]); // Bug #574
133        }
134
135        // On ajoute la langue en cours pour différencier le fichier de cache par langue
136        $datas['sLang'] = $spip_lang;
137
138        // Nom du fichier en cache pour calcul déjà fait
139        $CacheFileName=md5(serialize($datas));
140
141        // Initialisation de la classe chargée d'afficher le journal de calcul
142        $oLog = new cLog();
143
144        //Transformation des variables contenues dans $datas
145        foreach($datas as $champ=>$data) {
146                ${$champ}=$data;
147        }
148
149        // Contrôle du nombre de pas d'espace maximum
150        $iPasMax = 1000;
151        if($c_bief_rLong / $Param_calc_rDx > $iPasMax) {
152                $Param_calc_rDx = $c_bief_rLong / $iPasMax;
153                $oLog->Add(_T('hydraulic:pas_nombre').' > '.$iPasMax.' => '._T('hydraulic:pas_ajustement').$Param_calc_rDx.' m');
154        }
155        //spip_log(array($Cond_lim_rYaval,$c_bief_rKs,$Cond_lim_rQ,$c_bief_rLong,$c_bief_rIf,$Param_calc_rDx,$Param_calc_rPrec),'hydraulic');
156
157        // Enregistrement des paramètres dans les classes qui vont bien
158        $oParam= new cParam($c_bief_rKs,$Cond_lim_rQ,$c_bief_rIf,$Param_calc_rPrec,$c_bief_rYB);
159
160        // Création d'un objet de type Section selon la section choisie.
161        switch($crTypeSection) {
162                case 'FT':
163                include_spip('hyd_inc/sectionTrapez.class');
164                $oSection=new cSnTrapez($oLog,$oParam,$FT_rLargeurFond,$FT_rFruit);
165                break;
166
167                case 'FR':
168                include_spip('hyd_inc/sectionRectang.class');
169                $oSection=new cSnRectang($oLog,$oParam,$FR_rLargeurFond);
170                break;
171
172                case 'FC':
173                include_spip('hyd_inc/sectionCirc.class');
174                $oSection=new cSnCirc($oLog,$oParam,$FC_rD);
175                break;
176
177                case 'FP':
178                include_spip('hyd_inc/sectionPuiss.class');
179                $oSection=new cSnPuiss($oLog,$oParam,$FP_rCoef,$FP_rLargeurBerge);
180                break;
181
182                default:
183                include_spip('hyd_inc/sectionTrapez.class');
184                $oSection=new cSnTrapeze($oLog,$oParam,$FT_rLargeurFond,$FT_rFruit);
185        }
186
187        /***************************************************************************
188        *                        Calcul de la ligne d'eau
189        ****************************************************************************/
190        $bNoCache = true; // false pour activer le cache !!!! BUG : Il manque la méthode résolution comme clé de différenciation de $CacheFileName !!!!
191        if(!$bNoCache && is_file(HYD_CACHE_DIRECTORY.$CacheFileName)) {
192                // On récupère toutes les données dans un cache déjà créé
193                list($aC,$sLog,$oSection->rHautCritique,$oSection->rHautNormale) = ReadCacheFile($CacheFileName);
194        }
195        else {
196                // On calcule les données pour créer un cache et afficher le résultat
197                $oLog->Add(_T('hydraulic:largeur_berge').' = '.format_nombre($oSection->rLargeurBerge,$oParam->iPrec).' m');
198                $oLog->Add(_T('hydraulic:h_critique').' = '.format_nombre($oSection->CalcGeo('Yc'),$oParam->iPrec).' m');
199                $oLog->Add(_T('hydraulic:h_normale').' = '.format_nombre($oSection->CalcGeo('Yn'),$oParam->iPrec).' m');
200
201                // Calcul des courbes de remous
202                $aC = array(); // deux items (Flu et Tor) composé d'un vecteur avec key=X et value=Y
203
204                // Calcul depuis l'aval
205                if($oSection->rHautCritique <= $Cond_lim_rYaval) {
206                        $oLog->Add(_T('hydraulic:calcul_fluvial'));
207                        $oCRF = new cCourbeRemous($oLog, $oParam, $oSection, $Param_calc_rDx);
208                        $aC['Flu'] = $oCRF->calcul($Cond_lim_rYaval, $c_bief_rLong, _request('choix_resolution'));
209                }
210                else {
211                        $oLog->Add(_T('hydraulic:pas_calcul_depuis_aval'));
212                }
213
214                // Calcul depuis l'amont
215                if($oSection->rHautCritique >= $Cond_lim_rYamont) {
216                        $oLog->Add(_T('hydraulic:calcul_torrentiel'));
217                        $oCRT = new cCourbeRemous($oLog, $oParam, $oSection, -$Param_calc_rDx);
218                        $aC['Tor'] = $oCRT->calcul($Cond_lim_rYamont, $c_bief_rLong, _request('choix_resolution'));
219                }
220                else {
221                        $oLog->Add(_T('hydraulic:pas_calcul_depuis_amont'));
222                }
223                spip_log($oParam,'hydraulic',_LOG_DEBUG);
224                spip_log($aC,'hydraulic',_LOG_DEBUG);
225
226                // Détection du ressaut hydraulique
227                $bDetectRessaut = true;
228                if($bDetectRessaut && isset($aC['Flu']) && isset($aC['Tor'])) {
229                        if(count($aC['Flu']) > count($aC['Tor']) || (count($aC['Flu']) == count($aC['Tor']) && $oSection->Calc('Imp', end($aC['Flu'])) > $oSection->Calc('Imp', end($aC['Tor'])))) {
230                                // La courbe fluviale va jusqu'au bout
231                                $sCC = 'Flu';
232                                $sCN = 'Tor';
233                                $iSens = 1; // On cherche l'aval du ressaut
234                                $sSens = _T('hydraulic:amont');
235                        } else {
236                                // La courbe torrentielle va jusqu'au bout
237                                $sCC = 'Tor';
238                                $sCN = 'Flu';
239                                $iSens = -1; // On cherche l'amont du ressaut
240                                $sSens = _T('hydraulic:aval');
241                        }
242                        $trX = array_reverse(array_keys($aC[$sCN])); // Parcours des sections de la ligne d'eau la plus courte
243                        $bRessaut = false;
244                        foreach($trX as $rX) {
245                                // Calcul de l'abscisse de la section dans l'autre régime
246                                $Yco = $oSection->Calc('Yco', $aC[$sCN][$rX]); // Y conjugué
247                                $rLongRst = 5 * abs($aC[$sCN][$rX] - $Yco); // Longueur du ressaut
248                                $xRst = $rX + round($iSens * $rLongRst / $Param_calc_rDx) * $Param_calc_rDx; // Abscisse où comparer Yconj et Y
249                                $xRst = sprintf('%1.'.round($oParam->iPrec).'f',$xRst);
250                                //spip_log("\nrX=$rX xRst=$xRst Yco=$Yco",'hydraulic',_LOG_DEBUG);
251                                if(isset($aC[$sCC][$xRst])) {
252                                        // Hauteur décalée de la longueur du ressaut (il faut gérer la pente du fond)
253                                        $Ydec = $aC[$sCC][$xRst] + $rLongRst * $oParam->rIf * $iSens;
254                                        spip_log("\nrX=$rX xRst=$xRst Yco=$Yco Ydec=$Ydec",'hydraulic',_LOG_DEBUG);
255                                        if($iSens * ($Yco - $Ydec) > 0) {
256                                                $oLog->Add(_T('hydraulic:ressaut_hydrau', array('Xmin'=>min($rX,$xRst), 'Xmax'=>max($rX,$xRst))));
257                                                spip_log("rX=$rX xRst=$xRst",'hydraulic',_LOG_DEBUG);
258                                                // Modification de la ligne d'eau CC
259                                                foreach(array_keys($aC[$sCN]) as $rXCC) {
260                                                        if($iSens * ($rXCC - $rX) < 0) {
261                                                                unset($aC[$sCC][$rXCC]);
262                                                        } elseif($rXCC == $rX) {
263                                                                $aC[$sCC][$rXCC] = $aC[$sCN][$rXCC];
264                                                                break;
265                                                        }
266                                                }
267                                                // Modification de la ligne d'eau CN
268                                                foreach($trX as $rXCN) {
269                                                        if($iSens * ($rXCN - $xRst) > 0) {
270                                                                unset($aC[$sCN][$rXCN]);
271                                                        } elseif($rXCN == $xRst) {
272                                                                $aC[$sCN][$rXCN] = $aC[$sCC][$rXCN];
273                                                                break;
274                                                        }
275                                                }
276                                                $bRessaut = true;
277                                                break;
278                                        }
279                                }
280                        }
281                        if(!$bRessaut) {
282                                // Le ressaut est en dehors du canal
283                                $oLog->Add(_T('hydraulic:ressaut_dehors', array('Sens' => $sSens, 'X' => end($trX))));
284                                $aC[$sCN] = array();
285                        }
286                }
287
288                //Production du journal de calcul
289                $sLog = $oLog->Result();
290                //Enregistrement des données dans fichier cache
291                WriteCacheFile($CacheFileName,array($aC,$sLog,$oSection->rHautCritique,$oSection->rHautNormale));
292        }
293        //Construction d'un tableau des indices x combinant les abscisses des 2 lignes d'eau
294        $trX = array();
295        if(isset($aC['Flu'])) $trX = array_merge($trX, array_keys($aC['Flu']));
296        if(isset($aC['Tor'])) $trX = array_merge($trX, array_keys($aC['Tor']));
297        $trX = array_unique($trX, SORT_NUMERIC);
298        sort($trX, SORT_NUMERIC);
299        //~ spip_log($tr,'hydraulic'); // Debug
300
301
302        /***************************************************************************
303        *                        Affichage du graphique
304        ****************************************************************************/
305        $oGraph = new cGraph();
306        // Cote des berges
307        $oGraph->AddSerie(
308                'berge',
309                $trX,
310                $oParam->rYB,  // La cote des berges sera calculée à partir de la pente fournie dans GetGraph
311                '#C58f50',
312                'lineWidth:1'
313        );
314        // Cote du fond
315        $oGraph->AddSerie(
316                'fond',
317                $trX,
318                0,  // La cote du fond sera calculée à partir de la pente fournie dans GetGraph
319                '#753f00',
320                'lineWidth:1, fill:true'
321        );
322        // Ligne d'eau fluviale
323        if(isset($aC['Flu'])) {
324                $oGraph->AddSerie(
325                        'ligne_eau_fluviale',
326                        array_keys($aC['Flu']),
327                        array_values($aC['Flu']),
328                        '#0093bd',
329                        'lineWidth:3, showMarker:true, markerOptions:{style:\'filledCircle\', size:8}'
330                );
331        }
332        // Ligne d'eau torrentielle
333        if(isset($aC['Tor'])) {
334                $oGraph->AddSerie(
335                        'ligne_eau_torrentielle',
336                        array_keys($aC['Tor']),
337                        array_values($aC['Tor']),
338                        '#77a3cd',
339                        'lineWidth:3, showMarker:true, markerOptions:{style:\'filledCircle\', size:8}'
340                );
341        }
342        // Hauteur critique
343        if(is_numeric($oSection->rHautCritique)) {
344                $oGraph->AddSerie(
345                        'h_critique',
346                        $trX,
347                        $oSection->rHautCritique,  // La cote du fond sera calculée à partir de la pente fournie dans GetGraph
348                        '#ff0000',
349                        'lineWidth:2'
350                );
351        }
352        // Hauteur normale
353        if(is_numeric($oSection->rHautNormale)) {
354                $oGraph->AddSerie(
355                        'h_normale',
356                        $trX,
357                        $oSection->rHautNormale,  // La cote du fond sera calculée à partir de la pente fournie dans GetGraph
358                        '#a4c537',
359                        'lineWidth:2'
360                );
361        }
362
363        // Décalage des données par rapport au fond
364        $oGraph->Decal(0, $c_bief_rIf, $c_bief_rLong);
365
366        // Récupération du graphique
367        $echo .= $oGraph->GetGraph('graphique',400,600);
368
369
370        $echo .= $sLog;
371
372        /***************************************************************************
373        *                   Affichage du tableau de données
374        ****************************************************************************/
375        $echo.='<table class="spip">
376                <thead>
377                        <tr class="row_first">
378                                <th scope="col" colspan="1" rowspan="2">'._T('hydraulic:abscisse').' (m)</th>
379                                <th scope="col" colspan="2" rowspan="1">'._T('hydraulic:ligne_eau_fluviale').'</th>
380                                <th scope="col" colspan="2" rowspan="1">'._T('hydraulic:ligne_eau_torrentielle').'</th>
381                        </tr>
382                        <tr class="row_first">
383                                <th scope="col">'._T('hydraulic:tirant_eau').'</th>
384                                <th scope="col">Froude</th>
385                                <th scope="col">'._T('hydraulic:tirant_eau').'</th>
386                                <th scope="col">Froude</th>
387                        </tr>
388                </thead>
389                <tbody>';
390                        $i=0;
391                        foreach($trX as $rX) {
392                                $i+=1;
393                                $echo.='<tr class="align_right ';
394                                        $echo.=($i%2==0)?'row_even':'row_odd';
395                                        $echo.='"><td>'.format_nombre($rX,$oParam->iPrec).'</td>';
396                                        if(isset($aC['Flu'][$rX])) {
397                                                // On formalise les résultats, avec le nombre de chiffres aprés la virgule adéquat
398                                                $echo .= '<td>'.format_nombre($aC['Flu'][$rX],$oParam->iPrec).'</td>';
399                                                $echo .= '<td>'.format_nombre($oSection->Calc('Fr', $aC['Flu'][$rX]),$oParam->iPrec).'</td>';
400                                        }
401                                        else {
402                                                $echo .= '<td></td><td></td>';
403                                        }
404                                        if(isset($aC['Tor'][$rX])) {
405                                                $echo .= '<td>'.format_nombre($aC['Tor'][$rX],$oParam->iPrec).'</td>';
406                                                $echo .= '<td>'.format_nombre($oSection->Calc('Fr', $aC['Tor'][$rX]),$oParam->iPrec).'</td>';
407                                        }
408                                        else {
409                                                $echo .= '<td></td><td></td>';
410                                        }
411                                $echo .= '</tr>';
412                        }
413                $echo.='</tbody>
414        </table>';
415
416        $res['message_ok'] = $echo;
417
418        return $res;
419}
420?>
Note: See TracBrowser for help on using the repository browser.