-
Notifications
You must be signed in to change notification settings - Fork 3.6k
/
Copy pathDiscardMissingTileImagePolicy.js
149 lines (126 loc) · 5.18 KB
/
DiscardMissingTileImagePolicy.js
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
define([
'../Core/defaultValue',
'../Core/defined',
'../Core/DeveloperError',
'../Core/getImagePixels',
'../Core/Resource'
], function(
defaultValue,
defined,
DeveloperError,
getImagePixels,
Resource) {
'use strict';
/**
* 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;
var resource = Resource.createIfNeeded(options.missingImageUrl);
var that = this;
function success(image) {
if (defined(image.blob)) {
that._missingImageByteLength = image.blob.size;
}
var pixels = getImagePixels(image);
if (options.disableCheckIfAllPixelsAreTransparent) {
var allAreTransparent = true;
var width = image.width;
var pixelsToCheck = options.pixelsToCheck;
for (var i = 0, len = pixelsToCheck.length; allAreTransparent && i < len; ++i) {
var pos = pixelsToCheck[i];
var index = pos.x * 4 + pos.y * width;
var 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).otherwise(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 {Image} 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');
var pixelsToCheck = this._pixelsToCheck;
var 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;
}
var pixels = getImagePixels(image);
var width = image.width;
for (var i = 0, len = pixelsToCheck.length; i < len; ++i) {
var pos = pixelsToCheck[i];
var index = pos.x * 4 + pos.y * width;
for (var offset = 0; offset < 4; ++offset) {
var pixel = index + offset;
if (pixels[pixel] !== missingImagePixels[pixel]) {
return false;
}
}
}
return true;
};
return DiscardMissingTileImagePolicy;
});