diff --git a/public/css/form.css b/public/css/form.css index e4495b6..12d35d1 100644 --- a/public/css/form.css +++ b/public/css/form.css @@ -82,12 +82,18 @@ .header-grid.wissel-only, .header-grid.overweg-only, .header-grid.spoor-only { display: none; } -body.type-wissel .header-grid.wissel-only { display: grid; } +body.type-wissel .header-grid.wissel-only, +body.type-engelsman .header-grid.wissel-only, +body.type-kruising .header-grid.wissel-only { display: grid; } body.type-overweg .header-grid.overweg-only { display: grid; } body.type-spoor .header-grid.spoor-only { display: grid; } -.wissel-overview { display: none; } +.wissel-overview, +.engelsman-overview, +.kruising-overview { display: none; } body.type-wissel .wissel-overview { display: grid; } +body.type-engelsman .engelsman-overview { display: grid; } +body.type-kruising .kruising-overview { display: grid; } .overweg-overview { display: none; } body.type-overweg .overweg-overview { display: block; } @@ -97,17 +103,50 @@ body.type-spoor .spoor-overview { display: block; } .instruction-box.wissel-only, .instruction-box.overweg-only, -.instruction-box.spoor-only { display: none; } +.instruction-box.spoor-only, +.instruction-box.engelsman-only, +.instruction-box.kruising-only { display: none; } body.type-wissel .instruction-box.wissel-only { display: block; } body.type-overweg .instruction-box.overweg-only { display: block; } body.type-spoor .instruction-box.spoor-only { display: block; } +body.type-engelsman .instruction-box.engelsman-only { display: block; } +body.type-kruising .instruction-box.kruising-only { display: block; } .svg-link-row { display: none; } body.type-wissel .svg-link-row { display: block; } +/* Overwegbevloering spatial diagram */ +.ow-special-row { + display: flex; justify-content: center; gap: 24px; padding: 12px 0; + border-bottom: 1px solid #ddd; margin-bottom: 8px; +} +.ow-diagram { + display: grid; grid-template-columns: 100px 1fr 100px; + gap: 0; max-width: 700px; margin: 0 auto; min-height: 320px; +} +.ow-side { + display: flex; flex-direction: column; align-items: center; + justify-content: space-around; padding: 4px 0; +} +.ow-km-label { + font-size: 10px; font-weight: 700; color: var(--prorail-blue); + writing-mode: vertical-rl; text-orientation: mixed; + letter-spacing: 0.5px; margin-bottom: 8px; +} +.ow-center { + position: relative; display: flex; align-items: center; justify-content: center; +} +.ow-crossing-svg { width: 100%; height: 100%; max-height: 360px; } +.ow-weg-label { + position: absolute; font-size: 11px; font-weight: 700; color: #666; + left: 50%; transform: translateX(-50%); +} +.ow-weg-top { top: 4px; } +.ow-weg-bottom { bottom: 4px; } + +/* Generic photo grid for spoor overview */ .ov-photo-grid { - display: grid; grid-template-columns: repeat(3, 1fr); - gap: 12px; max-width: 500px; margin: 0 auto; padding: 16px 0; + display: flex; justify-content: center; gap: 24px; padding: 16px 0; } .ov-photo-grid .capture-label { padding: 12px 8px; } @@ -240,9 +279,21 @@ body.type-wissel .svg-link-row { display: block; } position: relative; border: 1px solid #aaa; display: flex; flex-direction: column; justify-content: center; align-items: center; min-height: 140px; overflow: hidden; } -.section-strip.puntstuk { background: var(--section-punt); border-radius: 4px 4px 0 0; } +.section-strip.puntstuk { background: var(--section-punt); } .section-strip.midden { background: var(--section-midden); } -.section-strip.tong { background: var(--section-tong); border-radius: 0 0 4px 4px; } +.section-strip.tong { background: var(--section-tong); } +.section-strip.kruisstuk { background: #80deea; } + +.eng-nr-label { + font-size: 11px; font-weight: 700; color: var(--prorail-blue); + text-align: center; align-self: center; +} + +.engelsman-overview, .kruising-overview { + grid-template-columns: 110px 1fr 110px; + grid-template-rows: auto; + gap: 0; max-width: 700px; margin: 0 auto 16px auto; align-items: stretch; +} .section-strip .section-name { font-size: 13px; font-weight: 700; color: var(--prorail-blue); text-align: center; z-index: 1; text-shadow: 0 0 4px rgba(255,255,255,0.8); diff --git a/public/index.html b/public/index.html index f903e4c..dd7ab21 100644 --- a/public/index.html +++ b/public/index.html @@ -49,6 +49,8 @@
+ + @@ -220,6 +222,18 @@ Foto's met bijzonderheden dienen in het opmerkingen-veld begeleid te worden in combinatie met het fotonummer.
+
+ Instructie: Eerste foto bevat het bordje met het wisselnummer. + Daarna dienen de foto's buitenom of rechtsom in volgorde te worden gemaakt. + Foto's met bijzonderheden dienen in het opmerkingen-veld begeleid te worden + in combinatie met het fotonummer. +
+
+ Instructie: Eerste foto bevat het bordje met het wisselnummer. + Daarna dienen de foto's links of rechtsom in volgorde te worden gemaakt. + Foto's met bijzonderheden dienen in het opmerkingen-veld begeleid te worden + in combinatie met het fotonummer. +
Instructie: Maak overzichtsfoto's vanuit beide richtingen van het spoorvak. Maak per beoordeeld segment minimaal een foto via de beoordelingstabel. @@ -275,38 +289,105 @@
+
+
+ +
+ Hoogste wisselnummer +
+ +
+
+
Puntstuk
gedeelte
Sectie 5
+
+
+
Kruisstuk
gedeelte
Sectie 4
+
+
+
Midden-
gedeelte
Sectie 3
+
+
+
Tong-
beweging
Sectie 2
+
+
+
Puntstuk
gedeelte
Sectie 1
+
+
+ +
+ Laagste wisselnummer +
+ +
+
+
+
+ +
+ Laagste wisselnummer +
+ +
+
+
Puntstuk
gedeelte
Sectie 4
+
+
+
Kruisstuk
gedeelte
Sectie 3
+
+
+
Midden-
gedeelte
Sectie 2
+
+
+
Puntstuk
gedeelte
Sectie 1
+
+
+ +
+ Laagste wisselnummer + kruisnummerbord +
+ +
+
-
- - - - - - +
+ + +
+
+
+ Lage kilometrering + + + + + + +
+
+ + + + + + + + + + + Overweg + + Weg + Weg +
+
+ Hoge kilometrering + + + + + + +
diff --git a/src/Application/exportService.js b/src/Application/exportService.js index 03902f7..f4d22b1 100644 --- a/src/Application/exportService.js +++ b/src/Application/exportService.js @@ -4,7 +4,7 @@ x.push(''); for (var [nr, data] of Object.entries(fd.scores)) { var fNrs = (fd.photos[nr] || []).map(function (_, i) { return fd.orderNr + '_loc' + nr + '_foto' + (i + 1); }).join('; '); - if (type === D.TYPE_WISSEL) { + if (D.usesDwlBal(type)) { x.push('' + nr + '' + I.esc(data.dwl || '') + '' + I.esc(data.bal || '') + '' + I.esc(fNrs) + '' + I.esc(data.opm || '') + ''); } else if (type === D.TYPE_OVERWEG) { x.push('' + I.esc(data.locatie || '') + '' + I.esc(data.score || '') + ''); @@ -25,7 +25,8 @@ x.push('' + I.esc(document.getElementById('inp_techjaar').value) + ''); x.push('' + I.esc(document.getElementById('inp_inspjaar').value) + ''); x.push('' + I.esc(document.getElementById('inp_opmerkingen').value) + ''); - if (fd.type === D.TYPE_WISSEL) { + var hasOvPhotos = Object.values(fd.overviewPhotos).some(function (p) { return p.length > 0; }); + if (hasOvPhotos) { x.push(''); for (var [pos, photos] of Object.entries(fd.overviewPhotos)) { photos.forEach(function (_, i) { diff --git a/src/Application/inspectionForm.js b/src/Application/inspectionForm.js index 441edb8..57d881d 100644 --- a/src/Application/inspectionForm.js +++ b/src/Application/inspectionForm.js @@ -11,25 +11,30 @@ A.applyFormType = function (type) { A.state.formData.type = type; var body = document.body; - body.classList.remove('type-wissel', 'type-overweg', 'type-spoor'); + body.classList.remove('type-wissel', 'type-overweg', 'type-spoor', 'type-engelsman', 'type-kruising'); body.classList.add('type-' + type); var thead = document.getElementById('assessmentHead'); - if (type === D.TYPE_WISSEL) { - thead.innerHTML = 'NrLocatie in wisselDWL ScoreBAL ScoreFoto\'sOpmerkingen'; - document.getElementById('formTitle').textContent = 'Duimstokformulier Gewoon of Symmetrisch wissel'; + var titles = {}; + titles[D.TYPE_WISSEL] = 'Duimstokformulier Gewoon of Symmetrisch wissel'; + titles[D.TYPE_ENGELSMAN] = 'Duimstokformulier Half of Heel Engelsman'; + titles[D.TYPE_KRUISING] = 'Duimstokformulier Kruising'; + titles[D.TYPE_OVERWEG] = 'Duimstokformulier Overwegbevloering'; + titles[D.TYPE_SPOOR] = 'Duimstokformulier Spoor'; + + if (D.usesDwlBal(type)) { + thead.innerHTML = 'NrLocatieDWL ScoreBAL ScoreFoto\'sOpmerkingen'; } else if (type === D.TYPE_OVERWEG) { thead.innerHTML = 'LocatieScoreFoto\'sOpmerkingen'; - document.getElementById('formTitle').textContent = 'Duimstokformulier Overwegbevloering'; } else if (type === D.TYPE_SPOOR) { thead.innerHTML = 'NrKM vanKM totLengteScoreFoto\'sOpmerkingen'; - document.getElementById('formTitle').textContent = 'Duimstokformulier Spoor'; } + document.getElementById('formTitle').textContent = titles[type] || 'Duimstokformulier'; }; A.resetForm = function () { A.state.formData = A.emptyFormData(); - document.body.classList.remove('type-wissel', 'type-overweg', 'type-spoor'); + document.body.classList.remove('type-wissel', 'type-overweg', 'type-spoor', 'type-engelsman', 'type-kruising'); document.querySelectorAll('.header-grid .value').forEach(el => el.textContent = ''); document.querySelectorAll('#hdr_taakomschrijving, #hdr_aanleiding').forEach(el => el.textContent = ''); document.getElementById('inp_inspecteur').value = ''; @@ -83,16 +88,17 @@ btn.addEventListener('click', () => A.openPhotoModal(+btn.dataset.nr, btn.dataset.loc))); } - A.buildWisselAssessment = function (scoreElements) { + A.buildWisselAssessment = function (scoreElements, type) { var tbody = document.getElementById('assessmentBody'); tbody.innerHTML = ''; var currentSection = ''; + var assessType = type || A.state.formData.type; scoreElements.forEach(el => { var nr = parseInt(el.querySelector('NR').textContent.trim()); var locatie = el.querySelector('LOCATIE').textContent.trim(); var dwlScore = el.querySelector('DWL_SCORE').textContent.trim(); var balScore = el.querySelector('BAL_SCORE').textContent.trim(); - var section = D.getSectionForNr(nr); + var section = D.getSectionForNr(nr, assessType); if (section && section !== currentSection) { currentSection = section; var sr = document.createElement('tr'); @@ -174,7 +180,7 @@ }; A.buildAssessmentForType = function (type, scoreElements) { - if (type === D.TYPE_WISSEL) A.buildWisselAssessment(scoreElements); + if (D.usesDwlBal(type)) A.buildWisselAssessment(scoreElements, type); else if (type === D.TYPE_OVERWEG) A.buildOverwegAssessment(scoreElements); else if (type === D.TYPE_SPOOR) A.buildSpoorAssessment(scoreElements); }; @@ -208,7 +214,7 @@ A.updateTotaalscore = function () { var type = A.state.formData.type; var worst; - if (type === D.TYPE_WISSEL) { + if (D.usesDwlBal(type)) { worst = D.computeWorstScore(A.state.formData.scores); } else { var order = ['', ...D.SCORE_VALUES]; diff --git a/src/Application/xmlImport.js b/src/Application/xmlImport.js index 6a0106f..e9d4613 100644 --- a/src/Application/xmlImport.js +++ b/src/Application/xmlImport.js @@ -11,6 +11,9 @@ var eqart = getText('EQART'); var type = D.typeFromEqart(eqart); + if (type === D.TYPE_WISSEL) { + type = D.typeFromWisselSoort(getText('SOORT')); + } A.applyFormType(type); var orderNr = getText('AUFNR_VORNR'); @@ -31,7 +34,7 @@ setIfExists('hdr_taakomschrijving', getText('LTXA1')); setIfExists('hdr_aanleiding', getText('KURZTEXT')); - if (type === D.TYPE_WISSEL) { + if (D.usesDwlBal(type)) { setIfExists('hdr_wisselnr', getText('WISSELNR') || getText('EQFNR_EQUI')); setIfExists('hdr_soort', getText('SOORT')); setIfExists('hdr_hoekverhouding', getText('HOEKVERHOUDING')); @@ -67,7 +70,7 @@ if (getText('INSP_JAAR')) document.getElementById('inp_inspjaar').value = getText('INSP_JAAR'); if (getText('OPMERKING')) document.getElementById('inp_opmerkingen').value = getText('OPMERKING'); - if (type === D.TYPE_WISSEL) A.buildWisselAssessment(xml.querySelectorAll('WISSEL_SCORE')); + if (D.usesDwlBal(type)) A.buildWisselAssessment(xml.querySelectorAll('WISSEL_SCORE'), type); else if (type === D.TYPE_OVERWEG) A.buildOverwegAssessment(xml.querySelectorAll('OVERWEG_SCORE')); else if (type === D.TYPE_SPOOR) A.buildSpoorAssessment(xml.querySelectorAll('SPOOR_STUK')); diff --git a/src/Domain/inspectionTypes.js b/src/Domain/inspectionTypes.js index 6d6bfe7..b8b6b8b 100644 --- a/src/Domain/inspectionTypes.js +++ b/src/Domain/inspectionTypes.js @@ -2,17 +2,26 @@ D.TYPE_WISSEL = 'wissel'; D.TYPE_OVERWEG = 'overweg'; D.TYPE_SPOOR = 'spoor'; + D.TYPE_ENGELSMAN = 'engelsman'; + D.TYPE_KRUISING = 'kruising'; D.EQART_TO_TYPE = { 'WISSEL': D.TYPE_WISSEL, 'OVERWBEVL': D.TYPE_OVERWEG, - 'SPOORDWL': D.TYPE_SPOOR + 'SPOORDWL': D.TYPE_SPOOR, + 'ENGELSMAN': D.TYPE_ENGELSMAN, + 'KRUISING': D.TYPE_KRUISING }; D.OBJECTSOORT_TO_TYPE = { 'Wissel': D.TYPE_WISSEL, 'Overwegbevloering': D.TYPE_OVERWEG, - 'Spoor': D.TYPE_SPOOR + 'Spoor': D.TYPE_SPOOR, + 'Engelsman': D.TYPE_ENGELSMAN, + 'Half Engelsman': D.TYPE_ENGELSMAN, + 'Heel Engelsman': D.TYPE_ENGELSMAN, + 'Kruising': D.TYPE_KRUISING, + 'Ingesloten kruising': D.TYPE_KRUISING }; D.typeFromEqart = function (eqart) { @@ -23,10 +32,21 @@ return D.OBJECTSOORT_TO_TYPE[objectsoort] || D.TYPE_WISSEL; }; + D.typeFromWisselSoort = function (soort) { + soort = (soort || '').toLowerCase(); + if (soort.indexOf('engelsman') >= 0) return D.TYPE_ENGELSMAN; + if (soort.indexOf('kruising') >= 0) return D.TYPE_KRUISING; + return D.TYPE_WISSEL; + }; + D.OVERWEG_LOCATIONS = [ 'Ligging spoor', 'Ligging bevloering', 'Constructieve kwaliteit', 'Wegverharding' ]; + + D.usesDwlBal = function (type) { + return type === D.TYPE_WISSEL || type === D.TYPE_ENGELSMAN || type === D.TYPE_KRUISING; + }; })(window.App.Domain); diff --git a/src/Domain/sectionMap.js b/src/Domain/sectionMap.js index c456675..a8a5fd4 100644 --- a/src/Domain/sectionMap.js +++ b/src/Domain/sectionMap.js @@ -1,12 +1,34 @@ (function (D) { - D.sectionMap = { + D.wisselSectionMap = { 'Sectie 1: Tongbeweging': [1, 2, 3, 4], 'Sectie 2: Middengedeelte': [5, 6, 7, 8, 9, 10], 'Sectie 3: Puntstuk gedeelte': [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23] }; - D.getSectionForNr = function (nr) { - for (const [section, nrs] of Object.entries(D.sectionMap)) { + D.engelsmanSectionMap = { + 'Sectie 1: Puntstuk gedeelte (boven)': [1, 2, 3, 4, 5], + 'Sectie 2: Kruisstuk gedeelte': [6, 7, 8, 9, 10], + 'Sectie 3: Middengedeelte': [11, 12, 13, 14, 15, 16], + 'Sectie 4: Tongbeweging': [17, 18, 19, 20, 21, 22], + 'Sectie 5: Puntstuk gedeelte (onder)': [23, 24, 25, 26, 27, 28, 29, 30] + }; + + D.kruisingSectionMap = { + 'Sectie 1: Puntstuk gedeelte (boven)': [1, 2, 3, 4, 5, 6], + 'Sectie 2: Kruisstuk gedeelte': [7, 8, 9, 10, 11, 12], + 'Sectie 3: Middengedeelte': [13, 14, 15, 16, 17, 18], + 'Sectie 4: Puntstuk gedeelte (onder)': [19, 20, 21, 22, 23, 24] + }; + + D.sectionMapForType = function (type) { + if (type === 'engelsman') return D.engelsmanSectionMap; + if (type === 'kruising') return D.kruisingSectionMap; + return D.wisselSectionMap; + }; + + D.getSectionForNr = function (nr, type) { + var map = D.sectionMapForType(type); + for (const [section, nrs] of Object.entries(map)) { if (nrs.includes(nr)) return section; } return null; @@ -18,9 +40,26 @@ foto_s3_l: 'Foto Puntstuk L', foto_s3_r: 'Foto Puntstuk R', foto_s2_l: 'Foto Midden L', foto_s2_r: 'Foto Midden R', foto_s1_l: 'Foto Tong L', foto_s1_r: 'Foto Tong R', - ovz_ow_1: 'Overzichtsfoto 1', ovz_ow_2: 'Overzichtsfoto 2', - foto_ligging_spoor: 'Ligging spoor', foto_ligging_bevl: 'Ligging bevloering', - foto_constr_kwal: 'Constructieve kwaliteit', foto_wegverharding: 'Wegverharding', - ovz_sp_1: 'Overzichtsfoto begin', ovz_sp_2: 'Overzichtsfoto einde' + foto_ow_sticker: 'Sticker overwegpaal', foto_ow_spoorbord: 'Spoornaambordje', + foto_ow_lk_1: 'Lage km foto 1', foto_ow_lk_2: 'Lage km foto 2', + foto_ow_lk_3: 'Lage km foto 3', foto_ow_lk_4: 'Lage km foto 4', + foto_ow_lk_5: 'Lage km foto 5', foto_ow_lk_6: 'Lage km foto 6', + foto_ow_hk_1: 'Hoge km foto 1', foto_ow_hk_2: 'Hoge km foto 2', + foto_ow_hk_3: 'Hoge km foto 3', foto_ow_hk_4: 'Hoge km foto 4', + foto_ow_hk_5: 'Hoge km foto 5', foto_ow_hk_6: 'Hoge km foto 6', + ovz_sp_1: 'Overzichtsfoto begin', ovz_sp_2: 'Overzichtsfoto einde', + ovz_eng_tl: 'Overzichtsfoto LB', ovz_eng_tr: 'Overzichtsfoto RB', + ovz_eng_bl: 'Overzichtsfoto LO', ovz_eng_br: 'Overzichtsfoto RO', + foto_eng_s5_l: 'Foto Puntstuk boven L', foto_eng_s5_r: 'Foto Puntstuk boven R', + foto_eng_s4_l: 'Foto Kruisstuk L', foto_eng_s4_r: 'Foto Kruisstuk R', + foto_eng_s3_l: 'Foto Midden L', foto_eng_s3_r: 'Foto Midden R', + foto_eng_s2_l: 'Foto Tong L', foto_eng_s2_r: 'Foto Tong R', + foto_eng_s1_l: 'Foto Puntstuk onder L', foto_eng_s1_r: 'Foto Puntstuk onder R', + ovz_kr_tl: 'Overzichtsfoto LB', ovz_kr_tr: 'Overzichtsfoto RB', + ovz_kr_bl: 'Overzichtsfoto LO', ovz_kr_br: 'Overzichtsfoto RO', + foto_kr_s4_l: 'Foto Puntstuk boven L', foto_kr_s4_r: 'Foto Puntstuk boven R', + foto_kr_s3_l: 'Foto Kruisstuk L', foto_kr_s3_r: 'Foto Kruisstuk R', + foto_kr_s2_l: 'Foto Midden L', foto_kr_s2_r: 'Foto Midden R', + foto_kr_s1_l: 'Foto Puntstuk onder L', foto_kr_s1_r: 'Foto Puntstuk onder R' }; })(window.App.Domain);