UNPKG

terriajs

Version:

Geospatial data visualization platform.

84 lines 4.2 kB
import filterOutUndefined from "../../../Core/filterOutUndefined"; import flatten from "../../../Core/flatten"; import TerriaError from "../../../Core/TerriaError"; import GroupMixin from "../../../ModelMixins/GroupMixin"; import ReferenceMixin from "../../../ModelMixins/ReferenceMixin"; import CatalogIndexReferenceTraits from "../../../Traits/TraitsClasses/CatalogIndexReferenceTraits"; import CreateModel from "../../Definition/CreateModel"; import { BaseModel } from "../../Definition/Model"; /** The `CatalogIndexReference` is used to resolve items in the `catalogIndex` to actual models in terria.models. * * The `catalogIndex` is a "stripped-down" fully resolved tree of models generated using the `generateCatalogIndex` script. * An item in the `catalogIndex` will have `CatalogMemberReferenceTraits` with an additional `memberKnownContainerUniqueIds`. * * This means we can use the `catalogIndex` to search the entire catalog without loading models. * * When `loadReference` is called, it will attempt to load all parent models first (using `memberKnownContainerUniqueIds`) */ export default class CatalogIndexReference extends ReferenceMixin(CreateModel(CatalogIndexReferenceTraits)) { weakReference = true; static type = "catalog-index-reference"; get type() { return CatalogIndexReference.type; } async forceLoadReference(_previousTarget) { if (this.uniqueId === undefined) { return; } // If member already exists - return it let member = this.terria.getModelById(BaseModel, this.uniqueId); if (member) { return member; } const errors = []; // No member exists, so try to load containers // Get full list of containers by recursively searching for parent models const findContainers = (model) => [ ...model.memberKnownContainerUniqueIds, ...flatten(filterOutUndefined(model.memberKnownContainerUniqueIds.map((parentId) => { const parent = model.terria.catalogIndex?.models?.get(parentId); if (parent) { return findContainers(parent); } }))) ]; const containers = findContainers(this).reverse(); // Load containers if (containers) { for (let i = 0; i < containers.length; i++) { const containerId = containers[i]; let container = this.terria.getModelById(BaseModel, containerId); if (!container) { errors.push(TerriaError.from(`Failed to find containerID ${containerId}`)); } if (ReferenceMixin.isMixedInto(container)) { // Recursively load references up to a depth of 5. This is so that we // correctly resolve the final target item when we have a chain of // references like: MagdaReference -> TerriaReference -> ... -> SomeItem // We limit to a depth of 5 to avoid looping forever. (await container.recursivelyLoadReference(5)).pushErrorTo(errors, `Failed to load reference ${container.uniqueId}`); container = container.nestedTarget ?? container; } if (GroupMixin.isMixedInto(container)) { (await container.loadMembers()).pushErrorTo(errors, `Failed to load group ${container.uniqueId}`); } } } // Does member exist now? - return it member = this.terria.getModelById(BaseModel, this.uniqueId); if (member) { // member.sourceReference = target.sourceReference return member; } const parentErrorMessage = new TerriaError({ title: `Failed to find dataset "${this.name ?? this.uniqueId}"`, message: { key: "core.terriaError.networkRequestMessage" }, importance: 1 }); // No member exists - throw error throw TerriaError.combine(errors, parentErrorMessage) ?? parentErrorMessage; } } //# sourceMappingURL=CatalogIndexReference.js.map