Skip to content

Commit b4fe781

Browse files
hackermdhackermd
authored andcommitted
Creating private methods was a bad idea
1 parent 0658928 commit b4fe781

File tree

2 files changed

+197
-179
lines changed

2 files changed

+197
-179
lines changed

src/api.js

Lines changed: 156 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,157 @@ import {
4242
import DICOMwebClient from 'dicomweb-client/build/dicomweb-client.js'
4343

4444

45-
const _client = Symbol('client');
46-
const _controls = Symbol('controls');
47-
const _coordinateFormatScoord3d2Geometry = Symbol('coordinateFormatScoord3d2Geometry');
48-
const _coordinateFormatGeometry2Scoord3d = Symbol('coordinateFormatGeometry2Scoord3d');
45+
function _geometry2Scoord3d(geometry, pyramid) {
46+
const type = geometry.getType();
47+
if (type === 'Point') {
48+
let coordinates = geometry.getCoordinates();
49+
coordinates = _geometryCoordinates2scoord3dCoordinates(coordinates, pyramid);
50+
return new Point({
51+
coordinates,
52+
referencedFrameOfReferenceUID: pyramid[pyramid.length-1].frameOfReferenceUID
53+
});
54+
} else if (type === 'Polygon') {
55+
/*
56+
* The first linear ring of the array defines the outer-boundary (surface).
57+
* Each subsequent linear ring defines a hole in the surface.
58+
*/
59+
let coordinates = geometry.getCoordinates()[0].map(c => {
60+
return _geometryCoordinates2scoord3dCoordinates(c, pyramid);
61+
});
62+
return new Polygon({
63+
coordinates,
64+
referencedFrameOfReferenceUID: pyramid[pyramid.length-1].frameOfReferenceUID
65+
});
66+
} else if (type === 'LineString') {
67+
let coordinates = geometry.getCoordinates().map(c => {
68+
return _geometryCoordinates2scoord3dCoordinates(c, pyramid);
69+
});
70+
return new Polyline({
71+
coordinates,
72+
referencedFrameOfReferenceUID: pyramid[pyramid.length-1].frameOfReferenceUID
73+
});
74+
} else if (type === 'Circle') {
75+
// chunking the Flat Coordinates into two arrays within 3 elements each
76+
let coordinates = geometry.getFlatCoordinates().reduce((all,one,i) => {
77+
const ch = Math.floor(i/2)
78+
all[ch] = [].concat((all[ch]||[]),one)
79+
return all
80+
}, [])
81+
coordinates = coordinates.map(c => {
82+
c.push(0)
83+
return _geometryCoordinates2scoord3dCoordinates(c, pyramid)
84+
})
85+
return new Circle({
86+
coordinates,
87+
referencedFrameOfReferenceUID: pyramid[pyramid.length-1].frameOfReferenceUID
88+
});
89+
} else {
90+
// TODO: Combine multiple points into MULTIPOINT.
91+
console.error(`unknown geometry type "${type}"`)
92+
}
93+
}
94+
95+
function _scoord3d2Geometry(scoord3d, pyramid) {
96+
const type = scoord3d.graphicType;
97+
const data = scoord3d.graphicData;
98+
if (type === 'POINT') {
99+
let coordinates = _scoord3dCoordinates2geometryCoordinates(data, pyramid);
100+
return new PointGeometry(coordinates);
101+
} else if (type === 'POLYLINE') {
102+
const coordinates = data.map(d => {
103+
return _scoord3dCoordinates2geometryCoordinates(d, pyramid);
104+
});
105+
return new LineStringGeometry(coordinates);
106+
} else if(type === 'POLYGON'){
107+
const coordinates = data.map(d => {
108+
return _scoord3dCoordinates2geometryCoordinates(d, pyramid);
109+
});
110+
return new PolygonGeometry([coordinates]);
111+
} else if (type === 'CIRCLE') {
112+
let coordinates = data.map(d => {
113+
return _scoord3dCoordinates2geometryCoordinates(d, pyramid);
114+
})
115+
// to flat coordinates
116+
coordinates = [...coordinates[0].slice(0,2), ...coordinates[1].slice(0,2)]
117+
118+
// flat coordinates in combination with opt_layout and no opt_radius are also accepted
119+
// and internaly it calculates the Radius
120+
return new CircleGeometry(coordinates, null, "XY");
121+
} else {
122+
console.error(`unsupported graphic type "${type}"`)
123+
}
124+
}
125+
126+
function _geometryCoordinates2scoord3dCoordinates(coordinates, pyramid) {
127+
return _coordinateFormatGeometry2Scoord3d([coordinates[0] + 1, -coordinates[1], coordinates[2]], pyramid);
128+
}
129+
130+
function _scoord3dCoordinates2geometryCoordinates(coordinates, pyramid) {
131+
return _coordinateFormatScoord3d2Geometry([coordinates[0], coordinates[1], coordinates[2]], pyramid)
132+
}
133+
134+
/*
135+
* Translate pixel units of total pixel matrix into millimeters of
136+
* slide coordinate system
137+
*/
138+
function _coordinateFormatGeometry2Scoord3d(coordinates, pyramid) {
139+
if(coordinates.length === 3){
140+
coordinates = [coordinates];
141+
}
142+
coordinates.map(coord =>{
143+
let x = (coord[0] * pyramid[pyramid.length-1].pixelSpacing[0]).toFixed(4);
144+
let y = (-(coord[1] - 1) * pyramid[pyramid.length-1].pixelSpacing[1]).toFixed(4);
145+
let z = (1).toFixed(4);
146+
coordinates = [Number(x), Number(y), Number(z)];
147+
})
148+
return(coordinates);
149+
}
150+
151+
/*
152+
* Translate millimeters into pixel units of total pixel matrix of
153+
* slide coordinate system
154+
*/
155+
function _coordinateFormatScoord3d2Geometry(coordinates, pyramid) {
156+
if(coordinates.length === 3){
157+
coordinates = [coordinates];
158+
}
159+
coordinates.map(coord =>{
160+
let x = (coord[0] / pyramid[pyramid.length-1].pixelSpacing[0] - 1);
161+
let y = (coord[1] / pyramid[pyramid.length-1].pixelSpacing[1] - 1);
162+
let z = coord[2];
163+
coordinates = [x, y, z];
164+
});
165+
return(coordinates);
166+
}
167+
168+
function _getROIFromFeature(feature, pyramid){
169+
let roi = {}
170+
if (feature !== undefined) {
171+
const geometry = feature.getGeometry();
172+
const scoord3d = _geometry2Scoord3d(geometry, pyramid);
173+
const properties = feature.getProperties();
174+
// Remove geometry from properties mapping
175+
const geometryName = feature.getGeometryName();
176+
delete properties[geometryName];
177+
const uid = feature.getId();
178+
roi = new ROI({scoord3d, properties, uid});
179+
}
180+
return roi;
181+
}
182+
183+
const _usewebgl = Symbol('usewebgl');
184+
const _map = Symbol('map');
185+
const _features = Symbol('features');
49186
const _drawingSource = Symbol('drawingSource');
50187
const _drawingLayer = Symbol('drawingLayer');
51-
const _features = Symbol('features');
52-
const _geometryCoordinates2scoord3dCoordinates = Symbol('geometryCoordinates2scoord3dCoordinates');
53-
const _geometry2Scoord3d = Symbol('geometry2Scoord3d');
54-
const _getROIFromFeature = Symbol('getROIFromFeature');
55-
const _interactions = Symbol('interactions');
56-
const _map = Symbol('map');
57-
const _metadata = Symbol('metadata');
188+
const _segmentations = Symbol('segmentations');
58189
const _pyramid = Symbol('pyramid');
190+
const _client = Symbol('client');
191+
const _controls = Symbol('controls');
192+
const _interactions = Symbol('interactions');
59193
const _pyramidBase = Symbol('pyramidBaseLayer');
60-
const _scoord3d2Geometry = Symbol('scoord3d2Geometry');
61-
const _scoord3dCoordinates2geometryCoordinates = Symbol('scoord3dCoordinates2geometryCoordinates');
62-
const _segmentations = Symbol('segmentations');
63-
const _usewebgl = Symbol('usewebgl');
194+
const _metadata = Symbol('metadata');
195+
64196

65197
class VLWholeSlideMicroscopyImageViewer {
66198

@@ -522,18 +654,17 @@ class VLWholeSlideMicroscopyImageViewer {
522654
scaleInnerElement.style.willChange = 'contents,width';
523655

524656
const container = this[_map].getTargetElement();
525-
const getROIFromFeature = this[_getROIFromFeature].bind(this);
526657

527658
this[_drawingSource].on(VectorEventType.ADDFEATURE, (e) => {
528-
publish(container, EVENT.ROI_ADDED, getROIFromFeature(e.feature));
659+
publish(container, EVENT.ROI_ADDED, _getROIFromFeature(e.feature, this._pyramid));
529660
});
530661

531662
this[_drawingSource].on(VectorEventType.CHANGEFEATURE, (e) => {
532-
publish(container, EVENT.ROI_MODIFIED, getROIFromFeature(e.feature));
663+
publish(container, EVENT.ROI_MODIFIED, _getROIFromFeature(e.feature, this._pyramid));
533664
});
534665

535666
this[_drawingSource].on(VectorEventType.REMOVEFEATURE, (e) => {
536-
publish(container, EVENT.ROI_REMOVED, getROIFromFeature(e.feature));
667+
publish(container, EVENT.ROI_REMOVED, _getROIFromFeature(e.feature, this._pyramid));
537668
});
538669

539670
this[_map].on(MapEventType.MOVESTART, (e) => {
@@ -602,12 +733,11 @@ class VLWholeSlideMicroscopyImageViewer {
602733
this[_interactions].draw = new Draw(allDrawOptions);
603734

604735
const container = this[_map].getTargetElement();
605-
const getROIFromFeature = this[_getROIFromFeature].bind(this);
606736

607737
//attaching openlayers events handling
608738
this[_interactions].draw.on('drawend', (e) => {
609739
e.feature.setId(generateUuid());
610-
publish(container, EVENT.ROI_DRAWN, getROIFromFeature(e.feature));
740+
publish(container, EVENT.ROI_DRAWN, _getROIFromFeature(e.feature, this._pyramid));
611741
});
612742

613743
this[_map].addInteraction(this[_interactions].draw);
@@ -638,7 +768,7 @@ class VLWholeSlideMicroscopyImageViewer {
638768
const container = this[_map].getTargetElement();
639769

640770
this[_interactions].select.on('select', (e) => {
641-
publish(container, EVENT.ROI_SELECTED, _getROIFromFeature(e.selected[0]));
771+
publish(container, EVENT.ROI_SELECTED, _getROIFromFeature(e.selected[0], this._pyramid));
642772
});
643773

644774
this[_map].addInteraction(this[_interactions].select);
@@ -696,7 +826,7 @@ class VLWholeSlideMicroscopyImageViewer {
696826

697827
getROI(index) {
698828
const feature = this[_features].item(index);
699-
return this[_getROIFromFeature](feature);
829+
return _getROIFromFeature(feature, this._pyramid);
700830
}
701831

702832
indexOfROI(item) {
@@ -710,18 +840,18 @@ class VLWholeSlideMicroscopyImageViewer {
710840

711841
popROI() {
712842
const feature = this[_features].pop();
713-
return this[_getROIFromFeature](feature);
843+
return _getROIFromFeature(feature, this._pyramid);
714844
}
715845

716846
addROI(item) {
717-
const geometry = this[_scoord3d2Geometry](item.scoord3d, this._pyramid);
847+
const geometry = _scoord3d2Geometry(item.scoord3d, this._pyramid);
718848
const feature = new Feature(geometry);
719849
feature.setProperties(item.properties, true);
720850
this[_features].push(feature);
721851
}
722852

723853
updateROI(index, item) {
724-
const geometry = this[_scoord3d2Geometry](item.scoord3d, this._pyramid);
854+
const geometry = _scoord3d2Geometry(item.scoord3d, this._pyramid);
725855
const feature = new Feature(geometry);
726856
feature.setProperties(item.properties, true);
727857
feature.setId(item.uid);
@@ -743,144 +873,6 @@ class VLWholeSlideMicroscopyImageViewer {
743873
get areROIsVisible() {
744874
return this[_drawingLayer].getVisible();
745875
}
746-
747-
[_geometry2Scoord3d](geometry) {
748-
const type = geometry.getType();
749-
if (type === 'Point') {
750-
let coordinates = geometry.getCoordinates();
751-
coordinates = this[_geometryCoordinates2scoord3dCoordinates](coordinates);
752-
return new Point({
753-
coordinates,
754-
referencedFrameOfReferenceUID: this[_pyramidBase].frameOfReferenceUID
755-
});
756-
} else if (type === 'Polygon') {
757-
/*
758-
* The first linear ring of the array defines the outer-boundary (surface).
759-
* Each subsequent linear ring defines a hole in the surface.
760-
*/
761-
let coordinates = geometry.getCoordinates()[0].map(c => {
762-
return this[_geometryCoordinates2scoord3dCoordinates](c);
763-
});
764-
return new Polygon({
765-
coordinates,
766-
referencedFrameOfReferenceUID: this[_pyramidBase].frameOfReferenceUID
767-
});
768-
} else if (type === 'LineString') {
769-
let coordinates = geometry.getCoordinates().map(c => {
770-
return this[_geometryCoordinates2scoord3dCoordinates](c);
771-
});
772-
return new Polyline({
773-
coordinates,
774-
referencedFrameOfReferenceUID: this[_pyramidBase].frameOfReferenceUID
775-
});
776-
} else if (type === 'Circle') {
777-
// chunking the Flat Coordinates into two arrays within 3 elements each
778-
let coordinates = geometry.getFlatCoordinates().reduce((all,one,i) => {
779-
const ch = Math.floor(i/2)
780-
all[ch] = [].concat((all[ch]||[]),one)
781-
return all
782-
}, [])
783-
coordinates = coordinates.map(c => {
784-
c.push(0)
785-
return this[_geometryCoordinates2scoord3dCoordinates](c)
786-
})
787-
return new Circle({
788-
coordinates,
789-
referencedFrameOfReferenceUID: this[_pyramidBase].frameOfReferenceUID
790-
});
791-
} else {
792-
// TODO: Combine multiple points into MULTIPOINT.
793-
console.error(`unknown geometry type "${type}"`)
794-
}
795-
}
796-
797-
[_scoord3d2Geometry](scoord3d) {
798-
const type = scoord3d.graphicType;
799-
const data = scoord3d.graphicData;
800-
if (type === 'POINT') {
801-
let coordinates = this[_scoord3dCoordinates2geometryCoordinates](data);
802-
return new PointGeometry({coordinates});
803-
} else if (type === 'POLYLINE') {
804-
const coordinates = data.map(d => {
805-
return this[_scoord3dCoordinates2geometryCoordinates](d);
806-
});
807-
return new LineStringGeometry({coordinates});
808-
} else if(type === 'POLYGON'){
809-
const coordinates = data.map(d => {
810-
return this[_scoord3dCoordinates2geometryCoordinates](d);
811-
});
812-
return new PolygonGeometry([coordinates]);
813-
} else if (type === 'CIRCLE') {
814-
let coordinates = data.map(d => {
815-
return this[_scoord3dCoordinates2geometryCoordinates](d);
816-
})
817-
// to flat coordinates
818-
coordinates = [...coordinates[0].slice(0,2), ...coordinates[1].slice(0,2)]
819-
820-
// flat coordinates in combination with opt_layout and no opt_radius are also accepted
821-
// and internaly it calculates the Radius
822-
return new CircleGeometry(coordinates, null, "XY");
823-
} else {
824-
console.error(`unsupported graphic type "${type}"`)
825-
}
826-
}
827-
828-
[_geometryCoordinates2scoord3dCoordinates](coordinates) {
829-
return this[_coordinateFormatGeometry2Scoord3d]([coordinates[0] + 1, -coordinates[1], coordinates[2]]);
830-
}
831-
832-
[_scoord3dCoordinates2geometryCoordinates](coordinates) {
833-
return this[_coordinateFormatScoord3d2Geometry]([coordinates[0], coordinates[1], coordinates[2]])
834-
}
835-
836-
/*
837-
* Translate pixel units of total pixel matrix into millimeters of
838-
* slide coordinate system
839-
*/
840-
[_coordinateFormatGeometry2Scoord3d](coordinates) {
841-
if(coordinates.length === 3){
842-
coordinates = [coordinates];
843-
}
844-
coordinates.map(coord =>{
845-
let x = (coord[0] * this[_pyramidBase].pixelSpacing[0]).toFixed(4);
846-
let y = (-(coord[1] - 1) * this[_pyramidBase].pixelSpacing[1]).toFixed(4);
847-
let z = (1).toFixed(4);
848-
coordinates = [Number(x), Number(y), Number(z)];
849-
})
850-
return(coordinates);
851-
}
852-
853-
/*
854-
* Translate millimeters into pixel units of total pixel matrix of
855-
* slide coordinate system
856-
*/
857-
[_coordinateFormatScoord3d2Geometry](coordinates) {
858-
if(coordinates.length === 3){
859-
coordinates = [coordinates];
860-
}
861-
coordinates.map(coord =>{
862-
let x = (coord[0] / this._pyramid[pyramid.length-1].pixelSpacing[0] - 1);
863-
let y = (coord[1] / this._pyramid[pyramid.length-1].pixelSpacing[1] - 1);
864-
let z = coord[2];
865-
coordinates = [x, y, z];
866-
});
867-
return(coordinates);
868-
}
869-
870-
[_getROIFromFeature](feature){
871-
let roi = {}
872-
if (feature !== undefined) {
873-
const geometry = feature.getGeometry();
874-
const scoord3d = this[_geometry2Scoord3d](geometry);
875-
const properties = feature.getProperties();
876-
// Remove geometry from properties mapping
877-
const geometryName = feature.getGeometryName();
878-
delete properties[geometryName];
879-
const uid = feature.getId();
880-
roi = new ROI({scoord3d, properties, uid});
881-
}
882-
return roi;
883-
}
884876
}
885877

886878
export { VLWholeSlideMicroscopyImageViewer };

0 commit comments

Comments
 (0)