Skip to content

Commit afd6786

Browse files
author
hackermd
committed
Fix map for pyramids with different tile sizes
1 parent be5e235 commit afd6786

File tree

2 files changed

+44
-31
lines changed

2 files changed

+44
-31
lines changed

src/api.js

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ class VLWholeSlideMicroscopyImageViewer {
173173
* images at the different pyramid levels.
174174
*/
175175
const metadata = options.metadata.map(m => formatImageMetadata(m));
176-
this[_pyramid] = [];
176+
this.pyramid = [];
177177
for (let i = 0; i < metadata.length; i++) {
178178
const cols = metadata[i].totalPixelMatrixColumns;
179179
const rows = metadata[i].totalPixelMatrixRows;
@@ -184,24 +184,24 @@ class VLWholeSlideMicroscopyImageViewer {
184184
*/
185185
let alreadyExists = false;
186186
let index = null;
187-
for (let j = 0; j < this[_pyramid].length; j++) {
187+
for (let j = 0; j < this.pyramid.length; j++) {
188188
if (
189-
(this[_pyramid][j].totalPixelMatrixColumns === cols) &&
190-
(this[_pyramid][j].totalPixelMatrixRows === rows)
189+
(this.pyramid[j].totalPixelMatrixColumns === cols) &&
190+
(this.pyramid[j].totalPixelMatrixRows === rows)
191191
) {
192192
alreadyExists = true;
193193
index = j;
194194
}
195195
}
196196
if (alreadyExists) {
197197
// Update with information obtained from current concatentation part.
198-
Object.assign(this[_pyramid][index].frameMapping, mapping);
198+
Object.assign(this.pyramid[index].frameMapping, mapping);
199199
} else {
200-
this[_pyramid].push(metadata[i]);
200+
this.pyramid.push(metadata[i]);
201201
}
202202
}
203203
// Sort levels in ascending order
204-
this[_pyramid].sort(function(a, b) {
204+
this.pyramid.sort(function(a, b) {
205205
if(a.totalPixelMatrixColumns < b.totalPixelMatrixColumns) {
206206
return -1;
207207
} else if(a.totalPixelMatrixColumns > b.totalPixelMatrixColumns) {
@@ -218,42 +218,54 @@ class VLWholeSlideMicroscopyImageViewer {
218218
const tileSizes = [];
219219
const totalSizes = [];
220220
const resolutions = [];
221-
const origins = [[0, -1]];
222-
const nLevels = this[_pyramid].length;
223-
for (let j = 0; j < nLevels; j++) {
224-
let columns = this[_pyramid][j].columns;
225-
let rows = this[_pyramid][j].rows;
226-
let totalPixelMatrixColumns = this[_pyramid][j].totalPixelMatrixColumns;
227-
let totalPixelMatrixRows = this[_pyramid][j].totalPixelMatrixRows;
228-
let pixelSpacing = this[_pyramid][j].pixelSpacing;
221+
const origins = [];
222+
const offset = [0, -1];
223+
const nLevels = this.pyramid.length;
224+
if (nLevels === 0) {
225+
console.error('empty pyramid - no levels found')
226+
}
227+
const basePixelSpacing = this.pyramid[nLevels-1].pixelSpacing;
228+
const baseColumns = this.pyramid[nLevels-1].columns;
229+
const baseRows = this.pyramid[nLevels-1].rows;
230+
const baseTotalPixelMatrixColumns = this.pyramid[nLevels-1].totalPixelMatrixColumns;
231+
const baseTotalPixelMatrixRows = this.pyramid[nLevels-1].totalPixelMatrixRows;
232+
const baseColFactor = Math.ceil(baseTotalPixelMatrixColumns / baseColumns);
233+
const baseRowFactor = Math.ceil(baseTotalPixelMatrixRows / baseRows);
234+
const baseAdjustedTotalPixelMatrixColumns = baseColumns * baseColFactor;
235+
const baseAdjustedTotalPixelMatrixRows = baseRows * baseRowFactor;
236+
for (let j = (nLevels - 1); j >= 0; j--) {
237+
let columns = this.pyramid[j].columns;
238+
let rows = this.pyramid[j].rows;
239+
let totalPixelMatrixColumns = this.pyramid[j].totalPixelMatrixColumns;
240+
let totalPixelMatrixRows = this.pyramid[j].totalPixelMatrixRows;
241+
let pixelSpacing = this.pyramid[j].pixelSpacing;
229242
let colFactor = Math.ceil(totalPixelMatrixColumns / columns);
230243
let rowFactor = Math.ceil(totalPixelMatrixRows / rows);
244+
let adjustedTotalPixelMatrixColumns = columns * colFactor;
245+
let adjustedTotalPixelMatrixRows = rows * rowFactor;
231246
tileSizes.push([columns, rows]);
232-
totalSizes.push([columns * colFactor, rows * rowFactor]);
247+
totalSizes.push([adjustedTotalPixelMatrixColumns, adjustedTotalPixelMatrixRows]);
233248

234249
/*
235250
* Compute the resolution at each pyramid level, since the zoom
236251
* factor may not be the same between adjacent pyramid levels.
237252
*/
238-
let zoomFactor = this[_pyramid][nLevels-1].totalPixelMatrixRows / totalPixelMatrixRows;
253+
let zoomFactor = pixelSpacing[0] / basePixelSpacing[0];
239254
resolutions.push(zoomFactor);
240255

241256
/*
242257
* TODO: One may have to adjust the offset slightly due to the
243-
* difference between extent of the image at a resolution level
258+
* difference between extent of the image at a given resolution level
244259
* and the actual number of tiles (frames).
245260
*/
246-
let orig = [0, -1]
247-
if (j < this[_pyramid].length-1) {
248-
origins.push(orig)
249-
}
261+
origins.push(offset);
250262
}
251-
totalSizes.reverse();
263+
resolutions.reverse();
252264
tileSizes.reverse();
253265
origins.reverse();
254266

255267
// We can't call "this" inside functions.
256-
const pyramid = this[_pyramid];
268+
const pyramid = this.pyramid;
257269

258270
/*
259271
* Translate pixel units of total pixel matrix into millimeters of
@@ -352,10 +364,10 @@ class VLWholeSlideMicroscopyImageViewer {
352364
* number of rows in the total pixel matrix.
353365
*/
354366
const extent = [
355-
0, // min X
356-
-pyramid[nLevels-1].totalPixelMatrixRows, // min Y
357-
pyramid[nLevels-1].totalPixelMatrixColumns, // max X
358-
-1 // max Y
367+
0, // min X
368+
-baseTotalPixelMatrixRows, // min Y
369+
baseTotalPixelMatrixColumns, // max X
370+
-1 // max Y
359371
];
360372

361373
/*
@@ -370,8 +382,8 @@ class VLWholeSlideMicroscopyImageViewer {
370382
*/
371383
var degrees = 0;
372384
if (
373-
(this[_pyramid][this[_pyramid].length-1].imageOrientationSlide[1] === -1) &&
374-
(this[_pyramid][this[_pyramid].length-1].imageOrientationSlide[3] === -1)
385+
(this.pyramid[this.pyramid.length-1].imageOrientationSlide[1] === -1) &&
386+
(this.pyramid[this.pyramid.length-1].imageOrientationSlide[3] === -1)
375387
) {
376388
/*
377389
* The row direction (left to right) of the total pixel matrix
@@ -446,7 +458,7 @@ class VLWholeSlideMicroscopyImageViewer {
446458
const imageLayer = new TileLayer({
447459
extent: extent,
448460
source: rasterSource,
449-
preload: 2,
461+
preload: 1,
450462
projection: projection
451463
});
452464

src/metadata.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ function formatImageMetadata(metadata) {
2222
const sharedFunctionalGroupsSequence = metadata['52009229']['Value'][0];
2323
const pixelMeasuresSequence = sharedFunctionalGroupsSequence['00289110']['Value'][0];
2424
const pixelSpacing = pixelMeasuresSequence['00280030']['Value'];
25+
// The top level (lowest resolution) image may be a single frame image.
2526
let numberOfFrames = 1;
2627
if ('00280008' in metadata) {
2728
numberOfFrames = Number(metadata['00280008']['Value'][0]);

0 commit comments

Comments
 (0)