@sapui5/sap.ui.vbm 1.84.8 → 1.84.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapui5/sap.ui.vbm",
3
- "version": "1.84.8",
3
+ "version": "1.84.10",
4
4
  "description": "SAPUI5 Library sap.ui.vbm",
5
5
  "homepage": "https://sap.github.io/ui5-tooling/pages/SAPUI5/",
6
6
  "author": "SAP SE (https://www.sap.com)",
@@ -3,7 +3,7 @@
3
3
  <name>sap.ui.vbm</name>
4
4
  <vendor>SAP SE</vendor>
5
5
  <copyright>SAP UI development toolkit for HTML5 (SAPUI5) (c) Copyright 2009-2012 SAP AG. All rights reserved</copyright>
6
- <version>1.84.8</version>
6
+ <version>1.84.10</version>
7
7
 
8
8
  <documentation>SAP UI library: sap.ui.vbm</documentation>
9
9
 
@@ -21,7 +21,7 @@ sap.ui.define([
21
21
  * @param {string} [sId] id for the new control, generated automatically if no id is given
22
22
  * @param {object} [mSettings] initial settings for the new object
23
23
  * @author SAP SE
24
- * @version 1.84.8
24
+ * @version 1.84.10
25
25
  * @extends sap.ui.core.Element
26
26
  * @constructor
27
27
  * @public
@@ -573,7 +573,13 @@ sap.ui.define([
573
573
  resolution : provider.resolution,
574
574
  retries : provider.retries,
575
575
  type : provider.type,
576
- Source : provider.Source ? [].concat(provider.Source).map(function(source) {
576
+ Header : provider.Header ? [].concat(provider.Header).map(function(header) {
577
+ return {
578
+ name : header.name,
579
+ value : header.value
580
+ };
581
+ }) : provider.Header,
582
+ Source : provider.Source ? [].concat(provider.Source).map(function(source) {
577
583
  return {
578
584
  id : source.id,
579
585
  url : source.url
@@ -42,7 +42,7 @@ sap.ui.define([
42
42
  * @param {string} [sId] id for the new control, generated automatically if no id is given
43
43
  * @param {object} [mSettings] initial settings for the new object
44
44
  * @author SAP SE
45
- * @version 1.84.8
45
+ * @version 1.84.10
46
46
  * @extends sap.ui.core.Element
47
47
  * @constructor
48
48
  * @public
@@ -247,7 +247,10 @@ sap.ui.define([
247
247
  this._parser = null;
248
248
  }
249
249
 
250
+ this._detail = null;
250
251
  this._context = null;
252
+ this._raycaster = null;
253
+ this._hoverInstance = null;
251
254
 
252
255
  if (basePrototype.exit) {
253
256
  basePrototype.exit.call(this);
@@ -321,7 +321,13 @@ sap.ui.define([
321
321
  }
322
322
 
323
323
  // get the name of the fragment........................................//
324
- tt = (f.properties && f.properties.name) ? f.properties.name : "";
324
+ if (f.properties && f.properties.name) {
325
+ tt = f.properties.name;
326
+ } else if (f.properties && f.properties.NAME) {
327
+ tt = f.properties.NAME;
328
+ } else {
329
+ tt = "";
330
+ }
325
331
  this.mNames[f.id2] = tt;
326
332
  this.mRegionProps[f.id2] = f.properties;
327
333
 
@@ -119,7 +119,7 @@ sap.ui.define([
119
119
  clusterVos: {
120
120
  type: "sap.ui.core.Control",
121
121
  multiple: true,
122
- visiblity: "hidden",
122
+ visibility: "hidden",
123
123
  singularName: "clusterVo"
124
124
  },
125
125
  /**
@@ -128,7 +128,7 @@ sap.ui.define([
128
128
  clusterContainers: {
129
129
  type: "sap.ui.vbm.ClusterContainer",
130
130
  multiple: true,
131
- visiblity: "hidden",
131
+ visibility: "hidden",
132
132
  singularName: "clusterContainer"
133
133
  }
134
134
 
@@ -686,23 +686,22 @@ sap.ui.define([
686
686
  * @param {string} oMapConfiguration.MapProvider.minLOD Minimal supported Level Of Detail.
687
687
  * @param {string} oMapConfiguration.MapProvider.maxLOD Maximal supported Level Of Detail.
688
688
  * @param {string} oMapConfiguration.MapProvider.copyright Copyright Information to be shown with the map.
689
- * @param {array} oMapConfiguration.MapProvider.Source Array of source definitions. At least on Source has to be given. Multiple sources can be
690
- * used for load distribution.
689
+ * @param {array} oMapConfiguration.MapProvider.Header Array of HTTP headers definitions. Optional.
690
+ * @param {string} oMapConfiguration.MapProvider.Header.name Name of the header.
691
+ * @param {string} oMapConfiguration.MapProvider.Header.value Value of the header.
692
+ * @param {array} oMapConfiguration.MapProvider.Source Array of source definitions. At least on Source has to be given. Multiple sources can be used for load distribution.
691
693
  * @param {string} oMapConfiguration.MapProvider.Source.id Source id.
692
- * @param {string} oMapConfiguration.MapProvider.Source.url Source URL for map tile service. URL includes place holders for variable informations
693
- * set at runtime, e.g. {LOD}.
694
+ * @param {string} oMapConfiguration.MapProvider.Source.url Source URL for map tile service. URL includes place holders for variable informations set at runtime, e.g. {LOD}.
694
695
  * @param {array} oMapConfiguration.MapLayerStacks Array of Map Layer Stacks
695
696
  * @param {string} oMapConfiguration.MapLayerStacks.name Name of Map Layer Stack. Use with the GeoMap refMapLayerStack property.
696
697
  * @param {string} oMapConfiguration.MapLayerStacks.previewPosition.latitude Latitude position to use when creating image tile
697
698
  * @param {string} oMapConfiguration.MapLayerStacks.previewPosition.longitude Longitude position to use when creating image tile
698
699
  * @param {string} oMapConfiguration.MapLayerStacks.previewPosition.lod Lod position to use when creating image tile
699
- * @param {array} oMapConfiguration.MapLayerStacks.MapLayer Array of Map Layers. Each Layer refers to a Map Proveride. Map Layers get overlayed in
700
- * the given sequence.
700
+ * @param {array} oMapConfiguration.MapLayerStacks.MapLayer Array of Map Layers. Each Layer refers to a Map Proveride. Map Layers get overlayed in the given sequence.
701
701
  * @param {string} oMapConfiguration.MapLayerStacks.MapLayer.name Name of Map Layer.
702
702
  * @param {string} oMapConfiguration.MapLayerStacks.MapLayer.refMapProvider Name of referenced Map Provider.
703
703
  * @param {string} oMapConfiguration.MapLayerStacks.MapLayer.opacity Opacity of Map Layer. Value range 0 to 1.
704
- * @param {sap.ui.core.CSSColor} oMapConfiguration.MapLayerStacks.colBkgnd Background color for Map Layer. Only meaningful if opacity is
705
- * below 1.
704
+ * @param {sap.ui.core.CSSColor} oMapConfiguration.MapLayerStacks.colBkgnd Background color for Map Layer. Only meaningful if opacity is below 1.
706
705
  * @returns {sap.ui.vbm.GeoMap} This allows method chaining
707
706
  * @public
708
707
  * @ui5-metamodel This method also will be described in the UI5 (legacy) designtime metamodel
@@ -25,7 +25,7 @@ sap.ui.define([
25
25
  *
26
26
  * @public
27
27
  * @author SAP SE
28
- * @version 1.84.8
28
+ * @version 1.84.10
29
29
  * @extends sap.ui.core.Control
30
30
  * @alias sap.ui.vbm.Viewport
31
31
  */
@@ -190,9 +190,14 @@ sap.ui.define([
190
190
  }
191
191
  this._stopRenderLoop();
192
192
 
193
+ this._cameraController.dispose();
194
+ this._cameraController = null;
195
+
196
+ this._renderer.dispose();
197
+ this._renderer = null;
198
+
193
199
  this._scene = null;
194
200
  this._camera = null;
195
- this._renderer = null;
196
201
 
197
202
  if (basePrototype.exit) {
198
203
  basePrototype.exit.call(this);
@@ -31,9 +31,9 @@ sap.ui.define([
31
31
  *
32
32
  * @private
33
33
  * @author SAP SE
34
- * @version 1.84.8
34
+ * @version 1.84.10
35
35
  * @alias sap.ui.vbm.adapter3d.ModelHandler
36
- */
36
+ */
37
37
  var ModelHandler = BaseObject.extend("sap.ui.vbm.adapter3d.ModelHandler", /** @lends sap.ui.vbm.adapter3d.ModelHandler.prototype */ {
38
38
 
39
39
  constructor: function(resources, textures, scene, root) {
@@ -96,11 +96,14 @@ sap.ui.define([
96
96
  this._textures = null;
97
97
  this._scene = null;
98
98
  this._root = null;
99
+ this._hotInstance = null;
99
100
 
100
101
  // destroy 'meta' meshes
101
- this._meshes.forEach(function(mesh) {
102
- mesh.objects3D.forEach(function(object) {
103
- this._deleteObject3D(object);
102
+ this._meshes.forEach(function(array) {
103
+ array.forEach(function(item) {
104
+ item.objects3D.forEach(function(object) {
105
+ this._deleteObject3D(object);
106
+ }, this);
104
107
  }, this);
105
108
  }, this);
106
109
 
@@ -110,15 +113,23 @@ sap.ui.define([
110
113
  subRef(instance.texture);
111
114
  }
112
115
  });
113
-
116
+
114
117
  // destroy models
115
118
  this._models.forEach(function(model, resource) {
116
119
  this._deleteModel(model);
117
120
  }, this);
118
121
 
119
122
  this._meshes.clear();
123
+ this._meshes = null;
124
+
120
125
  this._instances.clear();
126
+ this._instances = null;
127
+
121
128
  this._models.clear();
129
+ this._models = null;
130
+
131
+ this._glTFLoader = null;
132
+ this._colladaLoader = null;
122
133
 
123
134
  BaseObject.prototype.destroy.call(this);
124
135
  };
@@ -148,7 +159,7 @@ sap.ui.define([
148
159
  * @param {object} instance Model instance.
149
160
  * @public
150
161
  */
151
- ModelHandler.prototype.updateInstance = function(instance) {
162
+ ModelHandler.prototype.updateInstance = function(instance) {
152
163
  var data = this._instances.get(instance), update = false, hot = this._hotInstance && this._hotInstance === instance;
153
164
  if (data) {
154
165
  var normalized = Utilities.toBoolean(instance.normalize);
@@ -187,7 +198,7 @@ sap.ui.define([
187
198
  }
188
199
  update = true;
189
200
  }
190
-
201
+
191
202
  // when model normalization changed -> update model properties -> reset instance model matrices
192
203
  if (propertyChanged(instance, ["normalize", "model"])) {
193
204
  this._updateModel(data.model, normalized);
@@ -219,9 +230,9 @@ sap.ui.define([
219
230
  if (data.matrices.length === 0) {
220
231
  var world = this._root.matrixWorld.clone(); // start from the _root
221
232
  world.multiply(data.world); // apply instance world matrix
222
-
233
+
223
234
  // if instance normalized -> apply normalized model root matrix as otherwise (non normalized case) model root has identity matrix
224
- if (normalized) {
235
+ if (normalized) {
225
236
  world.multiply(data.model.normalized.world);
226
237
  }
227
238
  // apply individual mesh matrices from the model at last
@@ -255,7 +266,7 @@ sap.ui.define([
255
266
  this._instances.delete(instance);
256
267
  this._removeInstanceFromMesh(data);
257
268
  instance._last = {}; // reset all LRU variables at once
258
-
269
+
259
270
  if (data.model) {
260
271
  subRef(data.model); // model can be null if removing 'broken' instance
261
272
  }
@@ -430,7 +441,7 @@ sap.ui.define([
430
441
  ModelHandler.prototype._postprocess = function(model, content) {
431
442
  // mirror on Z axis entire collada root which is effectively the same as collada processing with baking transformations and inverting Z coordinates in ActiveX
432
443
  model.scene.scale.set(1,1,-1);
433
-
444
+
434
445
  var meshes = [], materials = new Set(), marked = "_sapUsed";
435
446
  // collect meshes only + calculate world matrix, mark used materials & maps
436
447
  model.scene.traverse(function(object) {
@@ -560,7 +571,7 @@ sap.ui.define([
560
571
  // remove instanced mesh from scene
561
572
  if (object.parent) {
562
573
  object.parent.remove(object);
563
- }
574
+ }
564
575
  // geometries are shared -> cannot dispose
565
576
  Utilities.toArray(object.material).forEach(function(material) {
566
577
  material.dispose(); // materials are cloned -> can be disposed, maps are shared -> don't touch, cannot be disposes
@@ -584,7 +595,7 @@ sap.ui.define([
584
595
  // target has to be added to _root to mimic original model and must have same world matrix as original model
585
596
  // so we calculate world matrix for target which will be under _root and not under _scene as instance mesh
586
597
  var world = data.world.clone(); // use instance world as starting point
587
- if (data.model.normalized) {
598
+ if (data.model.normalized) {
588
599
  world.multiply(data.model.normalized.world);
589
600
  }
590
601
  world.multiply(data.model.root.children[0].matrixWorld);
@@ -378,7 +378,7 @@ sap.ui.define([
378
378
  *
379
379
  * @private
380
380
  * @author SAP SE
381
- * @version 1.84.8
381
+ * @version 1.84.10
382
382
  * @alias sap.ui.vbm.adapter3d.ObjectFactory
383
383
  */
384
384
  var ObjectFactory = BaseObject.extend("sap.ui.vbm.adapter3d.ObjectFactory", /** @lends sap.ui.vbm.adapter3d.ObjectFactory.prototype */ {});
@@ -34,9 +34,9 @@ sap.ui.define([
34
34
  *
35
35
  * @private
36
36
  * @author SAP SE
37
- * @version 1.84.8
37
+ * @version 1.84.10
38
38
  * @alias sap.ui.vbm.adapter3d.PolygonHandler
39
- */
39
+ */
40
40
  var PolygonHandler = BaseObject.extend("sap.ui.vbm.adapter3d.PolygonHandler", /** @lends sap.ui.vbm.adapter3d.PolygonHandler.prototype */ {
41
41
 
42
42
  constructor: function(root) {
@@ -99,7 +99,7 @@ sap.ui.define([
99
99
  PolygonHandler.prototype.destroy = function() {
100
100
  // Reset references to shared objects.
101
101
  this._root = null;
102
- this._instances.clear();
102
+ this._hotInstance = null;
103
103
 
104
104
  // destroy 'meta' meshes
105
105
  this._meshes.forEach(function(key, array) {
@@ -114,10 +114,16 @@ sap.ui.define([
114
114
  this._deleteObject3D(border.object3D);
115
115
  }, this);
116
116
  }, this);
117
-
117
+
118
118
  // clear
119
+ this._instances.clear();
120
+ this._instances = null;
121
+
119
122
  this._meshes.clear();
123
+ this._meshes = null;
124
+
120
125
  this._borders.clear();
126
+ this._borders = null;
121
127
 
122
128
  BaseObject.prototype.destroy.call(this);
123
129
  };
@@ -137,11 +143,11 @@ sap.ui.define([
137
143
 
138
144
  /**
139
145
  * Adds polygon instance to polygon handler.
140
- *
146
+ *
141
147
  * @param {object} instance Polygon instance.
142
148
  * @public
143
149
  */
144
- PolygonHandler.prototype.addInstance = function(instance) {
150
+ PolygonHandler.prototype.addInstance = function(instance) {
145
151
  this._instances.set(instance, {
146
152
  instance : instance,
147
153
  indices: [],
@@ -161,11 +167,11 @@ sap.ui.define([
161
167
 
162
168
  /**
163
169
  * Updates polygon instance in polygon handler
164
- *
170
+ *
165
171
  * @param {object} instance Polygon instance.
166
172
  * @public
167
173
  */
168
- PolygonHandler.prototype.updateInstance = function(instance) {
174
+ PolygonHandler.prototype.updateInstance = function(instance) {
169
175
  var data = this._instances.get(instance), updateMesh = false, updateBorder = false;
170
176
  if (data) {
171
177
  // position, rotation, scale [mandatory attributes] when change -> recalculate matrix
@@ -188,7 +194,7 @@ sap.ui.define([
188
194
  }
189
195
 
190
196
  // if any property which affects polygon color changed -> check if polygon color actually changed
191
- // then update polygon color and remove polygon from current 'meta' mesh if it exists
197
+ // then update polygon color and remove polygon from current 'meta' mesh if it exists
192
198
  // and put it into another 'meta' mesh according to polygon updated color
193
199
  // color, selectColor, VB:s [mandatory attributes]
194
200
  if (propertyChanged(instance, ["color", "selectColor", "VB:s"])) {
@@ -329,13 +335,13 @@ sap.ui.define([
329
335
  // create 3 or 2 groups, depends on where hot instance geometry is within 'meta' mesh geometry
330
336
  geometry.addGroup(range.start, data.indices.length, 1); // use hot material with index #1
331
337
 
332
- if (range.start !== 0) {
338
+ if (range.start !== 0) {
333
339
  geometry.addGroup(0, range.start, 0); // use original material with index #0
334
340
  }
335
341
  if (range.start + data.indices.length < geometry.index.count) {
336
342
  geometry.addGroup(range.start + data.indices.length, geometry.index.count - range.start - data.indices.length, 0); // use original material with index #0
337
343
  }
338
- }
344
+ }
339
345
  }
340
346
  if (data.border) { // apply hover on polygon border geometry
341
347
  material = data.border.material;
@@ -365,13 +371,13 @@ sap.ui.define([
365
371
  var vertexCount = data.lines.length/3;
366
372
  geometry.addGroup(range.start, vertexCount, 1); // use hot material with index #1
367
373
 
368
- if (range.start !== 0) {
374
+ if (range.start !== 0) {
369
375
  geometry.addGroup(0, range.start, 0); // use original material with index #0
370
376
  }
371
377
  if (range.start + vertexCount < positions.count) {
372
378
  geometry.addGroup(range.start + vertexCount, positions.count - range.start - vertexCount, 0); // use original material with index #0
373
379
  }
374
- }
380
+ }
375
381
  }
376
382
  } else {
377
383
  log.error("Unable to find polygon instance data", "", thisModule);
@@ -430,7 +436,7 @@ sap.ui.define([
430
436
 
431
437
  /**
432
438
  * Updates 'meta' meshes requested for rebuild by combining geometry of all instances with the same color into one mesh.
433
- *
439
+ *
434
440
  * @returns {boolean} True if hot instance 'meta' mesh has been recreated.
435
441
  * @private
436
442
  */
@@ -441,11 +447,11 @@ sap.ui.define([
441
447
  for (var i = 0; i < array.length;) {
442
448
  if (array[i].dirty) {
443
449
  var j, instance, base, indices = [], vertices = [], normals = [], data = array[i];
444
-
450
+
445
451
  this._deleteObject3D(data.object3D);
446
452
  data.object3D = null;
447
453
  data.hitInfo.length = 0; // erase hitInfo
448
-
454
+
449
455
  data.instances.forEach(function(range, key) {
450
456
  instance = key; // to access instance outside forEach
451
457
 
@@ -481,24 +487,24 @@ sap.ui.define([
481
487
 
482
488
  if (indices.length) {
483
489
  var geometry = new THREE.BufferGeometry();
484
-
490
+
485
491
  geometry.setIndex(indices);
486
492
  geometry.setAttribute("position", new THREE.Float32BufferAttribute(vertices, 3));
487
493
  geometry.setAttribute("normal", new THREE.Float32BufferAttribute(normals, 3));
488
494
  geometry.computeBoundingBox(); // needed for ray casting
489
495
  geometry.computeBoundingSphere(); // needed for ray casting
490
-
496
+
491
497
  var material = createMaterial(true);
492
498
  material.color.copy(instance.color.rgb);
493
499
  material.opacity = instance.color.opacity;
494
500
  material.transparent = material.opacity < 1;
495
501
  material.needsUpdate = true;
496
-
502
+
497
503
  data.object3D = new THREE.Mesh(geometry, material);
498
504
  data.object3D.matrixAutoUpdate = false;
499
505
  data.object3D.layers.set(0); // put it to layer #0 to enable raycasting
500
506
  this._root.add(data.object3D);
501
-
507
+
502
508
  data.object3D._instanceHitTest = this._instanceHitTest.bind(data); // helper function to return instance based on hit test info
503
509
  data.triangleCount = indices.length/3; // update triangle count on full rebuild
504
510
  }
@@ -529,7 +535,7 @@ sap.ui.define([
529
535
 
530
536
  /**
531
537
  * Updates 'meta' borders requested for rebuild by combining geometry of all instances with the same color into one mesh.
532
- *
538
+ *
533
539
  * @returns {boolean} True if hot instance 'meta' border has been recreated.
534
540
  * @private
535
541
  */
@@ -567,13 +573,13 @@ sap.ui.define([
567
573
  var geometry = new THREE.BufferGeometry();
568
574
  geometry.setAttribute("position", new THREE.Float32BufferAttribute(vertices, 3));
569
575
  geometry.computeBoundingBox();
570
-
576
+
571
577
  var material = createLineMaterial();
572
578
  material.color.copy(instance.colorBorder.rgb);
573
579
  material.opacity = instance.colorBorder.opacity;
574
580
  material.transparent = material.opacity < 1;
575
581
  material.needsUpdate = true;
576
-
582
+
577
583
  data.object3D = new THREE.LineSegments(geometry, material);
578
584
  data.object3D.matrixAutoUpdate = false;
579
585
  data.object3D.layers.set(1); // put it to layer #1 to disable hit test
@@ -741,10 +747,10 @@ sap.ui.define([
741
747
  if (object) {
742
748
  if (object.parent) {
743
749
  object.parent.remove(object);
744
- }
750
+ }
745
751
  if (object.geometry) {
746
752
  object.geometry.dispose();
747
- }
753
+ }
748
754
  Utilities.toArray(object.material).forEach(function(material) {
749
755
  material.dispose(); // no maps to dispose
750
756
  });
@@ -9,7 +9,7 @@ sap.ui.define([
9
9
  "sap/ui/base/Object",
10
10
  "./Utilities",
11
11
  "./PolygonHandler",
12
- "./ModelHandler",
12
+ "./ModelHandler",
13
13
  "./thirdparty/three",
14
14
  "./thirdparty/DecalGeometry",
15
15
  "./thirdparty/html2canvas"],
@@ -50,7 +50,7 @@ function(jQuery, BaseObject, Utilities, PolygonHandler, ModelHandler, THREE, Dec
50
50
  *
51
51
  * @private
52
52
  * @author SAP SE
53
- * @version 1.84.8
53
+ * @version 1.84.10
54
54
  * @alias sap.ui.vbm.adapter3d.SceneBuilder
55
55
  */
56
56
  var SceneBuilder = BaseObject.extend("sap.ui.vbm.adapter3d.SceneBuilder", /** @lends sap.ui.vbm.adapter3d.SceneBuilder.prototype */ {
@@ -107,9 +107,11 @@ function(jQuery, BaseObject, Utilities, PolygonHandler, ModelHandler, THREE, Dec
107
107
  this._scene = null;
108
108
  this._viewport = null;
109
109
  this._context = null;
110
+ this._hotInstance = null;
111
+
110
112
 
111
113
  if (this._box4) {
112
- this._box.dispose();
114
+ this._box4.dispose();
113
115
  }
114
116
  if (this._box6) {
115
117
  this._box6.dispose();
@@ -125,15 +127,22 @@ function(jQuery, BaseObject, Utilities, PolygonHandler, ModelHandler, THREE, Dec
125
127
  this._decalHelper.material.dispose();
126
128
  this._decalHelper.geometry.dispose();
127
129
  this._scene.remove(this._decalHelper);
130
+ this._decalHelper = null;
128
131
  }
129
132
 
130
133
  this._polygonHandler.destroy();
134
+ this._polygonHandler = null;
135
+
131
136
  this._modelHandler.destroy();
137
+ this._modelHandler = null;
132
138
 
133
139
  this._textures.forEach(function(texture) {
134
140
  texture.dispose();
135
141
  });
136
142
 
143
+ this._targets.clear();
144
+ this._targets = null;
145
+
137
146
  BaseObject.prototype.destroy.call(this);
138
147
  };
139
148
 
@@ -194,7 +203,7 @@ function(jQuery, BaseObject, Utilities, PolygonHandler, ModelHandler, THREE, Dec
194
203
  [].concat(toAdd, toUpdate).forEach(function(instance) {
195
204
  if (instance.isModel) {
196
205
  that._modelHandler.addModel(instance);
197
- }
206
+ }
198
207
  if (instance.texture && propertyChanged(instance, "texture")) {
199
208
  addTexture(instance.texture);
200
209
  }
@@ -313,7 +322,7 @@ function(jQuery, BaseObject, Utilities, PolygonHandler, ModelHandler, THREE, Dec
313
322
  var state = {
314
323
  zoom: 1.0,
315
324
  // convert from left handed (DirectX) to right handed (OpenGL)
316
- target: new Vector3(-camTarget.x, -camTarget.z, camTarget.y),
325
+ target: new Vector3(-camTarget.x, -camTarget.z, camTarget.y),
317
326
  position: new Vector3(-pos.x, -pos.z, pos.y)
318
327
  };
319
328
 
@@ -580,7 +589,7 @@ function(jQuery, BaseObject, Utilities, PolygonHandler, ModelHandler, THREE, Dec
580
589
  // var timestamp = performance.now();
581
590
  this._polygonHandler.updateHotInstance(instance);
582
591
  this._modelHandler.updateHotInstance(instance);
583
-
592
+
584
593
  // perform pending updates if any
585
594
  this._polygonHandler.update();
586
595
  this._modelHandler.update();
@@ -592,7 +601,7 @@ function(jQuery, BaseObject, Utilities, PolygonHandler, ModelHandler, THREE, Dec
592
601
  if (instance) {
593
602
  this._updateHotStatus(instance, true);
594
603
  }
595
-
604
+
596
605
  this._hotInstance = instance;
597
606
  // DEBUG
598
607
  // log.info("update hover took " + (performance.now() - timestamp) + " milliseconds", "", thisModule);
@@ -615,9 +624,9 @@ function(jQuery, BaseObject, Utilities, PolygonHandler, ModelHandler, THREE, Dec
615
624
  box.layers.set(0); // put it to layer #0 to enable raycasting
616
625
  box._sapInstance = instance; // keep reference to instance
617
626
  instance.object3D.add(box);
618
- }
627
+ }
619
628
  }
620
-
629
+
621
630
  // update properties after processing is done
622
631
  updateProperty(instance, "texture6");
623
632
 
@@ -666,7 +675,7 @@ function(jQuery, BaseObject, Utilities, PolygonHandler, ModelHandler, THREE, Dec
666
675
  cylinder.layers.set(0); // put it to layer #0 to enable raycasting
667
676
  cylinder._sapInstance = instance; // keep reference to instance
668
677
  instance.object3D.add(cylinder);
669
- }
678
+ }
670
679
  }
671
680
 
672
681
  if (propertyChanged(instance, "textureCap") || updateTextureCap) {
@@ -689,12 +698,12 @@ function(jQuery, BaseObject, Utilities, PolygonHandler, ModelHandler, THREE, Dec
689
698
  }
690
699
  }
691
700
  }
692
-
701
+
693
702
  // update cylinder properties after processing is done
694
703
  updateProperty(instance, ["isOpen", "testureCap"]);
695
704
 
696
705
  // handle common properties
697
- this._assignProperties(instance, hot);
706
+ this._assignProperties(instance, hot);
698
707
  };
699
708
 
700
709
  SceneBuilder.prototype._assignProperties = function(instance, hot) {
@@ -818,9 +827,9 @@ function(jQuery, BaseObject, Utilities, PolygonHandler, ModelHandler, THREE, Dec
818
827
  Utilities.subRef(material.map); // release current texture in use
819
828
  material.map = null;
820
829
  }
821
-
830
+
822
831
  material.map = this._textures.get(instance.text ? this._getDecalTextKey(instance) : instance.texture);
823
-
832
+
824
833
  if (material.map) {
825
834
  material.map.flipY = true;
826
835
  material.needsUpdate = true; // required by threeJS
@@ -829,7 +838,7 @@ function(jQuery, BaseObject, Utilities, PolygonHandler, ModelHandler, THREE, Dec
829
838
  log.error("Unable to apply texture, texture not found", instance.texture, thisModule);
830
839
  }
831
840
  }
832
-
841
+
833
842
  // update properties after processing is done
834
843
  updateProperty(instance, ["position", "direction", "size", "rotation", "target", "texture", "text", "planeOrigin", "planeNormal"]);
835
844
  };
@@ -996,7 +1005,7 @@ function(jQuery, BaseObject, Utilities, PolygonHandler, ModelHandler, THREE, Dec
996
1005
 
997
1006
  SceneBuilder.prototype._getDecalTarget = function(instance) {
998
1007
  if (instance.target) {
999
- var target = this._targets.get(instance.target);
1008
+ var target = this._targets.get(instance.target);
1000
1009
  if (target) {
1001
1010
  if (target.isBox || target.isCylinder) {
1002
1011
  return target.object3D.children[0]; // object3d is a group node, where its first child is actual mesh
@@ -58,7 +58,7 @@ sap.ui.define([
58
58
  *
59
59
  * @private
60
60
  * @author SAP SE
61
- * @version 1.84.8
61
+ * @version 1.84.10
62
62
  * @alias sap.ui.vbm.adapter3d.VBIJSONParser
63
63
  */
64
64
  var VBIJSONParser = BaseObject.extend("sap.ui.vbm.adapter3d.VBIJSONParser", /** @lends sap.ui.vbm.adapter3d.VBIJSONParser.prototype */ {
@@ -11,6 +11,7 @@ VBI.MapManager = (function() {
11
11
  mapmanager.m_tileWidth = 256;
12
12
  mapmanager.m_tileHeight = 256;
13
13
  mapmanager.m_runningRequests = 0;
14
+ mapmanager.m_runningXhrRequests = 0;
14
15
  mapmanager.m_limitRequests = 12;
15
16
  mapmanager.m_requestQueue = [];
16
17
  mapmanager.m_renderQueue = [];
@@ -19,13 +20,37 @@ VBI.MapManager = (function() {
19
20
  mapmanager.m_renderJunksize = 100;
20
21
  // image is loaded
21
22
 
23
+ /**
24
+ * Increments and Decrements counters related to tile download connections
25
+ *
26
+ * @private
27
+ * @param {Image} image - Image object to track counters agains
28
+ * @param {number} factor - A positive or negative integer to be added to the counter
29
+ */
30
+ mapmanager._modifyReqCounters = function(image, factor) {
31
+ if (image.m_Headers) { // if headers presents -> this is xhr request
32
+ mapmanager.m_runningXhrRequests += factor;
33
+ } else {
34
+ mapmanager.m_runningRequests += factor;
35
+ }
36
+ if (VBI.m_bTrace) {
37
+ VBI.Trace("Running Requests - Xhr: " + mapmanager.m_runningXhrRequests + ", src: " + mapmanager.m_runningRequests);
38
+ }
39
+ };
40
+
22
41
  mapmanager.onAbort = function(event) {
23
42
  var image = event.srcElement;
24
43
 
25
44
  if (VBI.m_bTrace) {
26
45
  VBI.Trace("onAbort " + image.src);
27
46
  }
47
+
48
+ //decrement the counters
49
+ mapmanager._modifyReqCounters(image, -1);
50
+
51
+ //trigger more requests if there are some in the queue
28
52
  mapmanager.CheckReqQueue();
53
+
29
54
  // unlink the image from within the image chain
30
55
  mapmanager.UnlinkImage(image);
31
56
  mapmanager.CheckTmpCanvas(image.m_Target, image.m_nRequest, image.m_nLayersAbove);
@@ -35,7 +60,9 @@ VBI.MapManager = (function() {
35
60
  if (VBI.m_bTrace) {
36
61
  VBI.Trace("onFailedSend " + object.src);
37
62
  }
38
- mapmanager.m_runningRequests--;
63
+
64
+ //decrement the counters
65
+ mapmanager._modifyReqCounters(object, -1);
39
66
  mapmanager.m_bRequestError = true;
40
67
 
41
68
  if (!mapmanager.m_failedSendTimer) {
@@ -51,6 +78,9 @@ VBI.MapManager = (function() {
51
78
  if (VBI.m_bTrace) {
52
79
  VBI.Trace("onError " + image.src);
53
80
  }
81
+
82
+ //decrement the counters
83
+ mapmanager._modifyReqCounters(image, -1);
54
84
  mapmanager.CheckReqQueue();
55
85
 
56
86
  var imageRender = null;
@@ -62,8 +92,10 @@ VBI.MapManager = (function() {
62
92
  if (image.m_Prev == null && image.m_Next != null && image.m_Next.complete == true) {
63
93
  imageRender = image.m_Next;
64
94
  }
95
+
65
96
  // unlink the image from within the image chain
66
97
  mapmanager.UnlinkImage(image);
98
+
67
99
  // when the image is the first in current and would be rendered
68
100
  if (imageRender != null) {
69
101
  mapmanager.m_renderQueue.push(imageRender);
@@ -81,9 +113,18 @@ VBI.MapManager = (function() {
81
113
  if (!image.complete) { //skip odd onload event from IE where image is not loaded yet
82
114
  return;
83
115
  }
116
+
117
+ //If the request is xhr then we need to revoke the blob data url once loaded
118
+ if (image.m_Headers) {
119
+ (window.URL || window.webkitURL).revokeObjectURL(image.src);
120
+ }
121
+
84
122
  if (VBI.m_bTrace) {
85
- VBI.Trace("VBI.MapManager: onLoad " + image.src);
123
+ VBI.Trace("VBI.MapManager: onLoad " + (image.m_Headers ? "(xhr) " : " ") + (image.m_Headers ? image.src2execute : image.src));
86
124
  }
125
+
126
+ //decrement the counters
127
+ mapmanager._modifyReqCounters(image, -1);
87
128
  mapmanager.CheckReqQueue();
88
129
 
89
130
  var bChainComplete = true; // I for myself am complete as I am in onLoad.
@@ -111,7 +152,6 @@ VBI.MapManager = (function() {
111
152
  clearInterval(mapmanager.m_failedSendTimer);
112
153
  mapmanager.m_failedSendTimer = 0;
113
154
  mapmanager.m_bRequestError = false;
114
- mapmanager.m_runningRequests++;
115
155
  mapmanager.CheckReqQueue();
116
156
  };
117
157
 
@@ -124,7 +164,14 @@ VBI.MapManager = (function() {
124
164
  mapmanager.CheckTmpCanvas(targetCanvas, image.m_nRequest, image.m_nLayersAbove);
125
165
  } else {
126
166
  try {
127
- image.src = image.src2execute;
167
+ //Check for xhr object and resend if present, otherwise set image src
168
+ if (image.m_Headers) {
169
+ mapmanager._createHttpRequest(image);
170
+ } else {
171
+ mapmanager.m_bRequestError = false;
172
+ mapmanager._modifyReqCounters(image, 1);
173
+ image.src = image.src2execute;
174
+ }
128
175
  } catch (e) {
129
176
  mapmanager.m_requestQueue.unshift(image);
130
177
  mapmanager.onFailedSend(image);
@@ -133,7 +180,6 @@ VBI.MapManager = (function() {
133
180
  }
134
181
  }
135
182
  // no further request to be executed
136
- mapmanager.m_runningRequests--;
137
183
  };
138
184
 
139
185
  mapmanager.RenderTiles = function() {
@@ -146,11 +192,14 @@ VBI.MapManager = (function() {
146
192
 
147
193
  mapmanager.RenderTile = function(image) {
148
194
  if (!image.bRendered) {
195
+
196
+ //get the target canvas reference from the image property and check whether rendering should be redirected to another canvas
149
197
  var targetCanvas = image.m_Target;
150
198
  if ((targetCanvas.m_CanvasRedirect != undefined) && (targetCanvas.m_CanvasRedirRequest == image.m_nRequest)) {
151
199
  targetCanvas = targetCanvas.m_CanvasRedirect;
152
200
  }
153
201
 
202
+ //If the canvas isn't connected to a scene then don't render
154
203
  var currentScene = targetCanvas.m_Scene;
155
204
  if (!currentScene) {
156
205
  return;
@@ -162,16 +211,17 @@ VBI.MapManager = (function() {
162
211
  targetCanvas.m_nAppliedRequest = Math.max(targetCanvas.m_nAppliedRequest, image.m_nRequest);
163
212
  var context = targetCanvas.getContext('2d');
164
213
 
214
+ //Get the maximum number of tiles for the specified zoom level
165
215
  var nMaxX = (1 << context.canvas.m_nCurrentLOD);
166
216
 
217
+ //Calculate whether current image is still visibile for the current canvas
167
218
  var nCol = ((image.m_nReqX - context.canvas.m_nCurrentX) % nMaxX + nMaxX) % nMaxX; // double mod for neg.numbers
168
219
  if (nMaxX < currentScene.m_nTilesX) {
169
220
  nCol = image.m_nCol + image.m_nXOrigin - context.canvas.m_nCurrentX;
170
221
  }
171
-
172
222
  var nRow = image.m_nReqY - context.canvas.m_nCurrentY;
173
223
 
174
- // unlink and return when image request is outdated
224
+ // unlink and return when image request is outdated / would not be visible
175
225
  if (image.m_bOutdated || (nCol < 0) || (nRow < 0) || (nCol >= image.m_numCol) || (nRow >= image.m_numRow) || (image.m_nLOD != targetCanvas.m_nCurrentLOD || targetCanvas.m_bInvalid)) {
176
226
  mapmanager.UnlinkImage(image);
177
227
 
@@ -193,10 +243,15 @@ VBI.MapManager = (function() {
193
243
  targetCanvas.setPixelWidth(nWidth);
194
244
  targetCanvas.setPixelHeight(nHeight);
195
245
 
246
+ //Calculate the current image/tile width relative to the canvas
196
247
  var tilewidth = nWidth / currentScene.m_nTilesX;
197
248
  var tileheight = nHeight / currentScene.m_nTilesY;
249
+
250
+ //Calculate the correct offset for this tile on the current canvas
198
251
  var left = nCol * tilewidth;
199
252
  var top = nRow * tileheight;
253
+
254
+ //Scale the image to canvas if required (e.g. smaller tile / static map image)
200
255
  var picWidth = image.m_nXExpansion * tilewidth;
201
256
  var picHeight = image.m_nYExpansion * tileheight;
202
257
 
@@ -206,6 +261,7 @@ VBI.MapManager = (function() {
206
261
  while (imageTemp.m_Prev != null) {
207
262
  imageTemp = imageTemp.m_Prev;
208
263
  }
264
+
209
265
  while (imageTemp != null && imageTemp.complete == true) {
210
266
  // optional draw the image background into the canvas
211
267
  if (imageTemp.m_FillStyle != null) {
@@ -217,7 +273,8 @@ VBI.MapManager = (function() {
217
273
  context.fillRect(left, top, picWidth, picHeight);
218
274
  context.fillStyle = tmpFillStyle;
219
275
  }
220
- // as soon as an image is rendererd set the parent of the next to null
276
+
277
+ //Draw the image to the canvas with the specified opacity
221
278
  if (VBI.m_bTrace) {
222
279
  VBI.Trace("RenderTile drawImage " + imageTemp.src);
223
280
  }
@@ -226,6 +283,7 @@ VBI.MapManager = (function() {
226
283
  context.drawImage(imageTemp, left, top, picWidth, picHeight);
227
284
  imageTemp.bRendered = true;
228
285
 
286
+ // as soon as an image is rendererd set the parent of the next to null
229
287
  if (imageTemp.m_Next != null) {
230
288
  imageTemp.m_Next.m_Prev = null;
231
289
  }
@@ -258,7 +316,7 @@ VBI.MapManager = (function() {
258
316
  };
259
317
 
260
318
  mapmanager.CheckTmpCanvas = function(targetCanvas, imgRequest, nTilesAbove) {
261
-
319
+ //tries to fill the hidden canvas with tiles before displaying it
262
320
  if ((targetCanvas.m_nTilesBefSwitch != undefined) && (targetCanvas.m_nRequest == imgRequest) && !nTilesAbove) {
263
321
  targetCanvas.m_nTilesBefSwitch--;
264
322
  if (!targetCanvas.m_nTilesBefSwitch) {
@@ -267,6 +325,7 @@ VBI.MapManager = (function() {
267
325
  }
268
326
 
269
327
  };
328
+
270
329
  // request the tiles
271
330
  mapmanager.RequestTiles = function(targetCanvas, maplayerstack, x, y, nx, ny, leftOffset, topOffset, rightOffset, bottomOffset, lod, bclear) {
272
331
  mapmanager.m_bRequestError = false;
@@ -288,6 +347,8 @@ VBI.MapManager = (function() {
288
347
  }
289
348
 
290
349
  var nCount = 0;
350
+
351
+ //Calculate XMax based on the YMax for a given ratio of X->Y for the current projection
291
352
  var nYMax = (1 << lod);
292
353
  var xyRatio = sc.m_Proj.m_nXYRatio;
293
354
  var nXMax = nYMax * xyRatio;
@@ -313,6 +374,7 @@ VBI.MapManager = (function() {
313
374
  var ni, nk, nYExpansion, nCurrentXExpansion = 1;
314
375
  var yCorr = y;
315
376
 
377
+ //future: Adjust logic to account for m_bSingleBMP on maplayer level
316
378
  if (maplayerstack.m_bSingleBMP) {
317
379
  nk = 1;
318
380
  yCorr = Math.max(0, y);
@@ -335,6 +397,7 @@ VBI.MapManager = (function() {
335
397
  if (nReqX < 0) {
336
398
  nReqX = nXMax + nReqX;
337
399
  }
400
+
338
401
  var nReqY = yCorr + topOffset + k;
339
402
  if ((nReqY + nYExpansion) <= 0 || nReqY >= nYMax) {
340
403
  if ((targetCanvas.m_nTilesBefSwitch != undefined) && (targetCanvas.m_nTilesBefSwitch > 0)) {
@@ -396,25 +459,28 @@ VBI.MapManager = (function() {
396
459
  var url;
397
460
 
398
461
  if (mapProv.m_bPosRequired) {
399
- var leftupper = [
400
- nReqX * fTileSize / xyRatio - 1, nReqY * fTileSize - 1
401
- ];
402
- var rightlower = [
403
- (nReqX + nCurrentXExpansion) * fTileSize / xyRatio - 1, (nReqY + nYExpansion) * fTileSize - 1
404
- ];
462
+ var leftupper = [nReqX * fTileSize / xyRatio - 1, nReqY * fTileSize - 1];
463
+ var rightlower = [(nReqX + nCurrentXExpansion) * fTileSize / xyRatio - 1, (nReqY + nYExpansion) * fTileSize - 1];
405
464
  // VBI.Trace("Requesting "+nReqX+","+nReqY+" with Extension "+nCurrentXExpansion+". Coordinates :
406
465
  // "+leftupper[0]+"-->"+rightlower[0]+","+rightlower[1]);
407
466
  url = mapProv.CombineUrlWPos(nReqX, nReqY, lod, fTileSize, leftupper, rightlower, nCurrentXExpansion, nYExpansion, mapmanager.m_requestTileWidth, mapmanager.m_requestTileHeight);
408
467
  } else {
409
468
  url = mapProv.CombineUrl(nReqX, nReqY, lod);
410
469
  }
470
+
411
471
  image.onload = mapmanager.onLoad;
412
472
  image.onerror = mapmanager.onError;
413
473
  image.onabort = mapmanager.onAbort;
414
474
 
415
- if ((mapmanager.m_runningRequests < mapmanager.m_limitRequests) && (!mapmanager.m_bRequestError)) {
416
- mapmanager.m_runningRequests++;
475
+ //If the provider has headers defined, then we must use the HTTP Request approach
476
+ //as it is possible that the application provided an image via the URL callback, we check for a data url before proceeding with the HTTP Request creation
477
+ if (mapProv.m_Headers && url.substring(0, 5).toLowerCase() != "data:") {
478
+ image.m_Headers = mapProv.m_Headers;
479
+ image.src2execute = url; //store the URL in case the request ends up being queued
480
+ mapmanager._createHttpRequest(image);
481
+ } else if ((mapmanager.m_runningRequests < mapmanager.m_limitRequests) && (!mapmanager.m_bRequestError)) { //The request is for a URL only or it is a data URL
417
482
  try {
483
+ mapmanager._modifyReqCounters(image, 1);
418
484
  image.src = url;
419
485
  } catch (e) {
420
486
  image.src2execute = url;
@@ -425,6 +491,7 @@ VBI.MapManager = (function() {
425
491
  image.src2execute = url;
426
492
  mapmanager.m_requestQueue.push(image);
427
493
  }
494
+
428
495
  image.m_nCount = nCount;
429
496
 
430
497
  if (VBI.m_bTrace) {
@@ -466,7 +533,7 @@ VBI.MapManager = (function() {
466
533
 
467
534
  mapmanager.GetPreviewImage = function(lon, lat, lod, maplayerstack, scene, callback) {
468
535
  //extend layer configuration object with preview location object which is {lat, lon, lod}
469
- if (!callback || !maplayerstack || !lon || !lod || !lat || !scene ) { //check that parameters are valid
536
+ if (!callback || !maplayerstack || !lon || !lod || !lat || !scene) { //check that parameters are valid
470
537
  return;
471
538
  }
472
539
 
@@ -478,7 +545,7 @@ VBI.MapManager = (function() {
478
545
  var xyRatio = scene.m_Proj.m_nXYRatio; //ratio from current projection
479
546
  var lodDistance = (1 << lod); //how many tiles on a particular lod?
480
547
  var tileSize = 2.0 / lodDistance; //???
481
- var lonlat = VBI.MathLib.DegToRad([parseFloat(lon),parseFloat(lat)]); //from degrees to radians
548
+ var lonlat = VBI.MathLib.DegToRad([parseFloat(lon), parseFloat(lat)]); //from degrees to radians
482
549
  var uxy = [lodDistance * tileWidth, lodDistance * tileHeight]; //prepare conversion from lat,lon
483
550
  scene.m_Proj.LonLatToUCS(lonlat, uxy); // to User Coordinate System (pixel space of a target lod)
484
551
  var x = Math.floor(uxy[0] / tileWidth); // calculate X tile coordinate
@@ -527,7 +594,7 @@ VBI.MapManager = (function() {
527
594
  var stretchY = canvas.height;
528
595
 
529
596
  // Draw image based on measurments
530
- context.drawImage(this.m_Images[i],clipPosX,clipPosY,clipWidth,clipHeight, offsetX,offsetY, stretchX, stretchY); //draw image to canvas
597
+ context.drawImage(this.m_Images[i], clipPosX, clipPosY, clipWidth, clipHeight, offsetX, offsetY, stretchX, stretchY); //draw image to canvas
531
598
  }
532
599
  }
533
600
  var tileImages = new Image();
@@ -543,6 +610,11 @@ VBI.MapManager = (function() {
543
610
  VBI.Trace("onLoad " + event.target.src);
544
611
  }
545
612
  var image = event.target;
613
+
614
+ //If the request was xhr then we need to revoke the blob data url once loaded
615
+ if (image.m_Headers) {
616
+ (window.URL || window.webkitURL).revokeObjectURL(image.src);
617
+ }
546
618
  image.m_Context.compose();
547
619
  };
548
620
 
@@ -589,12 +661,20 @@ VBI.MapManager = (function() {
589
661
  if (layer.m_fOpacity) {
590
662
  image.m_Opacity = layer.m_fOpacity;
591
663
  }
664
+
592
665
  image.onload = onImageLoad;
593
666
  image.onabort = onImageAbort;
594
667
  image.onerror = onImageError;
595
668
 
596
669
  try {
597
- image.src = url;
670
+ if (provider.m_Headers && url.substring(0, 5).toLowerCase() != "data:") {
671
+ //Handle requests that require headers
672
+ image.m_Headers = provider.m_Headers;
673
+ image.src2execute = url;
674
+ mapmanager._createHttpRequest(image, true);
675
+ } else {
676
+ image.src = url;
677
+ }
598
678
  } catch (ex) {
599
679
  if (VBI.m_bTrace) {
600
680
  VBI.Trace("GetPreviewImage " + ex);
@@ -604,5 +684,93 @@ VBI.MapManager = (function() {
604
684
  }
605
685
  }
606
686
  };
687
+
688
+ /**
689
+ * Helper function used to create and manage HTTP request objects
690
+ *
691
+ * @private
692
+ * @param {Image} image - Image object to use for request
693
+ * @param {boolean} preview - True if image is requested for preview.
694
+ */
695
+ mapmanager._createHttpRequest = function(image, preview) {
696
+ if (preview || mapmanager.m_runningXhrRequests < mapmanager.m_limitRequests) { // 'preview' images are not participated in requests limitation process
697
+ if (!preview) { // modify counter only if it is not a 'preview' image
698
+ mapmanager._modifyReqCounters(image, 1);
699
+ }
700
+ //Make a xhr request promise
701
+ var oXMLHttpRequest = (typeof window.sinon === "object" && window.sinon.xhr && window.sinon.xhr.XMLHttpRequest) ? window.sinon.xhr.XMLHttpRequest : XMLHttpRequest;
702
+ var xhr = new oXMLHttpRequest();
703
+ xhr.m_Image = image;
704
+
705
+ xhr.onerror = function(event) {
706
+ // onerror event caters for events such as CORS errors
707
+ if (this.m_Image && this.m_Image.onerror) {
708
+ this.m_Image.onerror({
709
+ srcElement: this.m_Image, // in case of a normal image
710
+ target: this.m_Image // in case of a 'preview' image
711
+ });
712
+ }
713
+ jQuery.sap.log.error("Download error: " + this.statusText);
714
+ }
715
+
716
+ if (!preview) { // skip for 'preview' images as they cannot be outdated
717
+ //If the mapmanager has decided the image is outdated then abort loading
718
+ xhr.onprogress = function(event) {
719
+ if (this.m_Image && this.m_Image.m_bOutdated) {
720
+ this.abort();
721
+ this.m_Image.onabort({
722
+ srcElement: this.m_Image
723
+ });
724
+ jQuery.sap.log.error("Download error: image outdated");
725
+ }
726
+ }
727
+ }
728
+
729
+ xhr.onload = function(event) {
730
+ // When file is loaded from a Cordova container the status equals 0
731
+ if (this.status === 200 || this.status === 0) {
732
+ var contentType = this.getResponseHeader("Content-Type");
733
+ if (contentType.split("/")[0] == "image") {
734
+ this.m_Image.src = (window.URL || window.webkitURL).createObjectURL(this.response);
735
+ } else {
736
+ this.m_Image.onerror({
737
+ srcElement: this.m_Image, // in case of a normal image
738
+ target: this.m_Image // in case of a 'preview' image
739
+ });
740
+ jQuery.sap.log.error("Download error: image response type expected. Recieved: " + contentType);
741
+ }
742
+ } else {
743
+ // onload event is also called in the case of status code 404 Not Found.
744
+ // This is why we have to check for the right status. If the status is not
745
+ // something that indicates success, we fire the fireItemFailed event.
746
+ if (preview) {
747
+ this.m_Image.onerror({
748
+ target: this.m_Image // in case of a 'preview' image
749
+ });
750
+ } else {
751
+ if (this.m_Image && !this.m_Image.m_bOutdated) {
752
+ mapmanager.m_requestQueue.push(this.m_Image);
753
+ }
754
+ mapmanager.onFailedSend(this.m_Image);
755
+ }
756
+ jQuery.sap.log.error("Download error: " + this.statusText);
757
+ }
758
+ };
759
+
760
+ xhr.open("GET", image.src2execute, true);
761
+
762
+ //Add headers array to the request
763
+ image.m_Headers.forEach(function(header) {
764
+ xhr.setRequestHeader(header.name, header.value);
765
+ });
766
+
767
+ xhr.responseType = "blob";
768
+ xhr.send(null);
769
+ } else {
770
+ mapmanager.m_requestQueue.push(image);
771
+ return;
772
+ }
773
+ };
774
+
607
775
  return mapmanager;
608
776
  })();
@@ -22,14 +22,14 @@ VBI.MapProviders = function() {
22
22
 
23
23
  mapproviders.load = function(dat, ctx) {
24
24
  // load the json delta data............................................//
25
- // todo: do more than only set
25
+ // future: do more than only set
26
26
  if (dat.Set) {
27
27
  var mp;
28
28
 
29
- // todo: refine delta loading
29
+ // future: refine delta loading
30
30
  mapproviders.clear();
31
31
  // load the mapproviders............................................//
32
- // todo: support specialized sets and removes.......................//
32
+ // future: support specialized sets and removes.......................//
33
33
  if (dat.Set.MapProvider) {
34
34
  if (jQuery.type(dat.Set.MapProvider) == 'object') {
35
35
  mp = new VBI.MapProvider();
@@ -67,7 +67,7 @@ VBI.MapProviders = function() {
67
67
  // ...........................................................................//
68
68
  // MapProvider namespace.....................................................//
69
69
 
70
- VBI.MapProvider = function(name, description, copyright, tileX, tileY, minLOD, maxLOD, fillStyle, resolution, projection) {
70
+ VBI.MapProvider = function(name, description, copyright, tileX, tileY, minLOD, maxLOD, fillStyle, resolution, projection, headers) {
71
71
  "use strict";
72
72
  var mapprovider = {};
73
73
  mapprovider.vbiclass = "MapProvider";
@@ -83,6 +83,7 @@ VBI.MapProvider = function(name, description, copyright, tileX, tileY, minLOD, m
83
83
  mapprovider.m_minLOD = typeof minLOD !== 'undefined' ? minLOD : 0;
84
84
  mapprovider.m_nResolution = typeof resolution != 'undefined' ? resolution : 256;
85
85
  mapprovider.m_nProjection = typeof projection != 'undefined' ? projection : 1;
86
+ mapprovider.m_Headers = headers; // Headers can be undefined
86
87
 
87
88
  // set optional background style of map provider..........................//
88
89
  if (fillStyle != null) {
@@ -140,7 +141,7 @@ VBI.MapProvider = function(name, description, copyright, tileX, tileY, minLOD, m
140
141
 
141
142
  mapprovider.load = function(dat) {
142
143
  // load dataprovider attributes........................................//
143
- // todo: add additional attributes
144
+ // future: add additional attributes
144
145
  if (dat.name) {
145
146
  mapprovider.m_Name = dat.name;
146
147
  }
@@ -178,6 +179,17 @@ VBI.MapProvider = function(name, description, copyright, tileX, tileY, minLOD, m
178
179
  mapprovider.m_nProjection = 3;
179
180
  }
180
181
  }
182
+ if (dat.Header) {
183
+ [].concat(dat.Header).forEach(function(header) {
184
+ if (header.name) { // name must not be empty, while value can be empty (HTTP headers spec)
185
+ if (!mapprovider.m_Headers) {
186
+ mapprovider.m_Headers = [];
187
+ }
188
+ mapprovider.m_Headers.push(header);
189
+ }
190
+ });
191
+ }
192
+
181
193
  var mapBase = dat.MapBase;
182
194
  mapprovider.m_StdMapBase = mapprovider.addMapBase(-1, 1, 1, -1, 10);
183
195
  if (dat.MapBase) {
@@ -217,8 +229,8 @@ VBI.MapProvider = function(name, description, copyright, tileX, tileY, minLOD, m
217
229
 
218
230
  var nMax = 1 << lod;
219
231
  // check levels......................................................//
220
- // if( x < 0 || ( y + yExpansion ) <= 0 || ( x >= nMax ) || ( y >= nYMax ) )
221
- // return null;
232
+ // if( x < 0 || ( y + yExpansion ) <= 0 || ( x >= nMax ) || ( y >= nYMax ) )
233
+ // return null;
222
234
  // VBI.Trace("Org on lod "+lod+" : ["+(lu[0]).toFixed(7)+","+(lu[1]).toFixed(7)+"] - ["+(rl[0]).toFixed(7)+","+(rl[1]).toFixed(7)+"]");
223
235
  var nRound = 10;
224
236
  if (mapprovider.m_MapBase) {
@@ -673,18 +673,24 @@ VBI.Scene = function(target) {
673
673
  }
674
674
  // standard case - click on single object
675
675
  if (event.hitTests.length > 0) {
676
- event.hitCached = event.hitTests[0];
677
- var obj = event.hitCached.m_Vo;
678
- delete event.hitTests; //has to be deleted to avoid collecting hits information again
679
- return obj["on" + eventType].call(obj, event);
676
+ event.hitCached = event.hitTests[0]; // cache first hit test
677
+ delete event.hitTests; // has to be deleted to avoid collecting hits information again
678
+ // if there is a VO then pass event to it
679
+ if (event.hitCached.m_Vo) {
680
+ return event.hitCached.m_Vo["on" + eventType].call(event.hitCached.m_Vo, event);
681
+ } else {
682
+ delete event.hitCached; // remove it to keep things going "old" way
683
+ }
684
+ } else {
685
+ return false; // not handled
680
686
  }
681
- } else { // old approach -> process from last to first which corresponds to the rendering order (from topmost to last)
682
- for (var i = scene.m_VOS.length - 1; i >= 0; --i) {
683
- if ((func = scene.m_VOS[i]["on" + eventType]) && typeof (func) == 'function') {
684
- // call the handler with the context set to corresponded visual object
685
- if (func.call(scene.m_VOS[i], event)) {
686
- return true; // handled
687
- }
687
+ }
688
+ // "old" approach -> process from last to first which corresponds to the rendering order (from topmost to last)
689
+ for (var i = scene.m_VOS.length - 1; i >= 0; --i) {
690
+ if ((func = scene.m_VOS[i]["on" + eventType]) && typeof (func) == 'function') {
691
+ // call the handler with the context set to corresponded visual object
692
+ if (func.call(scene.m_VOS[i], event)) {
693
+ return true; // handled
688
694
  }
689
695
  }
690
696
  }
@@ -3352,7 +3358,7 @@ VBI.GeoScene = function(target, mapmanager, maplayerstack) {
3352
3358
  }
3353
3359
  var sCopyright = scene.m_MapLayerStack.GetCopyright();
3354
3360
  if (sCopyright) {
3355
- scene.m_DivCopyright.innerHTML = jQuery.sap.encodeHTML(sCopyright);
3361
+ scene.m_DivCopyright.innerHTML = sCopyright;
3356
3362
  } else {
3357
3363
  scene.m_DivCopyright.style.paddingRight = 0;
3358
3364
  scene.m_DivCopyright.style.paddingLeft = 0;
@@ -1951,6 +1951,11 @@ VBI.Utilities.AssembleCopyrightString = function(Copyright, CopyrightLink, Copyr
1951
1951
  var regex3 = /\{LINK\|([^\}]+)\}/;
1952
1952
 
1953
1953
  if (Copyright) {
1954
+ if (!CopyrightLink && !CopyrightImage) {
1955
+ Copyright = jQuery.sap.encodeHTML(Copyright);
1956
+ }
1957
+ CopyrightLink = CopyrightLink ? jQuery.sap.encodeHTML(CopyrightLink):CopyrightLink;
1958
+ CopyrightImage = CopyrightImage ? jQuery.sap.encodeHTML(CopyrightImage):CopyrightImage;
1954
1959
  var tmp = Copyright.replace(regex1, "<a href='" + CopyrightLink + "'><img src='" + CopyrightImage + "' width='10' height='10' border='none'></a>");
1955
1960
  tmp = tmp.replace(regex2, "<img src='" + CopyrightImage + "' width='10' height='10' border='none' >");
1956
1961
  return tmp.replace(regex3, "<a href='" + CopyrightLink + "'>$1</a>");
@@ -1220,7 +1220,7 @@ VBI.VisualObjects = function() {
1220
1220
  }
1221
1221
  // check for design handle context menu subscription.............//
1222
1222
  var action, actions = scene.m_Ctx.m_Actions;
1223
- if (actions && ocb.m_Design && ocb.m_Handle > -1) {
1223
+ if (actions && ocb.m_Design && (ocb.m_Handle > -1 || ocb.m_Hit === VBI.HTBOX)) {
1224
1224
  // the action is raised whenever a design action has stopped..//
1225
1225
  // for the instanced type.....................................//
1226
1226
  // is it a HandleMoved or a HandleClick action ...............//
@@ -17,7 +17,7 @@ sap.ui.define([
17
17
  * @namespace
18
18
  * @name sap.ui.vbm
19
19
  * @author SAP SE
20
- * @version 1.84.8
20
+ * @version 1.84.10
21
21
  * @public
22
22
  */
23
23
 
@@ -47,7 +47,7 @@ sap.ui.define([
47
47
  "sap.ui.vbm.ClusterBase", "sap.ui.vbm.ClusterTree", "sap.ui.vbm.ClusterGrid", "sap.ui.vbm.ClusterDistance", "sap.ui.vbm.Heatmap",
48
48
  "sap.ui.vbm.HeatPoint", "sap.ui.vbm.ClusterContainer", "sap.ui.vbm.Adapter", "sap.ui.vbm.Adapter3D"
49
49
  ],
50
- version: "1.84.8"
50
+ version: "1.84.10"
51
51
  });
52
52
 
53
53
  jQuery.sap.registerModuleShims({