geojs 1.6.5 → 1.6.6

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/geo.js CHANGED
@@ -6360,6 +6360,10 @@ var inherit = __webpack_require__(5699);
6360
6360
  var registerFeature = (__webpack_require__(4647).registerFeature);
6361
6361
 
6362
6362
  var pixelmapFeature = __webpack_require__(6374);
6363
+
6364
+ var geo_event = __webpack_require__(5108);
6365
+
6366
+ var util = __webpack_require__(4634);
6363
6367
  /**
6364
6368
  * Create a new instance of class pixelmapFeature.
6365
6369
  *
@@ -6383,6 +6387,216 @@ var canvas_pixelmapFeature = function canvas_pixelmapFeature(arg) {
6383
6387
  var object = __webpack_require__(3160);
6384
6388
 
6385
6389
  object.call(this);
6390
+ var m_quadFeature,
6391
+ s_exit = this._exit,
6392
+ m_this = this;
6393
+ /**
6394
+ * If the specified coordinates are in the rendered quad, use the basis
6395
+ * information from the quad to determine the pixelmap index value so that it
6396
+ * can be included in the `found` results.
6397
+ *
6398
+ * @param {geo.geoPosition} geo Coordinate.
6399
+ * @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
6400
+ * the interface gcs, `null` to use the map gcs, or any other transform.
6401
+ * @returns {geo.feature.searchResult} An object with a list of features and
6402
+ * feature indices that are located at the specified point.
6403
+ */
6404
+
6405
+ this.pointSearch = function (geo, gcs) {
6406
+ if (m_quadFeature && m_this.m_info) {
6407
+ var result = m_quadFeature.pointSearch(geo, gcs);
6408
+
6409
+ if (result.index.length === 1 && result.extra && result.extra[result.index[0]].basis) {
6410
+ var basis = result.extra[result.index[0]].basis,
6411
+ x,
6412
+ y,
6413
+ idx;
6414
+ x = Math.floor(basis.x * m_this.m_info.width);
6415
+ y = Math.floor(basis.y * m_this.m_info.height);
6416
+
6417
+ if (x >= 0 && x < m_this.m_info.width && y >= 0 && y < m_this.m_info.height) {
6418
+ idx = m_this.m_info.indices[y * m_this.m_info.width + x];
6419
+ result = {
6420
+ index: [idx],
6421
+ found: [m_this.data()[idx]]
6422
+ };
6423
+ return result;
6424
+ }
6425
+ }
6426
+ }
6427
+
6428
+ return {
6429
+ index: [],
6430
+ found: []
6431
+ };
6432
+ };
6433
+ /**
6434
+ * Compute information for this pixelmap image. It is wasteful to call this
6435
+ * if the pixelmap has already been prepared (it is invalidated by a change
6436
+ * in the image).
6437
+ *
6438
+ * @returns {geo.pixelmapFeature.info}
6439
+ */
6440
+
6441
+
6442
+ this._preparePixelmap = function () {
6443
+ var i, idx, pixelData;
6444
+
6445
+ if (!util.isReadyImage(m_this.m_srcImage)) {
6446
+ return;
6447
+ }
6448
+
6449
+ m_this.m_info = {
6450
+ width: m_this.m_srcImage.naturalWidth,
6451
+ height: m_this.m_srcImage.naturalHeight,
6452
+ canvas: document.createElement('canvas')
6453
+ };
6454
+ m_this.m_info.canvas.width = m_this.m_info.width;
6455
+ m_this.m_info.canvas.height = m_this.m_info.height;
6456
+ m_this.m_info.context = m_this.m_info.canvas.getContext('2d');
6457
+ m_this.m_info.context.drawImage(m_this.m_srcImage, 0, 0);
6458
+ m_this.m_info.imageData = m_this.m_info.context.getImageData(0, 0, m_this.m_info.canvas.width, m_this.m_info.canvas.height);
6459
+ pixelData = m_this.m_info.imageData.data;
6460
+ m_this.m_info.indices = new Array(pixelData.length / 4);
6461
+ m_this.m_info.area = pixelData.length / 4;
6462
+ m_this.m_info.mappedColors = {};
6463
+
6464
+ for (i = 0; i < pixelData.length; i += 4) {
6465
+ idx = pixelData[i] + (pixelData[i + 1] << 8) + (pixelData[i + 2] << 16);
6466
+ m_this.m_info.indices[i / 4] = idx;
6467
+
6468
+ if (!m_this.m_info.mappedColors[idx]) {
6469
+ m_this.m_info.mappedColors[idx] = {
6470
+ first: i / 4
6471
+ };
6472
+ }
6473
+
6474
+ m_this.m_info.mappedColors[idx].last = i / 4;
6475
+ }
6476
+
6477
+ return m_this.m_info;
6478
+ };
6479
+ /**
6480
+ * Given the loaded pixelmap image, create a canvas the size of the image.
6481
+ * Compute a color for each distinct index and recolor the canvas based on
6482
+ * these colors, then draw the resultant image as a quad.
6483
+ *
6484
+ * @fires geo.event.pixelmap.prepared
6485
+ */
6486
+
6487
+
6488
+ this._computePixelmap = function () {
6489
+ var data = m_this.data() || [],
6490
+ colorFunc = m_this.style.get('color'),
6491
+ i,
6492
+ idx,
6493
+ lastidx,
6494
+ color,
6495
+ pixelData,
6496
+ indices,
6497
+ mappedColors,
6498
+ updateFirst,
6499
+ updateLast = -1,
6500
+ update,
6501
+ prepared;
6502
+
6503
+ if (!m_this.m_info) {
6504
+ if (!m_this._preparePixelmap()) {
6505
+ return;
6506
+ }
6507
+
6508
+ prepared = true;
6509
+ }
6510
+
6511
+ mappedColors = m_this.m_info.mappedColors;
6512
+ updateFirst = m_this.m_info.area;
6513
+
6514
+ for (idx in mappedColors) {
6515
+ if (mappedColors.hasOwnProperty(idx)) {
6516
+ color = colorFunc(data[idx], +idx) || {};
6517
+ color = [(color.r || 0) * 255, (color.g || 0) * 255, (color.b || 0) * 255, color.a === undefined ? 255 : color.a * 255];
6518
+ mappedColors[idx].update = !mappedColors[idx].color || mappedColors[idx].color[0] !== color[0] || mappedColors[idx].color[1] !== color[1] || mappedColors[idx].color[2] !== color[2] || mappedColors[idx].color[3] !== color[3];
6519
+
6520
+ if (mappedColors[idx].update) {
6521
+ mappedColors[idx].color = color;
6522
+ updateFirst = Math.min(mappedColors[idx].first, updateFirst);
6523
+ updateLast = Math.max(mappedColors[idx].last, updateLast);
6524
+ }
6525
+ }
6526
+ }
6527
+ /* If nothing was updated, we are done */
6528
+
6529
+
6530
+ if (updateFirst >= updateLast) {
6531
+ return;
6532
+ }
6533
+ /* Update only the extent that has changed */
6534
+
6535
+
6536
+ pixelData = m_this.m_info.imageData.data;
6537
+ indices = m_this.m_info.indices;
6538
+
6539
+ for (i = updateFirst; i <= updateLast; i += 1) {
6540
+ idx = indices[i];
6541
+
6542
+ if (idx !== lastidx) {
6543
+ lastidx = idx;
6544
+ color = mappedColors[idx].color;
6545
+ update = mappedColors[idx].update;
6546
+ }
6547
+
6548
+ if (update) {
6549
+ pixelData[i * 4] = color[0];
6550
+ pixelData[i * 4 + 1] = color[1];
6551
+ pixelData[i * 4 + 2] = color[2];
6552
+ pixelData[i * 4 + 3] = color[3];
6553
+ }
6554
+ }
6555
+ /* Place the updated area into the canvas */
6556
+
6557
+
6558
+ m_this.m_info.context.putImageData(m_this.m_info.imageData, 0, 0, 0, Math.floor(updateFirst / m_this.m_info.width), m_this.m_info.width, Math.ceil((updateLast + 1) / m_this.m_info.width));
6559
+ /* If we haven't made a quad feature, make one now. The quad feature needs
6560
+ * to have the canvas capability. */
6561
+
6562
+ if (!m_quadFeature) {
6563
+ m_quadFeature = m_this.layer().createFeature('quad', {
6564
+ selectionAPI: false,
6565
+ gcs: m_this.gcs(),
6566
+ visible: m_this.visible(undefined, true)
6567
+ });
6568
+ m_this.dependentFeatures([m_quadFeature]);
6569
+ m_quadFeature.style({
6570
+ image: m_this.m_info.canvas,
6571
+ position: m_this.style.get('position')
6572
+ }).data([{}]).draw();
6573
+ }
6574
+ /* If we prepared the pixelmap and rendered it, send a prepared event */
6575
+
6576
+
6577
+ if (prepared) {
6578
+ m_this.geoTrigger(geo_event.pixelmap.prepared, {
6579
+ pixelmap: m_this
6580
+ });
6581
+ }
6582
+ };
6583
+ /**
6584
+ * Destroy. Deletes the associated quadFeature.
6585
+ *
6586
+ * @returns {this}
6587
+ */
6588
+
6589
+
6590
+ this._exit = function () {
6591
+ if (m_quadFeature && m_this.layer()) {
6592
+ m_this.layer().deleteFeature(m_quadFeature);
6593
+ m_quadFeature = null;
6594
+ m_this.dependentFeatures([]);
6595
+ }
6596
+
6597
+ s_exit();
6598
+ return m_this;
6599
+ };
6386
6600
 
