source: spip-zone/_plugins_/hydraulic/trunk/hyd_inc/form_courbe_remous.class.php @ 103636

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

Courbe de remous : correction bug sur pente négative
Il faut accepter les valeurs négatives sur le champ "Pente du fond" et décaler le graph pour avoir des altitudes débutant à 0.

File size: 12.6 KB
Line 
1<?php
2include_spip('hyd_inc/form_section.abstract.class');
3
4class form_courbe_remous extends form_section {
5
6        // Définition du nombre de colonnes du formulaire
7        protected $nb_col = 2;
8
9        function __construct() {
10
11                $this->bFVC = false; // Ce n'est pas un formulaire avec les boutons fixe, varie, calcul
12
13                $this->saisies['cond_lim']    = array(
14                        'condition_limite',
15                        array(
16                                'rQ'     =>array('debit_amont',2,'op'),
17                                'rYaval' =>array('h_aval_imposee',0.4,'pn'),
18                                'rYamont'=>array('h_amont_imposee',0.15,'pn')
19                        ),
20                        'fix'
21                );
22
23                $this->saisies['param_calc']  = array(
24                        'param_calcul',
25                        array(
26                                'rDx'    =>array('pas_discret',5,'op'),
27                                'rPrec'  =>array('precision_calc',0.001,'op'),
28                                'Methode' => array('choix_resolution','form_courbe_remous_methode','s')
29                        ),
30                        'fix'
31                );
32
33                $this->saisies['val_a_cal'] = array(
34                        'donnee_calc',
35                        array(
36                                'val_a_cal' => array('choix_donnee_calc','form_calcul_section_valacal','s')
37                        ),
38                        'fix'
39                );
40                parent::__construct(true);
41
42                foreach($this->saisies as &$saisie) {
43                        $saisie[2] = 'fix';
44                }
45        }
46
47
48        public function charger() {
49                $valeurs = parent::charger(true);
50                $valeurs = array_merge($valeurs,
51                        array(
52                                'choix_section' => 'FT',
53                                'val_a_cal'  => 'none',
54                                'choix_champs_select' => array_merge(
55                                        array('none' => 'aucune'),
56                                        $this->champs_select_calc
57                                )
58                        )
59                );
60                if(self::DBG_CHARGER) spip_log($valeurs,'hydraulic',_LOG_DEBUG);
61                return $valeurs;
62        }
63
64
65        protected function calculer() {
66                $this->creer_section_param();
67
68                // On transforme les champs du tableau des données du formulaire en variables
69                extract($this->data, EXTR_OVERWRITE|EXTR_REFS);
70
71                include_spip('hyd_inc/courbe_remous');
72
73                $oLog = &$this->oLog;
74
75                // On calcule les données pour créer un cache et afficher le résultat
76                $this->oLog->Add(_T('hydraulic:largeur_berge').' = '.format_nombre($this->oSn->rLargeurBerge,$this->oP->iPrec).' m');
77                $this->oLog->Add(_T('hydraulic:h_critique').' = '.format_nombre($this->oSn->CalcGeo('Yc'),$this->oP->iPrec).' m');
78                $this->oLog->Add(_T('hydraulic:h_normale').' = '.format_nombre($this->oSn->CalcGeo('Yn'),$this->oP->iPrec).' m');
79
80                // Calcul des courbes de remous
81                $aC = array(); // deux items (Flu et Tor) composé d'un vecteur avec key=X et value=Y
82
83                // Calcul depuis l'aval
84                if($this->oSn->rHautCritique <= $rYaval) {
85                        $this->oLog->Add(_T('hydraulic:calcul_fluvial'));
86                        $oCRF = new cCourbeRemous($this->oLog, $this->oP, $this->oSn, $rDx);
87                        $aC['Flu'] = $oCRF->calcul($rYaval, $rLong, $Methode);
88                }
89                else {
90                        $this->oLog->Add(_T('hydraulic:pas_calcul_depuis_aval'));
91                }
92
93                // Calcul depuis l'amont
94                if($this->oSn->rHautCritique >= $rYamont) {
95                        $this->oLog->Add(_T('hydraulic:calcul_torrentiel'));
96                        $oCRT = new cCourbeRemous($this->oLog, $this->oP, $this->oSn, -$rDx);
97                        $aC['Tor'] = $oCRT->calcul($rYamont, $rLong, $Methode);
98                }
99                else {
100                        $this->oLog->Add(_T('hydraulic:pas_calcul_depuis_amont'));
101                }
102                spip_log($aC,'hydraulic',_LOG_DEBUG);
103
104                // Détection du ressaut hydraulique
105                $bDetectRessaut = true;
106                if($bDetectRessaut && isset($aC['Flu']) && isset($aC['Tor'])) {
107                        if(count($aC['Flu']) > count($aC['Tor']) || (count($aC['Flu']) == count($aC['Tor']) && $this->oSn->Calc('Imp', end($aC['Flu'])) > $this->oSn->Calc('Imp', end($aC['Tor'])))) {
108                                // La courbe fluviale va jusqu'au bout
109                                $sCC = 'Flu';
110                                $sCN = 'Tor';
111                                $iSens = 1; // On cherche l'aval du ressaut
112                                $sSens = _T('hydraulic:amont');
113                        } else {
114                                // La courbe torrentielle va jusqu'au bout
115                                $sCC = 'Tor';
116                                $sCN = 'Flu';
117                                $iSens = -1; // On cherche l'amont du ressaut
118                                $sSens = _T('hydraulic:aval');
119                        }
120                        $trX = array_reverse(array_keys($aC[$sCN])); // Parcours des sections de la ligne d'eau la plus courte
121                        $bRessaut = false;
122                        foreach($trX as $rX) {
123                                // Calcul de l'abscisse de la section dans l'autre régime
124                                $Yco = $this->oSn->Calc('Yco', $aC[$sCN][$rX]); // Y conjugué
125                                $rLongRst = 5 * abs($aC[$sCN][$rX] - $Yco); // Longueur du ressaut
126                                $xRst = $rX + round($iSens * $rLongRst / $rDx) * $rDx; // Abscisse où comparer Yconj et Y
127                                $xRst = sprintf('%1.'.round($this->oP->iPrec).'f',$xRst);
128                                //spip_log("\nrX=$rX xRst=$xRst Yco=$Yco",'hydraulic',_LOG_DEBUG);
129                                if(isset($aC[$sCC][$xRst])) {
130                                        // Hauteur décalée de la longueur du ressaut (il faut gérer la pente du fond)
131                                        $Ydec = $aC[$sCC][$xRst] + $rLongRst * $this->oP->rIf * $iSens;
132                                        spip_log("\nrX=$rX xRst=$xRst Yco=$Yco Ydec=$Ydec",'hydraulic',_LOG_DEBUG);
133                                        if(($Yco - $Ydec) > 0) {
134                                                $this->oLog->Add(_T('hydraulic:ressaut_hydrau', array('Xmin'=>min($rX,$xRst), 'Xmax'=>max($rX,$xRst))));
135                                                spip_log("rX=$rX xRst=$xRst",'hydraulic',_LOG_DEBUG);
136                                                // Modification de la ligne d'eau CC
137                                                foreach(array_keys($aC[$sCN]) as $rXCC) {
138                                                        if($iSens * ($rXCC - $rX) < 0) {
139                                                                unset($aC[$sCC][$rXCC]);
140                                                        } elseif($rXCC == $rX) {
141                                                                $aC[$sCC][$rXCC] = $aC[$sCN][$rXCC];
142                                                                break;
143                                                        }
144                                                }
145                                                // Modification de la ligne d'eau CN
146                                                foreach($trX as $rXCN) {
147                                                        if($iSens * ($rXCN - $xRst) > 0) {
148                                                                unset($aC[$sCN][$rXCN]);
149                                                        } elseif($rXCN == $xRst) {
150                                                                $aC[$sCN][$rXCN] = $aC[$sCC][$rXCN];
151                                                                break;
152                                                        }
153                                                }
154                                                $bRessaut = true;
155                                                break;
156                                        }
157                                }
158                        }
159                        if(!$bRessaut) {
160                                // Le ressaut est en dehors du canal
161                                $this->oLog->Add(_T('hydraulic:ressaut_dehors', array('Sens' => $sSens, 'X' => end($trX))));
162                                $aC[$sCN] = array();
163                        }
164                }
165
166                // Définition des abscisses
167                $trX = array();
168                if(isset($aC['Flu'])) $trX = array_merge($trX, array_keys($aC['Flu']));
169                if(isset($aC['Tor'])) $trX = array_merge($trX, array_keys($aC['Tor']));
170                $trX = array_unique($trX, SORT_NUMERIC);
171                sort($trX, SORT_NUMERIC);
172
173                // Calcul de la variable à calculer
174                $this->data['ValCal'] = $val_a_cal;
175                $tRes = array();
176                if($val_a_cal != 'none') {
177                        foreach($trX as $rX) {
178                                $rY = false;
179                                if(isset($aC['Flu'][$rX]) && !isset($aC['Tor'][$rX])) {
180                                        $rY = $aC['Flu'][$rX];
181                                }
182                                if(isset($aC['Tor'][$rX])) {
183                                        if(!isset($aC['Flu'][$rX]) || (isset($aC['Flu'][$rX]) && $aC['Flu'][$rX]==$aC['Tor'][$rX])) {
184                                                $rY = $aC['Tor'][$rX];
185                                        }
186                                }
187                                if($rY !== false) {
188                                        if(!in_array($val_a_cal,array('Yn', 'Yc', 'Hsc'))){
189                                                $tRes[$rX] = $this->oSn->Calc($val_a_cal, $rY);
190                                        }
191                                        else{
192                                                $tRes[$rX] = $this->oSn->CalcGeo($val_a_cal, $rY);
193                                        }
194                                }
195                        }
196                }
197
198                return array_merge(
199                        $aC,
200                        array(
201                                'trX' => $trX,
202                                'tRes' => $tRes
203                        )
204                );
205        }
206
207
208        /** ************************************************************************
209        * Affichage des tableaux et graphiques des résultats des calculs
210        * @return Chaîne de caractère avec le code HTML à afficher
211        ***************************************************************************/
212        protected function afficher_result() {
213                // Code de langue du champ de la valeur calculée
214                if($this->data['ValCal'] != 'none') {
215                        $sCodeLangValCal = $this->champs_select_calc[$this->data['ValCal']];
216                        $sLibValCal = _T("hydraulic:$sCodeLangValCal");
217                } else {
218                        $sLibValCal = '';
219                }
220
221                // Gestion du graphique affichant la variable à calculer
222                if(in_array($this->data['ValCal'], array('Hs', 'Hsc', 'Yf', 'Yt', 'Yco')))
223                {
224                        // Affichage d'une courbe supplémentaire sur le graphique courbe de remous
225                        $choix_graph = 'courbe';
226                }
227                elseif(in_array($this->data['ValCal'], array('B', 'P', 'S', 'R', 'V', 'Fr', 'J', 'I-J', 'Imp', 'Tau0')))
228                {
229                        // Affichage de la donnée sur un nouveau graphique
230                        $choix_graph = 'graph';
231                }
232                else
233                {
234                        // Pas de graph pour la hauteur normale et la hauteur critique qui sont déjà affichés par défaut
235                        $choix_graph = 'none';
236                }
237
238                //Construction d'un tableau des indices x combinant les abscisses des 2 lignes d'eau
239                $trX = $this->result['trX'];
240
241                /***************************************************************************
242                *                        Affichage du graphique
243                ****************************************************************************/
244                include_spip('hyd_inc/graph.class');
245                $oGraph = new cGraph();
246                // Cote des berges
247                $oGraph->AddSerie(
248                        'berge',
249                        $trX,
250                        $this->oP->rYB,  // La cote des berges sera calculée à partir de la pente fournie dans GetGraph
251                        '#C58f50',
252                        'lineWidth:1'
253                );
254                // Cote du fond
255                $oGraph->AddSerie(
256                        'fond',
257                        $trX,
258                        0,  // La cote du fond sera calculée à partir de la pente fournie dans GetGraph
259                        '#753f00',
260                        'lineWidth:1, fill:true'
261                );
262                // Ligne d'eau fluviale
263                if(isset($this->result['Flu'])) {
264                        $oGraph->AddSerie(
265                                'ligne_eau_fluviale',
266                                array_keys($this->result['Flu']),
267                                array_values($this->result['Flu']),
268                                '#0093bd',
269                                'lineWidth:3, showMarker:true, markerOptions:{style:\'filledCircle\', size:8}'
270                        );
271                }
272                // Ligne d'eau torrentielle
273                if(isset($this->result['Tor'])) {
274                        $oGraph->AddSerie(
275                                'ligne_eau_torrentielle',
276                                array_keys($this->result['Tor']),
277                                array_values($this->result['Tor']),
278                                '#77a3cd',
279                                'lineWidth:3, showMarker:true, markerOptions:{style:\'filledCircle\', size:8}'
280                        );
281                }
282                // Hauteur critique
283                if(is_numeric($this->oSn->rHautCritique)) {
284                        $oGraph->AddSerie(
285                                'h_critique',
286                                $trX,
287                                $this->oSn->rHautCritique,  // La cote du fond sera calculée à partir de la pente fournie dans GetGraph
288                                '#ff0000',
289                                'lineWidth:2'
290                        );
291                }
292                // Hauteur normale
293                if(is_numeric($this->oSn->rHautNormale)) {
294                        $oGraph->AddSerie(
295                                'h_normale',
296                                $trX,
297                                $this->oSn->rHautNormale,  // La cote du fond sera calculée à partir de la pente fournie dans GetGraph
298                                '#a4c537',
299                                'lineWidth:2'
300                        );
301                }
302
303                // Valeur calculée
304                if($choix_graph == 'courbe') {
305                        $oGraph->AddSerie(
306                                $sCodeLangValCal,
307                                array_keys($this->result['tRes']),
308                                array_values($this->result['tRes']),
309                                '#C17AF0',
310                                'lineWidth:3, showMarker:true, markerOptions:{style:\'filledCircle\', size:8}'
311                        );
312                }
313
314                // Décalage des données par rapport au fond
315                $oGraph->Decal(max(0,-$this->data['rIf']*$this->data['rLong']), $this->data['rIf'], $this->data['rLong']);
316
317                // Récupération du graphique
318                $echo = $oGraph->GetGraph('courbe_remous',400,600);
319
320                // Affichage du graphique
321                if($choix_graph == 'graph') {
322                        $echo .= $this->getGraph(
323                                _T('hydraulic:abscisse'),
324                                $sLibValCal,
325                                array_keys($this->result['tRes']),
326                                array_values($this->result['tRes'])
327                        );
328                }
329
330                // Journal de calcul
331                $echo .= $this->oLog->Result();
332
333                /***************************************************************************
334                *                   Affichage du tableau de données
335                ****************************************************************************/
336                $echo.='<table class="spip">
337                        <thead>
338                                <tr class="row_first">
339                                        <th scope="col" colspan="1" rowspan="2">'._T('hydraulic:abscisse').' (m)</th>
340                                        <th scope="col" colspan="2" rowspan="1">'._T('hydraulic:ligne_eau_fluviale').'</th>
341                                        <th scope="col" colspan="2" rowspan="1">'._T('hydraulic:ligne_eau_torrentielle').'</th>
342                                </tr>
343                                <tr class="row_first">
344                                        <th scope="col">'._T('hydraulic:tirant_eau').'</th>
345                                        <th scope="col">'.$sLibValCal.'</th>
346                                        <th scope="col">'._T('hydraulic:tirant_eau').'</th>
347                                        <th scope="col">'.$sLibValCal.'</th>
348                                </tr>
349                        </thead>
350                        <tbody>';
351                                $i=0;
352                                foreach($trX as $rX) {
353                                        $i+=1;
354                                        $echo.='<tr class="align_right ';
355                                                $echo.=($i%2==0)?'row_even':'row_odd';
356                                                $echo.='"><td>'.format_nombre($rX,$this->oP->iPrec).'</td>';
357                                                if(isset($this->result['tRes'][$rX])) {
358                                                        $sValCal = format_nombre($this->result['tRes'][$rX],$this->oP->iPrec);
359                                                } else {
360                                                        $sValCal = '-';
361                                                }
362                                                if(isset($this->result['Flu'][$rX])) {
363                                                        // On formalise les résultats, avec le nombre de chiffres aprés la virgule adéquat
364                                                        $echo .= '<td>'.format_nombre($this->result['Flu'][$rX],$this->oP->iPrec).'</td>';
365                                                        $echo .= "<td>$sValCal</td>";
366                                                }
367                                                else {
368                                                        $echo .= '<td></td><td></td>';
369                                                }
370                                                if(isset($this->result['Tor'][$rX])) {
371                                                        $echo .= '<td>'.format_nombre($this->result['Tor'][$rX],$this->oP->iPrec).'</td>';
372                                                        $echo .= "<td>$sValCal</td>";
373                                                }
374                                                else {
375                                                        $echo .= '<td></td><td></td>';
376                                                }
377                                        $echo .= '</tr>';
378                                }
379                        $echo.='</tbody>
380                </table>';
381
382                return $echo;
383        }
384
385
386        protected function get_champs_libelles() {
387                $lib = parent::get_champs_libelles();
388                foreach($this->champs_select_calc as $cle=>$champ) {
389                        $lib[$cle] = _T('hydraulic:'.$champ);
390                }
391                return $lib;
392        }
393}
394?>
Note: See TracBrowser for help on using the repository browser.