@@ -7,9 +7,7 @@ import LineStringGeometry from 'ol/geom/LineString'
77
88import {
99 applyInverseTransform ,
10- applyTransform ,
11- buildInverseTransform ,
12- buildTransform
10+ applyTransform
1311} from './utils.js'
1412
1513/**
@@ -18,17 +16,22 @@ import {
1816 *
1917 * @param {object } feature - OpenLayers Feature
2018 * @param {Object[] } pyramid - Metadata for resolution levels of image pyramid
19+ * @param {number[][] } affine - 3x3 affine transformation matrix
2120 * @returns {Scoord3D } DICOM Microscopy Viewer Scoord3D
2221 * @private
2322 */
24- function _geometry2Scoord3d ( feature , pyramid ) {
23+ function _geometry2Scoord3d ( feature , pyramid , affine ) {
2524 const geometry = feature . getGeometry ( )
2625 console . info ( 'map coordinates from pixel matrix to slide coordinate system' )
2726 const frameOfReferenceUID = pyramid [ pyramid . length - 1 ] . FrameOfReferenceUID
2827 const type = geometry . getType ( )
2928 if ( type === 'Point' ) {
3029 let coordinates = geometry . getCoordinates ( )
31- coordinates = _geometryCoordinates2scoord3dCoordinates ( coordinates , pyramid )
30+ coordinates = _geometryCoordinates2scoord3dCoordinates (
31+ coordinates ,
32+ pyramid ,
33+ affine
34+ )
3235 return new Point ( {
3336 coordinates,
3437 frameOfReferenceUID : frameOfReferenceUID
@@ -39,16 +42,15 @@ function _geometry2Scoord3d (feature, pyramid) {
3942 * Each subsequent linear ring defines a hole in the surface.
4043 */
4144 const coordinates = geometry . getCoordinates ( ) [ 0 ] . map ( ( c ) => {
42- return _geometryCoordinates2scoord3dCoordinates ( c , pyramid )
45+ return _geometryCoordinates2scoord3dCoordinates ( c , pyramid , affine )
4346 } )
4447 return new Polygon ( {
4548 coordinates,
4649 frameOfReferenceUID : frameOfReferenceUID
4750 } )
4851 } else if ( type === 'LineString' ) {
4952 const coordinates = geometry . getCoordinates ( ) . map ( ( c ) => {
50- const result = _geometryCoordinates2scoord3dCoordinates ( c , pyramid )
51- return result
53+ return _geometryCoordinates2scoord3dCoordinates ( c , pyramid , affine )
5254 } )
5355 return new Polyline ( {
5456 coordinates,
@@ -65,7 +67,7 @@ function _geometry2Scoord3d (feature, pyramid) {
6567 [ center [ 0 ] , center [ 1 ] + radius , 0 ]
6668 ]
6769 coordinates = coordinates . map ( ( c ) => {
68- return _geometryCoordinates2scoord3dCoordinates ( c , pyramid )
70+ return _geometryCoordinates2scoord3dCoordinates ( c , pyramid , affine )
6971 } )
7072 return new Ellipse ( {
7173 coordinates,
@@ -83,25 +85,30 @@ function _geometry2Scoord3d (feature, pyramid) {
8385 *
8486 * @param {Scoord3D } scoord3d - DICOM Microscopy Viewer Scoord3D
8587 * @param {Object[] } pyramid - Metadata for resolution levels of image pyramid
88+ * @param {number[][] } affine - 3x3 affine transformation matrix
8689 * @returns {object } Openlayers Geometry
8790 * @private
8891 */
89- function _scoord3d2Geometry ( scoord3d , pyramid ) {
92+ function _scoord3d2Geometry ( scoord3d , pyramid , affine ) {
9093 console . info ( 'map coordinates from slide coordinate system to pixel matrix' )
9194 const type = scoord3d . graphicType
9295 const data = scoord3d . graphicData
9396
9497 if ( type === 'POINT' ) {
95- const coordinates = _scoord3dCoordinates2geometryCoordinates ( data , pyramid )
98+ const coordinates = _scoord3dCoordinates2geometryCoordinates (
99+ data ,
100+ pyramid ,
101+ affine
102+ )
96103 return new PointGeometry ( coordinates )
97104 } else if ( type === 'POLYLINE' ) {
98105 const coordinates = data . map ( ( d ) => {
99- return _scoord3dCoordinates2geometryCoordinates ( d , pyramid )
106+ return _scoord3dCoordinates2geometryCoordinates ( d , pyramid , affine )
100107 } )
101108 return new LineStringGeometry ( coordinates )
102109 } else if ( type === 'POLYGON' ) {
103110 const coordinates = data . map ( ( d ) => {
104- return _scoord3dCoordinates2geometryCoordinates ( d , pyramid )
111+ return _scoord3dCoordinates2geometryCoordinates ( d , pyramid , affine )
105112 } )
106113 return new PolygonGeometry ( [ coordinates ] )
107114 } else if ( type === 'ELLIPSE' ) {
@@ -122,7 +129,7 @@ function _scoord3d2Geometry (scoord3d, pyramid) {
122129 point2
123130 ]
124131 coordinates = coordinates . map ( ( d ) => {
125- return _scoord3dCoordinates2geometryCoordinates ( d , pyramid )
132+ return _scoord3dCoordinates2geometryCoordinates ( d , pyramid , affine )
126133 } )
127134 // to flat coordinates
128135 coordinates = [
@@ -177,29 +184,20 @@ function getPixelSpacing (metadata) {
177184 *
178185 * @param {array } coordinates - Array of Openlayers map coordinates
179186 * @param {object } pyramid - Metadata of images in the pyramid
187+ * @param {number[][] } affine - 3x3 affine transformation matrix
180188 * @returns {array } Array of slide coordinates
181189 * @private
182190 */
183- function _geometryCoordinates2scoord3dCoordinates ( coordinates , pyramid ) {
191+ function _geometryCoordinates2scoord3dCoordinates (
192+ coordinates ,
193+ pyramid ,
194+ affine
195+ ) {
184196 let transform = false
185197 if ( ! Array . isArray ( coordinates [ 0 ] ) ) {
186198 coordinates = [ coordinates ]
187199 transform = true
188200 }
189- const metadata = pyramid [ pyramid . length - 1 ]
190- const origin = metadata . TotalPixelMatrixOriginSequence [ 0 ]
191- const orientation = metadata . ImageOrientationSlide
192- const spacing = getPixelSpacing ( metadata )
193- const offset = [
194- Number ( origin . XOffsetInSlideCoordinateSystem ) ,
195- Number ( origin . YOffsetInSlideCoordinateSystem )
196- ]
197-
198- const affine = buildTransform ( {
199- offset,
200- orientation,
201- spacing
202- } )
203201 coordinates = coordinates . map ( ( c ) => {
204202 const pixelCoord = [ c [ 0 ] , - ( c [ 1 ] + 1 ) ]
205203 const slideCoord = applyTransform ( { coordinate : pixelCoord , affine } )
@@ -216,30 +214,21 @@ function _geometryCoordinates2scoord3dCoordinates (coordinates, pyramid) {
216214 *
217215 * @param {array } coordinates - Array of slide coordinates
218216 * @param {object } pyramid - Metadata of images in the pyramid
217+ * @param {number[][] } affine - 3x3 affine transformation matrix
219218 * @returns {array } Array of Openlayers map coordinates
220219 * @private
221220 */
222- function _scoord3dCoordinates2geometryCoordinates ( coordinates , pyramid ) {
221+ function _scoord3dCoordinates2geometryCoordinates (
222+ coordinates ,
223+ pyramid ,
224+ affine
225+ ) {
223226 let transform = false
224227 if ( ! Array . isArray ( coordinates [ 0 ] ) ) {
225228 coordinates = [ coordinates ]
226229 transform = true
227230 }
228- const metadata = pyramid [ pyramid . length - 1 ]
229- const orientation = metadata . ImageOrientationSlide
230- const spacing = getPixelSpacing ( metadata )
231- const origin = metadata . TotalPixelMatrixOriginSequence [ 0 ]
232- const offset = [
233- Number ( origin . XOffsetInSlideCoordinateSystem ) ,
234- Number ( origin . YOffsetInSlideCoordinateSystem )
235- ]
236-
237231 let outOfFrame = false
238- const affine = buildInverseTransform ( {
239- offset,
240- orientation,
241- spacing
242- } )
243232 coordinates = coordinates . map ( ( c ) => {
244233 if ( c [ 0 ] > 25 || c [ 1 ] > 76 ) {
245234 outOfFrame = true
@@ -292,18 +281,19 @@ function _computeAreaOfPolygon (coordinates) {
292281 *
293282 * @param {Feature } feature - Openlayers feature
294283 * @param {object } pyramid - Metadata of images in the pyramid
284+ * @param {number[][] } affine - 3x3 affine transformation matrix
295285 * @returns {number } Length in millimeter
296286 * @private
297287 */
298- function _getFeatureLength ( feature , pyramid ) {
288+ function _getFeatureLength ( feature , pyramid , affine ) {
299289 const geometry = feature . getGeometry ( )
300290 const type = geometry . getType ( )
301291
302292 if ( type === 'LineString' ) {
303293 const coordinates = geometry . getCoordinates ( )
304294 if ( coordinates && coordinates . length ) {
305295 const scoord3dCoordinates = coordinates . map ( ( c ) =>
306- _geometryCoordinates2scoord3dCoordinates ( c , pyramid )
296+ _geometryCoordinates2scoord3dCoordinates ( c , pyramid , affine )
307297 )
308298 let length = 0
309299 for ( let i = 0 ; i < ( scoord3dCoordinates . length - 1 ) ; i ++ ) {
@@ -327,10 +317,11 @@ function _getFeatureLength (feature, pyramid) {
327317 *
328318 * @param {Feature } feature - Openlayers feature
329319 * @param {object } pyramid - Metadata of images in the pyramid
320+ * @param {number[][] } affine - 3x3 affine transformation matrix
330321 * @returns {number } Area in square millimeter
331322 * @private
332323 */
333- function _getFeatureArea ( feature , pyramid ) {
324+ function _getFeatureArea ( feature , pyramid , affine ) {
334325 let geometry = feature . getGeometry ( )
335326 let type = geometry . getType ( )
336327
@@ -344,7 +335,9 @@ function _getFeatureArea (feature, pyramid) {
344335 if ( coordinates && coordinates . length ) {
345336 const scoord3dCoordinates = geometry
346337 . getCoordinates ( ) [ 0 ]
347- . map ( ( c ) => _geometryCoordinates2scoord3dCoordinates ( c , pyramid ) )
338+ . map ( ( c ) => {
339+ return _geometryCoordinates2scoord3dCoordinates ( c , pyramid , affine )
340+ } )
348341 return _computeAreaOfPolygon ( scoord3dCoordinates ) * 1000
349342 }
350343 }
0 commit comments