123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- import defaultValue from "../Core/defaultValue.js";
- import defined from "../Core/defined.js";
- import DeveloperError from "../Core/DeveloperError.js";
- import getImagePixels from "../Core/getImagePixels.js";
- import Resource from "../Core/Resource.js";
- /**
- * A policy for discarding tile images that match a known image containing a
- * "missing" image.
- *
- * @alias DiscardMissingTileImagePolicy
- * @constructor
- *
- * @param {object} options Object with the following properties:
- * @param {Resource|string} options.missingImageUrl The URL of the known missing image.
- * @param {Cartesian2[]} options.pixelsToCheck An array of {@link Cartesian2} pixel positions to
- * compare against the missing image.
- * @param {boolean} [options.disableCheckIfAllPixelsAreTransparent=false] If true, the discard check will be disabled
- * if all of the pixelsToCheck in the missingImageUrl have an alpha value of 0. If false, the
- * discard check will proceed no matter the values of the pixelsToCheck.
- */
- function DiscardMissingTileImagePolicy(options) {
- options = defaultValue(options, defaultValue.EMPTY_OBJECT);
- //>>includeStart('debug', pragmas.debug);
- if (!defined(options.missingImageUrl)) {
- throw new DeveloperError("options.missingImageUrl is required.");
- }
- if (!defined(options.pixelsToCheck)) {
- throw new DeveloperError("options.pixelsToCheck is required.");
- }
- //>>includeEnd('debug');
- this._pixelsToCheck = options.pixelsToCheck;
- this._missingImagePixels = undefined;
- this._missingImageByteLength = undefined;
- this._isReady = false;
- const resource = Resource.createIfNeeded(options.missingImageUrl);
- const that = this;
- function success(image) {
- if (defined(image.blob)) {
- that._missingImageByteLength = image.blob.size;
- }
- let pixels = getImagePixels(image);
- if (options.disableCheckIfAllPixelsAreTransparent) {
- let allAreTransparent = true;
- const width = image.width;
- const pixelsToCheck = options.pixelsToCheck;
- for (
- let i = 0, len = pixelsToCheck.length;
- allAreTransparent && i < len;
- ++i
- ) {
- const pos = pixelsToCheck[i];
- const index = pos.x * 4 + pos.y * width;
- const alpha = pixels[index + 3];
- if (alpha > 0) {
- allAreTransparent = false;
- }
- }
- if (allAreTransparent) {
- pixels = undefined;
- }
- }
- that._missingImagePixels = pixels;
- that._isReady = true;
- }
- function failure() {
- // Failed to download "missing" image, so assume that any truly missing tiles
- // will also fail to download and disable the discard check.
- that._missingImagePixels = undefined;
- that._isReady = true;
- }
- resource
- .fetchImage({
- preferBlob: true,
- preferImageBitmap: true,
- flipY: true,
- })
- .then(success)
- .catch(failure);
- }
- /**
- * Determines if the discard policy is ready to process images.
- * @returns {boolean} True if the discard policy is ready to process images; otherwise, false.
- */
- DiscardMissingTileImagePolicy.prototype.isReady = function () {
- return this._isReady;
- };
- /**
- * Given a tile image, decide whether to discard that image.
- *
- * @param {HTMLImageElement} image An image to test.
- * @returns {boolean} True if the image should be discarded; otherwise, false.
- *
- * @exception {DeveloperError} <code>shouldDiscardImage</code> must not be called before the discard policy is ready.
- */
- DiscardMissingTileImagePolicy.prototype.shouldDiscardImage = function (image) {
- //>>includeStart('debug', pragmas.debug);
- if (!this._isReady) {
- throw new DeveloperError(
- "shouldDiscardImage must not be called before the discard policy is ready."
- );
- }
- //>>includeEnd('debug');
- const pixelsToCheck = this._pixelsToCheck;
- const missingImagePixels = this._missingImagePixels;
- // If missingImagePixels is undefined, it indicates that the discard check has been disabled.
- if (!defined(missingImagePixels)) {
- return false;
- }
- if (defined(image.blob) && image.blob.size !== this._missingImageByteLength) {
- return false;
- }
- const pixels = getImagePixels(image);
- const width = image.width;
- for (let i = 0, len = pixelsToCheck.length; i < len; ++i) {
- const pos = pixelsToCheck[i];
- const index = pos.x * 4 + pos.y * width;
- for (let offset = 0; offset < 4; ++offset) {
- const pixel = index + offset;
- if (pixels[pixel] !== missingImagePixels[pixel]) {
- return false;
- }
- }
- }
- return true;
- };
- export default DiscardMissingTileImagePolicy;
|