6387
6601
  this._init(arg);
6388
6602
 
@@ -21986,8 +22200,6 @@ var inherit = __webpack_require__(5699);
21986
22200
 
21987
22201
  var feature = __webpack_require__(6837);
21988
22202
 
21989
- var geo_event = __webpack_require__(5108);
21990
-
21991
22203
  var util = __webpack_require__(4634);
21992
22204
  /**
21993
22205
  * Pixelmap feature specification.
@@ -22060,12 +22272,8 @@ var pixelmapFeature = function pixelmapFeature(arg) {
22060
22272
  */
22061
22273
 
22062
22274
  var m_this = this,
22063
- m_quadFeature,
22064
- m_srcImage,
22065
- m_info,
22066
22275
  s_update = this._update,
22067
- s_init = this._init,
22068
- s_exit = this._exit;
22276
+ s_init = this._init;
22069
22277
  this.featureType = 'pixelmap';
22070
22278
  /**
22071
22279
  * Get/Set position accessor.
@@ -22102,7 +22310,7 @@ var pixelmapFeature = function pixelmapFeature(arg) {
22102
22310
  if (val === undefined) {
22103
22311
  return m_this.style('url');
22104
22312
  } else if (val !== m_this.style('url')) {
22105
- m_srcImage = m_info = undefined;
22313
+ m_this.m_srcImage = m_this.m_info = undefined;
22106
22314
  m_this.style('url', val);
22107
22315
  m_this.dataTime().modified();
22108
22316
  m_this.modified();
@@ -22110,31 +22318,6 @@ var pixelmapFeature = function pixelmapFeature(arg) {
22110
22318
 
22111
22319
  return m_this;
22112
22320
  };
22113
- /**
22114
- * Get the maximum index value from the pixelmap. This is a value present in
22115
- * the pixelmap.
22116
- *
22117
- * @returns {number} The maximum index value.
22118
- */
22119
-
22120
-
22121
- this.maxIndex = function () {
22122
- if (m_info) {
22123
- /* This isn't just m_info.mappedColors.length - 1, since there
22124
- * may be more data than actual indices. */
22125
- if (m_info.maxIndex === undefined) {
22126
- m_info.maxIndex = 0;
22127
-
22128
- for (var idx in m_info.mappedColors) {
22129
- if (m_info.mappedColors.hasOwnProperty(idx)) {
22130
- m_info.maxIndex = Math.max(m_info.maxIndex, idx);
22131
- }
22132
- }
22133
- }
22134
-
22135
- return m_info.maxIndex;
22136
- }
22137
- };
22138
22321
  /**
22139
22322
  * Get/Set color accessor.
22140
22323
  *
@@ -22156,46 +22339,57 @@ var pixelmapFeature = function pixelmapFeature(arg) {
22156
22339
  return m_this;
22157
22340
  };
22158
22341
  /**
22159
- * If the specified coordinates are in the rendered quad, use the basis
22160
- * information from the quad to determine the pixelmap index value so that it
22161
- * can be included in the `found` results.
22342
+ * Update.
22162
22343
  *
22163
- * @param {geo.geoPosition} geo Coordinate.
22164
- * @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
22165
- * the interface gcs, `null` to use the map gcs, or any other transform.
22166
- * @returns {geo.feature.searchResult} An object with a list of features and
22167
- * feature indices that are located at the specified point.
22344
+ * @returns {this}
22168
22345
  */
