diff --git a/Source/DataSources/CzmlDataSource.js b/Source/DataSources/CzmlDataSource.js index 64b9c5d83cc4..5c445300d706 100644 --- a/Source/DataSources/CzmlDataSource.js +++ b/Source/DataSources/CzmlDataSource.js @@ -21,12 +21,14 @@ define([ '../Core/HermitePolynomialApproximation', '../Core/isArray', '../Core/Iso8601', + '../Core/joinUrls', '../Core/JulianDate', '../Core/LagrangePolynomialApproximation', '../Core/LinearApproximation', '../Core/loadJson', '../Core/Math', '../Core/NearFarScalar', + '../Core/objectToQuery', '../Core/Quaternion', '../Core/Rectangle', '../Core/ReferenceFrame', @@ -107,12 +109,14 @@ define([ HermitePolynomialApproximation, isArray, Iso8601, + joinUrls, JulianDate, LagrangePolynomialApproximation, LinearApproximation, loadJson, CesiumMath, NearFarScalar, + objectToQuery, Quaternion, Rectangle, ReferenceFrame, @@ -217,7 +221,16 @@ define([ function unwrapUriInterval(czmlInterval, sourceUri) { var result = defaultValue(czmlInterval.uri, czmlInterval); if (defined(sourceUri)) { - result = getAbsoluteUri(result, getAbsoluteUri(sourceUri)); + var uriComponents = sourceUri.split('?'); + var sourceUriPath = uriComponents[0]; + var query = uriComponents[1]; + result = getAbsoluteUri(result, getAbsoluteUri(sourceUriPath)); + + if (defined(query)) { + // Add back the question mark and append to the result + query = '?' + query; + result = joinUrls(result, query, false); + } } return result; } @@ -1892,9 +1905,18 @@ define([ var promise = czml; var sourceUri = options.sourceUri; + var query = options.query; + var queryBlob = defined(query) ? '?' + objectToQuery(query) : ''; + + // If the czml is a URL if (typeof czml === 'string') { - promise = loadJson(czml); sourceUri = defaultValue(sourceUri, czml); + czml = joinUrls(czml, queryBlob, false); + promise = loadJson(czml); + } + + if (defined(sourceUri)) { + sourceUri = joinUrls(sourceUri, queryBlob, false); } DataSource.setLoading(dataSource, true); @@ -1973,6 +1995,7 @@ define([ * @param {String|Object} czml A url or CZML object to be processed. * @param {Object} [options] An object with the following properties: * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links. + * @param {Object} [options.query] Key-value pairs which are appended to all URIs in the CZML. * @returns {Promise.} A promise that resolves to the new instance once the data is processed. */ CzmlDataSource.load = function(czml, options) { diff --git a/Specs/DataSources/CzmlDataSourceSpec.js b/Specs/DataSources/CzmlDataSourceSpec.js index 58f4d10f22ed..5bf2bc771748 100644 --- a/Specs/DataSources/CzmlDataSourceSpec.js +++ b/Specs/DataSources/CzmlDataSourceSpec.js @@ -15,6 +15,7 @@ defineSuite([ 'Core/Iso8601', 'Core/JulianDate', 'Core/loadJson', + 'Core/loadWithXhr', 'Core/Math', 'Core/NearFarScalar', 'Core/Quaternion', @@ -51,6 +52,7 @@ defineSuite([ Iso8601, JulianDate, loadJson, + loadWithXhr, CesiumMath, NearFarScalar, Quaternion, @@ -258,13 +260,13 @@ defineSuite([ it('process loads expected data', function() { var dataSource = new CzmlDataSource(); - dataSource.process(simple, simpleUrl); + dataSource.process(simple); expect(dataSource.entities.values.length).toEqual(10); }); it('process loads data on top of existing', function() { var dataSource = new CzmlDataSource(); - dataSource.process(simple, simpleUrl); + dataSource.process(simple); expect(dataSource.entities.values.length === 10); dataSource.process(vehicle, vehicleUrl); @@ -273,7 +275,7 @@ defineSuite([ it('load replaces data', function() { var dataSource = new CzmlDataSource(); - dataSource.process(simple, simpleUrl); + dataSource.process(simple); expect(dataSource.entities.values.length).toEqual(10); dataSource.load(vehicle, vehicleUrl); @@ -554,6 +556,52 @@ defineSuite([ expect(imageProperty.getValue(JulianDate.fromIso8601('2013-01-01T01:00:00Z'))).toEqual(source + 'image2.png'); }); + it('appends query to all uri', function() { + var source = 'http://some.url.invalid/'; + var packet = { + billboard : { + image : [{ + interval : '2013-01-01T00:00:00Z/2013-01-01T01:00:00Z', + uri : 'image.png' + }, { + interval : '2013-01-01T01:00:00Z/2013-01-01T02:00:00Z', + uri : 'image2.png' + }] + } + }; + + var dataSource = new CzmlDataSource(); + dataSource.load(makePacket(packet), { + sourceUri : source, + query : { + token : 34570, + password : "Passw0rd" + } + }); + var entity = dataSource.entities.values[0]; + var imageProperty = entity.billboard.image; + expect(imageProperty.getValue(JulianDate.fromIso8601('2013-01-01T00:00:00Z'))).toEqual(source + 'image.png' + '?token=34570&password=Passw0rd'); + expect(imageProperty.getValue(JulianDate.fromIso8601('2013-01-01T01:00:00Z'))).toEqual(source + 'image2.png' + '?token=34570&password=Passw0rd'); + }); + + it('appends query tokens to source URL', function() { + var dataSource = new CzmlDataSource(); + var requestNetworkLink = when.defer(); + + spyOn(loadWithXhr, 'load').and.callFake(function(url, responseType, method, data, headers, deferred, overrideMimeType) { + requestNetworkLink.resolve(url); + deferred.reject(); + }); + + dataSource.process(simpleUrl, { query : { + "token" : 30203, + "pass" : "passw0rd" + }}); + return requestNetworkLink.promise.then(function(url) { + expect(url).toEqual(simpleUrl + '?token=30203&pass=passw0rd'); + }); + }); + it('CZML adds data for constrained billboard.', function() { var billboardPacket = { billboard : {