geojs 1.6.6 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/geo.js +320 -57
- package/geo.lean.js +320 -57
- package/geo.lean.min.js +2 -2
- package/geo.min.js +2 -2
- package/package.json +1 -1
- package/src/canvas/pixelmapFeature.js +21 -0
- package/src/index.js +1 -0
- package/src/pixelmapFeature.js +45 -21
- package/src/pixelmapLayer.js +145 -0
- package/src/tileLayer.js +3 -2
- package/src/webgl/pixelmapFeature.js +62 -31
- package/src/webgl/quadFeature.js +3 -1
package/package.json
CHANGED
|
@@ -4,6 +4,25 @@ var pixelmapFeature = require('../pixelmapFeature');
|
|
|
4
4
|
var geo_event = require('../event');
|
|
5
5
|
var util = require('../util');
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Pixelmap feature information record.
|
|
9
|
+
*
|
|
10
|
+
* @typedef {object} geo.pixelmapFeature.info
|
|
11
|
+
* @property {number} width The width of the source image.
|
|
12
|
+
* @property {number} height The width of the source image.
|
|
13
|
+
* @property {CanvasRenderingContext2D} context The HTMLCanvasElement context
|
|
14
|
+
* used for handling the pixelmap.
|
|
15
|
+
* @property {ImageData} imageData The context's image data.
|
|
16
|
+
* @property {number[]} indices An array, one per pixel, of the index value in
|
|
17
|
+
* the image. This decodes the pixel value to the corresponding integer.
|
|
18
|
+
* @property number} area The number of pixels in the image. This is
|
|
19
|
+
* `width * height`.
|
|
20
|
+
* @property {object[]} mappedColors This has one entry for each distinct index
|
|
21
|
+
* value. Each entry has `first` and `last` with the first and last pixel
|
|
22
|
+
* locations where that index occurs. Note that last is the inclusive value
|
|
23
|
+
* of the location (so its maximum possible value is `size - 1`).
|
|
24
|
+
*/
|
|
25
|
+
|
|
7
26
|
/**
|
|
8
27
|
* Create a new instance of class pixelmapFeature.
|
|
9
28
|
*
|
|
@@ -116,11 +135,13 @@ var canvas_pixelmapFeature = function (arg) {
|
|
|
116
135
|
updateFirst, updateLast = -1, update, prepared;
|
|
117
136
|
|
|
118
137
|
if (!m_this.m_info) {
|
|
138
|
+
m_this.indexModified(undefined, 'clear');
|
|
119
139
|
if (!m_this._preparePixelmap()) {
|
|
120
140
|
return;
|
|
121
141
|
}
|
|
122
142
|
prepared = true;
|
|
123
143
|
}
|
|
144
|
+
m_this.indexModified(undefined, 'clear');
|
|
124
145
|
mappedColors = m_this.m_info.mappedColors;
|
|
125
146
|
updateFirst = m_this.m_info.area;
|
|
126
147
|
for (idx in mappedColors) {
|
package/src/index.js
CHANGED
|
@@ -77,6 +77,7 @@ module.exports = $.extend({
|
|
|
77
77
|
polygonFeature: require('./polygonFeature'),
|
|
78
78
|
quadFeature: require('./quadFeature'),
|
|
79
79
|
pixelmapFeature: require('./pixelmapFeature'),
|
|
80
|
+
pixelmapLayer: require('./pixelmapLayer'),
|
|
80
81
|
renderer: require('./renderer'),
|
|
81
82
|
sceneObject: require('./sceneObject'),
|
|
82
83
|
textFeature: require('./textFeature'),
|
package/src/pixelmapFeature.js
CHANGED
|
@@ -30,25 +30,6 @@ var util = require('./util');
|
|
|
30
30
|
* transformations for those two triangles.
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
-
/**
|
|
34
|
-
* Pixelmap feature information record.
|
|
35
|
-
*
|
|
36
|
-
* @typedef {object} geo.pixelmapFeature.info
|
|
37
|
-
* @property {number} width The width of the source image.
|
|
38
|
-
* @property {number} height The width of the source image.
|
|
39
|
-
* @property {context} context The HTMLCanvasElement context used for handling
|
|
40
|
-
* the pixelmap.
|
|
41
|
-
* @property {ImageData} imageData The context's image data.
|
|
42
|
-
* @property {number[]} indices An array, one per pixel, of the index value in
|
|
43
|
-
* the image. This decodes the pixel value to the corresponding integer.
|
|
44
|
-
* @property number} area The number of pixels in the image. This is
|
|
45
|
-
* `width * height`.
|
|
46
|
-
* @property {object[]} mappedColors This has one entry for each distinct index
|
|
47
|
-
* value. Each entry has `first` and `last` with the first and last pixel
|
|
48
|
-
* locations where that index occurs. Note that last is the inclusive value
|
|
49
|
-
* of the location (so its maximum possible value is `size - 1`).
|
|
50
|
-
*/
|
|
51
|
-
|
|
52
33
|
/**
|
|
53
34
|
* Create a new instance of class pixelmapFeature
|
|
54
35
|
*
|
|
@@ -72,6 +53,7 @@ var pixelmapFeature = function (arg) {
|
|
|
72
53
|
*/
|
|
73
54
|
var m_this = this,
|
|
74
55
|
s_update = this._update,
|
|
56
|
+
m_modifiedIndexRange,
|
|
75
57
|
s_init = this._init;
|
|
76
58
|
|
|
77
59
|
this.featureType = 'pixelmap';
|
|
@@ -134,6 +116,42 @@ var pixelmapFeature = function (arg) {
|
|
|
134
116
|
return m_this;
|
|
135
117
|
};
|
|
136
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Mark that an index's data value (and hence its color) has changed without
|
|
121
|
+
* marking all of the data array as changed. If this function is called
|
|
122
|
+
* without any parameters, it clears the tracked changes.
|
|
123
|
+
*
|
|
124
|
+
* @param {number} [idx] The lowest data index that has changed. If
|
|
125
|
+
* `undefined`, return the current tracked changed range.
|
|
126
|
+
* @param {number|'clear'} [idx2] If an index was specified in `idx` and
|
|
127
|
+
* this is specified, the highest index (inclusive) that has changed. If
|
|
128
|
+
* returning the tracked changed range and this is `clear`, clear the
|
|
129
|
+
* tracked range.
|
|
130
|
+
* @returns {this|number[]} When returning a range, this is the lowest and
|
|
131
|
+
* highest index values that have changed (inclusive), so their range is
|
|
132
|
+
* `[0, data.length)`.
|
|
133
|
+
*/
|
|
134
|
+
this.indexModified = function (idx, idx2) {
|
|
135
|
+
if (idx === undefined) {
|
|
136
|
+
const range = m_modifiedIndexRange;
|
|
137
|
+
if (idx2 === 'clear') {
|
|
138
|
+
m_modifiedIndexRange = undefined;
|
|
139
|
+
}
|
|
140
|
+
return range;
|
|
141
|
+
}
|
|
142
|
+
m_this.modified();
|
|
143
|
+
if (m_modifiedIndexRange === undefined) {
|
|
144
|
+
m_modifiedIndexRange = [idx, idx];
|
|
145
|
+
}
|
|
146
|
+
if (idx < m_modifiedIndexRange[0]) {
|
|
147
|
+
m_modifiedIndexRange[0] = idx;
|
|
148
|
+
}
|
|
149
|
+
if ((idx2 || idx) > m_modifiedIndexRange[1]) {
|
|
150
|
+
m_modifiedIndexRange[1] = (idx2 || idx);
|
|
151
|
+
}
|
|
152
|
+
return m_this;
|
|
153
|
+
};
|
|
154
|
+
|
|
137
155
|
/**
|
|
138
156
|
* Update.
|
|
139
157
|
*
|
|
@@ -192,7 +210,6 @@ var pixelmapFeature = function (arg) {
|
|
|
192
210
|
* drawing a quad, which can trigger a full layer update, which in turn
|
|
193
211
|
* checks if this feature is built. Setting the build time avoids calling
|
|
194
212
|
* this a second time. */
|
|
195
|
-
m_this.buildTime().modified();
|
|
196
213
|
if (!m_this.m_srcImage) {
|
|
197
214
|
var src = m_this.style.get('url')();
|
|
198
215
|
if (util.isReadyImage(src)) {
|
|
@@ -243,6 +260,7 @@ var pixelmapFeature = function (arg) {
|
|
|
243
260
|
} else if (m_this.m_info) {
|
|
244
261
|
m_this._computePixelmap();
|
|
245
262
|
}
|
|
263
|
+
m_this.buildTime().modified();
|
|
246
264
|
return m_this;
|
|
247
265
|
};
|
|
248
266
|
|
|
@@ -282,6 +300,10 @@ var pixelmapFeature = function (arg) {
|
|
|
282
300
|
}
|
|
283
301
|
m_this.style(style);
|
|
284
302
|
m_this.dataTime().modified();
|
|
303
|
+
if (arg.quadFeature) {
|
|
304
|
+
m_this.m_srcImage = true;
|
|
305
|
+
m_this._computePixelmap();
|
|
306
|
+
}
|
|
285
307
|
|
|
286
308
|
return m_this;
|
|
287
309
|
};
|
|
@@ -307,7 +329,9 @@ pixelmapFeature.create = function (layer, spec) {
|
|
|
307
329
|
|
|
308
330
|
pixelmapFeature.capabilities = {
|
|
309
331
|
/* core feature name -- support in any manner */
|
|
310
|
-
feature: 'pixelmap'
|
|
332
|
+
feature: 'pixelmap',
|
|
333
|
+
/* support for image-based lookup */
|
|
334
|
+
lookup: 'pixelmap.lookup'
|
|
311
335
|
};
|
|
312
336
|
|
|
313
337
|
inherit(pixelmapFeature, feature);
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
var $ = require('jquery');
|
|
2
|
+
var inherit = require('./inherit');
|
|
3
|
+
var tileLayer = require('./tileLayer');
|
|
4
|
+
var registry = require('./registry');
|
|
5
|
+
var quadFeature = require('./quadFeature');
|
|
6
|
+
var pixelmapFeature = require('./pixelmapFeature');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Object specification for a pixelmap layer.
|
|
10
|
+
*
|
|
11
|
+
* @typedef {geo.tileLayer.spec} geo.pixelmapLayer.spec
|
|
12
|
+
* @extends {geo.tileLayer.spec}
|
|
13
|
+
* @property {geo.geoColor|function} [color] The color that should be used
|
|
14
|
+
* for each data element. Data elements correspond to the indices in the
|
|
15
|
+
* pixel map. If an index is larger than the number of data elements, it will
|
|
16
|
+
* be transparent. If there is more data than there are indices, it is
|
|
17
|
+
* ignored.
|
|
18
|
+
* @property {object} [style] An optional style object that could contain
|
|
19
|
+
* `color` or other style values.
|
|
20
|
+
* @property {array} [data] A new data array.
|
|
21
|
+
* @property {string} [crossDomain='anonymous'] Image CORS attribute. This is
|
|
22
|
+
* used for the `crossorigin` property when loading images.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Create a new instance of pixelmapLayer. This is a {@link geo.tileLayer} with
|
|
27
|
+
* an OSM url and attribution defaults and with the tiles centered on the
|
|
28
|
+
* origin.
|
|
29
|
+
*
|
|
30
|
+
* @class
|
|
31
|
+
* @alias geo.pixelmapLayer
|
|
32
|
+
* @extends geo.tileLayer
|
|
33
|
+
*
|
|
34
|
+
* @param {geo.pixelmapLayer.spec} [arg] Specification for the layer.
|
|
35
|
+
*/
|
|
36
|
+
var pixelmapLayer = function (arg) {
|
|
37
|
+
|
|
38
|
+
var imageTile = require('./imageTile');
|
|
39
|
+
|
|
40
|
+
if (!(this instanceof pixelmapLayer)) {
|
|
41
|
+
return new pixelmapLayer(arg);
|
|
42
|
+
}
|
|
43
|
+
arg = arg || {};
|
|
44
|
+
arg = $.extend(
|
|
45
|
+
true,
|
|
46
|
+
{},
|
|
47
|
+
this.constructor.defaults,
|
|
48
|
+
arg);
|
|
49
|
+
tileLayer.call(this, arg);
|
|
50
|
+
|
|
51
|
+
var s_init = this._init,
|
|
52
|
+
m_pixelmapFeature,
|
|
53
|
+
m_this = this;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Returns an instantiated imageTile object with the given indices. This
|
|
57
|
+
* method always returns a new tile object. Use `_getTileCached` to use
|
|
58
|
+
* the caching layer.
|
|
59
|
+
*
|
|
60
|
+
* @param {object} index The tile index.
|
|
61
|
+
* @param {number} index.x
|
|
62
|
+
* @param {number} index.y
|
|
63
|
+
* @param {number} index.level
|
|
64
|
+
* @param {object} source The tile index used for constructing the url.
|
|
65
|
+
* @param {number} source.x
|
|
66
|
+
* @param {number} source.y
|
|
67
|
+
* @param {number} source.level
|
|
68
|
+
* @returns {geo.tile}
|
|
69
|
+
*/
|
|
70
|
+
this._getTile = function (index, source) {
|
|
71
|
+
var urlParams = source || index;
|
|
72
|
+
return imageTile({
|
|
73
|
+
index: index,
|
|
74
|
+
size: {x: m_this._options.tileWidth, y: m_this._options.tileHeight},
|
|
75
|
+
queue: m_this._queue,
|
|
76
|
+
overlap: m_this._options.tileOverlap,
|
|
77
|
+
scale: m_this._options.tileScale,
|
|
78
|
+
url: m_this._options.url.call(
|
|
79
|
+
m_this, urlParams.x, urlParams.y, urlParams.level || 0,
|
|
80
|
+
m_this._options.subdomains),
|
|
81
|
+
crossDomain: m_this._options.crossDomain
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Initialize.
|
|
87
|
+
*
|
|
88
|
+
* @returns {this} The current layer.
|
|
89
|
+
*/
|
|
90
|
+
this._init = function () {
|
|
91
|
+
// Call super class init
|
|
92
|
+
s_init.apply(m_this, arguments);
|
|
93
|
+
|
|
94
|
+
const pixelmapArgs = {quadFeature: m_this.features()[0]};
|
|
95
|
+
if (arg.style) {
|
|
96
|
+
pixelmapArgs.style = arg.style;
|
|
97
|
+
}
|
|
98
|
+
if (arg.color) {
|
|
99
|
+
pixelmapArgs.color = arg.color;
|
|
100
|
+
}
|
|
101
|
+
m_pixelmapFeature = m_this.createFeature('pixelmap', pixelmapArgs);
|
|
102
|
+
if (arg.data) {
|
|
103
|
+
m_pixelmapFeature.data(arg.data);
|
|
104
|
+
}
|
|
105
|
+
m_this.style = m_pixelmapFeature.style;
|
|
106
|
+
m_this.data = m_pixelmapFeature.data;
|
|
107
|
+
m_this.indexModified = m_pixelmapFeature.indexModified;
|
|
108
|
+
const s_dataTimeModified = m_this.dataTime().modified;
|
|
109
|
+
m_this.dataTime().modified = () => {
|
|
110
|
+
m_pixelmapFeature.dataTime().modified();
|
|
111
|
+
return s_dataTimeModified();
|
|
112
|
+
};
|
|
113
|
+
['modified', 'geoOn', 'geoOff', 'geoOnce'].forEach((funcName) => {
|
|
114
|
+
const superFunc = m_this[funcName];
|
|
115
|
+
m_this[funcName] = function () {
|
|
116
|
+
m_pixelmapFeature[funcName].apply(this, arguments);
|
|
117
|
+
return superFunc.apply(this, arguments);
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
return m_this;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
return m_this;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* This object contains the default options used to initialize the
|
|
128
|
+
* pixelmapLayer.
|
|
129
|
+
*/
|
|
130
|
+
pixelmapLayer.defaults = $.extend({}, tileLayer.defaults, {
|
|
131
|
+
features: [quadFeature.capabilities.image, pixelmapFeature.capabilities.lookup],
|
|
132
|
+
tileOffset : function (level) {
|
|
133
|
+
var s = Math.pow(2, level - 1) * 256;
|
|
134
|
+
return {x: s, y: s};
|
|
135
|
+
},
|
|
136
|
+
url: ''
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
inherit(pixelmapLayer, tileLayer);
|
|
140
|
+
/* By default, ask to support image quads. If the user needs full
|
|
141
|
+
* reprojection, they will need to require the
|
|
142
|
+
* quadFeature.capabilities.imageFull feature */
|
|
143
|
+
registry.registerLayer('pixelmap', pixelmapLayer, [quadFeature.capabilities.image]);
|
|
144
|
+
|
|
145
|
+
module.exports = pixelmapLayer;
|
package/src/tileLayer.js
CHANGED
|
@@ -676,7 +676,7 @@ var tileLayer = function (arg) {
|
|
|
676
676
|
this._getTiles = function (maxLevel, bounds, sorted, onlyIfChanged) {
|
|
677
677
|
var i, j, tiles = [], index, nTilesLevel,
|
|
678
678
|
start, end, indexRange, source, center, changed = false, old, level,
|
|
679
|
-
minLevel = (m_this._options.keepLower ? m_this._options.minLevel : maxLevel);
|
|
679
|
+
minLevel = (m_this._options.keepLower ? m_this._options.minLevel : Math.max(maxLevel, m_this._options.minLevel));
|
|
680
680
|
if (maxLevel < minLevel) {
|
|
681
681
|
maxLevel = minLevel;
|
|
682
682
|
}
|
|
@@ -1532,7 +1532,8 @@ var tileLayer = function (arg) {
|
|
|
1532
1532
|
* finished, purge all but the current layer. This is important for
|
|
1533
1533
|
* semi-transparent layers. */
|
|
1534
1534
|
if ((doneLoading || m_this._isCovered(tile)) &&
|
|
1535
|
-
zoom !== tile.index.level
|
|
1535
|
+
zoom !== tile.index.level &&
|
|
1536
|
+
(zoom >= m_this._options.minLevel || tile.index.level !== m_this._options.minLevel)) {
|
|
1536
1537
|
return true;
|
|
1537
1538
|
}
|
|
1538
1539
|
}
|
|
@@ -28,6 +28,7 @@ var webgl_pixelmapFeature = function (arg) {
|
|
|
28
28
|
const fragmentShader = require('./pixelmapFeature.frag');
|
|
29
29
|
|
|
30
30
|
var m_quadFeature,
|
|
31
|
+
m_quadFeatureInit,
|
|
31
32
|
s_exit = this._exit,
|
|
32
33
|
m_lookupTable,
|
|
33
34
|
m_this = this;
|
|
@@ -46,25 +47,28 @@ var webgl_pixelmapFeature = function (arg) {
|
|
|
46
47
|
this.pointSearch = function (geo, gcs) {
|
|
47
48
|
if (m_quadFeature && m_this.m_info) {
|
|
48
49
|
let result = m_quadFeature.pointSearch(geo, gcs);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
50
|
+
// use the last index by preference, since for tile layers, this is the
|
|
51
|
+
// topmosttile
|
|
52
|
+
let idxIdx = result.index.length - 1;
|
|
53
|
+
for (; idxIdx >= 0; idxIdx -= 1) {
|
|
54
|
+
if (result.extra[result.index[idxIdx]]._quad &&
|
|
55
|
+
result.extra[result.index[idxIdx]]._quad.image) {
|
|
56
|
+
const img = result.extra[result.index[idxIdx]]._quad.image;
|
|
57
|
+
const basis = result.extra[result.index[idxIdx]].basis;
|
|
58
|
+
const x = Math.floor(basis.x * img.width);
|
|
59
|
+
const y = Math.floor(basis.y * img.height);
|
|
60
|
+
const canvas = document.createElement('canvas');
|
|
61
|
+
canvas.width = canvas.height = 1;
|
|
62
|
+
const context = canvas.getContext('2d');
|
|
63
|
+
context.drawImage(img, x, y, 1, 1, 0, 0, 1, 1);
|
|
64
|
+
const pixel = context.getImageData(0, 0, 1, 1).data;
|
|
65
|
+
const idx = pixel[0] + pixel[1] * 256 + pixel[2] * 256 * 256;
|
|
66
|
+
result = {
|
|
67
|
+
index: [idx],
|
|
68
|
+
found: [m_this.data()[idx]]
|
|
69
|
+
};
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
68
72
|
}
|
|
69
73
|
}
|
|
70
74
|
return {index: [], found: []};
|
|
@@ -78,34 +82,49 @@ var webgl_pixelmapFeature = function (arg) {
|
|
|
78
82
|
var data = m_this.data() || [],
|
|
79
83
|
colorFunc = m_this.style.get('color');
|
|
80
84
|
|
|
85
|
+
let indexRange = m_this.indexModified(undefined, 'clear');
|
|
86
|
+
let fullUpdate = m_this.dataTime().timestamp() >= m_this.buildTime().timestamp() || indexRange === undefined;
|
|
81
87
|
if (!m_lookupTable) {
|
|
82
88
|
m_lookupTable = lookupTable2D();
|
|
83
89
|
m_lookupTable.setTextureUnit(1);
|
|
90
|
+
fullUpdate = true;
|
|
84
91
|
}
|
|
85
92
|
let clrLen = Math.max(1, data.length);
|
|
86
93
|
const maxWidth = m_lookupTable.maxWidth();
|
|
87
94
|
if (clrLen > maxWidth && clrLen % maxWidth) {
|
|
88
95
|
clrLen += maxWidth - (clrLen % maxWidth);
|
|
89
96
|
}
|
|
90
|
-
|
|
91
|
-
|
|
97
|
+
|
|
98
|
+
let colors;
|
|
99
|
+
if (!fullUpdate) {
|
|
100
|
+
colors = m_lookupTable.colorTable();
|
|
101
|
+
fullUpdate = colors.length !== clrLen * 4;
|
|
102
|
+
indexRange[0] = Math.max(0, indexRange[0]);
|
|
103
|
+
indexRange[1] = Math.min(data.length, indexRange[1] + 1);
|
|
104
|
+
}
|
|
105
|
+
if (fullUpdate) {
|
|
106
|
+
colors = new Uint8Array(clrLen * 4);
|
|
107
|
+
indexRange = [0, data.length];
|
|
108
|
+
}
|
|
109
|
+
for (let i = indexRange[0]; i < indexRange[1]; i += 1) {
|
|
110
|
+
const d = data[i];
|
|
92
111
|
const color = util.convertColor(colorFunc.call(m_this, d, i));
|
|
93
112
|
colors[i * 4] = color.r * 255;
|
|
94
113
|
colors[i * 4 + 1] = color.g * 255;
|
|
95
114
|
colors[i * 4 + 2] = color.b * 255;
|
|
96
115
|
colors[i * 4 + 3] = color.a === undefined ? 255 : (color.a * 255);
|
|
97
|
-
}
|
|
116
|
+
}
|
|
98
117
|
m_this.m_info = {colors: colors};
|
|
99
118
|
// check if colors haven't changed
|
|
100
119
|
var oldcolors = m_lookupTable.colorTable();
|
|
101
120
|
if (oldcolors && oldcolors.length === colors.length) {
|
|
102
|
-
let idx = 0;
|
|
103
|
-
for (; idx <
|
|
121
|
+
let idx = indexRange[0] * 4;
|
|
122
|
+
for (; idx < indexRange[1] * 4; idx += 1) {
|
|
104
123
|
if (colors[idx] !== oldcolors[idx]) {
|
|
105
124
|
break;
|
|
106
125
|
}
|
|
107
126
|
}
|
|
108
|
-
if (idx ===
|
|
127
|
+
if (idx === indexRange[1] * 4) {
|
|
109
128
|
return;
|
|
110
129
|
}
|
|
111
130
|
}
|
|
@@ -117,6 +136,9 @@ var webgl_pixelmapFeature = function (arg) {
|
|
|
117
136
|
gcs: m_this.gcs(),
|
|
118
137
|
visible: m_this.visible(undefined, true)
|
|
119
138
|
});
|
|
139
|
+
m_quadFeatureInit = false;
|
|
140
|
+
}
|
|
141
|
+
if (!m_quadFeatureInit) {
|
|
120
142
|
m_this.dependentFeatures([m_quadFeature]);
|
|
121
143
|
m_quadFeature.setShader('image_fragment', fragmentShader);
|
|
122
144
|
m_quadFeature._hookBuild = (prog) => {
|
|
@@ -138,11 +160,14 @@ var webgl_pixelmapFeature = function (arg) {
|
|
|
138
160
|
});
|
|
139
161
|
m_lookupTable.bind(renderState, quads);
|
|
140
162
|
};
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
163
|
+
if (m_quadFeatureInit === false) {
|
|
164
|
+
m_quadFeature.style({
|
|
165
|
+
image: m_this.m_srcImage,
|
|
166
|
+
position: m_this.style.get('position')})
|
|
167
|
+
.data([{}])
|
|
168
|
+
.draw();
|
|
169
|
+
}
|
|
170
|
+
m_quadFeatureInit = true;
|
|
146
171
|
}
|
|
147
172
|
};
|
|
148
173
|
|
|
@@ -161,6 +186,9 @@ var webgl_pixelmapFeature = function (arg) {
|
|
|
161
186
|
return m_this;
|
|
162
187
|
};
|
|
163
188
|
|
|
189
|
+
if (arg.quadFeature) {
|
|
190
|
+
m_quadFeature = arg.quadFeature;
|
|
191
|
+
}
|
|
164
192
|
this._init(arg);
|
|
165
193
|
return this;
|
|
166
194
|
};
|
|
@@ -168,5 +196,8 @@ var webgl_pixelmapFeature = function (arg) {
|
|
|
168
196
|
inherit(webgl_pixelmapFeature, pixelmapFeature);
|
|
169
197
|
|
|
170
198
|
// Now register it
|
|
171
|
-
|
|
199
|
+
var capabilities = {};
|
|
200
|
+
capabilities[pixelmapFeature.capabilities.lookup] = true;
|
|
201
|
+
|
|
202
|
+
registerFeature('webgl', 'pixelmap', webgl_pixelmapFeature, capabilities);
|
|
172
203
|
module.exports = webgl_pixelmapFeature;
|
package/src/webgl/quadFeature.js
CHANGED
|
@@ -371,7 +371,9 @@ var webgl_quadFeature = function (arg) {
|
|
|
371
371
|
return;
|
|
372
372
|
}
|
|
373
373
|
quad.texture.bind(renderState);
|
|
374
|
-
if
|
|
374
|
+
// only check if the context is out of memory when using modestly large
|
|
375
|
+
// textures. The check is slow.
|
|
376
|
+
if ((quad.image.width > 4096 || quad.image.height > 4096 || quad.image.width * quad.image.height > 4194304) && context.getError() === context.OUT_OF_MEMORY) {
|
|
375
377
|
console.log('Insufficient GPU memory for texture');
|
|
376
378
|
}
|
|
377
379
|
if (quad.opacity !== opacity) {
|