22169
22346
 
22170
22347
 
22171
- this.pointSearch = function (geo, gcs) {
22172
- if (m_quadFeature && m_info) {
22173
- var result = m_quadFeature.pointSearch(geo, gcs);
22348
+ this._update = function () {
22349
+ s_update.call(m_this);
22174
22350
 
22175
- if (result.index.length === 1 && result.extra && result.extra[result.index[0]].basis) {
22176
- var basis = result.extra[result.index[0]].basis,
22177
- x,
22178
- y,
22179
- idx;
22180
- x = Math.floor(basis.x * m_info.width);
22181
- y = Math.floor(basis.y * m_info.height);
22351
+ if (m_this.buildTime().timestamp() <= m_this.dataTime().timestamp() || m_this.updateTime().timestamp() < m_this.timestamp()) {
22352
+ m_this._build();
22353
+ }
22182
22354
 
22183
- if (x >= 0 && x < m_info.width && y >= 0 && y < m_info.height) {
22184
- idx = m_info.indices[y * m_info.width + x];
22185
- result = {
22186
- index: [idx],
22187
- found: [m_this.data()[idx]]
22188
- };
22189
- return result;
22355
+ m_this.updateTime().modified();
22356
+ return m_this;
22357
+ };
22358
+ /**
22359
+ * Get the maximum index value from the pixelmap. This is a value present in
22360
+ * the pixelmap.
22361
+ *
22362
+ * @returns {number} The maximum index value.
22363
+ */
22364
+
22365
+
22366
+ this.maxIndex = function () {
22367
+ if (m_this.m_info) {
22368
+ /* This isn't just m_info.mappedColors.length - 1, since there
22369
+ * may be more data than actual indices. */
22370
+ if (m_this.m_info.maxIndex === undefined) {
22371
+ m_this.m_info.maxIndex = 0;
22372
+
22373
+ for (var idx in m_this.m_info.mappedColors) {
22374
+ if (m_this.m_info.mappedColors.hasOwnProperty(idx)) {
22375
+ m_this.m_info.maxIndex = Math.max(m_this.m_info.maxIndex, idx);
22376
+ }
22190
22377
  }
22191
22378
  }
22192
- }
22193
22379
 
22194
- return {
22195
- index: [],
22196
- found: []
22197
- };
22380
+ return m_this.m_info.maxIndex;
22381
+ }
22198
22382
  };
22383
+ /**
22384
+ * Given the loaded pixelmap image, create a canvas the size of the image.
22385
+ * Compute a color for each distinct index and recolor the canvas based on
22386
+ * these colors, then draw the resultant image as a quad.
22387
+ *
22388
+ * @fires geo.event.pixelmap.prepared
22389
+ */
22390
+
22391
+
22392
+ this._computePixelmap = function () {};
22199
22393
  /**
22200
22394
  * Build. Fetches the image if necessary.
22201
22395
  *
@@ -22210,12 +22404,12 @@ var pixelmapFeature = function pixelmapFeature(arg) {
22210
22404
  * this a second time. */
22211
22405
  m_this.buildTime().modified();
22212
22406
 
22213
- if (!m_srcImage) {
22407
+ if (!m_this.m_srcImage) {
22214
22408
  var src = m_this.style.get('url')();
22215
22409
 
22216
22410
  if (util.isReadyImage(src)) {
22217
22411
  /* we have an already loaded image, so we can just use it. */
22218
- m_srcImage = src;
22412
+ m_this.m_srcImage = src;
22219
22413
 
22220
22414
  m_this._computePixelmap();
22221
22415
  } else if (src) {
@@ -22226,19 +22420,19 @@ var pixelmapFeature = function pixelmapFeature(arg) {
22226
22420
  if (src instanceof Image) {
22227
22421
  /* we have an unloaded image. Hook to the load and error callbacks
22228
22422
  * so that when it is loaded we can use it. */
22229
- m_srcImage = src;
22423
+ m_this.m_srcImage = src;
22230
22424
  prev_onload = src.onload;
22231
22425
  prev_onerror = src.onerror;
22232
22426
  } else {
22233
22427
  /* we were given a url, so construct a new image */
22234
- m_srcImage = new Image(); // Only set the crossOrigin parameter if this is going across origins.
22428
+ m_this.m_srcImage = new Image(); // Only set the crossOrigin parameter if this is going across origins.
22235
22429
 
22236
22430
  if (src.indexOf(':') >= 0 && src.indexOf('/') === src.indexOf(':') + 1) {
22237
- m_srcImage.crossOrigin = m_this.style.get('crossDomain')() || 'anonymous';
22431
+ m_this.m_srcImage.crossOrigin = m_this.style.get('crossDomain')() || 'anonymous';
22238
22432
  }
22239
22433
  }
22240
22434
 
22241
- m_srcImage.onload = function () {
22435
+ m_this.m_srcImage.onload = function () {
22242
22436
  if (prev_onload) {
22243
22437
  prev_onload.apply(m_this, arguments);
22244
22438
  }
@@ -22247,7 +22441,7 @@ var pixelmapFeature = function pixelmapFeature(arg) {
22247
22441
 
22248
22442
 
22249
22443
  if (m_this.style.get('url')() === src) {
22250
- m_info = undefined;
22444
+ m_this.m_info = undefined;
22251
22445
 
22252
22446
  m_this._computePixelmap();
22253
22447
  }
@@ -22255,7 +22449,7 @@ var pixelmapFeature = function pixelmapFeature(arg) {
22255
22449
  defer.resolve();
22256
22450
  };
22257
22451
 
22258
- m_srcImage.onerror = function () {
22452
+ m_this.m_srcImage.onerror = function () {
22259
22453
  if (prev_onerror) {
22260
22454
  prev_onerror.apply(m_this, arguments);
22261
22455
  }
@@ -22267,199 +22461,15 @@ var pixelmapFeature = function pixelmapFeature(arg) {
22267
22461
  m_this.layer().addPromise(m_this);
22268
22462
 
22269
22463
  if (!(src instanceof Image)) {
22270
- m_srcImage.src = src;
22464
+ m_this.m_srcImage.src = src;
22271
22465
  }
22272
22466
  }
22273
- } else if (m_info) {
22467
+ } else if (m_this.m_info) {
22274
22468
  m_this._computePixelmap();
22275
22469
  }
22276
22470
 
22277
22471
  return m_this;
22278
22472
  };
22279
- /**
22280
- * Compute information for this pixelmap image. It is wasteful to call this
22281
- * if the pixelmap has already been prepared (it is invalidated by a change
22282
- * in the image).
22283
- *
22284
- * @returns {geo.pixelmapFeature.info}
22285
- */
22286
-
22287
-
22288
- this._preparePixelmap = function () {
22289
- var i, idx, pixelData;
22290
-
22291
- if (!util.isReadyImage(m_srcImage)) {
22292
- return;
22293
- }
22294
-
22295
- m_info = {
22296
- width: m_srcImage.naturalWidth,
22297
- height: m_srcImage.naturalHeight,
22298
- canvas: document.createElement('canvas')
22299
- };
22300
- m_info.canvas.width = m_info.width;
22301
- m_info.canvas.height = m_info.height;
22302
- m_info.context = m_info.canvas.getContext('2d');
22303
- m_info.context.drawImage(m_srcImage, 0, 0);
22304
- m_info.imageData = m_info.context.getImageData(0, 0, m_info.canvas.width, m_info.canvas.height);
22305
- pixelData = m_info.imageData.data;
22306
- m_info.indices = new Array(pixelData.length / 4);
22307
- m_info.area = pixelData.length / 4;
22308
- m_info.mappedColors = {};
22309
-
22310
- for (i = 0; i < pixelData.length; i += 4) {
22311
- idx = pixelData[i] + (pixelData[i + 1] << 8) + (pixelData[i + 2] << 16);
22312
- m_info.indices[i / 4] = idx;
22313
-
22314
- if (!m_info.mappedColors[idx]) {
22315
- m_info.mappedColors[idx] = {
22316
- first: i / 4
22317
- };
22318
- }
22319
-
22320
- m_info.mappedColors[idx].last = i / 4;
22321
- }
22322
-
22323
- return m_info;
22324
- };
22325
- /**
22326
- * Given the loaded pixelmap image, create a canvas the size of the image.
22327
- * Compute a color for each distinct index and recolor the canvas based on
22328
- * these colors, then draw the resultant image as a quad.
22329
- *
22330
- * @fires geo.event.pixelmap.prepared
22331
- */
22332
-
22333
-
22334
- this._computePixelmap = function () {
22335
- var data = m_this.data() || [],
22336
- colorFunc = m_this.style.get('color'),
22337
- i,
22338
- idx,
22339
- lastidx,
22340
- color,
22341
- pixelData,
22342
- indices,
22343
- mappedColors,
22344
- updateFirst,
22345
- updateLast = -1,
22346
- update,
22347
- prepared;
22348
-
22349
- if (!m_info) {
22350
- if (!m_this._preparePixelmap()) {
22351
- return;
22352
- }
22353
-
22354
- prepared = true;
22355
- }
22356
-
22357
- mappedColors = m_info.mappedColors;
22358
- updateFirst = m_info.area;
22359
-
22360
- for (idx in mappedColors) {
22361
- if (mappedColors.hasOwnProperty(idx)) {
22362
- color = colorFunc(data[idx], +idx) || {};
22363
- color = [(color.r || 0) * 255, (color.g || 0) * 255, (color.b || 0) * 255, color.a === undefined ? 255 : color.a * 255];
22364
- mappedColors[idx].update = !mappedColors[idx].color || mappedColors[idx].color[0] !== color[0] || mappedColors[idx].color[1] !== color[1] || mappedColors[idx].color[2] !== color[2] || mappedColors[idx].color[3] !== color[3];
22365
-
22366
- if (mappedColors[idx].update) {
22367
- mappedColors[idx].color = color;
22368
- updateFirst = Math.min(mappedColors[idx].first, updateFirst);
22369
- updateLast = Math.max(mappedColors[idx].last, updateLast);
22370
- }
22371
- }
22372
- }
22373
- /* If nothing was updated, we are done */
22374
-
22375
-
22376
- if (updateFirst >= updateLast) {
22377
- return;
22378
- }
22379
- /* Update only the extent that has changed */
22380
-
22381
-
22382
- pixelData = m_info.imageData.data;
22383
- indices = m_info.indices;
22384
-
22385
- for (i = updateFirst; i <= updateLast; i += 1) {
22386
- idx = indices[i];
22387
-
22388
- if (idx !== lastidx) {
22389
- lastidx = idx;
22390
- color = mappedColors[idx].color;
22391
- update = mappedColors[idx].update;
22392
- }
22393
-
22394
- if (update) {
22395
- pixelData[i * 4] = color[0];
22396
- pixelData[i * 4 + 1] = color[1];
22397
- pixelData[i * 4 + 2] = color[2];
22398
- pixelData[i * 4 + 3] = color[3];
22399
- }
22400
- }
22401
- /* Place the updated area into the canvas */
22402
-
22403
-
22404
- m_info.context.putImageData(m_info.imageData, 0, 0, 0, Math.floor(updateFirst / m_info.width), m_info.width, Math.ceil((updateLast + 1) / m_info.width));
22405
- /* If we haven't made a quad feature, make one now. The quad feature needs
22406
- * to have the canvas capability. */
22407
-
22408
- if (!m_quadFeature) {
22409
- m_quadFeature = m_this.layer().createFeature('quad', {
22410
- selectionAPI: false,
22411
- gcs: m_this.gcs(),
22412
- visible: m_this.visible(undefined, true)
22413
- });
22414
- m_this.dependentFeatures([m_quadFeature]);
22415
- m_quadFeature.style({
22416
- image: m_info.canvas,
22417
- position: m_this.style.get('position')
22418
- }).data([{}]).draw();
22419
- }
22420
- /* If we prepared the pixelmap and rendered it, send a prepared event */
22421
-
22422
-
22423
- if (prepared) {
22424
- m_this.geoTrigger(geo_event.pixelmap.prepared, {
22425
- pixelmap: m_this
22426
- });
22427
- }
22428
- };
22429
- /**
22430
- * Update.
22431
- *
22432
- * @returns {this}
22433
- */
22434
-
22435
-
22436
- this._update = function () {
22437
- s_update.call(m_this);
22438
-
22439
- if (m_this.buildTime().timestamp() <= m_this.dataTime().timestamp() || m_this.updateTime().timestamp() < m_this.timestamp()) {
22440
- m_this._build();
22441
- }
22442
-
22443
- m_this.updateTime().modified();
22444
- return m_this;
22445
- };
22446
- /**
22447
- * Destroy. Deletes the associated quadFeature.
22448
- *
22449
- * @returns {this}
22450
- */
22451
-
22452
-
22453
- this._exit = function () {
22454
- if (m_quadFeature && m_this.layer()) {
22455
- m_this.layer().deleteFeature(m_quadFeature);
22456
- m_quadFeature = null;
22457
- m_this.dependentFeatures([]);
22458
- }
22459
-
22460
- s_exit();
22461
- return m_this;
22462
- };
22463
22473
  /**
22464
22474
  * Initialize.
22465
22475
  *
@@ -24419,7 +24429,8 @@ var quadFeature = function quadFeature(arg) {
24419
24429
 
24420
24430
  if (coordbasis) {
24421
24431
  extra[quad.idx] = {
24422
- basis: coordbasis
24432
+ basis: coordbasis,
24433
+ _quad: quad
24423
24434
  };
24424
24435
  }
24425
24436
  }
@@ -26017,7 +26028,7 @@ module.exports = sceneObject;
26017
26028
  * @constant
26018
26029
  * @type {string}
26019
26030
  */
26020
- module.exports = "07bea0c1a0c68aece32ca33afaeed257361803e3";
26031
+ module.exports = "c554b05bdeb079f7ebd7d317e44a885f9a93710f";
26021
26032
 
26022
26033
  /***/ }),
26023
26034
 
@@ -38481,7 +38492,7 @@ module.exports = vectorFeature;
38481
38492
  * @constant
38482
38493
  * @type {string}
38483
38494
  */
38484
- module.exports = "1.6.5";
38495
+ module.exports = "1.6.6";
38485
38496
 
38486
38497
  /***/ }),
38487
38498
 
@@ -39244,8 +39255,10 @@ module.exports = {
39244
39255
  isolineFeature: __webpack_require__(9752),
39245
39256
  layer: __webpack_require__(5389),
39246
39257
  lineFeature: __webpack_require__(7390),
39258
+ lookupTable2D: __webpack_require__(8672),
39247
39259
  markerFeature: __webpack_require__(1848),
39248
39260
  meshColored: __webpack_require__(5651),
39261
+ pixelmapFeature: __webpack_require__(9685),
39249
39262
  pointFeature: __webpack_require__(5675),
39250
39263
  polygonFeature: __webpack_require__(2890),
39251
39264
  quadFeature: __webpack_require__(2182),
@@ -40195,6 +40208,139 @@ module.exports = webgl_lineFeature;
40195
40208
 
40196
40209
  /***/ }),
40197
40210
 
40211
+ /***/ 8672:
40212
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
40213
+
40214
+ var inherit = __webpack_require__(5699);
40215
+
40216
+ var timestamp = __webpack_require__(6618);
40217
+
40218
+ var vgl = __webpack_require__(320);
40219
+ /**
40220
+ * Switch to a specific texture unit.
40221
+ *
40222
+ * @param {vgl.renderState} renderState An object that contains the context
40223
+ * used for drawing.
40224
+ * @param {number} textureUnit The number of the texture unit [0-15].
40225
+ */
40226
+
40227
+
40228
+ function activateTextureUnit(renderState, textureUnit) {
40229
+ if (textureUnit >= 0 && textureUnit <= 31) {
40230
+ renderState.m_context.activeTexture(vgl.GL.TEXTURE0 + textureUnit);
40231
+ } else {
40232
+ throw Error('[error] Texture unit ' + textureUnit + ' is not supported');
40233
+ }
40234
+ }
40235
+ /**
40236
+ * Create a new instance of class webgl_lookupTable2D.
40237
+ *
40238
+ * @class
40239
+ * @alias geo.webgl.lookupTable2D
40240
+ * @param {object} arg Options object.
40241
+ * @param {number} [arg.maxWidth] Maximum width to use for the texture. If the
40242
+ * number of colors set is less than this, the texture is 1D. If greater, it
40243
+ * will be a rectangle of maxWidth x whatever height is necessary.
40244
+ * @param {number[]} [arg.colorTable] Initial color table for the texture.
40245
+ * This is of the form RGBARGBA... where each value is an integer on the
40246
+ * scale [0,255].
40247
+ * @extends vgl.texture
40248
+ * @returns {geo.webgl.lookupTable2D}
40249
+ */
40250
+
40251
+
40252
+ var webgl_lookupTable2D = function webgl_lookupTable2D(arg) {
40253
+ 'use strict';
40254
+
40255
+ if (!(this instanceof webgl_lookupTable2D)) {
40256
+ return new webgl_lookupTable2D(arg);
40257
+ }
40258
+
40259
+ arg = arg || {};
40260
+ vgl.texture.call(this);
40261
+ var m_setupTimestamp = timestamp(),
40262
+ m_maxWidth = arg.maxWidth || 4096,
40263
+ m_colorTable = new Uint8Array([0, 0, 0, 0]),
40264
+ m_colorTableOrig,
40265
+ m_this = this;
40266
+ /**
40267
+ * Create lookup table, initialize parameters, and bind data to it.
40268
+ *
40269
+ * @param {vgl.renderState} renderState An object that contains the context
40270
+ * used for drawing.
40271
+ */
40272
+
40273
+ this.setup = function (renderState) {
40274
+ activateTextureUnit(renderState, m_this.textureUnit());
40275
+ renderState.m_context.deleteTexture(m_this.m_textureHandle);
40276
+ m_this.m_textureHandle = renderState.m_context.createTexture();
40277
+ renderState.m_context.bindTexture(vgl.GL.TEXTURE_2D, m_this.m_textureHandle);
40278
+ renderState.m_context.texParameteri(vgl.GL.TEXTURE_2D, vgl.GL.TEXTURE_MIN_FILTER, vgl.GL.NEAREST);
40279
+ renderState.m_context.texParameteri(vgl.GL.TEXTURE_2D, vgl.GL.TEXTURE_MAG_FILTER, vgl.GL.NEAREST);
40280
+ renderState.m_context.texParameteri(vgl.GL.TEXTURE_2D, vgl.GL.TEXTURE_WRAP_S, vgl.GL.CLAMP_TO_EDGE);
40281
+ renderState.m_context.texParameteri(vgl.GL.TEXTURE_2D, vgl.GL.TEXTURE_WRAP_T, vgl.GL.CLAMP_TO_EDGE);
40282
+ renderState.m_context.pixelStorei(vgl.GL.UNPACK_ALIGNMENT, 1);
40283
+ renderState.m_context.pixelStorei(vgl.GL.UNPACK_FLIP_Y_WEBGL, true);
40284
+ renderState.m_context.texImage2D(vgl.GL.TEXTURE_2D, 0, vgl.GL.RGBA, m_this.width, m_this.height, 0, vgl.GL.RGBA, vgl.GL.UNSIGNED_BYTE, m_colorTable);
40285
+ renderState.m_context.bindTexture(vgl.GL.TEXTURE_2D, null);
40286
+ m_setupTimestamp.modified();
40287
+ };
40288
+ /**
40289
+ * Get/set color table.
40290
+ *
40291
+ * @param {number[]} [val] An array of RGBARGBA... integers on a scale
40292
+ * of [0, 255]. `undefined` to get the current value.
40293
+ * @returns {number[]|this}
40294
+ */
40295
+
40296
+
40297
+ this.colorTable = function (val) {
40298
+ if (val === undefined) {
40299
+ return m_colorTableOrig;
40300
+ }
40301
+
40302
+ m_colorTableOrig = val;
40303
+
40304
+ if (val.length < 4) {
40305
+ val = [0, 0, 0, 0];
40306
+ }
40307
+
40308
+ m_this.width = Math.min(m_maxWidth, val.length / 4);
40309
+ m_this.height = Math.ceil(val.length / 4 / m_maxWidth);
40310
+
40311
+ if (!(val instanceof Uint8Array) || val.length !== m_this.width * m_this.height * 4) {
40312
+ if (val.length < m_this.width * m_this.height * 4) {
40313
+ val = val.concat(new Array(m_this.width * m_this.height * 4 - val.length).fill(0));
40314
+ }
40315
+
40316
+ m_colorTable = new Uint8Array(val);
40317
+ } else {
40318
+ m_colorTable = val;
40319
+ }
40320
+
40321
+ m_this.modified();
40322
+ return m_this;
40323
+ };
40324
+ /**
40325
+ * Get maxWidth value.
40326
+ *
40327
+ * @returns {number} The maxWidth of the texture used.
40328
+ */
40329
+
40330
+
40331
+ this.maxWidth = function () {
40332
+ return m_maxWidth;
40333
+ };
40334
+
40335
+ this.colorTable(arg.colorTable || []);
40336
+ return this;
40337
+ };
40338
+
40339
+ inherit(webgl_lookupTable2D, vgl.texture);
40340
+ module.exports = webgl_lookupTable2D;
40341
+
40342
+ /***/ }),
40343
+
40198
40344
  /***/ 1848:
40199
40345
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
40200
40346
 
@@ -41134,6 +41280,209 @@ module.exports = webgl_object;
41134
41280
 
41135
41281
  /***/ }),
41136
41282
 
41283
+ /***/ 9685:
41284
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
41285
+
41286
+ var inherit = __webpack_require__(5699);
41287
+
41288
+ var registerFeature = (__webpack_require__(4647).registerFeature);
41289
+
41290
+ var pixelmapFeature = __webpack_require__(6374);
41291
+
41292
+ var lookupTable2D = __webpack_require__(8672);
41293
+
41294
+ var util = __webpack_require__(4634);
41295
+ /**
41296
+ * Create a new instance of class webgl.pixelmapFeature.
41297
+ *
41298
+ * @class
41299
+ * @alias geo.webgl.pixelmapFeature
41300
+ * @extends geo.pixelmapFeature
41301
+ * @param {geo.pixelmapFeature.spec} arg
41302
+ * @returns {geo.webgl.pixelmapFeature}
41303
+ */
41304
+
41305
+
41306
+ var webgl_pixelmapFeature = function webgl_pixelmapFeature(arg) {
41307
+ 'use strict';
41308
+
41309
+ if (!(this instanceof webgl_pixelmapFeature)) {
41310
+ return new webgl_pixelmapFeature(arg);
41311
+ }
41312
+
41313
+ pixelmapFeature.call(this, arg);
41314
+
41315
+ var object = __webpack_require__(7719);
41316
+
41317
+ object.call(this);
41318
+
41319
+ var vgl = __webpack_require__(320);
41320
+
41321
+ var fragmentShader = __webpack_require__(3953);
41322
+
41323
+ var m_quadFeature,
41324
+ s_exit = this._exit,
41325
+ m_lookupTable,
41326
+ m_this = this;
41327
+ /**
41328
+ * If the specified coordinates are in the rendered quad, use the basis
41329
+ * information from the quad to determine the pixelmap index value so that it
41330
+ * can be included in the `found` results.
41331
+ *
41332
+ * @param {geo.geoPosition} geo Coordinate.
41333
+ * @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
41334
+ * the interface gcs, `null` to use the map gcs, or any other transform.
41335
+ * @returns {geo.feature.searchResult} An object with a list of features and
41336
+ * feature indices that are located at the specified point.
41337
+ */
41338
+
41339
+ this.pointSearch = function (geo, gcs) {
41340
+ if (m_quadFeature && m_this.m_info) {
41341
+ var result = m_quadFeature.pointSearch(geo, gcs);
41342
+
41343
+ if (result.index.length === 1 && result.extra && result.extra[result.index[0]].basis && result.extra[result.index[0]]._quad && result.extra[result.index[0]]._quad.image) {
41344
+ var img = result.extra[result.index[0]]._quad.image;
41345
+ var basis = result.extra[result.index[0]].basis;
41346
+ var x = Math.floor(basis.x * img.width);
41347
+ var y = Math.floor(basis.y * img.height);
41348
+ var canvas = document.createElement('canvas');
41349
+ canvas.width = canvas.height = 1;
41350
+ var context = canvas.getContext('2d');
41351
+ context.drawImage(img, x, y, 1, 1, 0, 0, 1, 1);
41352
+ var pixel = context.getImageData(0, 0, 1, 1).data;
41353
+ var idx = pixel[0] + pixel[1] * 256 + pixel[2] * 256 * 256;
41354
+ result = {
41355
+ index: [idx],
41356
+ found: [m_this.data()[idx]]
41357
+ };
41358
+ return result;
41359
+ }
41360
+ }
41361
+
41362
+ return {
41363
+ index: [],
41364
+ found: []
41365
+ };
41366
+ };
41367
+ /**
41368
+ * Given the loaded pixelmap image, create a texture for the colors and a
41369
+ * quad that will use it.
41370
+ */
41371
+
41372
+
41373
+ this._computePixelmap = function () {
41374
+ var data = m_this.data() || [],
41375
+ colorFunc = m_this.style.get('color');
41376
+
41377
+ if (!m_lookupTable) {
41378
+ m_lookupTable = lookupTable2D();
41379
+ m_lookupTable.setTextureUnit(1);
41380
+ }
41381
+
41382
+ var clrLen = Math.max(1, data.length);
41383
+ var maxWidth = m_lookupTable.maxWidth();
41384
+
41385
+ if (clrLen > maxWidth && clrLen % maxWidth) {
41386
+ clrLen += maxWidth - clrLen % maxWidth;
41387
+ }
41388
+
41389
+ var colors = new Uint8Array(clrLen * 4);
41390
+ data.forEach(function (d, i) {
41391
+ var color = util.convertColor(colorFunc.call(m_this, d, i));
41392
+ colors[i * 4] = color.r * 255;
41393
+ colors[i * 4 + 1] = color.g * 255;
41394
+ colors[i * 4 + 2] = color.b * 255;
41395
+ colors[i * 4 + 3] = color.a === undefined ? 255 : color.a * 255;
41396
+ });
41397
+ m_this.m_info = {
41398
+ colors: colors
41399
+ }; // check if colors haven't changed
41400
+
41401
+ var oldcolors = m_lookupTable.colorTable();
41402
+
41403
+ if (oldcolors && oldcolors.length === colors.length) {
41404
+ var idx = 0;
41405
+
41406
+ for (; idx < colors.length; idx += 1) {
41407
+ if (colors[idx] !== oldcolors[idx]) {
41408
+ break;
41409
+ }
41410
+ }
41411
+
41412
+ if (idx === colors.length) {
41413
+ return;
41414
+ }
41415
+ }
41416
+
41417
+ m_lookupTable.colorTable(colors);
41418
+ /* If we haven't made a quad feature, make one now */
41419
+
41420
+ if (!m_quadFeature) {
41421
+ m_quadFeature = m_this.layer().createFeature('quad', {
41422
+ selectionAPI: false,
41423
+ gcs: m_this.gcs(),
41424
+ visible: m_this.visible(undefined, true)
41425
+ });
41426
+ m_this.dependentFeatures([m_quadFeature]);
41427
+ m_quadFeature.setShader('image_fragment', fragmentShader);
41428
+
41429
+ m_quadFeature._hookBuild = function (prog) {
41430
+ var lutSampler = new vgl.uniform(vgl.GL.INT, 'lutSampler');
41431
+ lutSampler.set(m_lookupTable.textureUnit());
41432
+ prog.addUniform(lutSampler);
41433
+ var lutWidth = new vgl.uniform(vgl.GL.INT, 'lutWidth');
41434
+ lutWidth.set(m_lookupTable.width);
41435
+ prog.addUniform(lutWidth);
41436
+ var lutHeight = new vgl.uniform(vgl.GL.INT, 'lutHeight');
41437
+ lutHeight.set(m_lookupTable.height);
41438
+ prog.addUniform(lutHeight);
41439
+ };
41440
+
41441
+ m_quadFeature._hookRenderImageQuads = function (renderState, quads) {
41442
+ quads.forEach(function (quad) {
41443
+ if (quad.image && quad.texture && !quad.texture.nearestPixel()) {
41444
+ quad.texture.setNearestPixel(true);
41445
+ }
41446
+ });
41447
+ m_lookupTable.bind(renderState, quads);
41448
+ };
41449
+
41450
+ m_quadFeature.style({
41451
+ image: m_this.m_srcImage,
41452
+ position: m_this.style.get('position')
41453
+ }).data([{}]).draw();
41454
+ }
41455
+ };
41456
+ /**
41457
+ * Destroy. Deletes the associated quadFeature.
41458
+ *
41459
+ * @returns {this}
41460
+ */
41461
+
41462
+
41463
+ this._exit = function () {
41464
+ if (m_quadFeature && m_this.layer()) {
41465
+ m_this.layer().deleteFeature(m_quadFeature);
41466
+ m_quadFeature = null;
41467
+ m_this.dependentFeatures([]);
41468
+ }
41469
+
41470
+ s_exit();
41471
+ return m_this;
41472
+ };
41473
+
41474
+ this._init(arg);
41475
+
41476
+ return this;
41477
+ };
41478
+
41479
+ inherit(webgl_pixelmapFeature, pixelmapFeature); // Now register it
41480
+
41481
+ registerFeature('webgl', 'pixelmap', webgl_pixelmapFeature);
41482
+ module.exports = webgl_pixelmapFeature;
41483
+
41484
+ /***/ }),
41485
+
41137
41486
  /***/ 5675:
