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: + * * @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: + * + * @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",