* init * more shifting * Move @babel dependencies up to workspace root * Begin updating dependent libraries to use sync'd webpack builds w/ watches * Commit changes before a long weekend * Split packages into platform and extensions * Consolidate how/where we specify file/module type entrypoints * Make it possible to pass in extensions as App props * Resolve viewer's modules * Target for UMD bundle * Add Webpack Stylus loader * Provide WebPack build options for microscopy, vtk, and ui * Better entrypoint for extensions * Push changes up to switch PCs * Fix ESM symlink build for Viewers * Shift docs to root * Specify additional lerna config props * Begin providing basic readme info * Rename example extension folder * Shift links to bottom of doc * First attempt at a netlify deploy preview * Attempt to fix deploy preview build * push workspace enabled to initial command; remove second yarn install; use npx to call gitbook cli commands * Try to use global gitbook-cli * Export node_modules path * More agressive with modifying PATH * Follow deploy log output advice * try again to set bin path * Try swapping bash with a new shell * Try bash -l instead of exec bash * Annd let's try again * and again * We may have figured it out johnny, boy * We need to pull cornerstone-wado-image-loader files from hoisted node_modules * Attempt to fix ticks/escapes * Change copy syntax; try running tests on viewers from root for circleci * Lower version to match circleci image * Try alternative jest-canvas-mock location and version file syntax * Run version command instead of calling node directly * Try alternative jest transform * Set path and enable workspaces * Add codecov flags * Use cpx so our copying finishes? * Get all platform unit tests to run * Run and report individually and in parallel * Try once relying on codecov yaml to split w/ flags * Add projects to split by flags * Generate separate reports * Trigger codecov after everything has finished running; these may not support flags * Use recommended flags from issue comments for codecov * Fix typo * Remove clear flag * Shift back to calling codecov from root * Generate example for codecov issue * Try fixing paths * Simplify * Try using codecov orb * Bump circleci version * Upload core and viewer * Use full string paths * Remove individual codecov calls * Fix dir * Combine files before upload * Escape anchors * tryfix syntax * Escape string literal * Combine lines to reduce path * long paths * Use home alias * Fix filename * Try to see the contents of our cat'd file * Also upload `core` * Try running with aliased folder * Fix path; split PR and Merge unit tests into separate jobs * Set default threshold * Fix typo * Changing to scoped package names * Adding note * Catch more updates * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.0 - @ohif/extension-dicom-html@0.0.4-alpha.0 - @ohif/extension-dicom-microscopy@0.0.9-alpha.0 - @ohif/extension-dicom-pdf@0.0.8-alpha.0 - @ohif/extension-vtk@0.1.4-alpha.0 - @ohif/core@0.11.1-alpha.0 - @ohif/i18n@0.2.3-alpha.0 - @ohif/ui@0.2.18-alpha.0 - @ohif/viewer@0.0.22-alpha.0 * Clean up primary readme * Support for dev and dev:* commands * Shift build command; satisfy default PWA build * Remove old scripts * Clean up UI to set webpack scripts * Tidy up project links * Clean duplicate code in UI project * Update UI project's docs * Clean up ui and i18n config * Reduce duplicate code in `@ohif/core` * Fix @ohif/ui versions * bump @ohif/core versions * Redux testkit dep * Remove unused/duplicate config files for projects/packages * ohif-core --> @ohif/core * Safer publish command * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.1 - @ohif/extension-dicom-html@0.0.4-alpha.1 - @ohif/extension-dicom-microscopy@0.0.9-alpha.1 - @ohif/extension-dicom-pdf@0.0.8-alpha.1 - @ohif/extension-vtk@0.1.4-alpha.1 - @ohif/core@0.11.1-alpha.1 - @ohif/i18n@0.2.3-alpha.1 - @ohif/ui@0.2.18-alpha.1 - @ohif/viewer@0.0.22-alpha.1 * test version bump * Add global prettier config * chore(release): publish %s [skip ci] - @ohif/viewer@0.0.22-alpha.2 * test lerna publish * Update package.jsons * Fix build scripts * catch changes * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.2 - @ohif/extension-dicom-html@0.0.4-alpha.2 - @ohif/extension-dicom-microscopy@0.0.9-alpha.2 - @ohif/extension-dicom-pdf@0.0.8-alpha.2 - @ohif/extension-vtk@0.1.4-alpha.2 - @ohif/core@0.11.1-alpha.2 - @ohif/i18n@0.2.3-alpha.2 - @ohif/ui@0.2.18-alpha.2 - @ohif/viewer@0.0.22-alpha.3 * fix eslint issues caused by eslint 6 and our react-app config * Publish with canary tag * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.3 - @ohif/extension-dicom-html@0.0.4-alpha.3 - @ohif/extension-dicom-microscopy@0.0.9-alpha.3 - @ohif/extension-dicom-pdf@0.0.8-alpha.3 - @ohif/extension-vtk@0.1.4-alpha.3 - @ohif/core@0.11.1-alpha.3 - @ohif/i18n@0.2.3-alpha.3 - @ohif/ui@0.2.18-alpha.3 - @ohif/viewer@0.0.22-alpha.4 * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.4 - @ohif/extension-dicom-html@0.0.4-alpha.4 - @ohif/extension-dicom-microscopy@0.0.9-alpha.4 - @ohif/extension-dicom-pdf@0.0.8-alpha.4 - @ohif/extension-vtk@0.1.4-alpha.4 - @ohif/core@0.11.1-alpha.4 - @ohif/i18n@0.2.3-alpha.4 - @ohif/ui@0.2.18-alpha.4 - @ohif/viewer@0.0.22-alpha.5 * Simplify build * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.5 - @ohif/extension-dicom-html@0.0.4-alpha.5 - @ohif/extension-dicom-microscopy@0.0.9-alpha.5 - @ohif/extension-dicom-pdf@0.0.8-alpha.5 - @ohif/extension-vtk@0.1.4-alpha.5 - @ohif/core@0.11.1-alpha.5 - @ohif/i18n@0.2.3-alpha.5 - @ohif/ui@0.2.18-alpha.5 - @ohif/viewer@0.0.22-alpha.6 * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.6 - @ohif/extension-dicom-html@0.0.4-alpha.6 - @ohif/extension-dicom-microscopy@0.0.9-alpha.6 - @ohif/extension-dicom-pdf@0.0.8-alpha.6 - @ohif/extension-vtk@0.1.4-alpha.6 - @ohif/core@0.11.1-alpha.6 - @ohif/i18n@0.2.3-alpha.6 - @ohif/ui@0.2.18-alpha.6 - @ohif/viewer@0.0.22-alpha.7 * Split version and publish * chore(release): publish %s [skip ci] - @ohif/extension-cornerstone@0.0.39-alpha.7 - @ohif/extension-dicom-html@0.0.4-alpha.7 - @ohif/extension-dicom-microscopy@0.0.9-alpha.7 - @ohif/extension-dicom-pdf@0.0.8-alpha.7 - @ohif/extension-vtk@0.1.4-alpha.7 - @ohif/core@0.11.1-alpha.7 - @ohif/i18n@0.2.3-alpha.7 - @ohif/ui@0.2.18-alpha.7 - @ohif/viewer@0.0.22-alpha.8 * Try simplify netlify build * react-viewerbase --> @ohif/ui * add test for stylus loader * Try new way to specify publish path * Use an output folder that won't be ignored * Try move command * fiddle with paths * Dig for some information * Make sure we're in root for our commands * Remove discovery * Setup script-tag example * Fix typo * Move config folder * Update cornerstone extension to use shared/root webpack configs * capture changes * Update extension webpack configs * Don't check in docz output * Fix babel runtime resolution issue * Simplify ui build steps * Push in progress * Shift directories * Get viewer dev path to work * Fix viewer commonjs build * Fix build pwa config for viewers * Make sure our package specific command can be called from root * Update notes * Fix imports and misc. merge notes * Bump wado-image-loader version * Switch up commands to remove webworkers copy * Fix CI config * Fix more broken package references * Add react-dropzone * Persist so e2e test can use * Fix lockfile * Use cypress orb to simplify CI * Fix config * Try again * Install yarn latest for orb * Install yarn a different way * Wait on correct port * Run tests in viewer project * Fix cypress config * Make Cypress happier - use default location * Simplify e2e testing * Capture UI changes since fork * Catch core up * Grab latest deps after merge * Fix broken import * Make sure cornerstone-wado-image-loader resolves to 3+ * Note regarding orbs * Fix refresh on 404 routes * Fix odd error for cornerstone-wado-image-loader * Different target for UMD * Simplify dev script * Try to get fancy with netlify output * Let's do it again * Try to fix measurementTools issue * See if we can get our lerna magic to work on merge to monorepo branch
413 lines
13 KiB
JavaScript
413 lines
13 KiB
JavaScript
import { parsingUtils } from '../lib/parsingUtils';
|
|
|
|
const FUNCTION = 'function';
|
|
|
|
class MetadataProvider {
|
|
constructor() {
|
|
// Define the main "metadataLookup" private property as an immutable property.
|
|
Object.defineProperty(this, 'metadataLookup', {
|
|
configurable: false,
|
|
enumerable: false,
|
|
writable: false,
|
|
value: new Map(),
|
|
});
|
|
|
|
// Local reference to provider function bound to current instance.
|
|
Object.defineProperty(this, '_provider', {
|
|
configurable: false,
|
|
enumerable: false,
|
|
writable: true,
|
|
value: null,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Cornerstone Metadata provider to store image meta data
|
|
* Data from instances, series, and studies are associated with
|
|
* imageIds to facilitate usage of this information by Cornerstone's Tools
|
|
*
|
|
* e.g. the imagePlane metadata object contains instance information about
|
|
* row/column pixel spacing, patient position, and patient orientation. It
|
|
* is used in CornerstoneTools to position reference lines and orientation markers.
|
|
*
|
|
* @param {String} imageId The Cornerstone ImageId
|
|
* @param {Object} data An object containing instance, series, and study metadata
|
|
*/
|
|
addMetadata(imageId, data) {
|
|
const instanceMetadata = data.instance;
|
|
const seriesMetadata = data.series;
|
|
const studyMetadata = data.study;
|
|
const numImages = data.numImages;
|
|
const metadata = {};
|
|
|
|
metadata.frameNumber = data.frameNumber;
|
|
|
|
metadata.study = {
|
|
accessionNumber: studyMetadata.accessionNumber,
|
|
patientId: studyMetadata.patientId,
|
|
studyInstanceUid: studyMetadata.studyInstanceUid,
|
|
studyDate: studyMetadata.studyDate,
|
|
studyTime: studyMetadata.studyTime,
|
|
studyDescription: studyMetadata.studyDescription,
|
|
institutionName: studyMetadata.institutionName,
|
|
patientHistory: studyMetadata.patientHistory,
|
|
};
|
|
|
|
metadata.series = {
|
|
seriesDescription: seriesMetadata.seriesDescription,
|
|
seriesNumber: seriesMetadata.seriesNumber,
|
|
seriesDate: seriesMetadata.seriesDate,
|
|
seriesTime: seriesMetadata.seriesTime,
|
|
modality: seriesMetadata.modality,
|
|
seriesInstanceUid: seriesMetadata.seriesInstanceUid,
|
|
numImages: numImages,
|
|
};
|
|
|
|
metadata.instance = instanceMetadata;
|
|
|
|
metadata.patient = {
|
|
name: studyMetadata.patientName,
|
|
id: studyMetadata.patientId,
|
|
birthDate: studyMetadata.patientBirthDate,
|
|
sex: studyMetadata.patientSex,
|
|
age: studyMetadata.patientAge,
|
|
};
|
|
|
|
// If there is sufficient information, populate
|
|
// the imagePlane object for easier use in the Viewer
|
|
metadata.imagePlane = this.getImagePlane(instanceMetadata);
|
|
|
|
// Add the metadata to the imageId lookup object
|
|
this.metadataLookup.set(imageId, metadata);
|
|
}
|
|
|
|
/**
|
|
* Return the metadata for the given imageId
|
|
* @param {String} imageId The Cornerstone ImageId
|
|
* @returns image metadata
|
|
*/
|
|
getMetadata(imageId) {
|
|
return this.metadataLookup.get(imageId);
|
|
}
|
|
|
|
/**
|
|
* Adds a set of metadata to the Cornerstone metadata provider given a specific
|
|
* imageId, type, and dataset
|
|
*
|
|
* @param imageId
|
|
* @param type (e.g. series, instance, tagDisplay)
|
|
* @param data
|
|
*/
|
|
addSpecificMetadata(imageId, type, data) {
|
|
const metadata = {};
|
|
metadata[type] = data;
|
|
|
|
const oldMetadata = this.metadataLookup.get(imageId);
|
|
this.metadataLookup.set(imageId, Object.assign(oldMetadata, metadata));
|
|
}
|
|
|
|
getFromImage(image, type, tag, attrName, defaultValue) {
|
|
let value;
|
|
|
|
if (image.data) {
|
|
value = this.getFromDataSet(image.data, type, tag);
|
|
} else {
|
|
value = image.instance[attrName];
|
|
}
|
|
|
|
return value === null ? defaultValue : value;
|
|
}
|
|
|
|
getFromDataSet(dataSet, type, tag) {
|
|
if (!dataSet) {
|
|
return;
|
|
}
|
|
|
|
const fn = dataSet[type];
|
|
if (!fn) {
|
|
return;
|
|
}
|
|
|
|
return fn.call(dataSet, tag);
|
|
}
|
|
|
|
getFrameIncrementPointer(image) {
|
|
const dataSet = image.data;
|
|
let frameInstancePointer = '';
|
|
|
|
if (parsingUtils.isValidDataSet(dataSet)) {
|
|
const frameInstancePointerNames = {
|
|
x00181063: 'frameTime',
|
|
x00181065: 'frameTimeVector',
|
|
};
|
|
|
|
// (0028,0009) = Frame Increment Pointer
|
|
const frameInstancePointerTag = parsingUtils.attributeTag(
|
|
dataSet,
|
|
'x00280009'
|
|
);
|
|
frameInstancePointer = frameInstancePointerNames[frameInstancePointerTag];
|
|
} else {
|
|
frameInstancePointer = image.instance.frameIncrementPointer;
|
|
}
|
|
|
|
return frameInstancePointer || '';
|
|
}
|
|
|
|
getFrameTimeVector(image) {
|
|
const dataSet = image.data;
|
|
|
|
if (parsingUtils.isValidDataSet(dataSet)) {
|
|
// Frame Increment Pointer points to Frame Time Vector (0018,1065) field
|
|
return parsingUtils.floatArray(dataSet, 'x00181065');
|
|
}
|
|
|
|
return image.instance.frameTimeVector;
|
|
}
|
|
|
|
getFrameTime(image) {
|
|
const dataSet = image.data;
|
|
|
|
if (parsingUtils.isValidDataSet(dataSet)) {
|
|
// Frame Increment Pointer points to Frame Time (0018,1063) field or is not defined (for addtional flexibility).
|
|
// Yet another value is possible for this field (5200,9230 for Multi-frame Functional Groups)
|
|
// but that case is currently not supported.
|
|
return dataSet.floatString('x00181063', -1);
|
|
}
|
|
|
|
return image.instance.frameTime;
|
|
}
|
|
|
|
/**
|
|
* Updates the related metadata for missing fields given a specified image
|
|
*
|
|
* @param image
|
|
*/
|
|
updateMetadata(image) {
|
|
const imageMetadata = this.metadataLookup.get(image.imageId);
|
|
if (!imageMetadata) {
|
|
return;
|
|
}
|
|
|
|
imageMetadata.patient.age =
|
|
imageMetadata.patient.age ||
|
|
this.getFromDataSet(image.data, 'string', 'x00101010');
|
|
|
|
imageMetadata.instance.rows = imageMetadata.instance.rows || image.rows;
|
|
imageMetadata.instance.columns =
|
|
imageMetadata.instance.columns || image.columns;
|
|
|
|
imageMetadata.instance.sopClassUid =
|
|
imageMetadata.instance.sopClassUid ||
|
|
this.getFromDataSet(image.data, 'string', 'x00080016');
|
|
imageMetadata.instance.sopInstanceUid =
|
|
imageMetadata.instance.sopInstanceUid ||
|
|
this.getFromDataSet(image.data, 'string', 'x00080018');
|
|
|
|
imageMetadata.instance.pixelSpacing =
|
|
imageMetadata.instance.pixelSpacing ||
|
|
this.getFromDataSet(image.data, 'string', 'x00280030');
|
|
imageMetadata.instance.frameOfReferenceUID =
|
|
imageMetadata.instance.frameOfReferenceUID ||
|
|
this.getFromDataSet(image.data, 'string', 'x00200052');
|
|
imageMetadata.instance.imageOrientationPatient =
|
|
imageMetadata.instance.imageOrientationPatient ||
|
|
this.getFromDataSet(image.data, 'string', 'x00200037');
|
|
imageMetadata.instance.imagePositionPatient =
|
|
imageMetadata.instance.imagePositionPatient ||
|
|
this.getFromDataSet(image.data, 'string', 'x00200032');
|
|
|
|
imageMetadata.instance.sliceThickness =
|
|
imageMetadata.instance.sliceThickness ||
|
|
this.getFromDataSet(image.data, 'string', 'x00180050');
|
|
imageMetadata.instance.sliceLocation =
|
|
imageMetadata.instance.sliceLocation ||
|
|
this.getFromDataSet(image.data, 'string', 'x00201041');
|
|
imageMetadata.instance.tablePosition =
|
|
imageMetadata.instance.tablePosition ||
|
|
this.getFromDataSet(image.data, 'string', 'x00189327');
|
|
imageMetadata.instance.spacingBetweenSlices =
|
|
imageMetadata.instance.spacingBetweenSlices ||
|
|
this.getFromDataSet(image.data, 'string', 'x00180088');
|
|
|
|
imageMetadata.instance.lossyImageCompression =
|
|
imageMetadata.instance.lossyImageCompression ||
|
|
this.getFromDataSet(image.data, 'string', 'x00282110');
|
|
imageMetadata.instance.lossyImageCompressionRatio =
|
|
imageMetadata.instance.lossyImageCompressionRatio ||
|
|
this.getFromDataSet(image.data, 'string', 'x00282112');
|
|
|
|
imageMetadata.instance.frameIncrementPointer =
|
|
imageMetadata.instance.frameIncrementPointer ||
|
|
this.getFromDataSet(image.data, 'string', 'x00280009');
|
|
imageMetadata.instance.frameTime =
|
|
imageMetadata.instance.frameTime ||
|
|
this.getFromDataSet(image.data, 'string', 'x00181063');
|
|
imageMetadata.instance.frameTimeVector =
|
|
imageMetadata.instance.frameTimeVector ||
|
|
this.getFromDataSet(image.data, 'string', 'x00181065');
|
|
|
|
if (
|
|
(image.data || image.instance) &&
|
|
!imageMetadata.instance.multiframeMetadata
|
|
) {
|
|
imageMetadata.instance.multiframeMetadata = this.getMultiframeModuleMetadata(
|
|
image
|
|
);
|
|
}
|
|
|
|
imageMetadata.imagePlane =
|
|
imageMetadata.imagePlane || this.getImagePlane(imageMetadata.instance);
|
|
}
|
|
|
|
/**
|
|
* Constructs and returns the imagePlane given the metadata instance
|
|
*
|
|
* @param metadataInstance The metadata instance (InstanceMetadata class) containing information to construct imagePlane
|
|
* @returns imagePlane The constructed imagePlane to be used in viewer easily
|
|
*/
|
|
getImagePlane(instance) {
|
|
if (
|
|
!instance.rows ||
|
|
!instance.columns ||
|
|
!instance.pixelSpacing ||
|
|
!instance.frameOfReferenceUID ||
|
|
!instance.imageOrientationPatient ||
|
|
!instance.imagePositionPatient
|
|
) {
|
|
return;
|
|
}
|
|
|
|
const imageOrientation = instance.imageOrientationPatient.split('\\');
|
|
const imagePosition = instance.imagePositionPatient.split('\\');
|
|
|
|
let columnPixelSpacing = 1.0;
|
|
let rowPixelSpacing = 1.0;
|
|
if (instance.pixelSpacing) {
|
|
const split = instance.pixelSpacing.split('\\');
|
|
rowPixelSpacing = parseFloat(split[0]);
|
|
columnPixelSpacing = parseFloat(split[1]);
|
|
}
|
|
|
|
return {
|
|
frameOfReferenceUID: instance.frameOfReferenceUID,
|
|
rows: instance.rows,
|
|
columns: instance.columns,
|
|
rowCosines: [
|
|
parseFloat(imageOrientation[0]),
|
|
parseFloat(imageOrientation[1]),
|
|
parseFloat(imageOrientation[2]),
|
|
],
|
|
columnCosines: [
|
|
parseFloat(imageOrientation[3]),
|
|
parseFloat(imageOrientation[4]),
|
|
parseFloat(imageOrientation[5]),
|
|
],
|
|
imagePositionPatient: [
|
|
parseFloat(imagePosition[0]),
|
|
parseFloat(imagePosition[1]),
|
|
parseFloat(imagePosition[2]),
|
|
],
|
|
rowPixelSpacing,
|
|
columnPixelSpacing,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* This function extracts miltiframe information from a dicomParser.DataSet object.
|
|
*
|
|
* @param dataSet {Object} An instance of dicomParser.DataSet object where multiframe information can be found.
|
|
* @return {Object} An object containing multiframe image metadata (frameIncrementPointer, frameTime, frameTimeVector, etc).
|
|
*/
|
|
getMultiframeModuleMetadata(image) {
|
|
const imageInfo = {
|
|
isMultiframeImage: false,
|
|
frameIncrementPointer: null,
|
|
numberOfFrames: 0,
|
|
frameTime: 0,
|
|
frameTimeVector: null,
|
|
averageFrameRate: 0, // backwards compatibility only... it might be useless in the future
|
|
};
|
|
|
|
let frameTime;
|
|
|
|
const numberOfFrames = this.getFromImage(
|
|
image,
|
|
'intString',
|
|
'x00280008',
|
|
'numberOfFrames',
|
|
-1
|
|
);
|
|
|
|
if (numberOfFrames > 0) {
|
|
// set multi-frame image indicator
|
|
imageInfo.isMultiframeImage = true;
|
|
imageInfo.numberOfFrames = numberOfFrames;
|
|
|
|
// (0028,0009) = Frame Increment Pointer
|
|
const frameIncrementPointer = this.getFrameIncrementPointer(image);
|
|
|
|
if (frameIncrementPointer === 'frameTimeVector') {
|
|
// Frame Increment Pointer points to Frame Time Vector (0018,1065) field
|
|
const frameTimeVector = this.getFrameTimeVector(image);
|
|
|
|
if (frameTimeVector instanceof Array && frameTimeVector.length > 0) {
|
|
imageInfo.frameIncrementPointer = frameIncrementPointer;
|
|
imageInfo.frameTimeVector = frameTimeVector;
|
|
frameTime =
|
|
frameTimeVector.reduce((a, b) => a + b) / frameTimeVector.length;
|
|
imageInfo.averageFrameRate = 1000 / frameTime;
|
|
}
|
|
} else if (
|
|
frameIncrementPointer === 'frameTime' ||
|
|
frameIncrementPointer === ''
|
|
) {
|
|
frameTime = this.getFrameTime(image);
|
|
|
|
if (frameTime > 0) {
|
|
imageInfo.frameIncrementPointer = frameIncrementPointer;
|
|
imageInfo.frameTime = frameTime;
|
|
imageInfo.averageFrameRate = 1000 / frameTime;
|
|
}
|
|
}
|
|
}
|
|
|
|
return imageInfo;
|
|
}
|
|
|
|
/**
|
|
* Get a bound reference to the provider function.
|
|
*/
|
|
getProvider() {
|
|
let provider = this._provider;
|
|
if (typeof this._provider !== FUNCTION) {
|
|
provider = this.provider.bind(this);
|
|
this._provider = provider;
|
|
}
|
|
|
|
return provider;
|
|
}
|
|
|
|
/**
|
|
* Looks up metadata for Cornerstone Tools given a specified type and imageId
|
|
* A type may be, e.g. 'study', or 'patient', or 'imagePlaneModule'. These types
|
|
* are keys in the stored metadata objects.
|
|
*
|
|
* @param type
|
|
* @param imageId
|
|
* @returns {Object} Relevant metadata of the specified type
|
|
*/
|
|
provider(type, imageId) {
|
|
const imageMetadata = this.metadataLookup.get(imageId);
|
|
if (!imageMetadata) {
|
|
return;
|
|
}
|
|
|
|
if (imageMetadata.hasOwnProperty(type)) {
|
|
return imageMetadata[type];
|
|
}
|
|
}
|
|
}
|
|
|
|
export default MetadataProvider;
|