diff --git a/CHANGES.md b/CHANGES.md
index b6d2e6e60acb..086525c8b090 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -13,6 +13,9 @@ Change Log
### 1.24 - 2016-08-01
* Fixed a crash that would occur when switching to 2D view when shadows are enabled. [#4051](https://github.com/AnalyticalGraphicsInc/cesium/issues/4051)
+* Add the `urlSchemeZeroPadding` property to `UrlTemplateImageryProvider` to allow the numeric parts of the URL, such as `{x}`, to be padded with zeros to make them a fixed width.
+* Updated the online [model converter](http://cesiumjs.org/convertmodel.html) to convert OBJ model to glTF with [obj2gltf](https://github.com/AnalyticalGraphicsInc/OBJ2GLTF), as well as optimize existing glTF models with the [gltf-pipeline](https://github.com/AnalyticalGraphicsInc/gltf-pipeline).
+* Fixed an issue causing entities to disappear when updating multiple entities simultaneously. [#4096](https://github.com/AnalyticalGraphicsInc/cesium/issues/4096)
### 1.23 - 2016-07-01
@@ -31,8 +34,7 @@ Change Log
* Improved performance and accuracy of polygon triangulation by using the [earcut](https://github.com/mapbox/earcut) library. Loading a GeoJSON with polygons for each country was 2x faster.
* Fix some large polygon triangulations. [#2788](https://github.com/AnalyticalGraphicsInc/cesium/issues/2788)
* Added support for the glTF extension [WEB3D_quantized_attributes](https://github.com/KhronosGroup/glTF/blob/master/extensions/Vendor/WEB3D_quantized_attributes/README.md). [#3241](https://github.com/AnalyticalGraphicsInc/cesium/issues/3241)
-* Updated the online [model converter](http://cesiumjs.org/convertmodel.html) to convert OBJ model to glTF with [obj2gltf](https://github.com/AnalyticalGraphicsInc/OBJ2GLTF), as well as optimize existing glTF models with the [gltf-pipeline](https://github.com/AnalyticalGraphicsInc/gltf-pipeline).
-* Added CZML support for `Box`, `Corridor` and `Cylinder`. Added new CZML properties:
+* Added CZML support for `Box`, `Corridor` and `Cylinder`. Added new CZML properties:
* `Billboard`: `width`, `height`, `heightReference`, `scaleByDistance`, `translucencyByDistance`, `pixelOffsetScaleByDistance`, `imageSubRegion`
* `Label`: `heightReference`, `translucencyByDistance`, `pixelOffsetScaleByDistance`
* `Model`: `heightReference`, `maximumScale`
diff --git a/Source/DataSources/StaticGeometryPerMaterialBatch.js b/Source/DataSources/StaticGeometryPerMaterialBatch.js
index 869d18e78eff..817ae04c1421 100644
--- a/Source/DataSources/StaticGeometryPerMaterialBatch.js
+++ b/Source/DataSources/StaticGeometryPerMaterialBatch.js
@@ -68,10 +68,8 @@ define([
Batch.prototype.remove = function(updater) {
var id = updater.entity.id;
- var createPrimitive = this.updaters.remove(id);
-
- if (createPrimitive) {
- this.geometry.remove(id);
+ this.createPrimitive = this.geometry.remove(id) || this.createPrimitive;
+ if (this.updaters.remove(id)) {
this.updatersWithAttributes.remove(id);
var unsubscribe = this.subscriptions.get(id);
if (defined(unsubscribe)) {
@@ -79,8 +77,7 @@ define([
this.subscriptions.remove(id);
}
}
- this.createPrimitive = createPrimitive;
- return createPrimitive;
+ return this.createPrimitive;
};
Batch.prototype.update = function(time) {
diff --git a/Source/Scene/UrlTemplateImageryProvider.js b/Source/Scene/UrlTemplateImageryProvider.js
index 1de2e3154205..99292a3c9f0d 100644
--- a/Source/Scene/UrlTemplateImageryProvider.js
+++ b/Source/Scene/UrlTemplateImageryProvider.js
@@ -91,6 +91,19 @@ define([
*
{latitudeProjected}
: The latitude of the picked position in the projected coordinates of the tiling scheme.
* {format}
: The format in which to get feature information, as specified in the {@link GetFeatureInfoFormat}.
*
+ * @param {Object} [options.urlSchemeZeroPadding] Gets the URL scheme zero padding for each tile coordinate. The format is '000' where
+ * each coordinate will be padded on the left with zeros to match the width of the passed string of zeros. e.g. Setting:
+ * urlSchemeZeroPadding : { '{x}' : '0000'}
+ * will cause an 'x' value of 12 to return the string '0012' for {x} in the generated URL.
+ * It the passed object has the following keywords:
+ *
+ * -
{z}
: The zero padding for the level of the tile in the tiling scheme.
+ * -
{x}
: The zero padding for the tile X coordinate in the tiling scheme.
+ * -
{y}
: The zero padding for the the tile Y coordinate in the tiling scheme.
+ * -
{reverseX}
: The zero padding for the tile reverseX coordinate in the tiling scheme.
+ * -
{reverseY}
: The zero padding for the tile reverseY coordinate in the tiling scheme.
+ * -
{reverseZ}
: The zero padding for the reverseZ coordinate of the tile in the tiling scheme.
+ *
* @param {String|String[]} [options.subdomains='abc'] The subdomains to use for the {s}
placeholder in the URL template.
* If this parameter is a single string, each character in the string is a subdomain. If it is
* an array, each element in the array is a subdomain.
@@ -172,6 +185,7 @@ define([
this._errorEvent = new Event();
this._url = undefined;
+ this._urlSchemeZeroPadding = undefined;
this._pickFeaturesUrl = undefined;
this._proxy = undefined;
this._tileWidth = undefined;
@@ -231,6 +245,31 @@ define([
}
},
+ /**
+ * Gets the URL scheme zero padding for each tile coordinate. The format is '000' where each coordinate will be padded on
+ * the left with zeros to match the width of the passed string of zeros. e.g. Setting:
+ * urlSchemeZeroPadding : { '{x}' : '0000'}
+ * will cause an 'x' value of 12 to return the string '0012' for {x} in the generated URL.
+ * It has the following keywords:
+ *
+ * -
{z}
: The zero padding for the level of the tile in the tiling scheme.
+ * -
{x}
: The zero padding for the tile X coordinate in the tiling scheme.
+ * -
{y}
: The zero padding for the the tile Y coordinate in the tiling scheme.
+ * -
{reverseX}
: The zero padding for the tile reverseX coordinate in the tiling scheme.
+ * -
{reverseY}
: The zero padding for the tile reverseY coordinate in the tiling scheme.
+ * -
{reverseZ}
: The zero padding for the reverseZ coordinate of the tile in the tiling scheme.
+ *
+ * @memberof UrlTemplateImageryProvider.prototype
+ * @type {Object}
+ * @readonly
+ */
+ urlSchemeZeroPadding : {
+ get : function() {
+ return this._urlSchemeZeroPadding;
+ }
+ },
+
+
/**
* Gets the URL template to use to use to pick features. If this property is not specified,
* {@link UrlTemplateImageryProvider#pickFeatures} will immediately returned undefined, indicating no
@@ -504,6 +543,7 @@ define([
//>>includeEnd('debug');
that.enablePickFeatures = defaultValue(properties.enablePickFeatures, that.enablePickFeatures);
that._url = properties.url;
+ that._urlSchemeZeroPadding = defaultValue(properties.urlSchemeZeroPadding, that.urlSchemeZeroPadding);
that._pickFeaturesUrl = properties.pickFeaturesUrl;
that._proxy = properties.proxy;
that._tileDiscardPolicy = properties.tileDiscardPolicy;
@@ -724,29 +764,48 @@ define([
return parts;
}
+ function padWithZerosIfNecessary(imageryProvider, key, value) {
+ if (imageryProvider &&
+ imageryProvider.urlSchemeZeroPadding &&
+ imageryProvider.urlSchemeZeroPadding.hasOwnProperty(key) )
+ {
+ var paddingTemplate = imageryProvider.urlSchemeZeroPadding[key];
+ if (typeof paddingTemplate === 'string') {
+ var paddingTemplateWidth = paddingTemplate.length;
+ if (paddingTemplateWidth > 1) {
+ value = (value.length >= paddingTemplateWidth) ? value : new Array(paddingTemplateWidth - value.toString().length + 1).join('0') + value;
+ }
+ }
+ }
+ return value;
+ }
+
function xTag(imageryProvider, x, y, level) {
- return x;
+ return padWithZerosIfNecessary(imageryProvider, '{x}', x);
}
function reverseXTag(imageryProvider, x, y, level) {
- return imageryProvider.tilingScheme.getNumberOfXTilesAtLevel(level) - x - 1;
+ var reverseX = imageryProvider.tilingScheme.getNumberOfXTilesAtLevel(level) - x - 1;
+ return padWithZerosIfNecessary(imageryProvider, '{reverseX}', reverseX);
}
function yTag(imageryProvider, x, y, level) {
- return y;
+ return padWithZerosIfNecessary(imageryProvider, '{y}', y);
}
function reverseYTag(imageryProvider, x, y, level) {
- return imageryProvider.tilingScheme.getNumberOfYTilesAtLevel(level) - y - 1;
+ var reverseY = imageryProvider.tilingScheme.getNumberOfYTilesAtLevel(level) - y - 1;
+ return padWithZerosIfNecessary(imageryProvider, '{reverseY}', reverseY);
}
function reverseZTag(imageryProvider, x, y, level) {
var maximumLevel = imageryProvider.maximumLevel;
- return defined(maximumLevel) && level < maximumLevel ? maximumLevel - level - 1 : level;
+ var reverseZ = defined(maximumLevel) && level < maximumLevel ? maximumLevel - level - 1 : level;
+ return padWithZerosIfNecessary(imageryProvider, '{reverseZ}', reverseZ);
}
function zTag(imageryProvider, x, y, level) {
- return level;
+ return padWithZerosIfNecessary(imageryProvider, '{z}', level);
}
function sTag(imageryProvider, x, y, level) {
diff --git a/Specs/Scene/UrlTemplateImageryProviderSpec.js b/Specs/Scene/UrlTemplateImageryProviderSpec.js
index c8728f8e8dc9..41b3af874c21 100644
--- a/Specs/Scene/UrlTemplateImageryProviderSpec.js
+++ b/Specs/Scene/UrlTemplateImageryProviderSpec.js
@@ -259,6 +259,93 @@ defineSuite([
});
});
+ it('evaluation of schema zero padding for X Y Z as 0000', function() {
+ var provider = new UrlTemplateImageryProvider({
+ url: 'made/up/tms/server/{z}/{reverseZ}/{reverseY}/{y}/{reverseX}/{x}.PNG',
+ urlSchemeZeroPadding: {
+ '{x}' : '0000',
+ '{y}' : '0000',
+ '{z}' : '0000'
+ },
+ tilingScheme: new GeographicTilingScheme(),
+ maximumLevel: 6
+ });
+
+ return pollToPromise(function() {
+ return provider.ready;
+ }).then(function() {
+ spyOn(loadImage, 'createImage').and.callFake(function(url, crossOrigin, deferred) {
+ expect(url).toEqual('made/up/tms/server/0002/3/2/0001/4/0003.PNG');
+
+ // Just return any old image.
+ loadImage.defaultCreateImage('Data/Images/Red16x16.png', crossOrigin, deferred);
+ });
+
+ return provider.requestImage(3, 1, 2).then(function(image) {
+ expect(loadImage.createImage).toHaveBeenCalled();
+ expect(image).toBeInstanceOf(Image);
+ });
+ });
+ });
+
+ it('evaluation of schema zero padding for reverseX reverseY reverseZ as 0000', function() {
+ var provider = new UrlTemplateImageryProvider({
+ url: 'made/up/tms/server/{z}/{reverseZ}/{reverseY}/{y}/{reverseX}/{x}.PNG',
+ urlSchemeZeroPadding: {
+ '{reverseX}' : '0000',
+ '{reverseY}' : '0000',
+ '{reverseZ}' : '0000'
+ },
+ tilingScheme: new GeographicTilingScheme(),
+ maximumLevel: 6
+ });
+
+ return pollToPromise(function() {
+ return provider.ready;
+ }).then(function() {
+ spyOn(loadImage, 'createImage').and.callFake(function(url, crossOrigin, deferred) {
+ expect(url).toEqual('made/up/tms/server/2/0003/0002/1/0004/3.PNG');
+
+ // Just return any old image.
+ loadImage.defaultCreateImage('Data/Images/Red16x16.png', crossOrigin, deferred);
+ });
+
+ return provider.requestImage(3, 1, 2).then(function(image) {
+ expect(loadImage.createImage).toHaveBeenCalled();
+ expect(image).toBeInstanceOf(Image);
+ });
+ });
+ });
+
+ it('evaluation of schema zero padding for x y z as 0000 and large x and y', function() {
+ var provider = new UrlTemplateImageryProvider({
+ url: 'made/up/tms/server/{z}/{reverseZ}/{reverseY}/{y}/{reverseX}/{x}.PNG',
+ urlSchemeZeroPadding: {
+ '{x}' : '0000',
+ '{y}' : '0000',
+ '{z}' : '0000'
+ },
+ tilingScheme: new GeographicTilingScheme(),
+ maximumLevel: 6
+ });
+
+ return pollToPromise(function() {
+ return provider.ready;
+ }).then(function() {
+ spyOn(loadImage, 'createImage').and.callFake(function(url, crossOrigin, deferred) {
+ expect(url).toEqual('made/up/tms/server/0005/0/21/0010/51/0012.PNG');
+
+ // Just return any old image.
+ loadImage.defaultCreateImage('Data/Images/Red16x16.png', crossOrigin, deferred);
+ });
+
+ return provider.requestImage(12, 10, 5).then(function(image) {
+ expect(loadImage.createImage).toHaveBeenCalled();
+ expect(image).toBeInstanceOf(Image);
+ });
+ });
+ });
+
it('evaluates pattern northDegrees', function() {
var provider = new UrlTemplateImageryProvider({
url: '{northDegrees}',
diff --git a/package.json b/package.json
index 4a3481bb6ea9..1c031c39ed0b 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,7 @@
"bluebird": "3.3.4",
"compressible": "2.0.7",
"compression": "1.6.1",
- "electron-prebuilt": "0.37.2",
+ "electron-prebuilt": "1.2.7",
"event-stream": "3.3.2",
"express": "4.13.4",
"globby": "4.0.0",