diff --git a/jalhyd_branch b/jalhyd_branch index d64531f1305e091791eac674c3a36d86b9e17ddd..3c757134f639b70824e3015c1c2631ce2b09c902 100644 --- a/jalhyd_branch +++ b/jalhyd_branch @@ -1 +1 @@ -devel +333-remous-renommer-la-ligne-d-eau-en-z-et-fournir-le-tirant-d-eau-d-apres-celle-ci diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 5be7fc6490d22a2085977ee37f375cf28cac738e..15eac95408a49c29f830397b606d7f95990029fc 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -123,6 +123,7 @@ import { DialogConfirmLoadSessionURLComponent } from "./components/dialog-confir import { StructureFieldsetContainerComponent } from "./components/structure-fieldset-container/structure-fieldset-container.component"; import { BasinFieldsetContainerComponent } from "./components/basin-fieldset-container/basin-fieldset-container.component"; import { PrebarrageService } from "./services/prebarrage.service"; +import { SelectSectionDetailsComponent } from "./components/select-section-details/select-section-details.component"; import { ServiceWorkerModule } from '@angular/service-worker'; import { environment } from '../environments/environment'; import { ServiceWorkerUpdateService } from "./services/service-worker-update.service"; @@ -266,7 +267,8 @@ const appRoutes: Routes = [ SelectFieldLineComponent, SessionPropertiesComponent, VarResultsComponent, - VerificateurResultsComponent + VerificateurResultsComponent, + SelectSectionDetailsComponent ], providers: [ // services ApplicationSetupService, diff --git a/src/app/calculators/courberemous/en.json b/src/app/calculators/courberemous/en.json index c238adfb5a991db7374b0e71fceb2536c7484eaa..8e4ac96ad750673367350a1a51b485dc15d12ef5 100644 --- a/src/app/calculators/courberemous/en.json +++ b/src/app/calculators/courberemous/en.json @@ -26,6 +26,8 @@ "Z2": "Downstream water elevation", "ZF1": "Upstream bottom elevation", "ZF2": "Downstream bottom elevation", + "Y": "Water depth", + "ZW": "Water line (m)", "UNIT_FLU": "m", "UNIT_HS": "m", diff --git a/src/app/calculators/courberemous/fr.json b/src/app/calculators/courberemous/fr.json index 3c84085311c6e37a869ee147787790da653b15d4..278c16ad429b35eaef592f49187980c96087a1e5 100644 --- a/src/app/calculators/courberemous/fr.json +++ b/src/app/calculators/courberemous/fr.json @@ -26,6 +26,8 @@ "Z2": "Cote de l'eau à l'aval", "ZF1": "Cote du fond à l'amont", "ZF2": "Cote du fond à l'aval", + "Y" : "Tirant d'eau", + "ZW" : "Ligne d'eau (m)", "UNIT_FLU": "m", "UNIT_HS": "m", diff --git a/src/app/components/generic-calculator/calculator.component.html b/src/app/components/generic-calculator/calculator.component.html index a61455db06fc8271a318e1955d57b18ba30bcfee..40cac6c063adec39c968550e7bb7e42cbc26d6e5 100644 --- a/src/app/components/generic-calculator/calculator.component.html +++ b/src/app/components/generic-calculator/calculator.component.html @@ -200,6 +200,8 @@ {{ uitextGenerateRuSp }} </button> + <select-section-details id="generate-cr-sps" *ngIf="hasCourbeRemousResults" [points]="courbeRemousPoints"></select-section-details> + <button mat-raised-button color="accent" id="generate-par-simulation" *ngIf="isPAR" (click)="generatePARSimulation()" [disabled]="! generatePARSimulationEnabled" [title]="uitextGenerateParSimulationTitle"> diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts index 901fa13436d5ae5e5bf4f864a65dafa7a1c0e1e0..49e81d946b6216bb123c23a0c64dea8c32cbe730 100644 --- a/src/app/components/generic-calculator/calculator.component.ts +++ b/src/app/components/generic-calculator/calculator.component.ts @@ -63,6 +63,8 @@ import { sprintf } from "sprintf-js"; import * as XLSX from "xlsx"; import { ServiceFactory } from "app/services/service-factory"; import { DefinedBoolean } from "app/definedvalue/definedboolean"; +import { FormulaireCourbeRemous } from "app/formulaire/definition/form-courbe-remous"; +import { RemousResults } from "app/results/remous-results"; @Component({ selector: "hydrocalc", @@ -710,6 +712,11 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe return this.is(CalculatorType.RegimeUniforme); } + // true if CourbeRemous results are present + public get hasCourbeRemousResults() { + return this.is(CalculatorType.CourbeRemous) && this.hasResults; + } + // true if current Nub is PAR public get isPAR() { return this.is(CalculatorType.Par); @@ -965,25 +972,25 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe * Génère une SectionParametree à partir du module RegimeUniforme en cours */ public async generateRuSp() { - const ru = (this._formulaire.currentNub as RegimeUniforme); - // copy section - const serialisedSection = ru.section.serialise(); - const sectionCopy = Session.getInstance().unserialiseSingleNub(serialisedSection, false).nub; - const secParam = new SectionParametree(sectionCopy as acSection); - // copy value of calculated param - const cp = ru.calculatedParam; - const scp = secParam.section.getParameter(cp.symbol); - if (cp.hasMultipleValues) { - scp.setValues(ru.result.getCalculatedValues().map(v => round(v, this.appSetupService.displayPrecision))); - } else { - scp.singleValue = ru.result.vCalc; - } - Session.getInstance().registerNub(secParam); - - const f: FormulaireDefinition = await this.formulaireService.createFormulaire(CalculatorType.SectionParametree, secParam); + const f = await this.formulaireService.generateParametricSectionForm(); // calculate f.doCompute(); // go to new SP + this.router.navigate(["/calculator", f.uid]); + } + + /** + * @returns liste des abscisses du graphe de courbes de remous + */ + public get courbeRemousPoints(): any[] { + if (this.hasCourbeRemousResults) { + const crForm = this._formulaire as FormulaireCourbeRemous; + for (const r of crForm.results) { + if (r instanceof RemousResults) { + return r.points; + } + } + } } public get generatePARSimulationEnabled(): boolean { diff --git a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts index 35c943ea68f282f7571f17e8838c6d2b3a72c303..5bbc25c8fe1b056c20b6aef522b49e9bc2d348e1 100644 --- a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts +++ b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts @@ -444,7 +444,7 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen label: ( this._results.variatedParameters.length > 0 ? this.getLegendForSeries(n) : - this.intlService.localizeText("INFO_LIB_Y") // ligne d'eau + this.intlService.localizeText("INFO_LIB_ZW") // ligne d'eau ), color: palette[ n % palette.length ] }); diff --git a/src/app/components/select-section-details/select-section-details.component.html b/src/app/components/select-section-details/select-section-details.component.html new file mode 100644 index 0000000000000000000000000000000000000000..4b3a06f5c1202f3ba8f91a0d2a21e8022944c2c7 --- /dev/null +++ b/src/app/components/select-section-details/select-section-details.component.html @@ -0,0 +1,5 @@ +<mat-select [placeholder]="uitextPlaceholder" (selectionChange)="generateCrSp($event.value)"> + <mat-option *ngFor="let p of points" [value]="p"> + {{ pointLabel(p) }} + </mat-option> +</mat-select> \ No newline at end of file diff --git a/src/app/components/select-section-details/select-section-details.component.scss b/src/app/components/select-section-details/select-section-details.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..c62ffafb0b9baab4bdc6fc24730e83df0ec3b666 --- /dev/null +++ b/src/app/components/select-section-details/select-section-details.component.scss @@ -0,0 +1,3 @@ +mat-select { + border: 1px solid #4dbbe9; +} diff --git a/src/app/components/select-section-details/select-section-details.component.ts b/src/app/components/select-section-details/select-section-details.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..55c21b523cead45096bfc15f39d2d733043aad92 --- /dev/null +++ b/src/app/components/select-section-details/select-section-details.component.ts @@ -0,0 +1,61 @@ +import { Component, Input } from '@angular/core'; +import { Router } from '@angular/router'; +import { FormulaireDefinition } from 'app/formulaire/definition/form-definition'; +import { FormulaireService } from 'app/services/formulaire.service'; +import { I18nService } from 'app/services/internationalisation.service'; +import { fv } from 'app/util'; +import { formattedValue } from 'jalhyd'; + +/** + * liste déroulante de boutons de génération de formulaire "section paramétrée" + */ + +@Component({ + selector: 'select-section-details', + templateUrl: './select-section-details.component.html', + styleUrls: ['./select-section-details.component.scss'] +}) +export class SelectSectionDetailsComponent { + private _points: any[]; + + /** + * points auxquels on peut créer un formulaire "section paramétrée" + */ + @Input() + public set points(ps: any[]) { + this._points = ps; + } + + public get points(): any[] { + return this._points; + } + + constructor( + private formulaireService: FormulaireService, + private router: Router, + private intlService: I18nService + ) { } + + public pointLabel(p: any): string { + const abs = this.intlService.localizeText("INFO_REMOUSRESULTS_ABSCISSE"); + const tirant = this.intlService.localizeText("INFO_REMOUSRESULTS_TIRANT"); + return abs + " : " + formattedValue(p.x, 1) + " - " + tirant + " : " + fv(p.y); + } + + /** + * Génère une SectionParametree à partir du module en cours + */ + public async generateCrSp(p: any) { + const f: FormulaireDefinition = await this.formulaireService.generateParametricSectionForm(p.y); + + // calculate form + f.doCompute(); + + // go to new form + this.router.navigate(["/calculator", f.uid]); + } + + public get uitextPlaceholder() { + return this.intlService.localizeText("INFO_REMOUSRESULTS_PARAM_SECTION_PLACEHOLDER"); + } +} diff --git a/src/app/results/remous-results.ts b/src/app/results/remous-results.ts index abb20aa69362c07f6dd26dd436b341d33190b0dc..6474180121bba3063eb77c3e80971d47cebf45ff 100644 --- a/src/app/results/remous-results.ts +++ b/src/app/results/remous-results.ts @@ -15,6 +15,12 @@ export class RemousResults extends CalculatorResults { /** pas de discrétisation */ private _Dx: number; + /** cote de fond amont */ + private _ZF1: number; + + /** cote de fond aval */ + private _ZF2: number; + /** longueur du bief */ private _Long: number; @@ -54,6 +60,11 @@ export class RemousResults extends CalculatorResults { /** pointer to form that instantiated this object */ protected _form: FormulaireDefinition; + /** + * liste des X,Y (fluvial ou torrentiel) + */ + private _points: any[]; + constructor(form?: FormulaireDefinition) { super(); this._form = form; @@ -75,17 +86,19 @@ export class RemousResults extends CalculatorResults { } public set parameters(p: CourbeRemousParams) { + const nub = p.parent as Nub; + // pente du fond - this._penteFond = (p.parent as Nub).getParameter("If").singleValue; + this._penteFond = nub.getParameter("If").singleValue; // hauteur de berge - this._hautBerge = (p.parent as Nub).getParameter("YB").singleValue; + this._hautBerge = nub.getParameter("YB").singleValue; // longueur du bief - this._Long = (p.parent as Nub).getParameter("Long").singleValue; + this._Long = nub.getParameter("Long").singleValue; // pas d'espace - this._Dx = (p.parent as Nub).getParameter("Dx").singleValue; + this._Dx = nub.getParameter("Dx").singleValue; // série de valeurs de X this._xValues = new ParamDefinition( @@ -93,6 +106,12 @@ export class RemousResults extends CalculatorResults { "ABSCISSE", ParamDomainValue.POS_NULL ); + + // cote de fond amont + this._ZF1 = nub.getParameter("ZF1").singleValue; + + // cote de fond aval + this._ZF2 = nub.getParameter("ZF2").singleValue; } public get log(): cLog { @@ -114,6 +133,35 @@ export class RemousResults extends CalculatorResults { return re.getValue("X"); }); this._xValues.setValues(abscissae); + + this.updatePoints(); + } + + private updatePoints() { + this._points = this._result.resultElements.map((re) => { + const X = re.getValue("X"); + + // cote de fond + const k = X / this._Long; + const Zf = (this._ZF2 - this._ZF1) * k + this._ZF1; + + // cote de l'eau + let Z = re.getValue("flu"); + if (Z === undefined) + Z = re.getValue("tor"); + + // tirant d'eau + const Y = Z - Zf; + + return { x: X, y: Y, z: Z }; + }); + } + + /* + * points pour lesquels on a des résultats + */ + public get points(): any[] { + return this._points; } public update() { @@ -131,6 +179,9 @@ export class RemousResults extends CalculatorResults { if (!this._hasExtra && re.getValue(this.extraParamSymbol)) { this._hasExtra = true; } + + if (this._hasFlu && this._hasTor && this._hasExtra ) + break; // micro optimisation : pas la peine de continuer à chercher } this._log.clear(); @@ -140,7 +191,8 @@ export class RemousResults extends CalculatorResults { this._varResults.variatedParameters = [ { param: this._xValues, values: this._xValues.paramValues } ]; this._varResults.result = this._result; const keys = []; - keys.push("Y"); // ligne d'eau + keys.push("ZW"); // ligne d'eau + keys.push("Y"); // tirant d'eau if (this._hasFlu) { keys.push("flu"); } diff --git a/src/app/services/formulaire.service.ts b/src/app/services/formulaire.service.ts index 83020d52734284438d807e65e6f402cb4fcc3127..19022be0bb65cf658472f29e979dd9f25c400aa3 100644 --- a/src/app/services/formulaire.service.ts +++ b/src/app/services/formulaire.service.ts @@ -21,7 +21,13 @@ import { LoiDebit, PbCloison, CreateStructure, - Structure + Structure, + SectionNub, + SectionParametree, + acSection, + round, + RegimeUniforme, + CourbeRemous } from "jalhyd"; import { ApplicationSetupService } from "./app-setup.service"; @@ -851,4 +857,37 @@ export class FormulaireService extends Observable { } } } + + /** + * Génère un formulaire SectionParametree à partir du module courant + * s'il est du type régime uniforme ou courbe de remous + */ + public async generateParametricSectionForm(Y?: number): Promise<FormulaireDefinition> { + if (this.currentForm.currentNub instanceof SectionNub) { + const sn: SectionNub = this.currentForm.currentNub; + if (sn instanceof RegimeUniforme || sn instanceof CourbeRemous) { + // copy section + const serialisedSection = sn.section.serialise(); + const sectionCopy: acSection = Session.getInstance().unserialiseSingleNub(serialisedSection, false).nub as acSection; + if (Y !== undefined) { + sectionCopy.prms.Y.singleValue = Y; + } + const secParam = new SectionParametree(sectionCopy); + if (sn instanceof RegimeUniforme) { + // copy value of calculated param + const cp: ParamDefinition = sn.calculatedParam; + const scp: ParamDefinition = secParam.section.getParameter(cp.symbol); + if (cp.hasMultipleValues) { + scp.setValues(sn.result.getCalculatedValues().map(v => round(v, this.appSetupService.displayPrecision))); + } else { + scp.singleValue = sn.result.vCalc; + } + } + Session.getInstance().registerNub(secParam); + + return await this.createFormulaire(CalculatorType.SectionParametree, secParam); + } + } + return Promise.reject("cannot create parametric section from current form"); + } } diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json index 4e7499a2b3d994c21c36285f4bcb1ffa11cc1887..6ac8ce559ee4a307c510e6ebdab1ed70a5fb7068 100755 --- a/src/locale/messages.en.json +++ b/src/locale/messages.en.json @@ -577,9 +577,10 @@ "INFO_REMOUSRESULTS_ABSCISSE": "Abscissa", "INFO_REMOUSRESULTS_BERGE": "Embankment", "INFO_REMOUSRESULTS_FOND": "Bottom", - "INFO_REMOUSRESULTS_TIRANT": "Water depth (m)", + "INFO_REMOUSRESULTS_TIRANT": "Water depth", "INFO_REMOUSRESULTS_TIRANTCRITIQUE": "Critical water level", "INFO_REMOUSRESULTS_TIRANTNORMAL": "Normal water level", + "INFO_REMOUSRESULTS_PARAM_SECTION_PLACEHOLDER": "Generate a parametric section for...", "INFO_REPORT_BUG_BODY": "This is an issue report.\n\nPlease describe quickly the issue you encountered, and the steps you followed:\n\n\n\n\n--- Current session state - do not modify text below ---\n------------------------------------------------------------------------\n\n", "INFO_REPORT_BUG_SUBJECT": "Issue report", "INFO_REQUIRES": "requires", diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json index 9aa28d5f1245fc1e43fd6e6d889181f82fff0c00..24135323659bf1aafcebc9ba8881f9ffe3e84e60 100755 --- a/src/locale/messages.fr.json +++ b/src/locale/messages.fr.json @@ -578,9 +578,10 @@ "INFO_REMOUSRESULTS_ABSCISSE": "Abscisse", "INFO_REMOUSRESULTS_BERGE": "Berge", "INFO_REMOUSRESULTS_FOND": "Fond", - "INFO_REMOUSRESULTS_TIRANT": "Tirant d'eau (m)", + "INFO_REMOUSRESULTS_TIRANT": "Tirant d'eau", "INFO_REMOUSRESULTS_TIRANTCRITIQUE": "Tirant d'eau critique", "INFO_REMOUSRESULTS_TIRANTNORMAL": "Tirant d'eau normal", + "INFO_REMOUSRESULTS_PARAM_SECTION_PLACEHOLDER": "Générer une section paramétrée pour...", "INFO_REPORT_BUG_BODY": "Ceci est un rapport d'erreur.\n\nMerci de décrire rapidement ci-dessous le problème rencontré, et les étapes qui vous y ont mené:\n\n\n\n\n--- État de la session en cours - ne pas modifier le texte ci-dessous ---\n--------------------------------------------------------------------------------------------\n\n", "INFO_REPORT_BUG_SUBJECT": "Rapport d'erreur", "INFO_REQUIRES": "dépend de",