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 @@
-
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 = '| Nr | Locatie in wissel | DWL Score | BAL Score | Foto\'s | Opmerkingen |
';
- 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 = '| Nr | Locatie | DWL Score | BAL Score | Foto\'s | Opmerkingen |
';
} else if (type === D.TYPE_OVERWEG) {
thead.innerHTML = '| Locatie | Score | Foto\'s | Opmerkingen |
';
- document.getElementById('formTitle').textContent = 'Duimstokformulier Overwegbevloering';
} else if (type === D.TYPE_SPOOR) {
thead.innerHTML = '| Nr | KM van | KM tot | Lengte | Score | Foto\'s | Opmerkingen |
';
- 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);