Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | 96x 96x 96x 96x 96x 91x 5x 4x 1x 95x 95x 95x 95x 95x 95x 95x 95x 95x 1x 1x 1x 1x 13x 13x 13x 1x 48x 20x 28x 10x 18x 18x 1x 269x 269x 269x 268x 269x 1x 53x 53x 53x 53x 53x 53x 53x 1x 2x 1x 1x 1x 2x 1x 31x 4x 27x 27x 27x 1x 268x 268x 268x 268x 268x 268x 268x 268x 268x 268x 268x 295x 295x 295x 295x 14x 14x 14x 14x 5x 9x 6x 6x 6x 3x 6x 6x 6x 6x 9x 9x 9x | import Uri from "urijs";
import Check from "./Check.js";
import Credit from "./Credit.js";
import Frozen from "./Frozen.js";
import defined from "./defined.js";
import Ion from "./Ion.js";
import Resource from "./Resource.js";
import RuntimeError from "./RuntimeError.js";
/**
* A function that will be invoked when the access token is refreshed.
* @callback IonResourceRefreshCallback
* @param {IonResource} ionResource The root IonResource being refreshed.
* @param {object} endpoint The result of the Cesium ion asset endpoint service. This may be modified in place by the callback.
* @private
*/
/**
* A {@link Resource} instance that encapsulates Cesium ion asset access.
* This object is normally not instantiated directly, use {@link IonResource.fromAssetId}.
*
* @alias IonResource
* @constructor
* @augments Resource
*
* @param {object} endpoint The result of the Cesium ion asset endpoint service.
* @param {Resource} endpointResource The original resource used to retrieve the endpoint.
*
* @see Ion
* @see IonImageryProvider
* @see createWorldTerrain
* @see https://cesium.com
*/
function IonResource(endpoint, endpointResource) {
//>>includeStart('debug', pragmas.debug);
Check.defined("endpoint", endpoint);
Check.defined("endpointResource", endpointResource);
//>>includeEnd('debug');
let options;
const externalType = endpoint.externalType;
const isExternal = defined(externalType);
if (!isExternal) {
options = {
url: endpoint.url,
retryAttempts: 1,
retryCallback: retryCallback,
};
} else if (
externalType === "3DTILES" ||
externalType === "STK_TERRAIN_SERVER"
) {
// 3D Tiles and STK Terrain Server external assets can still be represented as an IonResource
options = { url: endpoint.options.url };
} else {
//External imagery assets have additional configuration that can't be represented as a Resource
throw new RuntimeError(
"Ion.createResource does not support external imagery assets; use IonImageryProvider instead.",
);
}
Resource.call(this, options);
// The asset endpoint data returned from ion.
this._ionEndpoint = endpoint;
this._ionEndpointDomain = isExternal
? undefined
: new Uri(endpoint.url).authority();
// The endpoint resource to fetch when a new token is needed
this._ionEndpointResource = endpointResource;
// The primary IonResource from which an instance is derived
this._ionRoot = undefined;
// Shared promise for endpooint requests amd credits (only ever set on the root request)
this._pendingPromise = undefined;
this._credits = undefined;
this._isExternal = isExternal;
/**
* A function that, if defined, will be invoked when the access token is refreshed.
* @private
* @type {IonResourceRefreshCallback|undefined}
*/
this.refreshCallback = undefined;
}
Eif (defined(Object.create)) {
IonResource.prototype = Object.create(Resource.prototype);
IonResource.prototype.constructor = IonResource;
}
/**
* Asynchronously creates an instance.
*
* @param {number} assetId The Cesium ion asset id.
* @param {object} [options] An object with the following properties:
* @param {string} [options.accessToken=Ion.defaultAccessToken] The access token to use.
* @param {string|Resource} [options.server=Ion.defaultServer] The resource to the Cesium ion API server.
* @returns {Promise<IonResource>} A Promise to an instance representing the Cesium ion Asset.
*
* @example
* // Load a Cesium3DTileset with asset ID of 124624234
* try {
* const resource = await Cesium.IonResource.fromAssetId(124624234);
* const tileset = await Cesium.Cesium3DTileset.fromUrl(resource);
* scene.primitives.add(tileset);
* } catch (error) {
* console.error(`Error creating tileset: ${error}`);
* }
*
* @example
* //Load a CZML file with asset ID of 10890
* Cesium.IonResource.fromAssetId(10890)
* .then(function (resource) {
* viewer.dataSources.add(Cesium.CzmlDataSource.load(resource));
* });
*/
IonResource.fromAssetId = function (assetId, options) {
const endpointResource = IonResource._createEndpointResource(
assetId,
options,
);
return endpointResource.fetchJson().then(function (endpoint) {
return new IonResource(endpoint, endpointResource);
});
};
Object.defineProperties(IonResource.prototype, {
/**
* Gets the credits required for attribution of the asset.
*
* @memberof IonResource.prototype
* @type {Credit[]}
* @readonly
*/
credits: {
get: function () {
// Only we're not the root, return its credits;
if (defined(this._ionRoot)) {
return this._ionRoot.credits;
}
// We are the root
if (defined(this._credits)) {
return this._credits;
}
this._credits = IonResource.getCreditsFromEndpoint(
this._ionEndpoint,
this._ionEndpointResource,
);
return this._credits;
},
},
});
/** @private */
IonResource.getCreditsFromEndpoint = function (endpoint, endpointResource) {
const credits = endpoint.attributions.map(Credit.getIonCredit);
const defaultTokenCredit = Ion.getDefaultTokenCredit(
endpointResource.queryParameters.access_token,
);
if (defined(defaultTokenCredit)) {
credits.push(Credit.clone(defaultTokenCredit));
}
return credits;
};
/** @inheritdoc */
IonResource.prototype.clone = function (result) {
// We always want to use the root's information because it's the most up-to-date
const ionRoot = this._ionRoot ?? this;
Eif (!defined(result)) {
result = new IonResource(
ionRoot._ionEndpoint,
ionRoot._ionEndpointResource,
);
}
result = Resource.prototype.clone.call(this, result);
result._ionRoot = ionRoot;
result._isExternal = this._isExternal;
return result;
};
IonResource.prototype.fetchImage = function (options) {
if (!this._isExternal) {
const userOptions = options;
options = {
preferBlob: true,
};
Iif (defined(userOptions)) {
options.flipY = userOptions.flipY;
options.preferImageBitmap = userOptions.preferImageBitmap;
}
}
return Resource.prototype.fetchImage.call(this, options);
};
IonResource.prototype._makeRequest = function (options) {
// Don't send ion access token to non-ion servers.
if (
this._isExternal ||
new Uri(this.url).authority() !== this._ionEndpointDomain
) {
return Resource.prototype._makeRequest.call(this, options);
}
options.headers = addClientHeaders(options.headers);
options.headers.Authorization = `Bearer ${this._ionEndpoint.accessToken}`;
return Resource.prototype._makeRequest.call(this, options);
};
/**
* @private
**/
IonResource._createEndpointResource = function (assetId, options) {
//>>includeStart('debug', pragmas.debug);
Check.defined("assetId", assetId);
//>>includeEnd('debug');
options = options ?? Frozen.EMPTY_OBJECT;
let server = options.server ?? Ion.defaultServer;
const accessToken = options.accessToken ?? Ion.defaultAccessToken;
server = Resource.createIfNeeded(server);
const resourceOptions = {
url: `v1/assets/${assetId}/endpoint`,
};
Eif (defined(accessToken)) {
resourceOptions.queryParameters = { access_token: accessToken };
}
Iif (defined(options.queryParameters)) {
resourceOptions.queryParameters = {
...resourceOptions.queryParameters,
...options.queryParameters,
};
}
resourceOptions.headers = addClientHeaders(resourceOptions.headers);
return server.getDerivedResource(resourceOptions);
};
/**
* Adds CesiumJS client headers to the provided headers object.
* @private
* @param {object} [headers={}] The headers to modify.
* @returns {object} The modified headers.
*/
function addClientHeaders(headers = {}) {
headers["X-Cesium-Client"] = "CesiumJS";
/* global CESIUM_VERSION */
Eif (typeof CESIUM_VERSION !== "undefined") {
headers["X-Cesium-Client-Version"] = CESIUM_VERSION;
}
return headers;
}
function retryCallback(that, error) {
const ionRoot = that._ionRoot ?? that;
const endpointResource = ionRoot._ionEndpointResource;
// Image is not available in worker threads, so this avoids
// a ReferenceError
const imageDefined = typeof Image !== "undefined";
// We only want to retry in the case of invalid credentials (401) or image
// requests(since Image failures can not provide a status code)
if (
!defined(error) ||
(error.statusCode !== 401 &&
!(imageDefined && error.target instanceof Image))
) {
return Promise.resolve(false);
}
// We use a shared pending promise for all derived assets, since they share
// a common access_token. If we're already requesting a new token for this
// asset, we wait on the same promise.
if (!defined(ionRoot._pendingPromise)) {
ionRoot._pendingPromise = endpointResource
.fetchJson()
.then(function (newEndpoint) {
const refreshCallback = that.refreshCallback ?? ionRoot.refreshCallback;
if (defined(refreshCallback)) {
refreshCallback(ionRoot, newEndpoint);
}
// Set the token for root resource so new derived resources automatically pick it up
ionRoot._ionEndpoint = newEndpoint;
return ionRoot._ionEndpoint;
})
.finally(function (newEndpoint) {
// Pass or fail, we're done with this promise, the next failure should use a new one.
ionRoot._pendingPromise = undefined;
return newEndpoint;
});
}
return ionRoot._pendingPromise.then(function (newEndpoint) {
// Set the new token and endpoint for this resource
that._ionEndpoint = newEndpoint;
return true;
});
}
export default IonResource;
|