41138
41487
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
41139
41488
 
@@ -42498,7 +42847,7 @@ var webgl_quadFeature = function webgl_quadFeature(arg) {
42498
42847
 
42499
42848
 
42500
42849
  this._build = function () {
42501
- var mapper, mat, prog, srctex, unicrop, unicropsource, geom, context;
42850
+ var mapper, mat, prog, srctex, unicrop, unicropsource, geom, context, sampler2d;
42502
42851
 
42503
42852
  if (!m_this.position()) {
42504
42853
  return;
@@ -42523,6 +42872,11 @@ var webgl_quadFeature = function webgl_quadFeature(arg) {
42523
42872
  prog.addUniform(new vgl.projectionUniform('projectionMatrix'));
42524
42873
  prog.addUniform(new vgl.floatUniform('opacity', 1.0));
42525
42874
  prog.addUniform(new vgl.floatUniform('zOffset', 0.0));
42875
+ /* Use texture unit 0 */
42876
+
42877
+ sampler2d = new vgl.uniform(vgl.GL.INT, 'sampler2d');
42878
+ sampler2d.set(0);
42879
+ prog.addUniform(sampler2d);
42526
42880
  context = m_this.renderer()._glContext();
42527
42881
  unicrop = new vgl.uniform(context.FLOAT_VEC2, 'crop');
42528
42882
  unicrop.set([1.0, 1.0]);
@@ -42532,6 +42886,11 @@ var webgl_quadFeature = function webgl_quadFeature(arg) {
42532
42886
  prog.addUniform(unicropsource);
42533
42887
  prog.addShader(vgl.getCachedShader(context.VERTEX_SHADER, context, vertexShaderImage));
42534
42888
  prog.addShader(vgl.getCachedShader(context.FRAGMENT_SHADER, context, fragmentShaderImage));
42889
+
42890
+ if (m_this._hookBuild) {
42891
+ m_this._hookBuild(prog);
42892
+ }
42893
+
42535
42894
  mat.addAttribute(prog);
42536
42895
  mat.addAttribute(new vgl.blend());
42537
42896
  /* This is similar to vgl.planeSource */
@@ -42708,6 +43067,11 @@ var webgl_quadFeature = function webgl_quadFeature(arg) {
42708
43067
  h,
42709
43068
  quadw,
42710
43069
  quadh;
43070
+
43071
+ if (m_this._hookRenderImageQuads) {
43072
+ m_this._hookRenderImageQuads(renderState, m_quads.imgQuads);
43073
+ }
43074
+
42711
43075
  context.bindBuffer(context.ARRAY_BUFFER, m_glBuffers.imgQuadsPosition);
42712
43076
  $.each(m_quads.imgQuads, function (idx, quad) {
42713
43077
  if (!quad.image) {
@@ -42824,6 +43188,41 @@ var webgl_quadFeature = function webgl_quadFeature(arg) {
42824
43188
 
42825
43189
  m_this.modified();
42826
43190
  };
43191
+ /**
43192
+ * Set the image or color vertex or fragment shader.
43193
+ *
43194
+ * @param {string} shaderType One of `image_vertex`, `image_fragment`,
43195
+ * `color_vertex`, or `color_fragment`.
43196
+ * @param {string} shaderCode The shader program.
43197
+ * @returns {this} The class instance on success, undefined in an unknown
43198
+ * shaderType was specified.
43199
+ */
43200
+
43201
+
43202
+ this.setShader = function (shaderType, shaderCode) {
43203
+ switch (shaderType) {
43204
+ case 'image_vertex':
43205
+ vertexShaderImage = shaderCode;
43206
+ break;
43207
+
43208
+ case 'image_fragment':
43209
+ fragmentShaderImage = shaderCode;
43210
+ break;
43211
+
43212
+ case 'color_vertex':
43213
+ vertexShaderColor = shaderCode;
43214
+ break;
43215
+
43216
+ case 'color_fragment':
43217
+ fragmentShaderColor = shaderCode;
43218
+ break;
43219
+
43220
+ default:
43221
+ return;
43222
+ }
43223
+
43224
+ return m_this;
43225
+ };
42827
43226
  /**
42828
43227
  * Destroy.
42829
43228
  */
@@ -93906,6 +94305,13 @@ module.exports = "/* contourFeature vertex shader */\n\n#ifdef GL_ES\n precisio
93906
94305
 
93907
94306
  /***/ }),
93908
94307
 
94308
+ /***/ 3953:
94309
+ /***/ (function(module) {
94310
+
94311
+ module.exports = "/* pixelmapFeature fragment shader */\n\nvarying highp vec2 iTextureCoord;\nuniform sampler2D sampler2d;\nuniform sampler2D lutSampler;\nuniform int lutWidth;\nuniform int lutHeight;\nuniform mediump float opacity;\nuniform highp vec2 crop;\n\nvoid main(void) {\n if ((crop.s < 1.0 && iTextureCoord.s > crop.s) || (crop.t < 1.0 && 1.0 - iTextureCoord.t > crop.t)) {\n discard;\n }\n // to add anti-aliasing, we would need to know the current pixel size\n // (probably computed in the vertex shader) and then sample the base image at\n // multiple points, then average the output color.\n highp vec4 lutValue = texture2D(sampler2d, iTextureCoord);\n highp vec2 lutCoord;\n lutCoord.s = (\n mod(\n // add 0.5 to handle float imprecision\n floor(lutValue.r * 255.0 + 0.5) +\n floor(lutValue.g * 255.0 + 0.5) * 256.0,\n float(lutWidth)\n // center in pixel\n ) + 0.5) / float(lutWidth);\n // Our image is top-down, so invert the coordinate\n lutCoord.t = 1.0 - (\n floor(\n (\n // add 0.5 to handle float imprecision\n floor(lutValue.r * 255.0 + 0.5) +\n floor(lutValue.g * 255.0 + 0.5) * 256.0 +\n floor(lutValue.b * 255.0 + 0.5) * 256.0 * 256.0\n // We may want an option to use the alpha channel to allow more indices\n ) / float(lutWidth)\n // center in pixel\n ) + 0.5) / float(lutHeight);\n if (lutCoord.t < 0.0) {\n discard;\n }\n mediump vec4 color = texture2D(lutSampler, lutCoord);\n\n color.a *= opacity;\n gl_FragColor = color;\n}\n"
94312
+
94313
+ /***/ }),
94314
+
93909
94315
  /***/ 1815:
93910
94316
  /***/ (function(module) {
93911
94317